Addressing code review comments and trying to fix the windows break.

This commit is contained in:
Livar Cunha 2017-05-22 10:28:12 -07:00
parent a4213f78e0
commit 37267bf158
7 changed files with 233 additions and 291 deletions

View file

@ -0,0 +1,129 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.MSBuildSdkResolver
{
// Note: This is not SemVer (esp., in comparing pre-release part, fx_ver_t does not
// compare multiple dot separated identifiers individually.) ex: 1.0.0-beta.2 vs. 1.0.0-beta.11
// See the original version of this code here: https://github.com/dotnet/core-setup/blob/master/src/corehost/cli/fxr/fx_ver.cpp
internal sealed class FXVersion
{
public int Major { get; }
public int Minor { get; }
public int Patch { get; }
public string Pre { get; }
public string Build { get; }
public FXVersion(int major, int minor, int patch, string pre = "", string build = "")
{
Major = major;
Minor = minor;
Patch = patch;
Pre = pre;
Build = build;
}
public static int Compare(FXVersion s1, FXVersion s2)
{
if (s1.Major != s2.Major)
{
return s1.Major > s2.Major ? 1 : -1;
}
if (s1.Minor != s2.Minor)
{
return s1.Minor > s2.Minor ? 1 : -1;
}
if (s1.Patch != s2.Patch)
{
return s1.Patch > s2.Patch ? 1 : -1;
}
if (string.IsNullOrEmpty(s1.Pre) != string.IsNullOrEmpty(s2.Pre))
{
return string.IsNullOrEmpty(s1.Pre) ? 1 : -1;
}
int preCompare = string.CompareOrdinal(s1.Pre, s2.Pre);
if (preCompare != 0)
{
return preCompare;
}
return string.CompareOrdinal(s1.Build, s2.Build);
}
public static bool TryParse(string fxVersionString, out FXVersion FXVersion)
{
FXVersion = null;
if (string.IsNullOrEmpty(fxVersionString))
{
return false;
}
int majorSeparator = fxVersionString.IndexOf(".");
if (majorSeparator == -1)
{
return false;
}
int major = 0;
if (!int.TryParse(fxVersionString.Substring(0, majorSeparator), out major))
{
return false;
}
int minorStart = majorSeparator + 1;
int minorSeparator = fxVersionString.IndexOf(".", minorStart);
if (minorSeparator == -1)
{
return false;
}
int minor = 0;
if (!int.TryParse(fxVersionString.Substring(minorStart, minorSeparator - minorStart), out minor))
{
return false;
}
int patch = 0;
int patchStart = minorSeparator + 1;
int patchSeparator = fxVersionString.FindFirstNotOf("0123456789", patchStart);
if (patchSeparator == -1)
{
if (!int.TryParse(fxVersionString.Substring(patchStart), out patch))
{
return false;
}
FXVersion = new FXVersion(major, minor, patch);
return true;
}
if (!int.TryParse(fxVersionString.Substring(patchStart, patchSeparator - patchStart), out patch))
{
return false;
}
int preStart = patchSeparator;
int preSeparator = fxVersionString.IndexOf("+", preStart);
if (preSeparator == -1)
{
FXVersion = new FXVersion(major, minor, patch, fxVersionString.Substring(preStart));
}
else
{
int buildStart = preSeparator + 1;
FXVersion = new FXVersion(
major,
minor,
patch,
fxVersionString.Substring(preStart, preSeparator - preStart),
fxVersionString.Substring(buildStart));
}
return true;
}
}
}

View file

@ -53,15 +53,16 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
netcoreSdkVersion = new DirectoryInfo(netcoreSdkDir).Name;;
}
if (!string.IsNullOrEmpty(sdkReference.MinimumVersion) &&
SemanticVersion.Parse(netcoreSdkVersion) < SemanticVersion.Parse(sdkReference.MinimumVersion))
if (!IsNetCoreSDKOveridden(netcoreSdkVersion) &&
IsNetCoreSDKSmallerThanTheMinimumVersion(netcoreSdkVersion, sdkReference.MinimumVersion))
{
return factory.IndicateFailure(
new[]
{
$"Version {netcoreSdkVersion} of the SDK is smaller than the minimum version"
+ $" {sdkReference.MinimumVersion} requested. Check that a recent enough .NET Core SDK is"
+ " installed and/or increase the version specified in global.json."
+ " installed, increase the minimum version specified in the project, or increase"
+ " the version specified in global.json."
});
}
@ -79,6 +80,42 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
return factory.IndicateSuccess(msbuildSdkDir, netcoreSdkVersion);
}
private bool IsNetCoreSDKOveridden(string netcoreSdkVersion)
{
return netcoreSdkVersion == null;
}
private bool IsNetCoreSDKSmallerThanTheMinimumVersion(string netcoreSdkVersion, string minimumVersion)
{
FXVersion netCoreSdkFXVersion;
FXVersion minimumFXVersion;
if (string.IsNullOrEmpty(minimumVersion))
{
return false;
}
if (FailsToParseVersions(netcoreSdkVersion, minimumVersion, out netCoreSdkFXVersion, out minimumFXVersion))
{
return true;
}
return FXVersion.Compare(netCoreSdkFXVersion, minimumFXVersion) == -1;
}
private bool FailsToParseVersions(
string netcoreSdkVersion,
string minimumVersion,
out FXVersion netCoreSdkFXVersion,
out FXVersion minimumFXVersion)
{
netCoreSdkFXVersion = null;
minimumFXVersion = null;
return !FXVersion.TryParse(netcoreSdkVersion, out netCoreSdkFXVersion) ||
!FXVersion.TryParse(minimumVersion, out minimumFXVersion);
}
private string ResolveNetcoreSdkDirectory(SdkResolverContext context)
{
foreach (string exeDir in GetDotnetExeDirectoryCandidates())

View file

@ -1,181 +0,0 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
namespace Microsoft.DotNet.MSBuildSdkResolver
{
internal sealed class SemanticVersion
{
public int Major { get; private set; }
public int Minor { get; private set; }
public int Patch { get; private set; }
public string Pre { get; private set; }
public string Build { get; private set; }
public SemanticVersion(int major, int minor, int patch) : this(major, minor, patch, string.Empty, string.Empty)
{
}
public SemanticVersion(int major, int minor, int patch, string pre) :
this(major, minor, patch, pre, string.Empty)
{
}
public SemanticVersion(int major, int minor, int patch, string pre, string build)
{
Major = major;
Minor = minor;
Patch = patch;
Pre = pre;
Build = build;
}
public static bool operator ==(SemanticVersion s1, SemanticVersion s2)
{
return Compare(s1, s2) == 0;
}
public static bool operator !=(SemanticVersion s1, SemanticVersion s2)
{
return !(s1 == s2);
}
public static bool operator <(SemanticVersion s1, SemanticVersion s2)
{
return Compare(s1, s2) < 0;
}
public static bool operator >(SemanticVersion s1, SemanticVersion s2)
{
return Compare(s1, s2) > 0;
}
public static bool operator >=(SemanticVersion s1, SemanticVersion s2)
{
return Compare(s1, s2) >= 0;
}
public static bool operator <=(SemanticVersion s1, SemanticVersion s2)
{
return Compare(s1, s2) <= 0;
}
public static SemanticVersion Parse(string semanticVersionString)
{
int majorSeparator = semanticVersionString.IndexOf(".");
if (majorSeparator == -1)
{
return null;
}
int major = 0;
if (!int.TryParse(semanticVersionString.Substring(0, majorSeparator), out major))
{
return null;
}
int minorStart = majorSeparator + 1;
int minorSeparator = semanticVersionString.IndexOf(".", minorStart);
if (minorSeparator == -1)
{
return null;
}
int minor = 0;
if (!int.TryParse(semanticVersionString.Substring(minorStart, minorSeparator - minorStart), out minor))
{
return null;
}
int patch = 0;
int patchStart = minorSeparator + 1;
int patchSeparator = semanticVersionString.FindFirstNotOf("0123456789", patchStart);
if (patchSeparator == -1)
{
if (!int.TryParse(semanticVersionString.Substring(patchStart), out patch))
{
return null;
}
return new SemanticVersion(major, minor, patch);
}
if (!int.TryParse(semanticVersionString.Substring(patchStart, patchSeparator - patchStart), out patch))
{
return null;
}
int preStart = patchSeparator;
int preSeparator = semanticVersionString.IndexOf("+", preStart);
if (preSeparator == -1)
{
return new SemanticVersion(major, minor, patch, semanticVersionString.Substring(preStart));
}
else
{
int buildStart = preSeparator + 1;
return new SemanticVersion(
major,
minor,
patch,
semanticVersionString.Substring(preStart, preSeparator - preStart),
semanticVersionString.Substring(buildStart));
}
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
var other = obj as SemanticVersion;
if (other == null)
{
return false;
}
return this == other;
}
public override int GetHashCode()
{
return Major.GetHashCode() ^
Minor.GetHashCode() ^
Patch.GetHashCode() ^
Pre.GetHashCode() ^
Build.GetHashCode();
}
private static int Compare(SemanticVersion s1, SemanticVersion s2)
{
if (s1.Major != s2.Major)
{
return s1.Major > s2.Major ? 1 : -1;
}
if (s1.Minor != s2.Minor)
{
return s1.Minor > s2.Minor ? 1 : -1;
}
if (s1.Patch != s2.Patch)
{
return s1.Patch > s2.Patch ? 1 : -1;
}
if (string.IsNullOrEmpty(s1.Pre) != string.IsNullOrEmpty(s2.Pre))
{
return string.IsNullOrEmpty(s1.Pre) ? 1 : -1;
}
int preCompare = string.Compare(s1.Pre, s2.Pre);
if (preCompare != 0)
{
return preCompare;
}
return string.Compare(s1.Build, s2.Build);
}
}
}

View file

@ -71,8 +71,8 @@ namespace Microsoft.DotNet.Cli.Utils.Tests
result.Version.Should().BeNull();
result.Warnings.Should().BeNullOrEmpty();
result.Errors.Should().Contain("Version 99.99.99 of the SDK is smaller than the minimum version 999.99.99"
+ " requested. Check that a recent enough .NET Core SDK is installed and/or increase the version"
+ " specified in global.json.");
+ " requested. Check that a recent enough .NET Core SDK is installed, increase the minimum version"
+ " specified in the project, or increase the version specified in global.json.");
}
[Fact]

View file

@ -7,76 +7,29 @@ using FluentAssertions;
namespace Microsoft.DotNet.Cli.Utils.Tests
{
public class GivenThatWeWantToCompareSemanticVersions
public class GivenThatWeWantToCompareFXVersions
{
[Theory]
[InlineData("2.0.0", "1.0.0")]
[InlineData("1.1.0", "1.0.0")]
[InlineData("1.0.1", "1.0.0")]
[InlineData("1.0.0", "1.0.0-pre")]
[InlineData("1.0.0-pre+2", "1.0.0-pre+1")]
public void OneSemanticVersionIsBiggerThanTheOther(string s1, string s2)
[InlineData("2.0.0", "1.0.0", 1)]
[InlineData("1.1.0", "1.0.0", 1)]
[InlineData("1.0.1", "1.0.0", 1)]
[InlineData("1.0.0", "1.0.0-pre", 1)]
[InlineData("1.0.0-pre+2", "1.0.0-pre+1", 1)]
[InlineData("1.0.0", "2.0.0", -1)]
[InlineData("1.0.0", "1.1.0", -1)]
[InlineData("1.0.0", "1.0.1", -1)]
[InlineData("1.0.0-pre", "1.0.0", -1)]
[InlineData("1.0.0-pre+1", "1.0.0-pre+2", -1)]
[InlineData("1.2.3", "1.2.3", 0)]
[InlineData("1.2.3-pre", "1.2.3-pre", 0)]
[InlineData("1.2.3-pre+1", "1.2.3-pre+1", 0)]
public void OneFXVersionIsBiggerThanTheOther(string s1, string s2, int expectedResult)
{
var biggerThan = SemanticVersion.Parse(s1) > SemanticVersion.Parse(s2);
var smallerThan = SemanticVersion.Parse(s1) < SemanticVersion.Parse(s2);
biggerThan.Should().BeTrue();
smallerThan.Should().BeFalse();
}
[Theory]
[InlineData("1.0.0", "2.0.0")]
[InlineData("1.0.0", "1.1.0")]
[InlineData("1.0.0", "1.0.1")]
[InlineData("1.0.0-pre", "1.0.0")]
[InlineData("1.0.0-pre+1", "1.0.0-pre+2")]
public void OneSemanticVersionIsSmallerThanTheOther(string s1, string s2)
{
var smallerThan = SemanticVersion.Parse(s1) < SemanticVersion.Parse(s2);
var biggerThan = SemanticVersion.Parse(s1) > SemanticVersion.Parse(s2);
smallerThan.Should().BeTrue();
biggerThan.Should().BeFalse();
}
[Theory]
[InlineData("2.0.0", "1.0.0")]
[InlineData("1.0.0", "1.0.0")]
public void OneSemanticVersionIsBiggerThanOrEqualsTheOther(string s1, string s2)
{
var biggerThanOrEquals = SemanticVersion.Parse(s1) >= SemanticVersion.Parse(s2);
biggerThanOrEquals.Should().BeTrue();
}
[Theory]
[InlineData("1.0.0", "2.0.0")]
[InlineData("1.0.0", "1.0.0")]
public void OneSemanticVersionIsSmallerThanOrEqualsTheOther(string s1, string s2)
{
var smallerThanOrEquals = SemanticVersion.Parse(s1) <= SemanticVersion.Parse(s2);
smallerThanOrEquals.Should().BeTrue();
}
[Theory]
[InlineData("1.2.3", "1.2.3")]
[InlineData("1.2.3-pre", "1.2.3-pre")]
[InlineData("1.2.3-pre+1", "1.2.3-pre+1")]
public void SemanticVersionsCanBeEqual(string s1, string s2)
{
var equals = SemanticVersion.Parse(s1) == SemanticVersion.Parse(s2);
var different = SemanticVersion.Parse(s1) != SemanticVersion.Parse(s2);
equals.Should().BeTrue();
different.Should().BeFalse();
}
[Theory]
[InlineData("1.2.3", "1.2.0")]
[InlineData("1.2.3-pre", "1.2.3-pra")]
[InlineData("1.2.3-pre+1", "1.2.3-pre+2")]
public void SemanticVersionsCanBeDifferent(string s1, string s2)
{
var different = SemanticVersion.Parse(s1) != SemanticVersion.Parse(s2);
var equals = SemanticVersion.Parse(s1) == SemanticVersion.Parse(s2);
different.Should().BeTrue();
equals.Should().BeFalse();
FXVersion fxVersion1;
FXVersion fxVersion2;
FXVersion.TryParse(s1, out fxVersion1);
FXVersion.TryParse(s2, out fxVersion2);
FXVersion.Compare(fxVersion1, fxVersion2).Should().Be(expectedResult);
}
}
}

View file

@ -7,82 +7,83 @@ using FluentAssertions;
namespace Microsoft.DotNet.Cli.Utils.Tests
{
public class GivenThatWeWantToParseSemanticVersions
public class GivenThatWeWantToParseFXVersions
{
[Fact]
public void ReturnsNullWhenNoMajorSeparatorIsFound()
{
var semanticVersion = SemanticVersion.Parse("1");
semanticVersion.Should().BeNull();
FXVersion fxVersion;
FXVersion.TryParse("1", out fxVersion).Should().BeFalse();
}
[Fact]
public void ReturnsNullWhenMajorPortionIsNotANumber()
{
var semanticVersion = SemanticVersion.Parse("a.0.0");
semanticVersion.Should().BeNull();
FXVersion fxVersion;
FXVersion.TryParse("a.0.0", out fxVersion).Should().BeFalse();
}
[Fact]
public void ReturnsNullWhenNoMinorSeparatorIsFound()
{
var semanticVersion = SemanticVersion.Parse("1.0");
semanticVersion.Should().BeNull();
FXVersion fxVersion;
FXVersion.TryParse("1.0", out fxVersion).Should().BeFalse();
}
[Fact]
public void ReturnsNullWhenMinorPortionIsNotANumber()
{
var semanticVersion = SemanticVersion.Parse("1.a.0");
semanticVersion.Should().BeNull();
FXVersion fxVersion;
FXVersion.TryParse("1.a.0", out fxVersion).Should().BeFalse();
}
[Fact]
public void ReturnsNullWhenPatchPortionIsNotANumber()
{
var semanticVersion = SemanticVersion.Parse("1.0.a");
semanticVersion.Should().BeNull();
FXVersion fxVersion;
FXVersion.TryParse("1.0.a", out fxVersion).Should().BeFalse();
}
[Fact]
public void ReturnsSemanticVersionWhenOnlyMajorMinorPatchIsFound()
public void ReturnsFXVersionWhenOnlyMajorMinorPatchIsFound()
{
var semanticVersion = SemanticVersion.Parse("1.2.3");
FXVersion fxVersion;
semanticVersion.Should().NotBeNull();
semanticVersion.Major.Should().Be(1);
semanticVersion.Minor.Should().Be(2);
semanticVersion.Patch.Should().Be(3);
var result = FXVersion.TryParse("1.2.3", out fxVersion);
result.Should().BeTrue();
fxVersion.Major.Should().Be(1);
fxVersion.Minor.Should().Be(2);
fxVersion.Patch.Should().Be(3);
}
[Fact]
public void ReturnsSemanticVersionWhenOnlyMajorMinorPatchAndPreIsFound()
public void ReturnsFXVersionWhenOnlyMajorMinorPatchAndPreIsFound()
{
var semanticVersion = SemanticVersion.Parse("1.2.3-pre");
FXVersion fxVersion;
semanticVersion.Should().NotBeNull();
semanticVersion.Major.Should().Be(1);
semanticVersion.Minor.Should().Be(2);
semanticVersion.Patch.Should().Be(3);
semanticVersion.Pre.Should().Be("-pre");
var result = FXVersion.TryParse("1.2.3-pre", out fxVersion);
result.Should().BeTrue();
fxVersion.Major.Should().Be(1);
fxVersion.Minor.Should().Be(2);
fxVersion.Patch.Should().Be(3);
fxVersion.Pre.Should().Be("-pre");
}
[Fact]
public void ReturnsSemanticVersionWhenMajorMinorPatchAndPreAndBuildIsFound()
public void ReturnsFXVersionWhenMajorMinorPatchAndPreAndBuildIsFound()
{
var semanticVersion = SemanticVersion.Parse("1.2.3-pre+build");
FXVersion fxVersion;
var result = FXVersion.TryParse("1.2.3-pre+build", out fxVersion);
semanticVersion.Should().NotBeNull();
semanticVersion.Major.Should().Be(1);
semanticVersion.Minor.Should().Be(2);
semanticVersion.Patch.Should().Be(3);
semanticVersion.Pre.Should().Be("-pre");
semanticVersion.Build.Should().Be("build");
result.Should().BeTrue();
fxVersion.Major.Should().Be(1);
fxVersion.Minor.Should().Be(2);
fxVersion.Patch.Should().Be(3);
fxVersion.Pre.Should().Be("-pre");
fxVersion.Build.Should().Be("build");
}
}
}

View file

@ -21,7 +21,6 @@
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="FluentAssertions" Version="4.18.0" />
<PackageReference Include="runtime.linux-x64.Microsoft.NETCore.DotNetHostResolver" Version="$(CLI_SharedFrameworkVersion)" />
<PackageReference Include="runtime.osx-x64.Microsoft.NETCore.DotNetHostResolver" Version="$(CLI_SharedFrameworkVersion)" />
</ItemGroup>
@ -30,6 +29,10 @@
<None Update="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>