-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use built-in git
path interpolation for config settings
#439
Changes from 1 commit
dcd7219
79c2a27
8285315
3bfbe7d
67046ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
using System; | ||
using Xunit; | ||
|
||
namespace Microsoft.Git.CredentialManager.Tests | ||
{ | ||
public class GitVersionTests | ||
{ | ||
[Theory] | ||
[InlineData(null, 1)] | ||
[InlineData("2", 1)] | ||
[InlineData("3", -1)] | ||
[InlineData("2.33", 0)] | ||
[InlineData("2.32.0", 1)] | ||
[InlineData("2.33.0.windows.0.1", 0)] | ||
[InlineData("2.33.0.2", -1)] | ||
public void GitVersion_CompareTo_2_33_0(string input, int expectedCompare) | ||
{ | ||
GitVersion baseline = new GitVersion(2, 33, 0); | ||
GitVersion actual = new GitVersion(input); | ||
Assert.Equal(expectedCompare, baseline.CompareTo(actual)); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Microsoft.Git.CredentialManager | ||
{ | ||
public class GitVersion : IComparable, IComparable<GitVersion> | ||
{ | ||
private List<int> components; | ||
|
||
public GitVersion(string versionString) | ||
{ | ||
if (versionString is null) | ||
{ | ||
components = new List<int>(); | ||
return; | ||
} | ||
|
||
string[] splitVersion = versionString.Split('.'); | ||
components = new List<int>(splitVersion.Length); | ||
|
||
foreach (string part in splitVersion) | ||
{ | ||
if (Int32.TryParse(part, out int component)) | ||
{ | ||
components.Add(component); | ||
} | ||
else | ||
{ | ||
// Exit at the first non-integer component | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense, this would turn TBH version comparing is (in my experience) somewhat of an ill-defined problem, and the more simplistic we can make it without breaking our use cases, the better. As a point of reference, I would like to link to the version comparison in Git for Windows' installer and the code in I also had a brief hunch that there might be something in .NET, and there is: All this is to say: I think this implementation is nice and small, and good enough for our purposes. Thank you for implementing it! |
||
break; | ||
} | ||
} | ||
} | ||
|
||
public GitVersion(params int[] components) | ||
{ | ||
this.components = components.ToList(); | ||
} | ||
|
||
public override string ToString() | ||
{ | ||
return string.Join(".", this.components); | ||
} | ||
|
||
public int CompareTo(object obj) | ||
{ | ||
if (obj is null) | ||
{ | ||
return 1; | ||
} | ||
|
||
GitVersion other = obj as GitVersion; | ||
if (other == null) | ||
{ | ||
throw new ArgumentException("A GitVersion object is required for comparison.", "obj"); | ||
} | ||
|
||
return CompareTo(other); | ||
} | ||
|
||
public int CompareTo(GitVersion other) | ||
{ | ||
if (other is null) | ||
{ | ||
return 1; | ||
} | ||
|
||
// Compare for as many components as the two versions have in common. If a | ||
// component does not exist in a components list, it is assumed to be 0. | ||
int thisCount = this.components.Count, otherCount = other.components.Count; | ||
for (int i = 0; i < Math.Max(thisCount, otherCount); i++) | ||
{ | ||
int thisComponent = i < thisCount ? this.components[i] : 0; | ||
int otherComponent = i < otherCount ? other.components[i] : 0; | ||
if (thisComponent != otherComponent) | ||
{ | ||
return thisComponent.CompareTo(otherComponent); | ||
} | ||
} | ||
|
||
// No discrepencies found in versions | ||
return 0; | ||
} | ||
|
||
public static int Compare(GitVersion left, GitVersion right) | ||
{ | ||
if (object.ReferenceEquals(left, right)) | ||
{ | ||
return 0; | ||
} | ||
|
||
if (left is null) | ||
{ | ||
return -1; | ||
} | ||
|
||
return left.CompareTo(right); | ||
} | ||
|
||
public override bool Equals(object obj) | ||
{ | ||
GitVersion other = obj as GitVersion; | ||
if (other is null) | ||
{ | ||
return false; | ||
} | ||
|
||
return this.CompareTo(other) == 0; | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
return ToString().GetHashCode(); | ||
} | ||
|
||
public static bool operator ==(GitVersion left, GitVersion right) | ||
{ | ||
if (left is null) | ||
{ | ||
return right is null; | ||
} | ||
|
||
return left.Equals(right); | ||
} | ||
|
||
public static bool operator !=(GitVersion left, GitVersion right) | ||
{ | ||
return !(left == right); | ||
} | ||
|
||
public static bool operator <(GitVersion left, GitVersion right) | ||
{ | ||
return Compare(left, right) < 0; | ||
} | ||
|
||
public static bool operator >(GitVersion left, GitVersion right) | ||
{ | ||
return Compare(left, right) > 0; | ||
} | ||
|
||
public static bool operator <=(GitVersion left, GitVersion right) | ||
{ | ||
return Compare(left, right) <= 0; | ||
} | ||
|
||
public static bool operator >=(GitVersion left, GitVersion right) | ||
{ | ||
return Compare(left, right) >= 0; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementing
IComparable
on types can be hard to get right; looks like you've done a great job - nice! 😁Did you consider also implementing the
IEquatable
andIEquatable<GitVersion>
interfaces?The implementation is already there in your overridden
bool Equals(object)
method but adding the interface will mean should we ever putGitVersion
in a dictionary or set, that collection can know it can be equated.This change does not block this PR by the way..