Skip to content

Commit

Permalink
git: support release candidate and local git builds
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mjcheetham committed Jul 20, 2020
1 parent d2a818e commit d1fb2d4
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 21 deletions.
66 changes: 51 additions & 15 deletions Scalar.Common/Git/GitVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,22 @@ 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;
}

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; }

Expand Down Expand Up @@ -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))
Expand All @@ -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<N>".
//
// 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<N>.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)
Expand All @@ -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);
Expand Down
99 changes: 93 additions & 6 deletions Scalar.UnitTests/Common/GitVersionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,39 @@ 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);
}

[TestCase]
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);
}

Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
Expand All @@ -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);
Expand Down

0 comments on commit d1fb2d4

Please sign in to comment.