public int CompareTo(SemVersion other) { if (other is null) { throw new ArgumentNullException(nameof(other)); } // Compare revision numbers. int revisionNumbersComparisonResult = Version.Compare(this.revisionNumbers, other.revisionNumbers); if (revisionNumbersComparisonResult != 0) { return(revisionNumbersComparisonResult); } // If we get here, the major/minor/patch are all equal. if (IsPreRelease && !other.IsPreRelease) { return(-1); } if (!IsPreRelease && other.IsPreRelease) { return(1); } // If we get here, both versions are pre-release versions. string[] preReleaseParts = PreRelease?.Split('.') ?? Enumerable.Empty <string>().ToArray(); string[] otherPreReleaseParts = other.PreRelease?.Split('.') ?? Enumerable.Empty <string>().ToArray(); for (int i = 0; i < preReleaseParts.Count() && i < otherPreReleaseParts.Count(); ++i) { int compareResult = ComparePreReleaseIdentifiers(preReleaseParts[i], otherPreReleaseParts[i]); if (compareResult != 0) { return(compareResult); } } // If we get here, all pre-release identifiers were identical. if (preReleaseParts.Count() > otherPreReleaseParts.Count()) { return(1); } else if (preReleaseParts.Count() < otherPreReleaseParts.Count()) { return(-1); } // If we get here, the versions were exactly equal. return(0); }
/// <summary> /// Compare FullVersion accroding to semver 2.0 /// <para>http://semver.org/</para> /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareTo(SemVer other) { if (ReferenceEquals(other, null)) { return(1); } if (FullVersion == other.FullVersion) { return(0); } if (Major > other.Major) { return(1); } if (Major < other.Major) { return(-1); } // Major parts are equal if (Minor > other.Minor) { return(1); } if (Minor < other.Minor) { return(-1); } // Minor parts are equal if (Patch > other.Patch) { return(1); } if (Patch < other.Patch) { return(-1); } // Patch parts are equal // Precedence refers to how versions are compared to each other when ordered. Precedence MUST be // calculated by separating the version into major, minor, patch and pre-release identifiers in that order // (Build metadata does not figure into precedence). Precedence is determined by the first difference when // comparing each of these identifiers from left to right as follows: Major, minor, and patch versions are always // compared numerically. Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. When major, minor, and patch are equal, a // pre-release version has lower precedence than a normal version. Example: 1.0.0-alpha < 1.0.0. Precedence // for two pre-release versions with the same major, minor, and patch version MUST be determined by // comparing each dot separated identifier from left to right until a difference is found as follows: identifiers // consisting of only digits are compared numerically and identifiers with letters or hyphens are compared // lexically in ASCII sort order. Numeric identifiers always have lower precedence than non-numeric identifiers. // A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers // are equal. Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. // Source: http://semver.org/ if (PreRelease == other.PreRelease) { return(0); } if (!string.IsNullOrWhiteSpace(PreRelease) && string.IsNullOrWhiteSpace(other.PreRelease)) { return(-1); } if (string.IsNullOrWhiteSpace(PreRelease) && !string.IsNullOrWhiteSpace(other.PreRelease)) { return(1); } var parts = PreRelease.Split('.'); var otherParts = other.PreRelease.Split('.'); int commonLength = Math.Min(parts.Length, otherParts.Length); for (int i = 0; i < commonLength; i++) { int part; int otherPart; bool partIsInt = int.TryParse(parts[i], out part); bool otherPartIsInt = int.TryParse(otherParts[i], out otherPart); // Numeric identifiers always have lower precedence than non-numeric identifiers if (!partIsInt && otherPartIsInt) { return(1); } if (partIsInt && !otherPartIsInt) { return(-1); } // they are both the same type if (partIsInt) { // numeric if (part > otherPart) { return(1); } if (part < otherPart) { return(-1); } } else { // non-numeric int stringCompare = string.Compare(parts[i], otherParts[i], StringComparison.Ordinal); if (stringCompare != 0) { return(stringCompare); } } } // common parts are equal if (parts.Length > otherParts.Length) { return(1); } if (parts.Length < otherParts.Length) { return(-1); } return(0); }