Skip to content

Commit

Permalink
Merge pull request #154 from AArnott/fix145
Browse files Browse the repository at this point in the history
Add option for version.json to derive from parents folders
  • Loading branch information
AArnott authored Nov 23, 2017
2 parents 72a18cd + 9cff862 commit 771bb84
Show file tree
Hide file tree
Showing 14 changed files with 1,001 additions and 334 deletions.
18 changes: 9 additions & 9 deletions src/NerdBank.GitVersioning.Tests/BuildIntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ private void AssertStandardProperties(VersionOptions versionOptions, BuildResult
Assert.Equal(expectedBuildMetadata, buildResult.SemVerBuildSuffix);

// NuGet is now SemVer 2.0 and will pass additional build metadata if provided
bool semVer2 = (versionOptions?.NuGetPackageVersion ?? VersionOptions.NuGetPackageVersionOptions.DefaultInstance).SemVer == 2;
bool semVer2 = versionOptions?.NuGetPackageVersionOrDefault.SemVer == 2;
string pkgVersionSuffix = buildResult.PublicRelease ? string.Empty : $"-g{commitIdShort}";
if (semVer2)
{
Expand All @@ -935,19 +935,19 @@ private void AssertStandardProperties(VersionOptions versionOptions, BuildResult

Assert.Equal($"{idAsVersion.Major}.{idAsVersion.Minor}.{idAsVersion.Build}{GetSemVerAppropriatePrereleaseTag(versionOptions)}{pkgVersionSuffix}", buildResult.NuGetPackageVersion);

var buildNumberOptions = versionOptions.CloudBuild?.BuildNumber ?? new VersionOptions.CloudBuildNumberOptions();
if (buildNumberOptions.Enabled)
var buildNumberOptions = versionOptions.CloudBuildOrDefault.BuildNumberOrDefault;
if (buildNumberOptions.EnabledOrDefault)
{
var commitIdOptions = buildNumberOptions.IncludeCommitId ?? new VersionOptions.CloudBuildNumberCommitIdOptions();
var commitIdOptions = buildNumberOptions.IncludeCommitIdOrDefault;
var buildNumberSemVer = SemanticVersion.Parse(buildResult.CloudBuildNumber);
bool hasCommitData = commitIdOptions.When == VersionOptions.CloudBuildNumberCommitWhen.Always
|| (commitIdOptions.When == VersionOptions.CloudBuildNumberCommitWhen.NonPublicReleaseOnly && !buildResult.PublicRelease);
Version expectedVersion = hasCommitData && commitIdOptions.Where == VersionOptions.CloudBuildNumberCommitWhere.FourthVersionComponent
bool hasCommitData = commitIdOptions.WhenOrDefault == VersionOptions.CloudBuildNumberCommitWhen.Always
|| (commitIdOptions.WhenOrDefault == VersionOptions.CloudBuildNumberCommitWhen.NonPublicReleaseOnly && !buildResult.PublicRelease);
Version expectedVersion = hasCommitData && commitIdOptions.WhereOrDefault == VersionOptions.CloudBuildNumberCommitWhere.FourthVersionComponent
? idAsVersion
: new Version(version.Major, version.Minor, version.Build);
Assert.Equal(expectedVersion, buildNumberSemVer.Version);
Assert.Equal(buildResult.PrereleaseVersion, buildNumberSemVer.Prerelease);
string expectedBuildNumberMetadata = hasCommitData && commitIdOptions.Where == VersionOptions.CloudBuildNumberCommitWhere.BuildMetadata
string expectedBuildNumberMetadata = hasCommitData && commitIdOptions.WhereOrDefault == VersionOptions.CloudBuildNumberCommitWhere.BuildMetadata
? $"+g{commitIdShort}"
: string.Empty;
if (additionalBuildMetadata.Any())
Expand All @@ -967,7 +967,7 @@ private void AssertStandardProperties(VersionOptions versionOptions, BuildResult

private static string GetSemVerAppropriatePrereleaseTag(VersionOptions versionOptions)
{
return (versionOptions.NuGetPackageVersion ?? VersionOptions.NuGetPackageVersionOptions.DefaultInstance).SemVer == 1
return versionOptions.NuGetPackageVersionOrDefault.SemVer == 1
? versionOptions.Version.Prerelease?.Replace('.', '-')
: versionOptions.Version.Prerelease;
}
Expand Down
40 changes: 27 additions & 13 deletions src/NerdBank.GitVersioning.Tests/RepoTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,14 @@

public abstract class RepoTestBase : IDisposable
{
private readonly List<string> repoDirectories = new List<string>();

public RepoTestBase(ITestOutputHelper logger)
{
Requires.NotNull(logger, nameof(logger));

this.Logger = logger;
do
{
this.RepoPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
} while (Directory.Exists(this.RepoPath));
Directory.CreateDirectory(this.RepoPath);
this.RepoPath = this.CreateDirectoryForNewRepo();
}

protected ITestOutputHelper Logger { get; }
Expand All @@ -39,18 +37,34 @@ public void Dispose()
GC.SuppressFinalize(this);
}

protected string CreateDirectoryForNewRepo()
{
string repoPath;
do
{
repoPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
} while (Directory.Exists(repoPath));
Directory.CreateDirectory(repoPath);

this.repoDirectories.Add(repoPath);
return repoPath;
}

protected virtual void Dispose(bool disposing)
{
if (disposing)
{
this.Repo?.Dispose();
try
{
TestUtilities.DeleteDirectory(this.RepoPath);
}
catch (IOException)
foreach (string dir in this.repoDirectories)
{
// This happens in AppVeyor a lot.
try
{
TestUtilities.DeleteDirectory(dir);
}
catch (IOException)
{
// This happens in AppVeyor a lot.
}
}
}
}
Expand Down Expand Up @@ -107,7 +121,7 @@ protected Commit WriteVersionFile(VersionOptions versionData, string relativeDir
}

string versionFilePath = VersionFile.SetVersion(Path.Combine(this.RepoPath, relativeDirectory), versionData);
return this.CommitVersionFile(versionFilePath, versionData.Version.ToString());
return this.CommitVersionFile(versionFilePath, versionData.Version?.ToString());
}

protected Commit CommitVersionFile(string versionFilePath, string version)
Expand All @@ -129,7 +143,7 @@ protected Commit CommitVersionFile(string versionFilePath, string version)
}
}

return this.Repo.Commit($"Add/write {relativeFilePath} set to {version}", this.Signer, this.Signer, new CommitOptions { AllowEmptyCommit = true });
return this.Repo.Commit($"Add/write {relativeFilePath} set to {version ?? "Inherited"}", this.Signer, this.Signer, new CommitOptions { AllowEmptyCommit = true });
}

return null;
Expand Down
144 changes: 135 additions & 9 deletions src/NerdBank.GitVersioning.Tests/VersionFileTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ public void GetVersion_JsonCompatibility(string version, string assemblyVersion,
Assert.NotNull(options);
Assert.Equal(version, options.Version?.ToString());
Assert.Equal(assemblyVersion, options.AssemblyVersion?.Version?.ToString());
Assert.Equal(precision, options.AssemblyVersion?.Precision);
Assert.Equal(buildNumberOffset, options.BuildNumberOffset);
Assert.Equal(precision, options.AssemblyVersion?.PrecisionOrDefault);
Assert.Equal(buildNumberOffset, options.BuildNumberOffsetOrDefault);
Assert.Equal(publicReleaseRefSpec, options.PublicReleaseRefSpec);
}

Expand All @@ -114,17 +114,19 @@ public void SetVersion_GetVersionFromFile(string expectedVersion, string expecte
}

[Theory]
[InlineData("2.3", null, VersionOptions.VersionPrecision.Minor, 0, @"{""version"":""2.3""}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Minor, 0, @"{""version"":""2.3"",""assemblyVersion"":""2.2""}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Minor, -1, @"{""version"":""2.3"",""assemblyVersion"":""2.2"",""buildNumberOffset"":-1}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Revision, -1, @"{""version"":""2.3"",""assemblyVersion"":{""version"":""2.2"",""precision"":""revision""},""buildNumberOffset"":-1}")]
public void SetVersion_WritesSimplestFile(string version, string assemblyVersion, VersionOptions.VersionPrecision precision, int buildNumberOffset, string expectedJson)
[InlineData("2.3", null, VersionOptions.VersionPrecision.Minor, 0, false, @"{""version"":""2.3""}")]
[InlineData("2.3", null, VersionOptions.VersionPrecision.Minor, null, true, @"{""version"":""2.3"",""assemblyVersion"":{""precision"":""minor""},""inherit"":true}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Minor, 0, false, @"{""version"":""2.3"",""assemblyVersion"":""2.2""}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Minor, -1, false, @"{""version"":""2.3"",""assemblyVersion"":""2.2"",""buildNumberOffset"":-1}")]
[InlineData("2.3", "2.2", VersionOptions.VersionPrecision.Revision, -1, false, @"{""version"":""2.3"",""assemblyVersion"":{""version"":""2.2"",""precision"":""revision""},""buildNumberOffset"":-1}")]
public void SetVersion_WritesSimplestFile(string version, string assemblyVersion, VersionOptions.VersionPrecision? precision, int? buildNumberOffset, bool inherit, string expectedJson)
{
var versionOptions = new VersionOptions
{
Version = SemanticVersion.Parse(version),
AssemblyVersion = new VersionOptions.AssemblyVersionOptions(assemblyVersion != null ? new Version(assemblyVersion) : null, precision),
AssemblyVersion = assemblyVersion != null || precision != null ? new VersionOptions.AssemblyVersionOptions(assemblyVersion != null ? new Version(assemblyVersion) : null, precision) : null,
BuildNumberOffset = buildNumberOffset,
Inherit = inherit,
};
string pathWritten = VersionFile.SetVersion(this.RepoPath, versionOptions);
string actualFileContent = File.ReadAllText(pathWritten);
Expand All @@ -142,7 +144,7 @@ public void SetVersion_WritesSimplestFile(string version, string assemblyVersion
[InlineData(@"{""cloudBuild"":{""setVersionVariables"":true}}", @"{}")]
public void JsonMinification(string full, string minimal)
{
var settings = VersionOptions.JsonSettings;
var settings = VersionOptions.GetJsonSettings();
settings.Formatting = Formatting.None;

// Assert that the two representations are equivalent.
Expand Down Expand Up @@ -271,6 +273,130 @@ public void GetVersion_String_MissingFile()
Assert.Null(VersionFile.GetVersion(this.RepoPath));
}

[Fact]
public void VersionJson_InheritButNoParentFileFound()
{
this.InitializeSourceControl();
this.WriteVersionFile(
new VersionOptions
{
Inherit = true,
Version = SemanticVersion.Parse("14.2"),
});
Assert.Throws<InvalidOperationException>(() => VersionFile.GetVersion(this.Repo));
}

[Fact]
public void VersionJson_DoNotInheritButNoVersionSpecified()
{
this.InitializeSourceControl();
Assert.Throws<ArgumentException>(() => this.WriteVersionFile(
new VersionOptions
{
Inherit = false,
}));
}

[Theory]
[InlineData(false, false)]
[InlineData(true, false)]
[InlineData(true, true)]
public void VersionJson_Inheritance(bool commitInSourceControl, bool bareRepo)
{
if (commitInSourceControl)
{
this.InitializeSourceControl();
}

VersionOptions level1, level2, level3, level2NoInherit, level2InheritButResetVersion;
this.WriteVersionFile(
level1 = new VersionOptions
{
Version = SemanticVersion.Parse("14.2"),
AssemblyVersion = new VersionOptions.AssemblyVersionOptions { Precision = VersionOptions.VersionPrecision.Major },
});
this.WriteVersionFile(
level2 = new VersionOptions
{
Inherit = true,
AssemblyVersion = new VersionOptions.AssemblyVersionOptions { Precision = VersionOptions.VersionPrecision.Minor },
},
"foo");
this.WriteVersionFile(
level3 = new VersionOptions
{
Inherit = true,
BuildNumberOffset = 1,
},
@"foo\bar");
this.WriteVersionFile(
level2NoInherit = new VersionOptions
{
Version = SemanticVersion.Parse("10.1"),
},
@"noInherit");
this.WriteVersionFile(
level2InheritButResetVersion = new VersionOptions
{
Inherit = true,
Version = SemanticVersion.Parse("8.2"),
},
@"inheritWithVersion");

Repository operatingRepo = this.Repo;
if (bareRepo)
{
operatingRepo = new Repository(
Repository.Clone(this.RepoPath, CreateDirectoryForNewRepo(), new CloneOptions { IsBare = true }));
}

using (operatingRepo)
{
VersionOptions GetOption(string path) => commitInSourceControl ? VersionFile.GetVersion(operatingRepo, path) : VersionFile.GetVersion(Path.Combine(this.RepoPath, path));

var level1Options = GetOption(string.Empty);
Assert.False(level1Options.Inherit);

var level2Options = GetOption("foo");
Assert.Equal(level1.Version.Version.Major, level2Options.Version.Version.Major);
Assert.Equal(level1.Version.Version.Minor, level2Options.Version.Version.Minor);
Assert.Equal(level2.AssemblyVersion.Precision, level2Options.AssemblyVersion.Precision);
Assert.True(level2Options.Inherit);

var level3Options = GetOption(@"foo\bar");
Assert.Equal(level1.Version.Version.Major, level3Options.Version.Version.Major);
Assert.Equal(level1.Version.Version.Minor, level3Options.Version.Version.Minor);
Assert.Equal(level2.AssemblyVersion.Precision, level3Options.AssemblyVersion.Precision);
Assert.Equal(level2.AssemblyVersion.Precision, level3Options.AssemblyVersion.Precision);
Assert.Equal(level3.BuildNumberOffset, level3Options.BuildNumberOffset);
Assert.True(level3Options.Inherit);

var level2NoInheritOptions = GetOption("noInherit");
Assert.Equal(level2NoInherit.Version, level2NoInheritOptions.Version);
Assert.Equal(VersionOptions.DefaultVersionPrecision, level2NoInheritOptions.AssemblyVersionOrDefault.PrecisionOrDefault);
Assert.False(level2NoInheritOptions.Inherit);

var level2InheritButResetVersionOptions = GetOption("inheritWithVersion");
Assert.Equal(level2InheritButResetVersion.Version, level2InheritButResetVersionOptions.Version);
Assert.True(level2InheritButResetVersionOptions.Inherit);

if (commitInSourceControl)
{
int totalCommits = operatingRepo.Head.Commits.Count();

// The version height should be the same for all those that inherit the version from the base,
// even though the inheriting files were introduced in successive commits.
Assert.Equal(totalCommits, operatingRepo.GetVersionHeight());
Assert.Equal(totalCommits, operatingRepo.GetVersionHeight("foo"));
Assert.Equal(totalCommits, operatingRepo.GetVersionHeight(@"foo\bar"));

// These either don't inherit, or inherit but reset versions, so the commits were reset.
Assert.Equal(2, operatingRepo.GetVersionHeight("noInherit"));
Assert.Equal(1, operatingRepo.GetVersionHeight("inheritWithVersion"));
}
}
}

private void AssertPathHasVersion(Commit commit, string absolutePath, VersionOptions expected)
{
var actual = VersionFile.GetVersion(absolutePath);
Expand Down
28 changes: 21 additions & 7 deletions src/NerdBank.GitVersioning.Tests/VersionOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public void FromVersion()
Assert.Equal(new Version(1, 2), vo.Version.Version);
Assert.Equal("-pre", vo.Version.Prerelease);
Assert.Null(vo.AssemblyVersion);
Assert.Equal(0, vo.BuildNumberOffset);
Assert.Equal(0, vo.BuildNumberOffsetOrDefault);
}

[Fact]
Expand Down Expand Up @@ -100,7 +100,7 @@ public void CloudBuildOptions_Equality()

var cbo2a = new VersionOptions.CloudBuildOptions
{
SetVersionVariables = !cbo1a.SetVersionVariables,
SetVersionVariables = !cbo1a.SetVersionVariablesOrDefault,
};
Assert.NotEqual(cbo2a, cbo1a);

Expand All @@ -114,7 +114,7 @@ public void CloudBuildOptions_Equality()
{
BuildNumber = new VersionOptions.CloudBuildNumberOptions
{
Enabled = !(new VersionOptions.CloudBuildNumberOptions().Enabled),
Enabled = !cbo1a.BuildNumberOrDefault.EnabledOrDefault,
},
};
Assert.NotEqual(cbo4a, cbo1a);
Expand All @@ -129,7 +129,7 @@ public void CloudBuildNumberOptions_Equality()

var bno2a = new VersionOptions.CloudBuildNumberOptions
{
Enabled = !bno1a.Enabled,
Enabled = !bno1a.EnabledOrDefault,
};
Assert.NotEqual(bno1a, bno2a);

Expand All @@ -149,20 +149,34 @@ public void CloudBuildNumberOptions_Equality()
[Fact]
public void CloudBuildNumberCommitIdOptions_Equality()
{
var cio1a = new VersionOptions.CloudBuildNumberCommitIdOptions { };
var cio1a = new VersionOptions.CloudBuildNumberCommitIdOptions();
cio1a.Where = cio1a.WhereOrDefault;
cio1a.When = cio1a.WhenOrDefault;
var cio1b = new VersionOptions.CloudBuildNumberCommitIdOptions { };
Assert.Equal(cio1a, cio1b);

var cio2a = new VersionOptions.CloudBuildNumberCommitIdOptions
{
When = (VersionOptions.CloudBuildNumberCommitWhen)((int)cio1a.When + 1),
When = (VersionOptions.CloudBuildNumberCommitWhen)((int)cio1a.WhenOrDefault + 1),
};
Assert.NotEqual(cio1a, cio2a);

var cio3a = new VersionOptions.CloudBuildNumberCommitIdOptions
{
Where = (VersionOptions.CloudBuildNumberCommitWhere)((int)cio1a.Where + 1),
Where = (VersionOptions.CloudBuildNumberCommitWhere)((int)cio1a.WhereOrDefault + 1),
};
Assert.NotEqual(cio1a, cio3a);
}

[Fact]
public void CannotWriteToDefaultInstances()
{
var options = new VersionOptions();
Assert.Throws<InvalidOperationException>(() => options.AssemblyVersionOrDefault.Precision = VersionOptions.VersionPrecision.Revision);
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.BuildNumberOrDefault.Enabled = true);
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.BuildNumberOrDefault.IncludeCommitIdOrDefault.When = VersionOptions.CloudBuildNumberCommitWhen.Always);
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.BuildNumberOrDefault.IncludeCommitIdOrDefault.Where = VersionOptions.CloudBuildNumberCommitWhere.BuildMetadata);
Assert.Throws<InvalidOperationException>(() => options.CloudBuildOrDefault.SetVersionVariables = true);
Assert.Throws<InvalidOperationException>(() => options.NuGetPackageVersionOrDefault.SemVer = 2);
}
}
14 changes: 14 additions & 0 deletions src/NerdBank.GitVersioning.Tests/VersionSchemaTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,18 @@ public void VersionField_HeightMacroPlacement()
json = JObject.Parse(@"{ ""version"": ""2.3.0-beta+height-{height}"" }");
Assert.False(json.IsValid(this.schema));
}

[Fact]
public void Inherit_AllowsOmissionOfVersion()
{
json = JObject.Parse(@"{ ""inherit"": false, ""version"": ""1.2"" }");
Assert.True(json.IsValid(this.schema));
json = JObject.Parse(@"{ ""inherit"": false }");
Assert.False(json.IsValid(this.schema));
json = JObject.Parse(@"{ }");
Assert.False(json.IsValid(this.schema));

json = JObject.Parse(@"{ ""inherit"": true }");
Assert.True(json.IsValid(this.schema));
}
}
Loading

0 comments on commit 771bb84

Please sign in to comment.