static void InlineAssertInvariants(CSVersion v) { #if DEBUG if (!_alreadyInCheck && v.IsValid) { _alreadyInCheck = true; try { if (v.IsLongForm) { Debug.Assert(v.NormalizedText == ComputeLongFormVersion(v.Major, v.Minor, v.Patch, v.PrereleaseNameIdx, v.PrereleaseNumber, v.PrereleasePatch, v.BuildMetaData)); } else { Debug.Assert(v.NormalizedText == ComputeShortFormVersion(v.Major, v.Minor, v.Patch, v.PrereleaseNameIdx, v.PrereleaseNumber, v.PrereleasePatch, v.BuildMetaData)); } //// Systematically checks that a valid CSVersion can be parsed back in Long or Short form. Debug.Assert(SVersion.TryParse(v.ToString(CSVersionFormat.Normalized)).Equals(v.ToNormalizedForm())); Debug.Assert(SVersion.TryParse(v.ToString(CSVersionFormat.LongForm)).Equals(v.ToLongForm())); } finally { _alreadyInCheck = false; } } #endif }
static SVersion DoCreate(string?parsedText, int major, int minor, int patch, string prerelease, string buildMetaData, bool handleCSVersion, bool checkBuildMetaDataSyntax) { Debug.Assert(prerelease != null && buildMetaData != null); if (major < 0 || minor < 0 || patch < 0) { return(new SVersion("Major, minor and patch must positive or 0.", parsedText)); } if (buildMetaData.Length > 0 && checkBuildMetaDataSyntax) { var error = ValidateDottedIdentifiers(buildMetaData, "build metadata"); if (error != null) { return(new SVersion(error, parsedText)); } } // Try CSVersion first. CSVersion?c = CSVersion.FromSVersion(parsedText, major, minor, patch, prerelease, buildMetaData); if (handleCSVersion && c != null) { return(c); } // If it is not a CSVersion, validate the prerelease. // A Stable is not necessarily a CSVersion (too big Major/Minor/Patch). if (c == null && prerelease.Length > 0) { var error = ValidateDottedIdentifiers(prerelease, "pre-release"); if (error != null) { return(new SVersion(error, parsedText)); } } return(new SVersion(parsedText, major, minor, patch, prerelease, buildMetaData, c)); }
/// <summary> /// Relies only on <see cref="OrderedVersion"/>. /// </summary> /// <param name="other">Other release tag (can be null).</param> /// <returns>A signed number indicating the relative values of this instance and <paramref name="other"/>.</returns> public int CompareTo(CSVersion other) { if (other == null) { return(1); } return(_orderedVersion.Number.CompareTo(other._orderedVersion.Number)); }
/// <summary> /// Versions are equal if their <see cref="OrderedVersion"/> are equals. /// No other members are used for equality and comparison. /// </summary> /// <param name="other">Other version.</param> /// <returns>True if they have the same OrderedVersion.</returns> public bool Equals(CSVersion other) { if (other == null) { return(false); } return(_orderedVersion.Number == other._orderedVersion.Number); }
CSVersion(CSVersion other, string?buildMetaData) : base(other, buildMetaData ?? String.Empty, null) { PrereleaseNameIdx = other.PrereleaseNameIdx; PrereleaseNumber = other.PrereleaseNumber; PrereleasePatch = other.PrereleasePatch; _orderedVersion = other._orderedVersion; IsLongForm = other.IsLongForm; InlineAssertInvariants(this); }
/// <summary> /// Standard TryParse pattern that returns a boolean rather than the resulting <see cref="CSVersion"/>. /// See <see cref="TryParse(string,bool)"/>. /// </summary> /// <param name="s">String to parse.</param> /// <param name="v">Resulting version.</param> /// <param name="checkBuildMetaDataSyntax">False to opt-out of strict <see cref="SVersion.BuildMetaData"/> compliance.</param> /// <returns>True on success, false otherwise.</returns> public static bool TryParse(string s, out CSVersion v, bool checkBuildMetaDataSyntax = true) { v = null; SVersion sv = SVersion.TryParse(s, true, checkBuildMetaDataSyntax); if (!sv.IsValid) { return(false); } v = sv as CSVersion; return(v != null); }
/// <summary> /// Parses the specified string to a constrained semantic version and throws an <see cref="ArgumentException"/> /// it the resulting <see cref="SVersion"/> is not a <see cref="CSVersion"/> or <see cref="SVersion.IsValid"/> is false. /// </summary> /// <param name="s">The string to parse.</param> /// <param name="checkBuildMetaDataSyntax">False to opt-out of strict <see cref="SVersion.BuildMetaData"/> compliance.</param> /// <returns>The CSVersion object.</returns> public static CSVersion Parse(string s, bool checkBuildMetaDataSyntax = true) { SVersion sv = SVersion.TryParse(s, true, checkBuildMetaDataSyntax); if (!sv.IsValid) { throw new ArgumentException(sv.ErrorMessage, nameof(s)); } CSVersion v = sv as CSVersion; if (v == null) { throw new ArgumentException("Not a CSVersion.", nameof(s)); } return(v); }
/// <summary> /// Protected straight constructor for valid versions. /// No checks are done here. /// </summary> /// <param name="parsedText">The parsed text. Null if not parsed.</param> /// <param name="major">The major.</param> /// <param name="minor">The minor.</param> /// <param name="patch">The patch.</param> /// <param name="prerelease">The prerelease. Can be null (normalized to the empty string).</param> /// <param name="buildMetaData">The build meta data. Can be null (normalized to the empty string).</param> /// <param name="csVersion">Companion CSVersion.</param> protected SVersion(string parsedText, int major, int minor, int patch, string prerelease, string buildMetaData, CSVersion csVersion) { if (buildMetaData == null) { buildMetaData = String.Empty; } if (buildMetaData.Length > 0 && buildMetaData[0] == '+') { throw new ArgumentException("Must not start with '+'.", nameof(buildMetaData)); } _csVersion = csVersion ?? (this as CSVersion); Major = major; Minor = minor; Patch = patch; Prerelease = prerelease ?? String.Empty; BuildMetaData = buildMetaData; ParsedText = parsedText; NormalizedText = ComputeNormalizedText(major, minor, patch, prerelease); NormalizedTextWithBuildMetaData = buildMetaData.Length > 0 ? NormalizedText + '+' + buildMetaData : NormalizedText; }
/// <summary> /// Protected copy constructor with <see cref="BuildMetaData"/>. /// </summary> /// <param name="other">Origin version.</param> /// <param name="buildMetaData">New BuildMetaData. Must not be null.</param> /// <param name="csVersion">Companion CSVersion.</param> protected SVersion(SVersion other, string buildMetaData, CSVersion csVersion) { if (other == null) { throw new ArgumentNullException(nameof(other)); } if (buildMetaData == null) { throw new ArgumentNullException(nameof(buildMetaData)); } if (!other.IsValid) { throw new InvalidOperationException("Version must be valid."); } _csVersion = csVersion ?? (this as CSVersion); Major = other.Major; Minor = other.Minor; Patch = other.Patch; Prerelease = other.Prerelease; BuildMetaData = buildMetaData; NormalizedText = ComputeNormalizedText(Major, Minor, Patch, Prerelease); NormalizedTextWithBuildMetaData = buildMetaData.Length > 0 ? NormalizedText + '+' + buildMetaData : NormalizedText; }
static IReadOnlyList <CSVersion> BuildFirstPossibleVersions() { var versions = new CSVersion[3 * 9]; long v = 1L; int i = 0; while (i < 3 * 9) { versions[i++] = Create(v); if ((i % 18) == 0) { v += MulMajor - MulMinor - MulPatch + 1; } else if ((i % 9) == 0) { v += MulMinor - MulPatch + 1; } else { v += MulName; } } return(versions); }