Skip to content

Commit 99df816

Browse files
authored
Merge pull request #329 from qmfrederik/fixes/timestamp
Add a GitCommitDate property to ThisAssembly
2 parents 8f41a0d + 5e08dec commit 99df816

File tree

5 files changed

+96
-1
lines changed

5 files changed

+96
-1
lines changed

src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,18 @@ public async Task AssemblyInfo(bool isVB, bool includeNonVersionAttributes, bool
740740
Assert.Equal(result.AssemblyCopyright, thisAssemblyClass.GetField("AssemblyCopyright", fieldFlags)?.GetValue(null));
741741
Assert.Equal(result.GitCommitId, thisAssemblyClass.GetField("GitCommitId", fieldFlags)?.GetValue(null) ?? string.Empty);
742742

743+
if (gitRepo)
744+
{
745+
Assert.True(long.TryParse(result.GitCommitDateTicks, out _), $"Invalid value for GitCommitDateTicks: '{result.GitCommitDateTicks}'");
746+
DateTimeOffset gitCommitDate = new DateTimeOffset(long.Parse(result.GitCommitDateTicks), TimeSpan.Zero);
747+
Assert.Equal(gitCommitDate, thisAssemblyClass.GetProperty("GitCommitDate", fieldFlags)?.GetValue(null) ?? thisAssemblyClass.GetField("GitCommitDate", fieldFlags)?.GetValue(null) ?? string.Empty);
748+
}
749+
else
750+
{
751+
Assert.Empty(result.GitCommitDateTicks);
752+
Assert.Null(thisAssemblyClass.GetProperty("GitCommitDate", fieldFlags));
753+
}
754+
743755
// Verify that it doesn't have key fields
744756
Assert.Null(thisAssemblyClass.GetField("PublicKey", fieldFlags));
745757
Assert.Null(thisAssemblyClass.GetField("PublicKeyToken", fieldFlags));
@@ -936,6 +948,7 @@ private void AssertStandardProperties(VersionOptions versionOptions, BuildResult
936948
Assert.Equal(idAsVersion.Build.ToString(), buildResult.BuildVersionNumberComponent);
937949
Assert.Equal($"{idAsVersion.Major}.{idAsVersion.Minor}.{idAsVersion.Build}", buildResult.BuildVersionSimple);
938950
Assert.Equal(this.Repo.Head.Commits.First().Id.Sha, buildResult.GitCommitId);
951+
Assert.Equal(this.Repo.Head.Commits.First().Author.When.UtcTicks.ToString(CultureInfo.InvariantCulture), buildResult.GitCommitDateTicks);
939952
Assert.Equal(commitIdShort, buildResult.GitCommitIdShort);
940953
Assert.Equal(versionHeight.ToString(), buildResult.GitVersionHeight);
941954
Assert.Equal($"{version.Major}.{version.Minor}", buildResult.MajorMinorVersion);
@@ -1138,6 +1151,7 @@ internal BuildResults(BuildResult buildResult, IReadOnlyList<BuildEventArgs> log
11381151
public string MajorMinorVersion => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("MajorMinorVersion");
11391152
public string BuildVersionNumberComponent => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("BuildVersionNumberComponent");
11401153
public string GitCommitIdShort => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitCommitIdShort");
1154+
public string GitCommitDateTicks => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitCommitDateTicks");
11411155
public string GitVersionHeight => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("GitVersionHeight");
11421156
public string SemVerBuildSuffix => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("SemVerBuildSuffix");
11431157
public string BuildVersion3Components => this.BuildResult.ProjectStateAfterBuild.GetPropertyValue("BuildVersion3Components");

src/NerdBank.GitVersioning/VersionOracle.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibG
8383
this.VersionOptions = committedVersion ?? workingVersion;
8484

8585
this.GitCommitId = commit?.Id.Sha ?? cloudBuild?.GitCommitId ?? null;
86+
this.GitCommitDate = commit?.Author.When;
8687
this.VersionHeight = CalculateVersionHeight(relativeRepoProjectDirectory, commit, committedVersion, workingVersion);
8788
this.BuildingRef = cloudBuild?.BuildingTag ?? cloudBuild?.BuildingBranch ?? repo?.Head.CanonicalName;
8889

@@ -256,6 +257,11 @@ public IEnumerable<string> BuildMetadataWithCommitId
256257
/// </summary>
257258
public string GitCommitIdShort { get; }
258259

260+
/// <summary>
261+
/// Gets the Git revision control commit date for HEAD (the current source code version).
262+
/// </summary>
263+
public DateTimeOffset? GitCommitDate { get; }
264+
259265
/// <summary>
260266
/// Gets the number of commits in the longest single path between
261267
/// the specified commit and the most distant ancestor (inclusive)

src/Nerdbank.GitVersioning.Tasks/AssemblyVersionInfo.cs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ the code is regenerated.
7171

7272
public string GitCommitId { get; set; }
7373

74+
public string GitCommitDateTicks { get; set; }
75+
7476
#if NET461
7577
public override bool Execute()
7678
{
@@ -123,7 +125,7 @@ private CodeTypeDeclaration CreateThisAssemblyClass()
123125
IsPartial = true,
124126
TypeAttributes = TypeAttributes.NotPublic | TypeAttributes.Sealed,
125127
};
126-
128+
127129
var codeAttributeDeclarationCollection = new CodeAttributeDeclarationCollection();
128130
codeAttributeDeclarationCollection.Add(new CodeAttributeDeclaration("System.CodeDom.Compiler.GeneratedCode",
129131
new CodeAttributeArgument(new CodePrimitiveExpression(GeneratorName)),
@@ -151,6 +153,12 @@ private CodeTypeDeclaration CreateThisAssemblyClass()
151153
{ "AssemblyConfiguration", this.AssemblyConfiguration },
152154
{ "GitCommitId", this.GitCommitId },
153155
}).ToArray());
156+
157+
if (long.TryParse(this.GitCommitDateTicks, out long gitCommitDateTicks))
158+
{
159+
thisAssembly.Members.AddRange(CreateCommitDateProperty(gitCommitDateTicks).ToArray());
160+
}
161+
154162
if (hasKeyInfo)
155163
{
156164
thisAssembly.Members.AddRange(CreateFields(new Dictionary<string, string>
@@ -215,6 +223,38 @@ private static CodeMemberField CreateField(string name, string value)
215223
};
216224
}
217225

226+
private static IEnumerable<CodeTypeMember> CreateCommitDateProperty(long ticks)
227+
{
228+
// internal static System.DateTimeOffset GitCommitDate {{ get; }} = new System.DateTimeOffset({ticks}, System.TimeSpan.Zero);");
229+
yield return new CodeMemberField(typeof(DateTimeOffset), "gitCommitDate")
230+
{
231+
Attributes = MemberAttributes.Private,
232+
InitExpression = new CodeObjectCreateExpression(
233+
typeof(DateTimeOffset),
234+
new CodePrimitiveExpression(ticks),
235+
new CodePropertyReferenceExpression(
236+
new CodeTypeReferenceExpression(typeof(TimeSpan)),
237+
nameof(TimeSpan.Zero)))
238+
};
239+
240+
var property = new CodeMemberProperty()
241+
{
242+
Attributes = MemberAttributes.Assembly,
243+
Type = new CodeTypeReference(typeof(DateTimeOffset)),
244+
Name = "GitCommitDate",
245+
HasGet = true,
246+
HasSet = false,
247+
};
248+
249+
property.GetStatements.Add(
250+
new CodeMethodReturnStatement(
251+
new CodeFieldReferenceExpression(
252+
null,
253+
"gitCommitDate")));
254+
255+
yield return property;
256+
}
257+
218258
private static CodeAttributeDeclaration DeclareAttribute(Type attributeType, params CodeAttributeArgument[] arguments)
219259
{
220260
var assemblyTypeReference = new CodeTypeReference(attributeType);
@@ -325,6 +365,11 @@ private void GenerateThisAssemblyClass()
325365
}
326366
}
327367

368+
if (long.TryParse(this.GitCommitDateTicks, out long gitCommitDateTicks))
369+
{
370+
this.generator.AddCommitDateProperty(gitCommitDateTicks);
371+
}
372+
328373
// These properties should be defined even if they are empty.
329374
this.generator.AddThisAssemblyMember("RootNamespace", this.RootNamespace);
330375

@@ -380,6 +425,8 @@ internal void AddBlankLine()
380425
this.codeBuilder.AppendLine();
381426
}
382427

428+
internal abstract void AddCommitDateProperty(long ticks);
429+
383430
protected void AddCodeComment(string comment, string token)
384431
{
385432
var sr = new StringReader(comment);
@@ -414,6 +461,11 @@ internal override void DeclareAttribute(Type type, string arg)
414461
this.codeBuilder.AppendLine($"[<assembly: {type.FullName}(\"{arg}\")>]");
415462
}
416463

464+
internal override void AddCommitDateProperty(long ticks)
465+
{
466+
this.codeBuilder.AppendLine($" static member internal GitCommitDate = new DateTimeOffset({ticks}, TimeZpan.Zero)");
467+
}
468+
417469
internal override void EndThisAssemblyClass()
418470
{
419471
this.codeBuilder.AppendLine("do()");
@@ -450,6 +502,11 @@ internal override void AddThisAssemblyMember(string name, string value)
450502
this.codeBuilder.AppendLine($" internal const string {name} = \"{value}\";");
451503
}
452504

505+
internal override void AddCommitDateProperty(long ticks)
506+
{
507+
this.codeBuilder.AppendLine($" internal static readonly System.DateTimeOffset GitCommitDate = new System.DateTimeOffset({ticks}, System.TimeSpan.Zero);");
508+
}
509+
453510
internal override void EndThisAssemblyClass()
454511
{
455512
this.codeBuilder.AppendLine("}");
@@ -479,6 +536,11 @@ internal override void AddThisAssemblyMember(string name, string value)
479536
this.codeBuilder.AppendLine($" Friend Const {name} As String = \"{value}\"");
480537
}
481538

539+
internal override void AddCommitDateProperty(long ticks)
540+
{
541+
this.codeBuilder.AppendLine($" Friend Shared ReadOnly GitCommitDate As System.DateTimeOffset = New System.DateTimeOffset({ticks}, System.TimeSpan.Zero)");
542+
}
543+
482544
internal override void EndThisAssemblyClass()
483545
{
484546
this.codeBuilder.AppendLine("End Class");

src/Nerdbank.GitVersioning.Tasks/GetBuildVersion.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,19 @@ public GetBuildVersion()
132132
[Output]
133133
public string GitCommitId { get; private set; }
134134

135+
/// <summary>
136+
/// Gets the first several characters of the Git revision control commit id for HEAD (the current source code version).
137+
/// </summary>
135138
[Output]
136139
public string GitCommitIdShort { get; private set; }
137140

141+
/// <summary>
142+
/// Gets the Git revision control commit date for HEAD (the current source code version), expressed as the number of 100-nanosecond
143+
/// intervals that have elapsed since January 1, 0001 at 00:00:00.000 in the Gregorian calendar.
144+
/// </summary>
145+
[Output]
146+
public string GitCommitDateTicks { get; private set; }
147+
138148
/// <summary>
139149
/// Gets the number of commits in the longest single path between
140150
/// the specified commit and the most distant ancestor (inclusive)
@@ -213,6 +223,7 @@ protected override bool ExecuteInner()
213223
this.PrereleaseVersion = oracle.PrereleaseVersion;
214224
this.GitCommitId = oracle.GitCommitId;
215225
this.GitCommitIdShort = oracle.GitCommitIdShort;
226+
this.GitCommitDateTicks = oracle.GitCommitDate != null ? oracle.GitCommitDate.Value.Ticks.ToString(CultureInfo.InvariantCulture) : null;
216227
this.GitVersionHeight = oracle.VersionHeight;
217228
this.BuildMetadataFragment = oracle.BuildMetadataFragment;
218229
this.CloudBuildNumber = oracle.CloudBuildNumberEnabled ? oracle.CloudBuildNumber : null;

src/Nerdbank.GitVersioning.Tasks/build/Nerdbank.GitVersioning.targets

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
<Output TaskParameter="AssemblyVersion" PropertyName="AssemblyVersion" />
8080
<Output TaskParameter="GitCommitId" PropertyName="GitCommitId" />
8181
<Output TaskParameter="GitCommitIdShort" PropertyName="GitCommitIdShort" />
82+
<Output TaskParameter="GitCommitDateTicks" PropertyName="GitCommitDateTicks" />
8283
<Output TaskParameter="GitVersionHeight" PropertyName="GitVersionHeight" />
8384
<Output TaskParameter="BuildNumber" PropertyName="BuildNumber" />
8485
<Output TaskParameter="BuildNumber" PropertyName="BuildVersionNumberComponent" />
@@ -154,6 +155,7 @@
154155
AssemblyCompany="$(AssemblyCompany)"
155156
AssemblyConfiguration="$(Configuration)"
156157
GitCommitId="$(GitCommitId)"
158+
GitCommitDateTicks="$(GitCommitDateTicks)"
157159
EmitNonVersionCustomAttributes="$(NBGV_EmitNonVersionCustomAttributes)"
158160
/>
159161
<!-- Avoid applying the newly generated AssemblyVersionInfo.cs file to the build

0 commit comments

Comments
 (0)