/// <summary> /// Construct a new semantic version from a version string. /// </summary> /// <param name="input">The version string.</param> /// <param name="loose">When true, be more forgiving of some invalid version specifications.</param> /// <exception cref="System.ArgumentException">Thrown when the version string is invalid.</exception> public Version(string input, bool loose = false) { _inputString = input; var regex = loose ? looseRegex : strictRegex; var match = regex.Match(input); if (!match.Success) { throw new ArgumentException($"Invalid version string: {input}"); } Major = Int32.Parse(match.Groups[1].Value); Minor = Int32.Parse(match.Groups[2].Value); Patch = Int32.Parse(match.Groups[3].Value); if (match.Groups[4].Success) { var inputPreRelease = match.Groups[5].Value; var cleanedPreRelease = PreReleaseVersion.Clean(inputPreRelease); if (!loose && inputPreRelease != cleanedPreRelease) { throw new ArgumentException($"Invalid pre-release version: {inputPreRelease}"); } PreRelease = cleanedPreRelease; } if (match.Groups[6].Success) { Build = match.Groups[7].Value; } }
/// <summary> /// Return a cleaned, normalised version string. /// </summary> /// <returns>The cleaned version string.</returns> public string Clean() { var preReleaseString = PreRelease == null ? "" : $"-{PreReleaseVersion.Clean(PreRelease)}"; var buildString = Build == null ? "" : $"+{Build}"; return($"{Major}.{Minor}.{Patch}{preReleaseString}{buildString}"); }
// Implement IComparable<Version> public int CompareTo(Version other) { if (ReferenceEquals(other, null)) { return(1); } foreach (var c in PartComparisons(other)) { if (c != 0) { return(c); } } return(PreReleaseVersion.Compare(this.PreRelease, other.PreRelease)); }