예제 #1
0
 /// <summary>
 /// Full constructor. Used by <see cref="TryParse(string, bool)"/> and methods like <see cref="GetDirectSuccessors(bool, ReleaseTagVersion)"/>.
 /// </summary>
 /// <param name="tag">Original text version. Can be null: the <see cref="ReleaseTagFormat.Normalized"/> is automatically used to compute <see cref="OriginalTagText"/>.</param>
 /// <param name="major">Major (between 0 and 99999).</param>
 /// <param name="minor">Minor (between 0 and 99999).</param>
 /// <param name="patch">Patch (between 0 and 9999).</param>
 /// <param name="preReleaseName">Not null (empty for release). Can be any string [a-z]*.</param>
 /// <param name="preReleaseNameIdx">The index in StandardPreReleaseNames.</param>
 /// <param name="preReleaseNumber">Number between 0 (for release or first prerelease) and 99.</param>
 /// <param name="preReleaseFix">Number between 0 (not a fix, first actual fix starts at 1) and 99.</param>
 /// <param name="kind">One of the <see cref="ReleaseTagKind"/> value. Must be coherent with the other parameters.</param>
 ReleaseTagVersion(string tag, int major, int minor, int patch, string preReleaseName, int preReleaseNameIdx, int preReleaseNumber, int preReleaseFix, ReleaseTagKind kind)
 {
     Debug.Assert(_standardNames.Length == MaxPreReleaseNameIdx + 1);
     Debug.Assert(major >= 0 && major <= MaxMajor);
     Debug.Assert(minor >= 0 && minor <= MaxMinor);
     Debug.Assert(patch >= 0 && patch <= MaxPatch);
     Debug.Assert(preReleaseName != null);
     Debug.Assert(Regex.IsMatch(preReleaseName, "[a-z]*", RegexOptions.CultureInvariant));
     Debug.Assert(preReleaseNameIdx >= -1);
     Debug.Assert((preReleaseName.Length == 0 && preReleaseNameIdx == -1)
                  ||
                  (preReleaseName.Length > 0 && preReleaseNameIdx >= 0 && preReleaseNameIdx <= MaxPreReleaseNameIdx));
     Debug.Assert(preReleaseNumber >= 0 && preReleaseNumber <= MaxPreReleaseNumber);
     Debug.Assert(PreReleasePatch >= 0 && PreReleasePatch <= MaxPreReleaseNumber);
     Debug.Assert(kind != ReleaseTagKind.Malformed);
     Major = major;
     Minor = minor;
     Patch = patch;
     PreReleaseNameFromTag = preReleaseName;
     PreReleaseNameIdx     = preReleaseNameIdx;
     PreReleaseNumber      = preReleaseNumber;
     PreReleasePatch       = preReleaseFix;
     Kind            = kind;
     Marker          = kind.ToStringMarker();
     OriginalTagText = tag ?? ToString();
     //
     Debug.Assert(((Kind & ReleaseTagKind.PreRelease) != 0) == IsPreRelease);
     _orderedVersion = new SOrderedVersion()
     {
         Number = ComputeOrderedVersion(major, minor, patch, preReleaseNameIdx, preReleaseNumber, preReleaseFix)
     };
     DefinitionStrength = ComputeDefinitionStrength();
 }
예제 #2
0
 /// <summary>
 /// Obtains the marker as a string. <see cref="string.Empty"/> if this is nor marked.
 /// </summary>
 /// <param name="this">This <see cref="ReleaseTagKind"/>.</param>
 /// <param name="prefixPlus">Optionally removes the '+' build meta separator.</param>
 /// <returns>A string with the marker if any.</returns>
 public static string ToStringMarker(this ReleaseTagKind @this, bool prefixPlus = true)
 {
     if ((@this & ReleaseTagKind.MarkedInvalid) != 0)
     {
         return(prefixPlus ? "+invalid" : "invalid");
     }
     return(string.Empty);
 }
예제 #3
0
 /// <summary>
 /// Returns true if this tag is marked with <see cref="ReleaseTagKind.MarkedInvalid"/>.
 /// </summary>
 /// <param name="this"></param>
 /// <returns>True if MarkedInvalid.</returns>
 public static bool IsMarkedInvalid(this ReleaseTagKind @this)
 {
     return((@this & ReleaseTagKind.MarkedInvalid) != 0);
 }
예제 #4
0
        /// <summary>
        /// Attempts to parse a string like "4.0.0", "1.0-5-alpha.0", "1.0-5-rc.12.87".
        /// Initial 'v' (or 'V') is optional (GitHub convention).
        /// Numbers can not start with a 0 (except if it is 0).
        /// The pre release name (alpha, beta, gamma, ..., rc) must be any number of a-z (all lower case, no digit nor underscore).
        /// The pre release name can be followed by ".0" or a greater number (not greater than <see cref="MaxPreReleaseNumber"/>).
        /// Returns a ReleaseTagVersion where <see cref="ReleaseTagVersion.IsValid"/> is false if the string is not valid: <see cref="ParseErrorMessage"/>
        /// gives more information.
        /// </summary>
        /// <param name="s">String to parse.</param>
        /// <param name="analyseInvalidTag">
        /// True to analyse an invalid string for a more precise error:
        /// if the tag looks like a release tag, the <see cref="ParseErrorMessage"/> will describe the issue.
        /// </param>
        /// <returns>Resulting version (can be invalid).</returns>
        public static ReleaseTagVersion TryParse(string s, bool analyseInvalidTag = false)
        {
            if (s == null)
            {
                throw new ArgumentNullException();
            }
            Match m = _regexStrict.Match(s);

            if (!m.Success)
            {
                if (analyseInvalidTag)
                {
                    m = _regexApprox.Match(s);
                    if (m.Success)
                    {
                        return(new ReleaseTagVersion(s, true, SyntaxErrorHelper(s, m)));
                    }
                }
                return(new ReleaseTagVersion(s, false, _noTagParseErrorMessage));
            }
            string sMajor = m.Groups[1].Value;
            string sMinor = m.Groups[2].Value;
            string sPatch = m.Groups[3].Value;

            int major, minor, patch;

            if (!Int32.TryParse(sMajor, out major) || major > MaxMajor)
            {
                return(new ReleaseTagVersion(s, true, string.Format("Incorrect Major version. Must not be greater than {0}.", MaxMajor)));
            }
            if (!Int32.TryParse(sMinor, out minor) || minor > MaxMinor)
            {
                return(new ReleaseTagVersion(s, true, string.Format("Incorrect Minor version. Must not be greater than {0}.", MaxMinor)));
            }
            if (!Int32.TryParse(sPatch, out patch) || patch > MaxPatch)
            {
                return(new ReleaseTagVersion(s, true, string.Format("Incorrect Patch version. Must not be greater than {0}.", MaxPatch)));
            }

            string sPRName       = m.Groups[4].Value;
            string sPRNum        = m.Groups[5].Value;
            string sPRFix        = m.Groups[6].Value;
            string sBuldMetaData = m.Groups[7].Value;

            int prNameIdx = GetPreReleaseNameIdx(sPRName);
            int prNum     = 0;
            int prFix     = 0;

            if (prNameIdx >= 0)
            {
                if (sPRFix.Length > 0)
                {
                    prFix = Int32.Parse(sPRFix);
                }
                if (sPRNum.Length > 0)
                {
                    prNum = Int32.Parse(sPRNum);
                }
                if (prFix == 0 && prNum == 0 && sPRNum.Length > 0)
                {
                    return(new ReleaseTagVersion(s, true, string.Format("Incorrect '.0' Release Number version. 0 can appear only to fix the first pre release (ie. '.0.F' where F is between 1 and {0}).", MaxPreReleaseFix)));
                }
            }
            ReleaseTagKind kind = prNameIdx >= 0 ? ReleaseTagKind.PreRelease : ReleaseTagKind.OfficialRelease;

            if (sBuldMetaData.Length > 0)
            {
                kind |= ReleaseTagKind.MarkedInvalid;
            }
            return(new ReleaseTagVersion(s, major, minor, patch, sPRName, prNameIdx, prNum, prFix, kind));
        }