/// <summary> /// Parse a version string /// </summary> /// <returns>false if the version is not a strict semver</returns> public static bool TryParse(string value, out SemanticVersion version) { version = null; if (value != null) { Version systemVersion = null; Tuple<string, string[], string> sections = ParseSections(value); // null indicates the string did not meet the rules if (sections != null && Version.TryParse(sections.Item1, out systemVersion)) { // validate the version string string[] parts = sections.Item1.Split('.'); if (parts.Length != 3) { // versions must be 3 parts return false; } foreach (var part in parts) { if (!IsValidPart(part, false)) { // leading zeros are not allowed return false; } } // 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); version = new SemanticVersion(version: ver, releaseLabels: sections.Item2, metadata: sections.Item3 ?? string.Empty); return true; } } return false; }
private static string GetNormalizedString(SemanticVersion version) { StringBuilder sb = new StringBuilder(); sb.Append(Format('V', version)); if (version.IsPrerelease) { sb.Append('-'); sb.Append(version.Release); } if (version.HasMetadata) { sb.Append('+'); sb.Append(version.Metadata); } return sb.ToString(); }
/// <summary> /// Gives a hash code based on the normalized version string. /// </summary> public int GetHashCode(SemanticVersion version) { if (Object.ReferenceEquals(version, null)) { return 0; } HashCodeCombiner combiner = new HashCodeCombiner(); combiner.AddObject(version.Major); combiner.AddObject(version.Minor); combiner.AddObject(version.Patch); NuGetVersion nuGetVersion = version as NuGetVersion; if (nuGetVersion != null && nuGetVersion.Revision > 0) { combiner.AddObject(nuGetVersion.Revision); } if (_mode == VersionComparison.Default || _mode == VersionComparison.VersionRelease || _mode == VersionComparison.VersionReleaseMetadata) { if (version.IsPrerelease) { combiner.AddObject(version.Release.ToUpperInvariant()); } } if (_mode == VersionComparison.VersionReleaseMetadata) { if (version.HasMetadata) { combiner.AddObject(version.Metadata); } } return combiner.CombinedHash; }
private static string Format(char c, SemanticVersion version) { string s = null; switch (c) { case 'N': s = GetNormalizedString(version); break; case 'R': s = version.Release; break; case 'M': s = version.Metadata; break; case 'V': s = FormatVersion(version); break; case 'x': s = String.Format(CultureInfo.InvariantCulture, "{0}", version.Major); break; case 'y': s = String.Format(CultureInfo.InvariantCulture, "{0}", version.Minor); break; case 'z': s = String.Format(CultureInfo.InvariantCulture, "{0}", version.Patch); break; case 'r': NuGetVersion nuGetVersion = version as NuGetVersion; s = String.Format(CultureInfo.InvariantCulture, "{0}", nuGetVersion != null && nuGetVersion.IsLegacyVersion ? nuGetVersion.Version.Revision : 0); break; } return s; }
private static string FormatVersion(SemanticVersion version) { NuGetVersion nuGetVersion = version as NuGetVersion; bool legacy = nuGetVersion != null && nuGetVersion.IsLegacyVersion; return String.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}{3}", version.Major, version.Minor, version.Patch, legacy ? String.Format(CultureInfo.InvariantCulture, ".{0}", nuGetVersion.Version.Revision) : null); }
/// <summary> /// Compare versions. /// </summary> public int Compare(SemanticVersion x, SemanticVersion y) { if (Object.ReferenceEquals(x, y)) { return 0; } if (Object.ReferenceEquals(y, null)) { return 1; } if (Object.ReferenceEquals(x, null)) { return -1; } if (x != null && y != null) { // compare version int result = x.Major.CompareTo(y.Major); if (result != 0) return result; result = x.Minor.CompareTo(y.Minor); if (result != 0) return result; result = x.Patch.CompareTo(y.Patch); if (result != 0) return result; NuGetVersion legacyX = x as NuGetVersion; NuGetVersion legacyY = y as NuGetVersion; result = CompareLegacyVersion(legacyX, legacyY); if (result != 0) return result; if (_mode != VersionComparison.Version) { // compare release labels if (x.IsPrerelease && !y.IsPrerelease) return -1; if (!x.IsPrerelease && y.IsPrerelease) return 1; if (x.IsPrerelease && y.IsPrerelease) { result = CompareReleaseLabels(x.ReleaseLabels, y.ReleaseLabels); if (result != 0) return result; } // compare the metadata if (_mode == VersionComparison.VersionReleaseMetadata) { result = StringComparer.OrdinalIgnoreCase.Compare(x.Metadata ?? string.Empty, y.Metadata ?? string.Empty); if (result != 0) return result; } } } return 0; }
/// <summary> /// Compares the given versions using the VersionComparison mode. /// </summary> public static int Compare(SemanticVersion version1, SemanticVersion version2, VersionComparison versionComparison) { IVersionComparer comparer = new VersionComparer(versionComparison); return comparer.Compare(version1, version2); }
/// <summary> /// Determines if both versions are equal. /// </summary> public bool Equals(SemanticVersion x, SemanticVersion y) { return Compare(x, y) == 0; }
/// <summary> /// Creates a SemanticVersion from an existing SemanticVersion /// </summary> public SemanticVersion(SemanticVersion version) : this(version.Major, version.Minor, version.Patch, version.ReleaseLabels, version.Metadata) { }