11using System ;
2- using System . Text ;
32
43namespace GVFS . Common . Git
54{
65 public class GitVersion
76 {
87 public GitVersion ( int major , int minor , int build , string platform = null , int revision = 0 , int minorRevision = 0 )
8+ : this ( major , minor , build , null , platform , revision , minorRevision ) { }
9+
10+ public GitVersion ( int major , int minor , int build , int ? releaseCandidate = null , string platform = null , int revision = 0 , int minorRevision = 0 )
911 {
1012 this . Major = major ;
1113 this . Minor = minor ;
1214 this . Build = build ;
15+ this . ReleaseCandidate = releaseCandidate ;
1316 this . Platform = platform ;
1417 this . Revision = revision ;
1518 this . MinorRevision = minorRevision ;
@@ -18,6 +21,7 @@ public GitVersion(int major, int minor, int build, string platform = null, int r
1821 public int Major { get ; private set ; }
1922 public int Minor { get ; private set ; }
2023 public int Build { get ; private set ; }
24+ public int ? ReleaseCandidate { get ; private set ; }
2125 public string Platform { get ; private set ; }
2226 public int Revision { get ; private set ; }
2327 public int MinorRevision { get ; private set ; }
@@ -37,31 +41,12 @@ public static bool TryParseGitVersionCommandResult(string input, out GitVersion
3741 return TryParseVersion ( input , out version ) ;
3842 }
3943
40- public static bool TryParseInstallerName ( string input , string installerExtension , out GitVersion version )
41- {
42- // Installer name is of the form
43- // Git-2.14.1.gvfs.1.1.gb16030b-64-bit.exe
44-
45- version = null ;
46-
47- if ( ! input . StartsWith ( "Git-" , StringComparison . InvariantCultureIgnoreCase ) )
48- {
49- return false ;
50- }
51-
52- if ( ! input . EndsWith ( "-64-bit" + installerExtension , StringComparison . InvariantCultureIgnoreCase ) )
53- {
54- return false ;
55- }
56-
57- return TryParseVersion ( input . Substring ( 4 , input . Length - 15 ) , out version ) ;
58- }
59-
6044 public static bool TryParseVersion ( string input , out GitVersion version )
6145 {
6246 version = null ;
6347
6448 int major , minor , build , revision = 0 , minorRevision = 0 ;
49+ int ? releaseCandidate = null ;
6550 string platform = null ;
6651
6752 if ( string . IsNullOrWhiteSpace ( input ) )
@@ -73,10 +58,10 @@ public static bool TryParseVersion(string input, out GitVersion version)
7358 int numComponents = parsedComponents . Length ;
7459
7560 // We minimally accept the official Git version number format which
76- // consists of three components: "major.minor.build".
61+ // consists of three components: "major.minor.build[.rcN] ".
7762 //
7863 // The other supported formats are the Git for Windows and Microsoft Git
79- // formats which look like: "major.minor.build.platform.revision.minorRevision"
64+ // formats which look like: "major.minor.build[.rcN] .platform.revision.minorRevision"
8065 // 0 1 2 3 4 5
8166 // len 1 2 3 4 5 6
8267 //
@@ -103,25 +88,54 @@ public static bool TryParseVersion(string input, out GitVersion version)
10388 return false ;
10489 }
10590
106- // Take the platform component verbatim
91+ // Release candidate and/or platform
92+ // Both of these are optional, but the release candidate is expected to be of the format 'rcN'
93+ // where N is a number, helping us distinguish it from a platform string.
94+ int platformIdx = 3 ;
10795 if ( numComponents >= 4 )
10896 {
109- platform = parsedComponents [ 3 ] ;
97+ string tag = parsedComponents [ 3 ] ;
98+
99+ // Release candidate 'rcN'
100+ if ( tag . StartsWith ( "rc" , StringComparison . OrdinalIgnoreCase ) &&
101+ tag . Length > 2 && int . TryParse ( tag . Substring ( 2 ) , out int rc ) && rc >= 0 )
102+ {
103+ releaseCandidate = rc ;
104+
105+ // The next component will now be the (optional) platform.
106+ // Subsequent components will be revision and minor revision so we need to adjust
107+ // the platform index to account for the release candidate.
108+ platformIdx = 4 ;
109+ if ( numComponents >= 5 )
110+ {
111+ platform = parsedComponents [ 4 ] ;
112+ }
113+ }
114+ else // Platform string only
115+ {
116+ platform = tag ;
117+ }
110118 }
111119
112120 // Platform revision
113- if ( numComponents < 5 || ! TryParseComponent ( parsedComponents [ 4 ] , out revision ) )
121+ if ( numComponents > platformIdx + 1 )
114122 {
115- revision = 0 ;
123+ if ( ! TryParseComponent ( parsedComponents [ platformIdx + 1 ] , out revision ) )
124+ {
125+ revision = 0 ;
126+ }
116127 }
117128
118129 // Minor platform revision
119- if ( numComponents < 6 || ! TryParseComponent ( parsedComponents [ 5 ] , out minorRevision ) )
130+ if ( numComponents > platformIdx + 2 )
120131 {
121- minorRevision = 0 ;
132+ if ( ! TryParseComponent ( parsedComponents [ platformIdx + 2 ] , out minorRevision ) )
133+ {
134+ minorRevision = 0 ;
135+ }
122136 }
123137
124- version = new GitVersion ( major , minor , build , platform , revision , minorRevision ) ;
138+ version = new GitVersion ( major , minor , build , releaseCandidate , platform , revision , minorRevision ) ;
125139 return true ;
126140 }
127141
@@ -142,7 +156,12 @@ public bool IsLessThan(GitVersion other)
142156
143157 public override string ToString ( )
144158 {
145- return string . Format ( "{0}.{1}.{2}.{3}.{4}.{5}" , this . Major , this . Minor , this . Build , this . Platform , this . Revision , this . MinorRevision ) ;
159+ if ( ReleaseCandidate is null )
160+ {
161+ return $ "{ Major } .{ Minor } .{ Build } .{ Platform } .{ Revision } .{ MinorRevision } ";
162+ }
163+
164+ return $ "{ Major } .{ Minor } .{ Build } .rc{ ReleaseCandidate } .{ Platform } .{ Revision } .{ MinorRevision } ";
146165 }
147166
148167 private static bool TryParseComponent ( string component , out int parsedComponent )
@@ -182,6 +201,18 @@ private int CompareVersionNumbers(GitVersion other)
182201 return this . Build . CompareTo ( other . Build ) ;
183202 }
184203
204+ if ( this . ReleaseCandidate != other . ReleaseCandidate )
205+ {
206+ if ( this . ReleaseCandidate . HasValue && other . ReleaseCandidate . HasValue )
207+ {
208+ return this . ReleaseCandidate . Value . CompareTo ( other . ReleaseCandidate . Value ) ;
209+ }
210+
211+ // If one version has a release candidate and the other does not,
212+ // the one without a release candidate is considered "greater than" the one with.
213+ return other . ReleaseCandidate . HasValue ? 1 : - 1 ;
214+ }
215+
185216 if ( this . Revision != other . Revision )
186217 {
187218 return this . Revision . CompareTo ( other . Revision ) ;
0 commit comments