Reputation: 11
I'm trying to setup a csproj with assembly info automatically generated from compilation datetime and mercurial revision.
<!-- assembly info -->
<PropertyGroup>
<!-- versioning number: Maj.Min.TimeStamp.Rev -->
<Major>2</Major>
<Minor>90</Minor>
<!-- define Build based on the compilation date: yyddd that sould be integer in [0..65535] -->
<Build>$([System.DateTime]::Now.ToString(`yy`))$([System.DateTime]::Now.DayOfYear.ToString(`000`))</Build>
<Revision>0</Revision>
<Version>$(Major).$(Minor).$(Build)</Version>
<AssemblyVersion>$(Major).$(Minor).$(Build).$(Revision)</AssemblyVersion>
<FileVersion>$(Major).$(Minor).$(Build).$(Revision)</FileVersion>
</PropertyGroup>
<Import Project="..\packages\MSBuild.Mercurial.1.2.1\build\MSBuild.Mercurial.targets" Condition="Exists('..\packages\MSBuild.Mercurial.1.2.1\build\MSBuild.Mercurial.targets')" />
<Target Name="GetHgRev" BeforeTargets="GenerateAssemblyInfo" DependsOnTargets="PrepareForBuild">
<HgVersion LocalPath="$(SolutionDir)" Timeout="5000">
<Output TaskParameter="Revision" PropertyName="Revision" />
</HgVersion>
<Message Text="Last revision from HG: $(Revision)" Importance="High" />
<Message Text="$(Major).$(Minor).$(Build).$(Revision)" Importance="High" />
</Target>
On console output, I get something consistent: 2.90.20160.239 But only $(Build) is properly used in tmp AssemblyInfo.cs, $(Revision) is basically 0.
In previous csproj format (2015), I got the job done with explicit cmd in BeforeBuild target:
<PropertyGroup>
<AssemblyCompany>AAA</AssemblyCompany>
<MyAppName>BBB</MyAppName>
<Major>2</Major>
<Minor>90</Minor>
<Build>0</Build>
<Revision>0</Revision>
</PropertyGroup>
<Target Name="BeforeBuild">
<!-- get the Mercurial revision no -->
<HgVersion LocalPath="$(SolutionDir)" Timeout="5000">
<Output TaskParameter="Revision" PropertyName="Revision" />
</HgVersion>
<Message Text="Last revision from HG: $(Revision), today date $([System.DateTime]::Now.ToString(`yyyy.MM.dd`)) -> $([System.DateTime]::Now.ToString(`yy`))$([System.DateTime]::Now.DayOfYear.ToString(`000`))" Importance="High" />
<!-- define Build based on the compilation date: yyddd that sould be integer in [0..65535] -->
<CreateProperty Value="$([System.DateTime]::Now.ToString(`yy`))$([System.DateTime]::Now.DayOfYear.ToString(`000`))">
<Output PropertyName="Build" TaskParameter="Value" />
</CreateProperty>
<!-- generate version file, i.e. AssemblyInfo.cs used later for compilation -->
<Message Text="Creating Version File: $(Major).$(Minor).$(Build).$(Revision)" Importance="High" />
<AssemblyInfo CodeLanguage="CS" OutputFile=".\Properties\AssemblyInfo.cs" AssemblyTitle="AAA" AssemblyDescription="BBB" AssemblyCompany="$(AssemblyCompany)" AssemblyProduct="CCC" AssemblyCopyright="Copyright © DDD $([System.DateTime]::Now.ToString(`yyyy`))" AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)" AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
</Target>
Would you see any fix to this issue?
New test:
<Import Project="..\packages\MSBuild.Mercurial.1.2.1\build\MSBuild.Mercurial.targets" Condition="Exists('..\packages\MSBuild.Mercurial.1.2.1\build\MSBuild.Mercurial.targets')" />
<Target Name="GetHgRev" BeforeTargets="GenerateAssemblyInfo" DependsOnTargets="PrepareForBuild">
<HgVersion LocalPath="$(SolutionDir)" Timeout="5000">
<Output TaskParameter="Revision" PropertyName="Revision" />
</HgVersion>
<Message Text="Proposed number: $(Major).$(Minor).$(Build).$(Revision)" Importance="High" />
<Message Text="AssemblyVersion before: $(AssemblyVersion)" Importance="High" />
<PropertyGroup>
<AssemblyVersion>$(Major).$(Minor).$(Build).$(Revision)</AssemblyVersion>
</PropertyGroup>
<Message Text="AssemblyVersion after: $(AssemblyVersion)" Importance="High" />
</Target>
Kind regards, Charles
Upvotes: 1
Views: 848
Reputation: 100581
The static portion of a project file (everything outside a <Target>
) is evaluated completely before beginning to run the actual build logic (which is made up by targets).
Properties are like a string-to-string dictionary, so Version
and others will be set to the string values, with $() replacements being evaluated to in the string but not logically preserved.
This means that once the target runs, you will also need to update all the properties you now need to change again (Version
, AssemblyVersion
, FileVersion
etc.). You can do so by adding a <PropertyGroup>
inside the target after the HgVersion
task invocation.
Upvotes: 1