diff --git a/Directory.Packages.props b/Directory.Packages.props
index dafbe6936..231ddc1b8 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -29,7 +29,7 @@
-
+
diff --git a/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj b/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
index c32f070cc..9387d8839 100644
--- a/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
+++ b/src/Microsoft.ComponentDetection.Common/Microsoft.ComponentDetection.Common.csproj
@@ -1,11 +1,10 @@
-
+
-
diff --git a/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj b/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
index f51c4be23..3718d3e00 100644
--- a/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
+++ b/src/Microsoft.ComponentDetection.Detectors/Microsoft.ComponentDetection.Detectors.csproj
@@ -1,4 +1,4 @@
-
+
@@ -7,7 +7,7 @@
-
+
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/DependencySpecification.cs b/src/Microsoft.ComponentDetection.Detectors/rust/DependencySpecification.cs
index aa9ca5f6b..17ea313c4 100644
--- a/src/Microsoft.ComponentDetection.Detectors/rust/DependencySpecification.cs
+++ b/src/Microsoft.ComponentDetection.Detectors/rust/DependencySpecification.cs
@@ -1,10 +1,10 @@
-namespace Microsoft.ComponentDetection.Detectors.Rust;
+namespace Microsoft.ComponentDetection.Detectors.Rust;
using System;
using System.Collections.Generic;
using Microsoft.ComponentDetection.Detectors.Rust.Contracts;
-using Semver;
-using Range = Microsoft.ComponentDetection.Detectors.Rust.SemVer.Range;
+using Range = SemanticVersioning.Range;
+using Version = SemanticVersioning.Version;
public class DependencySpecification
{
@@ -41,7 +41,7 @@ public bool MatchesPackage(CargoPackage package)
var allSatisfied = true;
foreach (var range in ranges)
{
- if (SemVersion.TryParse(package.Version, out var sv))
+ if (Version.TryParse(package.Version, out var sv))
{
if (!range.IsSatisfied(sv))
{
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Comparator.cs b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Comparator.cs
deleted file mode 100644
index daf6c4631..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Comparator.cs
+++ /dev/null
@@ -1,227 +0,0 @@
-// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
-// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
-// that is used elsewhere in this project.
-//
-// This is a temporary solution, so avoid using this functionality outside of the Rust detector. The following
-// issues describe the problems with the SemanticVersioning package that make it problematic to use for versioning.
-// https://github.com/adamreeve/semver.net/issues/46
-// https://github.com/adamreeve/semver.net/issues/47
-
-namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer;
-using System;
-using System.Text.RegularExpressions;
-using Semver;
-
-internal class Comparator : IEquatable
-{
- private const string RangePattern = @"
- \s*
- ([=<>]*) # Comparator type (can be empty)
- \s*
- ([0-9a-zA-Z\-\+\.\*]+) # Version (potentially partial version)
- \s*
- ";
-
- private static readonly Regex RangePatternRegex = new Regex(
- RangePattern,
- RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled);
-
- public Comparator(string input)
- {
- var match = RangePatternRegex.Match(input);
- if (!match.Success)
- {
- throw new ArgumentException(string.Format("Invalid comparator string: {0}", input));
- }
-
- this.ComparatorType = ParseComparatorType(match.Groups[1].Value);
- var partialVersion = new PartialVersion(match.Groups[2].Value);
-
- if (!partialVersion.IsFull())
- {
- // For Operator.Equal, partial versions are handled by the StarRange
- // desugarer, and desugar to multiple comparators.
- switch (this.ComparatorType)
- {
- // For <= with a partial version, eg. <=1.2.x, this
- // means the same as < 1.3.0, and <=1.x means <2.0
- case Operator.LessThanOrEqual:
- this.ComparatorType = Operator.LessThan;
- if (!partialVersion.Major.HasValue)
- {
- // <=* means >=0.0.0
- this.ComparatorType = Operator.GreaterThanOrEqual;
- this.Version = new SemVersion(0, 0, 0);
- }
- else if (!partialVersion.Minor.HasValue)
- {
- this.Version = new SemVersion(partialVersion.Major.Value + 1, 0, 0);
- }
- else
- {
- this.Version = new SemVersion(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0);
- }
-
- break;
- case Operator.GreaterThan:
- this.ComparatorType = Operator.GreaterThanOrEqual;
- if (!partialVersion.Major.HasValue)
- {
- // >* is unsatisfiable, so use <0.0.0
- this.ComparatorType = Operator.LessThan;
- this.Version = new SemVersion(0, 0, 0);
- }
- else if (!partialVersion.Minor.HasValue)
- {
- // eg. >1.x -> >=2.0
- this.Version = new SemVersion(partialVersion.Major.Value + 1, 0, 0);
- }
- else
- {
- // eg. >1.2.x -> >=1.3
- this.Version = new SemVersion(partialVersion.Major.Value, partialVersion.Minor.Value + 1, 0);
- }
-
- break;
-
- case Operator.Equal:
- case Operator.LessThan:
- case Operator.GreaterThanOrEqual:
- default:
- // <1.2.x means <1.2.0
- // >=1.2.x means >=1.2.0
- this.Version = partialVersion.ToZeroVersion();
- break;
- }
- }
- else
- {
- this.Version = partialVersion.ToZeroVersion();
- }
- }
-
- public Comparator(Operator comparatorType, SemVersion comparatorVersion)
- {
- this.ComparatorType = comparatorType;
- this.Version = comparatorVersion ?? throw new ArgumentNullException(nameof(comparatorVersion), "Null comparator version");
- }
-
- public enum Operator
- {
- Equal = 0,
- LessThan,
- LessThanOrEqual,
- GreaterThan,
- GreaterThanOrEqual,
- }
-
- public Operator ComparatorType { get; }
-
- public SemVersion Version { get; }
-
- public static Tuple TryParse(string input)
- {
- var match = RangePatternRegex.Match(input);
-
- return match.Success ?
- Tuple.Create(
- match.Length,
- new Comparator(match.Value))
- : null;
- }
-
- public bool IsSatisfied(SemVersion version)
- {
- return this.ComparatorType switch
- {
- Operator.Equal => version == this.Version,
- Operator.LessThan => version < this.Version,
- Operator.LessThanOrEqual => version <= this.Version,
- Operator.GreaterThan => version > this.Version,
- Operator.GreaterThanOrEqual => version >= this.Version,
- _ => throw new InvalidOperationException("Comparator type not recognised."),
- };
- }
-
- public bool Intersects(Comparator other)
- {
- static bool OperatorIsGreaterThan(Comparator c) =>
- c.ComparatorType == Operator.GreaterThan ||
- c.ComparatorType == Operator.GreaterThanOrEqual;
- static bool OperatorIsLessThan(Comparator c) =>
- c.ComparatorType == Operator.LessThan ||
- c.ComparatorType == Operator.LessThanOrEqual;
- static bool OperatorIncludesEqual(Comparator c) =>
- c.ComparatorType == Operator.GreaterThanOrEqual ||
- c.ComparatorType == Operator.Equal ||
- c.ComparatorType == Operator.LessThanOrEqual;
-
- if (this.Version > other.Version && (OperatorIsLessThan(this) || OperatorIsGreaterThan(other)))
- {
- return true;
- }
-
- if (this.Version < other.Version && (OperatorIsGreaterThan(this) || OperatorIsLessThan(other)))
- {
- return true;
- }
-
- if (this.Version == other.Version && (
- (OperatorIncludesEqual(this) && OperatorIncludesEqual(other)) ||
- (OperatorIsLessThan(this) && OperatorIsLessThan(other)) ||
- (OperatorIsGreaterThan(this) && OperatorIsGreaterThan(other))))
- {
- return true;
- }
-
- return false;
- }
-
- public override string ToString()
- {
- string operatorString = null;
- operatorString = this.ComparatorType switch
- {
- Operator.Equal => "=",
- Operator.LessThan => "<",
- Operator.LessThanOrEqual => "<=",
- Operator.GreaterThan => ">",
- Operator.GreaterThanOrEqual => ">=",
- _ => throw new InvalidOperationException("Comparator type not recognised."),
- };
- return string.Format("{0}{1}", operatorString, this.Version);
- }
-
- public bool Equals(Comparator other)
- {
- if (other is null)
- {
- return false;
- }
-
- return this.ComparatorType == other.ComparatorType && this.Version == other.Version;
- }
-
- public override bool Equals(object other)
- {
- return this.Equals(other as Comparator);
- }
-
- public override int GetHashCode()
- {
- return this.ToString().GetHashCode();
- }
-
- private static Operator ParseComparatorType(string input)
- {
- return input switch
- {
- "" or "=" => Operator.Equal,
- "<" => Operator.LessThan,
- "<=" => Operator.LessThanOrEqual,
- ">" => Operator.GreaterThan,
- ">=" => Operator.GreaterThanOrEqual,
- _ => throw new ArgumentException(string.Format("Invalid comparator type: {0}", input)),
- };
- }
-}
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/ComparatorSet.cs b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/ComparatorSet.cs
deleted file mode 100644
index 1093c9c7f..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/ComparatorSet.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
-// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
-// that is used elsewhere in this project.
-//
-// This is a temporary solution, so avoid using this functionality outside of the Rust detector. The following
-// issues describe the problems with the SemanticVersioning package that make it problematic to use for versioning.
-// https://github.com/adamreeve/semver.net/issues/46
-// https://github.com/adamreeve/semver.net/issues/47
-
-namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Semver;
-
-internal class ComparatorSet : IEquatable
-{
- private readonly List comparators;
-
- public ComparatorSet(string spec)
- {
- this.comparators = new List { };
-
- spec = spec.Trim();
- if (string.IsNullOrEmpty(spec))
- {
- spec = "*";
- }
-
- var position = 0;
- var end = spec.Length;
-
- while (position < end)
- {
- var iterStartPosition = position;
-
- // A comparator set might be an advanced range specifier
- // like ~1.2.3, ^1.2, or 1.*.
- // Check for these first before standard comparators:
- foreach (var desugarer in new Func>[]
- {
- Desugarer.HyphenRange,
- Desugarer.TildeRange,
- Desugarer.CaretRange,
- Desugarer.StarRange,
- })
- {
- var result = desugarer(spec[position..]);
- if (result != null)
- {
- position += result.Item1;
- this.comparators.AddRange(result.Item2);
- }
- }
-
- // Check for standard comparator with operator and version:
- var comparatorResult = Comparator.TryParse(spec[position..]);
- if (comparatorResult != null)
- {
- position += comparatorResult.Item1;
- this.comparators.Add(comparatorResult.Item2);
- }
-
- if (position == iterStartPosition)
- {
- // Didn't manage to read any valid comparators
- throw new ArgumentException(string.Format("Invalid range specification: \"{0}\"", spec));
- }
- }
- }
-
- private ComparatorSet(IEnumerable comparators) => this.comparators = comparators.ToList();
-
- public bool IsSatisfied(SemVersion version)
- {
- var satisfied = this.comparators.All(c => c.IsSatisfied(version));
- if (!string.IsNullOrEmpty(version.Prerelease))
- {
- // If the version is a pre-release, then one of the
- // comparators must have the same version and also include
- // a pre-release tag.
- return satisfied && this.comparators.Any(c =>
- !string.IsNullOrEmpty(c.Version.Prerelease) &&
- c.Version.Major == version.Major &&
- c.Version.Minor == version.Minor &&
- c.Version.Patch == version.Patch);
- }
- else
- {
- return satisfied;
- }
- }
-
- public ComparatorSet Intersect(ComparatorSet other)
- {
- static bool OperatorIsGreaterThan(Comparator c) =>
- c.ComparatorType == Comparator.Operator.GreaterThan ||
- c.ComparatorType == Comparator.Operator.GreaterThanOrEqual;
- static bool OperatorIsLessThan(Comparator c) =>
- c.ComparatorType == Comparator.Operator.LessThan ||
- c.ComparatorType == Comparator.Operator.LessThanOrEqual;
- var maxOfMins =
- this.comparators.Concat(other.comparators)
- .Where(OperatorIsGreaterThan)
- .OrderByDescending(c => c.Version).FirstOrDefault();
- var minOfMaxs =
- this.comparators.Concat(other.comparators)
- .Where(OperatorIsLessThan)
- .OrderBy(c => c.Version).FirstOrDefault();
- if (maxOfMins != null && minOfMaxs != null && !maxOfMins.Intersects(minOfMaxs))
- {
- return null;
- }
-
- // If there is an equality operator, check that it satisfies other operators
- var equalityVersions =
- this.comparators.Concat(other.comparators)
- .Where(c => c.ComparatorType == Comparator.Operator.Equal)
- .Select(c => c.Version)
- .ToList();
- if (equalityVersions.Count > 1)
- {
- if (equalityVersions.Any(v => v != equalityVersions[0]))
- {
- return null;
- }
- }
-
- if (equalityVersions.Count > 0)
- {
- if (maxOfMins != null && !maxOfMins.IsSatisfied(equalityVersions[0]))
- {
- return null;
- }
-
- if (minOfMaxs != null && !minOfMaxs.IsSatisfied(equalityVersions[0]))
- {
- return null;
- }
-
- return new ComparatorSet(
- new List
- {
- new Comparator(Comparator.Operator.Equal, equalityVersions[0]),
- });
- }
-
- var comparators = new List();
- if (maxOfMins != null)
- {
- comparators.Add(maxOfMins);
- }
-
- if (minOfMaxs != null)
- {
- comparators.Add(minOfMaxs);
- }
-
- return comparators.Count > 0 ? new ComparatorSet(comparators) : null;
- }
-
- public bool Equals(ComparatorSet other)
- {
- if (other is null)
- {
- return false;
- }
-
- var thisSet = new HashSet(this.comparators);
- return thisSet.SetEquals(other.comparators);
- }
-
- public override bool Equals(object other)
- {
- return this.Equals(other as ComparatorSet);
- }
-
- public override string ToString()
- {
- return string.Join(" ", this.comparators.Select(c => c.ToString()).ToArray());
- }
-
- public override int GetHashCode()
- {
- // XOR is commutative, so this hash code is independent
- // of the order of comparators.
- return this.comparators.Aggregate(0, (accum, next) => accum ^ next.GetHashCode());
- }
-}
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Desugarer.cs b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Desugarer.cs
deleted file mode 100644
index 2fb16bb4c..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Desugarer.cs
+++ /dev/null
@@ -1,246 +0,0 @@
-// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
-// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
-// that is used elsewhere in this project.
-//
-// This is a temporary solution, so avoid using this functionality outside of the Rust detector. The following
-// issues describe the problems with the SemanticVersioning package that make it problematic to use for versioning.
-// https://github.com/adamreeve/semver.net/issues/46
-// https://github.com/adamreeve/semver.net/issues/47
-
-namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer;
-using System;
-using System.Text.RegularExpressions;
-using Semver;
-
-internal static class Desugarer
-{
- private const string VersionChars = @"[0-9a-zA-Z\-\+\.\*]";
-
- // tilde and caret requirements can't also have wildcards in them
- private const string VersionCharsNoWildcard = @"[0-9a-zA-Z\-\+\.]";
-
- private static readonly Regex TildePatternRegex = new Regex(
- $@"^\s*~\s*({VersionCharsNoWildcard}+)\s*$",
- RegexOptions.Compiled);
-
- // The caret is optional, as Cargo treats "x.y.z" like "^x.y.z":
- // https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-cratesio
- private static readonly Regex CaretPatternRegex = new Regex(
- $@"^\s*\^?\s*({VersionCharsNoWildcard}+)\s*$",
- RegexOptions.Compiled);
-
- private static readonly Regex HyphenPatternRegex = new Regex(
- $@"^\s*({VersionChars}+)\s+\-\s+({VersionChars}+)\s*",
- RegexOptions.Compiled);
-
- private static readonly Regex StarPatternRegex = new Regex(
- $@"^\s*=?\s*({VersionChars}+)\s*",
- RegexOptions.Compiled);
-
- // Allows patch-level changes if a minor version is specified
- // on the comparator. Allows minor-level changes if not.
- public static Tuple TildeRange(string spec)
- {
- var match = TildePatternRegex.Match(spec);
- if (!match.Success)
- {
- return null;
- }
-
- SemVersion minVersion = null;
- SemVersion maxVersion = null;
-
- var version = new PartialVersion(match.Groups[1].Value);
- if (version.Minor.HasValue)
- {
- // Doesn't matter whether patch version is null or not,
- // the logic is the same, min patch version will be zero if null.
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value, version.Minor.Value + 1, 0);
- }
- else
- {
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value + 1, 0, 0);
- }
-
- return Tuple.Create(
- match.Length,
- MinMaxComparators(minVersion, maxVersion));
- }
-
- // Allows changes that do not modify the left-most non-zero digit
- // in the [major, minor, patch] tuple.
- public static Tuple CaretRange(string spec)
- {
- var match = CaretPatternRegex.Match(spec);
- if (!match.Success)
- {
- return null;
- }
-
- SemVersion minVersion = null;
- SemVersion maxVersion = null;
-
- var version = new PartialVersion(match.Groups[1].Value);
-
- if (version.Major.Value > 0)
- {
- // Don't allow major version change
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value + 1, 0, 0);
- }
- else if (!version.Minor.HasValue)
- {
- // Don't allow major version change, even if it's zero
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value + 1, 0, 0);
- }
- else if (!version.Patch.HasValue)
- {
- // Don't allow minor version change, even if it's zero
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(0, version.Minor.Value + 1, 0);
- }
- else if (version.Minor > 0)
- {
- // Don't allow minor version change
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(0, version.Minor.Value + 1, 0);
- }
- else
- {
- // Only patch non-zero, don't allow patch change
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(0, 0, version.Patch.Value + 1);
- }
-
- return Tuple.Create(
- match.Length,
- MinMaxComparators(minVersion, maxVersion));
- }
-
- public static Tuple HyphenRange(string spec)
- {
- var match = HyphenPatternRegex.Match(spec);
- if (!match.Success)
- {
- return null;
- }
-
- PartialVersion minPartialVersion = null;
- PartialVersion maxPartialVersion = null;
-
- // Parse versions from lower and upper ranges, which might
- // be partial versions.
- try
- {
- minPartialVersion = new PartialVersion(match.Groups[1].Value);
- maxPartialVersion = new PartialVersion(match.Groups[2].Value);
- }
- catch (ArgumentException)
- {
- return null;
- }
-
- // Lower range has any non-supplied values replaced with zero
- var minVersion = minPartialVersion.ToZeroVersion();
-
- var maxOperator = maxPartialVersion.IsFull()
- ? Comparator.Operator.LessThanOrEqual : Comparator.Operator.LessThan;
-
- SemVersion maxVersion = null;
-
- // Partial upper range means supplied version values can't change
- if (!maxPartialVersion.Major.HasValue)
- {
- // eg. upper range = "*", then maxVersion remains null
- // and there's only a minimum
- }
- else if (!maxPartialVersion.Minor.HasValue)
- {
- maxVersion = new SemVersion(maxPartialVersion.Major.Value + 1, 0, 0);
- }
- else if (!maxPartialVersion.Patch.HasValue)
- {
- maxVersion = new SemVersion(maxPartialVersion.Major.Value, maxPartialVersion.Minor.Value + 1, 0);
- }
- else
- {
- // Fully specified max version
- maxVersion = maxPartialVersion.ToZeroVersion();
- }
-
- return Tuple.Create(
- match.Length,
- MinMaxComparators(minVersion, maxVersion, maxOperator));
- }
-
- public static Tuple StarRange(string spec)
- {
- var match = StarPatternRegex.Match(spec);
-
- if (!match.Success)
- {
- return null;
- }
-
- PartialVersion version = null;
- try
- {
- version = new PartialVersion(match.Groups[1].Value);
- }
- catch (ArgumentException)
- {
- return null;
- }
-
- // If partial version match is actually a full version,
- // then this isn't a star range, so return null.
- if (version.IsFull())
- {
- return null;
- }
-
- SemVersion minVersion = null;
- SemVersion maxVersion = null;
-
- if (!version.Major.HasValue)
- {
- minVersion = version.ToZeroVersion();
-
- // no max version
- }
- else if (!version.Minor.HasValue)
- {
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value + 1, 0, 0);
- }
- else
- {
- minVersion = version.ToZeroVersion();
- maxVersion = new SemVersion(version.Major.Value, version.Minor.Value + 1, 0);
- }
-
- return Tuple.Create(
- match.Length,
- MinMaxComparators(minVersion, maxVersion));
- }
-
- private static Comparator[] MinMaxComparators(SemVersion minVersion, SemVersion maxVersion, Comparator.Operator maxOperator = Comparator.Operator.LessThan)
- {
- var minComparator = new Comparator(
- Comparator.Operator.GreaterThanOrEqual,
- minVersion);
- if (maxVersion == null)
- {
- return new[] { minComparator };
- }
- else
- {
- var maxComparator = new Comparator(
- maxOperator, maxVersion);
- return new[] { minComparator, maxComparator };
- }
- }
-}
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/PartialVersion.cs b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/PartialVersion.cs
deleted file mode 100644
index 9578a4ff2..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/PartialVersion.cs
+++ /dev/null
@@ -1,109 +0,0 @@
-// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
-// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
-// that is used elsewhere in this project.
-//
-// This is a temporary solution, so avoid using this functionality outside of the Rust detector. The following
-// issues describe the problems with the SemanticVersioning package that make it problematic to use for versioning.
-// https://github.com/adamreeve/semver.net/issues/46
-// https://github.com/adamreeve/semver.net/issues/47
-
-namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer;
-using System;
-using System.Linq;
-using System.Text.RegularExpressions;
-using Semver;
-
-// A version that might not have a minor or patch
-// number, for use in ranges like "^1.2" or "2.x"
-internal class PartialVersion
-{
- private static readonly Regex VersionRegex = new Regex(
- @"^
- [v=\s]*
- (\d+|[Xx\*]) # major version
- (
- \.
- (\d+|[Xx\*]) # minor version
- (
- \.
- (\d+|[Xx\*]) # patch version
- (\-?([0-9A-Za-z\-\.]+))? # pre-release version
- (\+([0-9A-Za-z\-\.]+))? # build version (ignored)
- )?
- )?
- $",
- RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace);
-
- public PartialVersion(string input)
- {
- string[] xValues = { "X", "x", "*" };
-
- if (string.IsNullOrEmpty(input.Trim()))
- {
- // Empty input means any version
- return;
- }
-
- var match = VersionRegex.Match(input);
- if (!match.Success)
- {
- throw new ArgumentException(string.Format("Invalid version string: \"{0}\"", input));
- }
-
- if (xValues.Contains(match.Groups[1].Value))
- {
- this.Major = null;
- }
- else
- {
- this.Major = int.Parse(match.Groups[1].Value);
- }
-
- if (match.Groups[2].Success)
- {
- if (xValues.Contains(match.Groups[3].Value))
- {
- this.Minor = null;
- }
- else
- {
- this.Minor = int.Parse(match.Groups[3].Value);
- }
- }
-
- if (match.Groups[4].Success)
- {
- if (xValues.Contains(match.Groups[5].Value))
- {
- this.Patch = null;
- }
- else
- {
- this.Patch = int.Parse(match.Groups[5].Value);
- }
- }
-
- if (match.Groups[6].Success)
- {
- this.PreRelease = match.Groups[7].Value;
- }
- }
-
- public int? Major { get; set; }
-
- public int? Minor { get; set; }
-
- public int? Patch { get; set; }
-
- public string PreRelease { get; set; }
-
- public SemVersion ToZeroVersion()
- {
- return new SemVersion(this.Major ?? 0, this.Minor ?? 0, this.Patch ?? 0, this.PreRelease);
- }
-
- public bool IsFull()
- {
- return this.Major.HasValue && this.Minor.HasValue && this.Patch.HasValue;
- }
-}
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Range.cs b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Range.cs
deleted file mode 100644
index 0ab9aae4c..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Range.cs
+++ /dev/null
@@ -1,245 +0,0 @@
-// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
-// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
-// that is used elsewhere in this project.
-//
-// This is a temporary solution, so avoid using this functionality outside of the Rust detector. The following
-// issues describe the problems with the SemanticVersioning package that make it problematic to use for versioning.
-// https://github.com/adamreeve/semver.net/issues/46
-// https://github.com/adamreeve/semver.net/issues/47
-
-namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Semver;
-
-///
-/// Specifies valid versions.
-///
-public class Range : IEquatable
-{
- private readonly ComparatorSet[] comparatorSets;
-
- private readonly string rangeSpec;
-
- ///
- /// Construct a new range from a range specification.
- ///
- /// The range specification string.
- /// When true, be more forgiving of some invalid version specifications.
- /// Thrown when the range specification is invalid.
- public Range(string rangeSpec, bool loose = false)
- {
- this.rangeSpec = rangeSpec;
- var comparatorSetSpecs = rangeSpec.Split(new[] { "||" }, StringSplitOptions.None);
- this.comparatorSets = comparatorSetSpecs.Select(s => new ComparatorSet(s)).ToArray();
- }
-
- private Range(IEnumerable comparatorSets)
- {
- this.comparatorSets = comparatorSets.ToArray();
- this.rangeSpec = string.Join(" || ", comparatorSets.Select(cs => cs.ToString()).ToArray());
- }
-
- public static bool operator ==(Range a, Range b)
- {
- if (a is null)
- {
- return b is null;
- }
-
- return a.Equals(b);
- }
-
- public static bool operator !=(Range a, Range b) => !(a == b);
-
- // Static convenience methods
-
- ///
- /// Determine whether the given version satisfies a given range.
- /// With an invalid version this method returns false.
- ///
- /// The range specification.
- /// The version to check.
- /// When true, be more forgiving of some invalid version specifications.
- /// true if the range is satisfied by the version.
- public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false)
- {
- var range = new Range(rangeSpec);
- return range.IsSatisfied(versionString);
- }
-
- ///
- /// Return the set of version strings that satisfy a given range.
- /// Invalid version specifications are skipped.
- ///
- /// The range specification.
- /// The version strings to check.
- /// When true, be more forgiving of some invalid version specifications.
- /// An IEnumerable of satisfying version strings.
- public static IEnumerable Satisfying(string rangeSpec, IEnumerable versions, bool loose = false)
- {
- var range = new Range(rangeSpec);
- return range.Satisfying(versions);
- }
-
- ///
- /// Return the maximum version that satisfies a given range.
- ///
- /// The range specification.
- /// The version strings to select from.
- /// When true, be more forgiving of some invalid version specifications.
- /// The maximum satisfying version string, or null if no versions satisfied this range.
- public static string MaxSatisfying(string rangeSpec, IEnumerable versionStrings, bool loose = false)
- {
- var range = new Range(rangeSpec);
- return range.MaxSatisfying(versionStrings);
- }
-
- private IEnumerable ValidVersions(IEnumerable versionStrings, bool loose)
- {
- foreach (var v in versionStrings)
- {
- SemVersion version = null;
- try
- {
- SemVersion.TryParse(v, out version, loose);
- }
- catch (ArgumentException)
- {
- // Skip
- }
-
- if (version != null)
- {
- yield return version;
- }
- }
- }
-
- ///
- /// Determine whether the given version satisfies this range.
- ///
- /// The version to check.
- /// true if the range is satisfied by the version.
- public bool IsSatisfied(SemVersion version)
- {
- return this.comparatorSets.Any(s => s.IsSatisfied(version));
- }
-
- ///
- /// Determine whether the given version satisfies this range.
- /// With an invalid version this method returns false.
- ///
- /// The version to check.
- /// When true, be more forgiving of some invalid version specifications.
- /// true if the range is satisfied by the version.
- public bool IsSatisfied(string versionString, bool loose = false)
- {
- try
- {
- SemVersion.TryParse(versionString, out var version, loose);
- return this.IsSatisfied(version);
- }
- catch (ArgumentException)
- {
- return false;
- }
- }
-
- ///
- /// Return the set of versions that satisfy this range.
- ///
- /// The versions to check.
- /// An IEnumerable of satisfying versions.
- public IEnumerable Satisfying(IEnumerable versions)
- {
- return versions.Where(this.IsSatisfied);
- }
-
- ///
- /// Return the set of version strings that satisfy this range.
- /// Invalid version specifications are skipped.
- ///
- /// The version strings to check.
- /// When true, be more forgiving of some invalid version specifications.
- /// An IEnumerable of satisfying version strings.
- public IEnumerable Satisfying(IEnumerable versions, bool loose = false)
- {
- return versions.Where(v => this.IsSatisfied(v, loose));
- }
-
- ///
- /// Return the maximum version that satisfies this range.
- ///
- /// The versions to select from.
- /// The maximum satisfying version, or null if no versions satisfied this range.
- public SemVersion MaxSatisfying(IEnumerable versions)
- {
- return this.Satisfying(versions).Max();
- }
-
- ///
- /// Return the maximum version that satisfies this range.
- ///
- /// The version strings to select from.
- /// When true, be more forgiving of some invalid version specifications.
- /// The maximum satisfying version string, or null if no versions satisfied this range.
- public string MaxSatisfying(IEnumerable versionStrings, bool loose = false)
- {
- var versions = this.ValidVersions(versionStrings, loose);
- var maxVersion = this.MaxSatisfying(versions);
- return maxVersion?.ToString();
- }
-
- ///
- /// Calculate the intersection between two ranges.
- ///
- /// The Range to intersect this Range with.
- /// The Range intersection.
- public Range Intersect(Range other)
- {
- var allIntersections = this.comparatorSets.SelectMany(
- thisCs => other.comparatorSets.Select(thisCs.Intersect))
- .Where(cs => cs != null).ToList();
-
- if (allIntersections.Count == 0)
- {
- return new Range("<0.0.0");
- }
-
- return new Range(allIntersections);
- }
-
- ///
- /// Returns the range specification string used when constructing this range.
- ///
- /// The range string.
- public override string ToString()
- {
- return this.rangeSpec;
- }
-
- public bool Equals(Range other)
- {
- if (other is null)
- {
- return false;
- }
-
- var thisSet = new HashSet(this.comparatorSets);
- return thisSet.SetEquals(other.comparatorSets);
- }
-
- public override bool Equals(object obj)
- {
- return this.Equals(obj as Range);
- }
-
- public override int GetHashCode()
- {
- // XOR is commutative, so this hash code is independent
- // of the order of comparators.
- return this.comparatorSets.Aggregate(0, (accum, next) => accum ^ next.GetHashCode());
- }
-}
diff --git a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/cgmanifest.json b/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/cgmanifest.json
deleted file mode 100644
index 076add2c0..000000000
--- a/src/Microsoft.ComponentDetection.Detectors/rust/SemVer/cgmanifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "Registrations": [
- {
- "Component": {
- "Type": "git",
- "git": {
- "RepositoryUrl": "https://github.com/adamreeve/semver.net/",
- "CommitHash": "efe3e2e87276ba6b231fc73898ed1651e584f354"
- }
- },
- "DevelopmentDependency": false
- }
- ]
-}
\ No newline at end of file