/// <summary> /// Parses a version string using loose semantic versioning rules that allows 2-4 version components followed by an optional special version. /// </summary> public static bool TryParse(string value, out NuGetVersion version) { version = null; if (value != null) { Version systemVersion = null; // trim the value before passing it in since we not strict here Tuple<string, string[], string> sections = ParseSections(value.Trim()); // null indicates the string did not meet the rules if (sections != null && !string.IsNullOrEmpty(sections.Item1)) { string versionPart = sections.Item1; if (versionPart.IndexOf('.') < 0) { // System.Version requires at least a 2 part version to parse. versionPart += ".0"; } if (Version.TryParse(versionPart, out systemVersion)) { // labels if (sections.Item2 != null && !sections.Item2.All(s => IsValidPart(s, false))) { return false; } // build metadata if (sections.Item3 != null && !IsValid(sections.Item3, true)) { return false; } Version ver = NormalizeVersionValue(systemVersion); string originalVersion = value; if (originalVersion.IndexOf(' ') > -1) { originalVersion = value.Replace(" ", ""); } version = new NuGetVersion(version: ver, releaseLabels: sections.Item2, metadata: sections.Item3 ?? string.Empty, originalVersion: originalVersion); return true; } } } return false; }
/// <summary> /// Parses a version string using strict SemVer rules. /// </summary> public static bool TryParseStrict(string value, out NuGetVersion version) { version = null; SemanticVersion semVer = null; if (SemanticVersion.TryParse(value, out semVer)) { version = new NuGetVersion(semVer.Major, semVer.Minor, semVer.Patch, 0, semVer.ReleaseLabels, semVer.Metadata); } return true; }
/// <summary> /// Compares the 4th digit of the version number. /// </summary> private static int CompareLegacyVersion(NuGetVersion legacyX, NuGetVersion legacyY) { int result = 0; // true if one has a 4th version number if (legacyX != null && legacyY != null) { result = legacyX.Version.CompareTo(legacyY.Version); } else if (legacyX != null && legacyX.Version.Revision > 0) { result = 1; } else if (legacyY != null && legacyY.Version.Revision > 0) { result = -1; } return result; }
/// <summary> /// Creates a NuGetVersion from an existing NuGetVersion /// </summary> public NuGetVersion(NuGetVersion version) : this(version.Version, version.ReleaseLabels, version.Metadata, version.ToString()) { }
/// <summary> /// Creates a VersionRange with the given min and max. /// </summary> /// <param name="minVersion">Lower bound of the version range.</param> /// <param name="includeMinVersion">True if minVersion satisfies the condition.</param> /// <param name="maxVersion">Upper bound of the version range.</param> /// <param name="includeMaxVersion">True if maxVersion satisfies the condition.</param> /// <param name="includePrerelease">True if prerelease versions should satisfy the condition.</param> /// <param name="floatRange">The floating range subset used to find the best version match.</param> public VersionRange(NuGetVersion minVersion = null, bool includeMinVersion = true, NuGetVersion maxVersion = null, bool includeMaxVersion = false, bool? includePrerelease = null, FloatRange floatRange =null) : base(minVersion, includeMinVersion, maxVersion, includeMaxVersion, includePrerelease) { _floatRange = floatRange; }
/// <summary> /// Creates a range that is greater than or equal to the minVersion with the given float behavior. /// </summary> /// <param name="minVersion">Lower bound of the version range.</param> public VersionRange(NuGetVersion minVersion, FloatRange floatRange) : this(minVersion, true, null, false, null, floatRange) { }
/// <summary> /// Determines if a given version is better suited to the range than a current version. /// </summary> public bool IsBetter(NuGetVersion current, NuGetVersion considering) { if (Object.ReferenceEquals(current, considering)) { return false; } // null checks if (Object.ReferenceEquals(considering, null)) { return false; } if (!Satisfies(considering)) { // keep null over a value outside of the range return false; } if (Object.ReferenceEquals(current, null)) { return true; } if (IsFloating) { // check if either version is in the floating range bool curInRange = _floatRange.Satisfies(current); bool conInRange = _floatRange.Satisfies(considering); if (curInRange && !conInRange) { // take the version in the range return false; } else if (conInRange && !curInRange) { // take the version in the range return true; } else if (curInRange && conInRange) { // prefer the highest one if both are in the range return current < considering; } else { // neither are in range bool curToLower = current < _floatRange.MinVersion; bool conToLower = considering < _floatRange.MinVersion; if (curToLower && !conToLower) { // favor the version above the range return true; } else if (!curToLower && conToLower) { // favor the version above the range return false; } else if (!curToLower && !conToLower) { // favor the lower version if we are above the range return current > considering; } else if (curToLower && conToLower) { // favor the higher version if we are below the range return current < considering; } } } // Favor lower versions return current > considering; }
/// <summary> /// Creates a range that is greater than or equal to the minVersion. /// </summary> /// <param name="minVersion">Lower bound of the version range.</param> public VersionRange(NuGetVersion minVersion) : this(minVersion, null) { }