Adding a check for the min version in the CLI Resolver.
This commit is contained in:
parent
947c8daabc
commit
f61d1ffbb0
7 changed files with 386 additions and 1 deletions
|
@ -53,6 +53,17 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
|
|||
netcoreSdkVersion = new DirectoryInfo(netcoreSdkDir).Name;;
|
||||
}
|
||||
|
||||
if (SemanticVersion.Parse(netcoreSdkVersion) < SemanticVersion.Parse(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."
|
||||
});
|
||||
}
|
||||
|
||||
string msbuildSdkDir = Path.Combine(msbuildSdksDir, sdkReference.Name, "Sdk");
|
||||
if (!Directory.Exists(msbuildSdkDir))
|
||||
{
|
||||
|
@ -60,7 +71,7 @@ namespace Microsoft.DotNet.MSBuildSdkResolver
|
|||
new[]
|
||||
{
|
||||
$"{msbuildSdkDir} not found. Check that a recent enough .NET Core SDK is installed"
|
||||
+ " and/or increase the version specified in global.json. "
|
||||
+ " and/or increase the version specified in global.json."
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// 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.
|
||||
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Microsoft.DotNet.MSBuildSdkResolver.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
181
src/Microsoft.DotNet.MSBuildSdkResolver/SemanticVersion.cs
Normal file
181
src/Microsoft.DotNet.MSBuildSdkResolver/SemanticVersion.cs
Normal file
|
@ -0,0 +1,181 @@
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
15
src/Microsoft.DotNet.MSBuildSdkResolver/StringExtensions.cs
Normal file
15
src/Microsoft.DotNet.MSBuildSdkResolver/StringExtensions.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace Microsoft.DotNet.MSBuildSdkResolver
|
||||
{
|
||||
internal static class StringExtensions
|
||||
{
|
||||
public static int FindFirstNotOf(this string s, string chars, int startIndex)
|
||||
{
|
||||
for (int i = startIndex; i < s.Length; i++)
|
||||
{
|
||||
if (chars.IndexOf(s[i]) == -1) return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
// 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.
|
||||
|
||||
using Xunit;
|
||||
using Microsoft.DotNet.MSBuildSdkResolver;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||
{
|
||||
public class GivenThatWeWantToCompareSemanticVersions
|
||||
{
|
||||
[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)
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
// 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.
|
||||
|
||||
using Xunit;
|
||||
using Microsoft.DotNet.MSBuildSdkResolver;
|
||||
using FluentAssertions;
|
||||
|
||||
namespace Microsoft.DotNet.Cli.Utils.Tests
|
||||
{
|
||||
public class GivenThatWeWantToParseSemanticVersions
|
||||
{
|
||||
[Fact]
|
||||
public void ReturnsNullWhenNoMajorSeparatorIsFound()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1");
|
||||
|
||||
semanticVersion.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsNullWhenMajorPortionIsNotANumber()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("a.0.0");
|
||||
|
||||
semanticVersion.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsNullWhenNoMinorSeparatorIsFound()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.0");
|
||||
|
||||
semanticVersion.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsNullWhenMinorPortionIsNotANumber()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.a.0");
|
||||
|
||||
semanticVersion.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsNullWhenPatchPortionIsNotANumber()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.0.a");
|
||||
|
||||
semanticVersion.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsSemanticVersionWhenOnlyMajorMinorPatchIsFound()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.2.3");
|
||||
|
||||
semanticVersion.Should().NotBeNull();
|
||||
semanticVersion.Major.Should().Be(1);
|
||||
semanticVersion.Minor.Should().Be(2);
|
||||
semanticVersion.Patch.Should().Be(3);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsSemanticVersionWhenOnlyMajorMinorPatchAndPreIsFound()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.2.3-pre");
|
||||
|
||||
semanticVersion.Should().NotBeNull();
|
||||
semanticVersion.Major.Should().Be(1);
|
||||
semanticVersion.Minor.Should().Be(2);
|
||||
semanticVersion.Patch.Should().Be(3);
|
||||
semanticVersion.Pre.Should().Be("-pre");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReturnsSemanticVersionWhenMajorMinorPatchAndPreAndBuildIsFound()
|
||||
{
|
||||
var semanticVersion = SemanticVersion.Parse("1.2.3-pre+build");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
<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>
|
||||
|
|
Loading…
Reference in a new issue