From d1fb2d46be8f7f322770fff172ef21a88036d9c4 Mon Sep 17 00:00:00 2001 From: Matthew John Cheetham Date: Mon, 20 Jul 2020 15:57:48 +0100 Subject: [PATCH] git: support release candidate and local git builds Add support for parsing Git builds that include release candidate components. Also support partially parsing local builds of Git that may have other version formats such as "2.28.0.456.gabcdefg.dirty". In these cases we only parse the major, minor and build components. --- Scalar.Common/Git/GitVersion.cs | 66 +++++++++++---- Scalar.UnitTests/Common/GitVersionTests.cs | 99 ++++++++++++++++++++-- 2 files changed, 144 insertions(+), 21 deletions(-) diff --git a/Scalar.Common/Git/GitVersion.cs b/Scalar.Common/Git/GitVersion.cs index b3ca3ce7eee..65dc222df74 100644 --- a/Scalar.Common/Git/GitVersion.cs +++ b/Scalar.Common/Git/GitVersion.cs @@ -5,11 +5,12 @@ namespace Scalar.Common.Git { public class GitVersion { - public GitVersion(int major, int minor, int build, string platform = null, int revision = 0, int minorRevision = 0) + public GitVersion(int major, int minor, int build, string platform = null, int revision = 0, int minorRevision = 0, int? rc = null) { this.Major = major; this.Minor = minor; this.Build = build; + this.ReleaseCandidate = rc; this.Platform = platform; this.Revision = revision; this.MinorRevision = minorRevision; @@ -17,8 +18,9 @@ public GitVersion(int major, int minor, int build, string platform = null, int r public int Major { get; private set; } public int Minor { get; private set; } - public string Platform { get; private set; } public int Build { get; private set; } + public int? ReleaseCandidate { get; private set; } + public string Platform { get; private set; } public int Revision { get; private set; } public int MinorRevision { get; private set; } @@ -77,7 +79,8 @@ public static bool TryParseVersion(string input, out GitVersion version) { version = null; - int major, minor, build, revision, minorRevision; + int major, minor, build, revision = 0, minorRevision = 0; + int? rc = null; string platform = null; if (string.IsNullOrWhiteSpace(input)) @@ -86,53 +89,81 @@ public static bool TryParseVersion(string input, out GitVersion version) } string[] parsedComponents = input.Split('.'); + int numComponents = parsedComponents.Length; // We minimally accept the official Git version number format which - // consists of three components: "major.minor.build". + // consists of three components: "major.minor.build" or "major.minor.build-rc". // // The other supported formats are the Git for Windows and Microsoft Git - // formats which look like: "major.minor.build.platform.revision.minorRevision". + // formats which look like: "major.minor.build.platform.revision.minorRevision" + // or "major.minor.build-rc.platform.revision.minorRevision". + // 0 1 2 3 4 5 + // len 1 2 3 4 5 6 // - int numComponents = parsedComponents.Length; - if (numComponents < 2) + if (numComponents < 3) { return false; } + // Major version if (!TryParseComponent(parsedComponents[0], out major)) { return false; } + // Minor version if (!TryParseComponent(parsedComponents[1], out minor)) { return false; } - if (numComponents < 3 || !TryParseComponent(parsedComponents[2], out build)) + // Check if this is a release candidate version and if so split + // it from the build number. + string[] buildParts = parsedComponents[2].Split("-rc", StringSplitOptions.RemoveEmptyEntries); + if (buildParts.Length > 1 && TryParseComponent(buildParts[1], out int rcInt)) + { + rc = rcInt; + } + + // Build number + if (!TryParseComponent(buildParts[0], out build)) { return false; } + // Take the platform component verbatim if (numComponents >= 4) { platform = parsedComponents[3]; } - if (numComponents < 5 || !TryParseComponent(parsedComponents[4], out revision)) + // If this is a known platform (vfs = Microsoft Git, windows = Git for Windows) + // then also try and parse the revision and minor revision components. + if (IsKnownPlatform(platform)) { - revision = 0; - } + // Platform revision + if (numComponents < 5 || !TryParseComponent(parsedComponents[4], out revision)) + { + revision = 0; + } - if (numComponents < 6 || !TryParseComponent(parsedComponents[5], out minorRevision)) - { - minorRevision = 0; + // Minor platform revision + if (numComponents < 6 || !TryParseComponent(parsedComponents[5], out minorRevision)) + { + minorRevision = 0; + } } - version = new GitVersion(major, minor, build, platform, revision, minorRevision); + version = new GitVersion(major, minor, build, platform, revision, minorRevision, rc); return true; } + private static bool IsKnownPlatform(string platform) + { + return StringComparer.OrdinalIgnoreCase.Equals(platform, "windows") || + StringComparer.OrdinalIgnoreCase.Equals(platform, "vfs"); + } + public bool IsEqualTo(GitVersion other) { if (this.Platform != other.Platform) @@ -154,6 +185,11 @@ public override string ToString() sb.AppendFormat("{0}.{1}.{2}", this.Major, this.Minor, this.Build); + if (this.ReleaseCandidate.HasValue) + { + sb.AppendFormat("-rc{0}", this.ReleaseCandidate.Value); + } + if (!string.IsNullOrWhiteSpace(this.Platform)) { sb.AppendFormat(".{0}.{1}.{2}", this.Platform, this.Revision, this.MinorRevision); diff --git a/Scalar.UnitTests/Common/GitVersionTests.cs b/Scalar.UnitTests/Common/GitVersionTests.cs index 7f99c167924..20af86a37ab 100644 --- a/Scalar.UnitTests/Common/GitVersionTests.cs +++ b/Scalar.UnitTests/Common/GitVersionTests.cs @@ -64,7 +64,7 @@ public void Version_Data_Not_Enough_Numbers_Returns_False() public void Version_Data_Too_Many_Numbers_Returns_True() { GitVersion version; - bool success = GitVersion.TryParseVersion("2.0.1.test.1.4.3.6", out version); + bool success = GitVersion.TryParseVersion("2.0.1.windows.1.4.3.6", out version); success.ShouldEqual(true); } @@ -72,7 +72,31 @@ public void Version_Data_Too_Many_Numbers_Returns_True() public void Version_Data_Valid_Returns_True() { GitVersion version; - bool success = GitVersion.TryParseVersion("2.0.1.test.1.2", out version); + bool success = GitVersion.TryParseVersion("2.0.1", out version); + success.ShouldEqual(true); + } + + [TestCase] + public void Version_Data_Valid_With_RC_Returns_True() + { + GitVersion version; + bool success = GitVersion.TryParseVersion("2.0.1-rc3", out version); + success.ShouldEqual(true); + } + + [TestCase] + public void Version_Data_Valid_With_Platform_Returns_True() + { + GitVersion version; + bool success = GitVersion.TryParseVersion("2.0.1.windows.1.2", out version); + success.ShouldEqual(true); + } + + [TestCase] + public void Version_Data_Valid_With_RC_And_Platform_Returns_True() + { + GitVersion version; + bool success = GitVersion.TryParseVersion("2.0.1-rc3.windows.1.2", out version); success.ShouldEqual(true); } @@ -196,16 +220,32 @@ public void Compare_Version_MinorRevision_Greater() version1.IsEqualTo(version2).ShouldEqual(false); } + [TestCase] + public void Allow_Unknown_Platform_ParseOnly_MajorMinorBuildPlatform() + { + GitVersion version; + GitVersion.TryParseVersion("1.2.3.unknown.4.5", out version).ShouldEqual(true); + + version.Major.ShouldEqual(1); + version.Minor.ShouldEqual(2); + version.Build.ShouldEqual(3); + version.ReleaseCandidate.ShouldEqual(null); + version.Platform.ShouldEqual("unknown"); + version.Revision.ShouldEqual(0); + version.MinorRevision.ShouldEqual(0); + } + [TestCase] public void Allow_Blank_Minor_Revision() { GitVersion version; - GitVersion.TryParseVersion("1.2.3.test.4", out version).ShouldEqual(true); + GitVersion.TryParseVersion("1.2.3.windows.4", out version).ShouldEqual(true); version.Major.ShouldEqual(1); version.Minor.ShouldEqual(2); version.Build.ShouldEqual(3); - version.Platform.ShouldEqual("test"); + version.ReleaseCandidate.ShouldEqual(null); + version.Platform.ShouldEqual("windows"); version.Revision.ShouldEqual(4); version.MinorRevision.ShouldEqual(0); } @@ -214,16 +254,62 @@ public void Allow_Blank_Minor_Revision() public void Allow_Invalid_Minor_Revision() { GitVersion version; - GitVersion.TryParseVersion("1.2.3.test.4.notint", out version).ShouldEqual(true); + GitVersion.TryParseVersion("1.2.3.windows.4.notint", out version).ShouldEqual(true); version.Major.ShouldEqual(1); version.Minor.ShouldEqual(2); version.Build.ShouldEqual(3); - version.Platform.ShouldEqual("test"); + version.ReleaseCandidate.ShouldEqual(null); + version.Platform.ShouldEqual("windows"); version.Revision.ShouldEqual(4); version.MinorRevision.ShouldEqual(0); } + [TestCase] + public void Allow_ReleaseCandidate() + { + GitVersion version; + GitVersion.TryParseVersion("1.2.3-rc4", out version).ShouldEqual(true); + + version.Major.ShouldEqual(1); + version.Minor.ShouldEqual(2); + version.Build.ShouldEqual(3); + version.ReleaseCandidate.ShouldEqual(4); + version.Platform.ShouldBeNull(); + version.Revision.ShouldEqual(0); + version.MinorRevision.ShouldEqual(0); + } + + [TestCase] + public void Allow_ReleaseCandidate_Platform() + { + GitVersion version; + GitVersion.TryParseVersion("1.2.3-rc4.windows", out version).ShouldEqual(true); + + version.Major.ShouldEqual(1); + version.Minor.ShouldEqual(2); + version.Build.ShouldEqual(3); + version.ReleaseCandidate.ShouldEqual(4); + version.Platform.ShouldEqual("windows"); + version.Revision.ShouldEqual(0); + version.MinorRevision.ShouldEqual(0); + } + + [TestCase] + public void Allow_LocalGitBuildVersion_ParseMajorMinorBuildOnly() + { + GitVersion version; + GitVersion.TryParseVersion("1.2.3.456.abcdefg.hijk", out version).ShouldEqual(true); + + version.Major.ShouldEqual(1); + version.Minor.ShouldEqual(2); + version.Build.ShouldEqual(3); + version.ReleaseCandidate.ShouldEqual(null); + version.Platform.ShouldEqual("456"); + version.Revision.ShouldEqual(0); + version.MinorRevision.ShouldEqual(0); + } + private void ParseAndValidateInstallerVersion(string installerName) { GitVersion version; @@ -233,6 +319,7 @@ private void ParseAndValidateInstallerVersion(string installerName) version.Major.ShouldEqual(1); version.Minor.ShouldEqual(2); version.Build.ShouldEqual(3); + version.ReleaseCandidate.ShouldEqual(null); version.Platform.ShouldEqual("scalar"); version.Revision.ShouldEqual(4); version.MinorRevision.ShouldEqual(5);