Skip to content

Commit d9ed2fe

Browse files
authored
Merge pull request #719 from ap0llo/nuget-package-version-precision-setting
Add 'precision' setting for the NuGet package version
2 parents e2795b2 + 65e9b18 commit d9ed2fe

File tree

7 files changed

+262
-11
lines changed

7 files changed

+262
-11
lines changed

doc/versionJson.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ The content of the version.json file is a JSON serialized object with these prop
3939
"gitCommitIdShortAutoMinimum": 0, // optional. Set to use the short commit ID abbreviation provided by the git repository.
4040
"nugetPackageVersion": {
4141
"semVer": 1 // optional. Set to either 1 or 2 to control how the NuGet package version string is generated. Default is 1.
42+
"precision": "build" // optional. Use when you want to use a more or less precise package version than the default major.minor.build.
4243
},
4344
"pathFilters": [
4445
// optional list of paths to consider when calculating version height.

src/NerdBank.GitVersioning.Tests/VersionFileTests.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,38 @@ public void GetVersion_ProducesAbsolutePath()
608608
Assert.True(Path.IsPathRooted(actualDirectory));
609609
}
610610

611+
612+
[Theory]
613+
[InlineData(1)]
614+
[InlineData(2)]
615+
public void GetVersion_ReadNuGetPackageVersionSettings_SemVer(int semVer)
616+
{
617+
var json = $@"{{ ""version"" : ""1.0"", ""nugetPackageVersion"" : {{ ""semVer"" : {semVer} }} }}";
618+
var path = Path.Combine(this.RepoPath, "version.json");
619+
File.WriteAllText(path, json);
620+
621+
var versionOptions = this.Context.VersionFile.GetVersion();
622+
623+
Assert.NotNull(versionOptions.NuGetPackageVersion);
624+
Assert.NotNull(versionOptions.NuGetPackageVersion.SemVer);
625+
Assert.Equal(semVer, versionOptions.NuGetPackageVersion.SemVer);
626+
}
627+
628+
[Theory]
629+
[CombinatorialData]
630+
public void GetVersion_ReadNuGetPackageVersionSettings_Precision(VersionOptions.VersionPrecision precision)
631+
{
632+
var json = $@"{{ ""version"" : ""1.0"", ""nugetPackageVersion"" : {{ ""precision"" : ""{precision}"" }} }}";
633+
var path = Path.Combine(this.RepoPath, "version.json");
634+
File.WriteAllText(path, json);
635+
636+
var versionOptions = this.Context.VersionFile.GetVersion();
637+
638+
Assert.NotNull(versionOptions.NuGetPackageVersion);
639+
Assert.NotNull(versionOptions.NuGetPackageVersion.Precision);
640+
Assert.Equal(precision, versionOptions.NuGetPackageVersion.Precision);
641+
}
642+
611643
private void AssertPathHasVersion(string committish, string absolutePath, VersionOptions expected)
612644
{
613645
var actual = this.GetVersionOptions(absolutePath, committish);

src/NerdBank.GitVersioning.Tests/VersionOptionsTests.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ public void CannotWriteToDefaultInstances()
178178
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.BuildNumberOrDefault.IncludeCommitIdOrDefault.Where = VersionOptions.CloudBuildNumberCommitWhere.BuildMetadata);
179179
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.SetVersionVariables = true);
180180
Assert.Throws<InvalidOperationException>(() => options.NuGetPackageVersionOrDefault.SemVer = 2);
181+
Assert.Throws<InvalidOperationException>(() => options.NuGetPackageVersionOrDefault.Precision = VersionOptions.VersionPrecision.Revision);
181182
Assert.Throws<InvalidOperationException>(() => options.ReleaseOrDefault.BranchName = "BranchName");
182183
Assert.Throws<InvalidOperationException>(() => options.ReleaseOrDefault.VersionIncrement = VersionOptions.ReleaseVersionIncrement.Major);
183184
Assert.Throws<InvalidOperationException>(() => options.ReleaseOrDefault.FirstUnstableTag = "-tag");
@@ -226,4 +227,30 @@ public void ReleaseOptions_Equality()
226227
Assert.NotEqual(ro3, ro5);
227228
Assert.NotEqual(ro5, ro6);
228229
}
230+
231+
[Fact]
232+
public void NuGetPackageVersionOptions_Equality()
233+
{
234+
var npvo1a = new VersionOptions.NuGetPackageVersionOptions { };
235+
var npvo1b = new VersionOptions.NuGetPackageVersionOptions { };
236+
Assert.Equal(npvo1a, npvo1b);
237+
238+
var npvo2a = new VersionOptions.NuGetPackageVersionOptions
239+
{
240+
SemVer = 2
241+
};
242+
Assert.NotEqual(npvo2a, npvo1a);
243+
244+
var npvo3a = new VersionOptions.NuGetPackageVersionOptions
245+
{
246+
Precision = VersionOptions.VersionPrecision.Revision
247+
};
248+
Assert.NotEqual(npvo3a, npvo1a);
249+
250+
var npvo4a = new VersionOptions.NuGetPackageVersionOptions
251+
{
252+
Precision = VersionOptions.VersionPrecision.Build
253+
};
254+
Assert.Equal(npvo4a, npvo1a); // Equal because we haven't changed defaults.
255+
}
229256
}

src/NerdBank.GitVersioning.Tests/VersionOracleTests.cs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,122 @@ public void CanSetSemVer2ForNuGetPackageVersionPublicRelease()
372372
Assert.Equal($"7.8.9-foo.25", oracle.NuGetPackageVersion);
373373
}
374374

375+
[Theory]
376+
//
377+
// SemVer 1
378+
//
379+
// 2 version fields configured in version.json
380+
[InlineData(1, "1.2", VersionOptions.VersionPrecision.Major, "1.0.0")]
381+
[InlineData(1, "1.2", VersionOptions.VersionPrecision.Minor, "1.2.0")]
382+
[InlineData(1, "1.2", VersionOptions.VersionPrecision.Build, "1.2.1")]
383+
[InlineData(1, "1.2", VersionOptions.VersionPrecision.Revision, "1.2.1.<commit>")]
384+
// 2 version fields and a static prerelease tag configured in version.json
385+
[InlineData(1, "1.2-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
386+
[InlineData(1, "1.2-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
387+
[InlineData(1, "1.2-alpha", VersionOptions.VersionPrecision.Build, "1.2.1-alpha")]
388+
[InlineData(1, "1.2-alpha", VersionOptions.VersionPrecision.Revision, "1.2.1.<commit>-alpha")]
389+
// 2 version fields with git height in prerelease tag configured in version.json
390+
[InlineData(1, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha-0001")]
391+
[InlineData(1, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha-0001")]
392+
[InlineData(1, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.0-alpha-0001")]
393+
[InlineData(1, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.0.0-alpha-0001")]
394+
// 3 version fields configured in version.json
395+
[InlineData(1, "1.2.3", VersionOptions.VersionPrecision.Major, "1.0.0")]
396+
[InlineData(1, "1.2.3", VersionOptions.VersionPrecision.Minor, "1.2.0")]
397+
[InlineData(1, "1.2.3", VersionOptions.VersionPrecision.Build, "1.2.3")]
398+
[InlineData(1, "1.2.3", VersionOptions.VersionPrecision.Revision, "1.2.3.1")]
399+
// 3 version fields and a static prerelease tag configured in version.json
400+
[InlineData(1, "1.2.3-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
401+
[InlineData(1, "1.2.3-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
402+
[InlineData(1, "1.2.3-alpha", VersionOptions.VersionPrecision.Build, "1.2.3-alpha")]
403+
[InlineData(1, "1.2.3-alpha", VersionOptions.VersionPrecision.Revision, "1.2.3.1-alpha")]
404+
// 3 version fields with git height in prerelease tag configured in version.json
405+
[InlineData(1, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha-0001")]
406+
[InlineData(1, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha-0001")]
407+
[InlineData(1, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.3-alpha-0001")]
408+
[InlineData(1, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.3.0-alpha-0001")]
409+
// 4 version fields configured in version.json
410+
[InlineData(1, "1.2.3.4", VersionOptions.VersionPrecision.Major, "1.0.0")]
411+
[InlineData(1, "1.2.3.4", VersionOptions.VersionPrecision.Minor, "1.2.0")]
412+
[InlineData(1, "1.2.3.4", VersionOptions.VersionPrecision.Build, "1.2.3")]
413+
[InlineData(1, "1.2.3.4", VersionOptions.VersionPrecision.Revision, "1.2.3.4")]
414+
// 4 version fields and a static prerelease tag configured in version.json
415+
[InlineData(1, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
416+
[InlineData(1, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
417+
[InlineData(1, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Build, "1.2.3-alpha")]
418+
[InlineData(1, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Revision, "1.2.3.4-alpha")]
419+
// 4 version fields with git height in prerelease tag configured in version.json
420+
[InlineData(1, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha-0001")]
421+
[InlineData(1, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha-0001")]
422+
[InlineData(1, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.3-alpha-0001")]
423+
[InlineData(1, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.3.4-alpha-0001")]
424+
//
425+
// SemVer 2
426+
//
427+
// 2 version fields configured in version.json
428+
[InlineData(2, "1.2", VersionOptions.VersionPrecision.Major, "1.0.0")]
429+
[InlineData(2, "1.2", VersionOptions.VersionPrecision.Minor, "1.2.0")]
430+
[InlineData(2, "1.2", VersionOptions.VersionPrecision.Build, "1.2.1")]
431+
[InlineData(2, "1.2", VersionOptions.VersionPrecision.Revision, "1.2.1.<commit>")]
432+
// 2 version fields and a static prerelease tag configured in version.json
433+
[InlineData(2, "1.2-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
434+
[InlineData(2, "1.2-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
435+
[InlineData(2, "1.2-alpha", VersionOptions.VersionPrecision.Build, "1.2.1-alpha")]
436+
[InlineData(2, "1.2-alpha", VersionOptions.VersionPrecision.Revision, "1.2.1.<commit>-alpha")]
437+
// 2 version fields with git height in prerelease tag configured in version.json
438+
[InlineData(2, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha.1")]
439+
[InlineData(2, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha.1")]
440+
[InlineData(2, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.0-alpha.1")]
441+
[InlineData(2, "1.2-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.0.0-alpha.1")]
442+
// 3 version fields configured in version.json
443+
[InlineData(2, "1.2.3", VersionOptions.VersionPrecision.Major, "1.0.0")]
444+
[InlineData(2, "1.2.3", VersionOptions.VersionPrecision.Minor, "1.2.0")]
445+
[InlineData(2, "1.2.3", VersionOptions.VersionPrecision.Build, "1.2.3")]
446+
[InlineData(2, "1.2.3", VersionOptions.VersionPrecision.Revision, "1.2.3.1")]
447+
// 3 version fields and a static prerelease tag configured in version.json
448+
[InlineData(2, "1.2.3-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
449+
[InlineData(2, "1.2.3-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
450+
[InlineData(2, "1.2.3-alpha", VersionOptions.VersionPrecision.Build, "1.2.3-alpha")]
451+
[InlineData(2, "1.2.3-alpha", VersionOptions.VersionPrecision.Revision, "1.2.3.1-alpha")]
452+
// 3 version fields with git height in prerelease tag configured in version.json
453+
[InlineData(2, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha.1")]
454+
[InlineData(2, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha.1")]
455+
[InlineData(2, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.3-alpha.1")]
456+
[InlineData(2, "1.2.3-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.3.0-alpha.1")]
457+
// 4 version fields configured in version.json
458+
[InlineData(2, "1.2.3.4", VersionOptions.VersionPrecision.Major, "1.0.0")]
459+
[InlineData(2, "1.2.3.4", VersionOptions.VersionPrecision.Minor, "1.2.0")]
460+
[InlineData(2, "1.2.3.4", VersionOptions.VersionPrecision.Build, "1.2.3")]
461+
[InlineData(2, "1.2.3.4", VersionOptions.VersionPrecision.Revision, "1.2.3.4")]
462+
// 4 version fields and a static prerelease tag configured in version.json
463+
[InlineData(2, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Major, "1.0.0-alpha")]
464+
[InlineData(2, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha")]
465+
[InlineData(2, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Build, "1.2.3-alpha")]
466+
[InlineData(2, "1.2.3.4-alpha", VersionOptions.VersionPrecision.Revision, "1.2.3.4-alpha")]
467+
// 4 version fields with git height in prerelease tag configured in version.json
468+
[InlineData(2, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Major, "1.0.0-alpha.1")]
469+
[InlineData(2, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Minor, "1.2.0-alpha.1")]
470+
[InlineData(2, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Build, "1.2.3-alpha.1")]
471+
[InlineData(2, "1.2.3.4-alpha.{height}", VersionOptions.VersionPrecision.Revision, "1.2.3.4-alpha.1")]
472+
public void CanSetPrecisionForNuGetPackageVersion(int semVer, string version, VersionOptions.VersionPrecision precision, string expectedPackageVersion)
473+
{
474+
VersionOptions workingCopyVersion = new VersionOptions
475+
{
476+
Version = SemanticVersion.Parse(version),
477+
NuGetPackageVersion = new VersionOptions.NuGetPackageVersionOptions
478+
{
479+
SemVer = semVer,
480+
Precision = precision
481+
}
482+
};
483+
this.WriteVersionFile(workingCopyVersion);
484+
this.InitializeSourceControl();
485+
var oracle = new VersionOracle(this.Context);
486+
oracle.PublicRelease = true;
487+
expectedPackageVersion = expectedPackageVersion.Replace("<commit>", oracle.Version.Revision.ToString());
488+
Assert.Equal(expectedPackageVersion, oracle.NuGetPackageVersion);
489+
}
490+
375491
[Fact]
376492
public void CanSetSemVer2ForNuGetPackageVersionNonPublicRelease()
377493
{

src/NerdBank.GitVersioning/VersionOptions.cs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ public class NuGetPackageVersionOptions : IEquatable<NuGetPackageVersionOptions>
584584
{
585585
isFrozen = true,
586586
semVer = 1.0f,
587+
precision = DefaultPrecision,
587588
};
588589

589590
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
@@ -592,6 +593,14 @@ public class NuGetPackageVersionOptions : IEquatable<NuGetPackageVersionOptions>
592593
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
593594
private float? semVer;
594595

596+
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
597+
private VersionPrecision? precision;
598+
599+
/// <summary>
600+
/// Default value for <see cref="Precision"/>.
601+
/// </summary>
602+
public const VersionPrecision DefaultPrecision = VersionPrecision.Build;
603+
595604
/// <summary>
596605
/// Initializes a new instance of the <see cref="NuGetPackageVersionOptions" /> class.
597606
/// </summary>
@@ -623,6 +632,22 @@ public float? SemVer
623632
[JsonIgnore]
624633
public float? SemVerOrDefault => this.SemVer ?? DefaultInstance.SemVer;
625634

635+
/// <summary>
636+
/// Gets or sets number of version components to include when generating the package version.
637+
/// </summary>
638+
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
639+
public VersionPrecision? Precision
640+
{
641+
get => this.precision;
642+
set => this.SetIfNotReadOnly(ref this.precision, value);
643+
}
644+
645+
/// <summary>
646+
/// Gets the number of version components to include when generating the package version.
647+
/// </summary>
648+
[JsonIgnore]
649+
public VersionPrecision PrecisionOrDefault => this.Precision ?? DefaultInstance.Precision!.Value;
650+
626651
/// <summary>
627652
/// Gets a value indicating whether this instance rejects all attempts to mutate it.
628653
/// </summary>
@@ -679,13 +704,22 @@ public bool Equals(NuGetPackageVersionOptions? x, NuGetPackageVersionOptions? y)
679704
return false;
680705
}
681706

682-
return x.SemVerOrDefault == y.SemVerOrDefault;
707+
return x.SemVerOrDefault == y.SemVerOrDefault &&
708+
x.PrecisionOrDefault == y.PrecisionOrDefault;
683709
}
684710

685711
/// <inheritdoc />
686712
public int GetHashCode(NuGetPackageVersionOptions? obj)
687713
{
688-
return obj?.SemVerOrDefault.GetHashCode() ?? 0;
714+
if (obj is null)
715+
return 0;
716+
717+
unchecked
718+
{
719+
var hash = obj.SemVerOrDefault.GetHashCode() * 397;
720+
hash ^= obj.PrecisionOrDefault.GetHashCode();
721+
return hash;
722+
}
689723
}
690724
}
691725
}

0 commit comments

Comments
 (0)