我需要nuget pack
生成一个只有3位数的包版本(我们希望对其进行语义版本控制)但是当我在csproj上调用它时,{c <1}}属性设置为&# 34; 1.0.0&#34;,生成的nupkg文件以版本&#34; 1.0.0.0&#34;结尾在其中的元数据(和文件名)。为什么命令行工具不支持AssemblyVersion
属性中指定的位数?
我是通过调用AssemblyVersion
对csproj文件启动的,它生成了一个这样的存根nuspec文件(它实际上包含了带有占位符值的更多标签,但是我已经删除了它们,因为我们没有&# 39;不需要他们):
nuget spec
在TFS中将此nuspec文件与csproj文件放在同一文件夹中,我们现在可以像这样调用pack:
<?xml version="1.0"?>
<package >
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$title$</title>
<authors>$author$</authors>
<owners>$author$</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>$description$</description>
<releaseNotes>Release notes.</releaseNotes>
<copyright>Copyright 2015</copyright>
</metadata>
</package>
项目的AssemblyInfo.cs文件包含一行显式设置版本:
nuget pack MyProject.csproj
除了工具在检索装配版本时使用4位数这一事实外,所有工作都完美无缺。当我右键单击文件浏览器上的dll并转到详细信息时,甚至Windows显示只有3位数的版本。为什么NuGet使用4位数字?我可能错过了一些明显的东西吗?
在nuspec中对版本进行硬编码显然不是理想的,因为那时我们必须将版本号保持在两个不同的位置,而它们的目的始终是相同的。我的意思是,这应该是特殊占位符值[assembly: AssemblyVersion("1.0.0")]
背后的想法,NuGet本身知道如何从项目中提取。
答案 0 :(得分:9)
在Creating and Publishing a Package中,声明NuGet在使用令牌AssemblyVersionAttribute
时使用$version$
属性。
深入研究NuGet源代码,我发现它并不像人们想象的那样直截了当。
NuGet使用反射来获取您图书馆的版本。确切地说AssemblyName.Version
。由于版本的所有组件必须是大于或等于零的整数(请参阅AssemblyName.Version),因此提供的版本为1.0.0.0(在您的情况下)而不是AssemblyVersion
中声明的1.0.0属性。
可能的解决方案
Nuspec Reference页面会在$version$
令牌旁边添加更多信息。它提到AssemblyInformationalVersionAttribute
属性优先于AssemblyVersionAttribute
。使用它将解决您的问题。
深入挖掘
你可能想知道为什么AssemblyInformationalVersionAttribute
会工作而AssemblyVersionAttribute
赢了?
该问题的答案是NuGet使用CustomAttributeData.GetCustomAttributes(Assembly)
函数在使用Assembly.Version之前检索库的属性。上述函数不会列出AssemblyVersionAttribute
,但如果在程序集中使用它,它将列出AssemblyInformationalVersionAttribute
。
只有这样,如果找不到AssemblyInformationalVersionAttribute,将使用Assembly.Version。
编辑:
相关NuGet源代码:
NuGet使用以下代码获取程序集版本(如果找不到AssemblyInformationalVersionAttribute):
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(path);
AssemblyName assemblyName = assembly.GetName();
...
version = new SemanticVersion(assemblyName.Version);
问题始于assembly.GetName(),因为它创建并使用相关参数(包括版本)初始化AssemblyName。
(该代码可以在public AssemblyMetadata GetMetadata(string path)
类{{1}}下的{{1}}类中找到。)
答案 1 :(得分:1)
进入同样的问题并使用&#34; -version&#34;解决它。 nuget的属性。它会覆盖nuspec文件中的版本。非常适用于语义版本控制。
基于以上所述,我猜测在讨论开始时它是不可用的。
答案 2 :(得分:1)
NuGet似乎使用[assembly: AssemblyInformationalVersion()]
作为版本,而不是AssemblyVersion
或AssemblyFileVersion
将AssemblyInformationalVersion
设置为2或3个组件,nuget将按照您指定的方式将其打包
我还将AssemblyVersion
设置为某个自动递增的内容,因为.NET
使用它并且根据我的MSBuild
体验它更安全强迫它一直认为版本改变,所以它不会试图聪明一点
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyInformationalVersion("1.0")]
结果
Project.1.0.nupkg
包含
Project.dll
包含元数据(由ILSpy报告)..., Version=1.0.6246.25505, Culture=neutral, PublicKeyToken=null...
所以你得到了很好的nuget版本和傻瓜证明程序集版本(如果软件包版本保持不变,那么在构建过程中总是会改变所以没有奇怪的缓存,比如本地测试)