示例#1
0
        static PackageDBTests()
        {
            T0 = ArtifactType.Register("T0", true);
            T1 = ArtifactType.Register("T1", true, ';');
            T2 = ArtifactType.Register("T2", true, ',');

            PLevel0V1 = Create(SVersion.Parse("1.0.0"));
            PLevel0V2 = Create(SVersion.Parse("2.0.0"));
            PLevel0V3 = Create(SVersion.Parse("3.0.0"));
            PLevel0V4 = Create(SVersion.Parse("4.0.0"));
            PLevel0   = new PackageInfo[][] { PLevel0V1, PLevel0V2, PLevel0V3, PLevel0V4 };
            PackageInfo[] Create(SVersion v)
            {
                var result = new PackageInfo[60];

                for (int i = 0; i < result.Length; ++i)
                {
                    var type = i < (result.Length / 3)
                                ? T0
                                : i < (2 * result.Length / 3)
                                    ? T1
                                    : T2;
                    var p = new PackageInfo();
                    p.Key = new ArtifactInstance(type, $"P{i}", v);
                    p.FeedNames.Add($"F{i / (result.Length / 10)}");
                    result[i] = p;
                }
                return(result);
            }
        }
示例#2
0
        public void this_is_not_a_csversion(string t)
        {
            var v = SVersion.Parse(t);

            v.AsCSVersion.Should().BeNull();
            v.ToNormalizedString().Should().Be(t);
        }
        public void collecting_multiple_versions(string versions, string result)
        {
            var v = versions.Split(',').Select(x => SVersion.Parse(x.Trim())).ToArray();
            var q = new PackageQualityVersions(v, false);

            q.ToString().Should().Be(result);
        }
示例#4
0
        /// <summary>
        /// Parses a full path and extracts a <see cref="SVersion"/>.
        /// </summary>
        /// <param name="fullPath">The full path of the package.</param>
        /// <returns>The <see cref="SVersion"/> of the package.</returns>
        static SVersion ParseVersionFromPackagePath(string fullPath)
        {
            var fName = Path.GetFileNameWithoutExtension(fullPath);
            int idxV  = Regex.Match(fName, "\\.\\d").Index;
            var id    = fName.Substring(0, idxV);

            return(SVersion.Parse(fName.Substring(idxV + 1)));
        }
示例#5
0
        /// <summary>
        /// Parses a full path and extracts a <see cref="LocalNPMPackageFile"/>.
        /// </summary>
        /// <param name="fullPath">The full path of the package.</param>
        /// <returns>The local NPM package file.</returns>
        public static LocalNPMPackageFile Parse(string fullPath)
        {
            var fName = Path.GetFileNameWithoutExtension(fullPath);
            int idxV  = Regex.Match(fName, "-\\d").Index;
            var id    = fName.Substring(0, idxV);
            var v     = SVersion.Parse(fName.Substring(idxV + 1));

            return(new LocalNPMPackageFile(fullPath, id, v));
        }
示例#6
0
        public void collecting_best_version(string versions, string result)
        {
            var v = versions.Split(',').Select(x => SVersion.Parse(x.Trim())).ToArray();
            var q = new PackageQualityVector(v, false);

            q.ToString().Should().Be(result);
            q.IsValid.Should().Be(result.Length > 0);
            q.ActualCount.Should().Be(result.Length > 0 ? 1 : 0);
        }
示例#7
0
        /// <summary>
        /// Adds the <see cref="NPMSolution"/> to the <paramref name="globalInfo"/>
        /// </summary>
        /// <param name="this">This global info.</param>
        /// <param name="solution">The NPM solution.</param>
        /// <returns>This info.</returns>
        public static StandardGlobalInfo AddNPM(this StandardGlobalInfo globalInfo, NPMSolution solution)
        {
            SVersion minmimalNpmVersionRequired = SVersion.Create(6, 7, 0);
            string   npmVersion = globalInfo.Cake.NpmGetNpmVersion();

            if (SVersion.Parse(npmVersion) < minmimalNpmVersionRequired)
            {
                globalInfo.Cake.TerminateWithError("Outdated npm. Version older than v6.7.0 are known to fail on publish.");
            }
            globalInfo.RegisterSolution(solution);
            return(globalInfo);
        }
示例#8
0
 static IEnumerable <SVersion> GetAllVersionsFromFeed(string path, string packageId)
 {
     // Do not use TryParse here: pattern MUST be a version since we remove
     // .symbols and "sub packages" (like CK.Text.Virtual for CK.Text by filtering only
     // suffixes that start with a digit.
     // If an error occurs here it should be an exception since this should never happen.
     // Note: Max on reference type returns null on empty source.
     return(System.IO.Directory.EnumerateFiles(path, packageId + ".*.nupkg")
            .Select(p => System.IO.Path.GetFileName(p))
            .Select(n => n.Substring(packageId.Length + 1, n.Length - packageId.Length - 7))
            .Where(n => !n.EndsWith(".symbols") && Char.IsDigit(n, 0))
            .Select(v => SVersion.Parse(v)));
 }
示例#9
0
        public void pre_release_with_standard_names_nugetV2_mappings(string tag, string nuget, bool isPrereleasePatch)
        {
            CSVersion fromShortForm = CSVersion.Parse(nuget);
            CSVersion t             = CSVersion.TryParse(tag);

            Assert.That(t, Is.EqualTo(fromShortForm));

            Assert.That(t.IsValid);
            Assert.That(t.IsPrerelease);
            Assert.That(t.IsPreReleasePatch, Is.EqualTo(isPrereleasePatch));
            Assert.That(t.ToString(CSVersionFormat.LongForm), Is.EqualTo(tag));
            Assert.That(t.ToString(CSVersionFormat.Normalized), Is.EqualTo(nuget));
            Assert.That(SVersion.Parse(nuget).Prerelease.Length, Is.LessThanOrEqualTo(20));
        }
示例#10
0
        static void DumpVersionInfo(CIBuildDescriptor buildInfo, CSVersion t)
        {
            var nugetV2Build      = t.ToString(CSVersionFormat.Normalized, buildInfo);
            int nugetV2BuildSNLen = SVersion.Parse(nugetV2Build).Prerelease.Length;

            Console.WriteLine("{0}, CI = {1}, NuGet = {2}, NuGet CI = {3}, NugetV2Build.SpecialName.Length = {4}",
                              t,
                              t.ToString(CSVersionFormat.Normalized, buildInfo),
                              t.ToString(CSVersionFormat.Normalized),
                              nugetV2Build,
                              nugetV2BuildSNLen
                              );
            Assert.That(nugetV2BuildSNLen, Is.LessThanOrEqualTo(20));
        }
示例#11
0
        internal static CIReleaseInfo Create(
            Commit commit,
            CIBranchVersionMode ciVersionMode,
            string ciBuildName,
            StringBuilder errors,
            BasicCommitInfo info)
        {
            var       actualBaseTag = info?.MaxCommit.ThisTag;
            CSVersion ciBaseTag = actualBaseTag ?? CSVersion.VeryFirstVersion;
            SVersion  ciBuildVersionNuGet = null, ciBuildVersion = null;

            // If there is no base release found, we fall back to ZeroTimedBased mode.
            if (ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null)
            {
                DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime;
                string   vS          = CIBuildDescriptor.CreateSemVerZeroTimed(ciBuildName, timeRelease);
                string   vN          = CIBuildDescriptor.CreateShortFormZeroTimed(ciBuildName, timeRelease);
                if (actualBaseTag != null)
                {
                    string buildMetaData = "+v" + actualBaseTag;
                    vS += buildMetaData;
                    vN += buildMetaData;
                }
                ciBuildVersion      = SVersion.Parse(vS);
                ciBuildVersionNuGet = SVersion.Parse(vN, false);
                return(new CIReleaseInfo(ciBaseTag, 0, ciBuildVersion, ciBuildVersionNuGet, true));
            }
            Debug.Assert(ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null);
            CIBuildDescriptor ci = new CIBuildDescriptor {
                BranchName = ciBuildName, BuildIndex = info.BelowDepth
            };

            if (!ci.IsValidForShortForm)
            {
                errors.AppendLine("Due to ShortForm (NuGet V2 compliance) limitation, the branch name must not be longer than 8 characters. ");
                errors.Append("Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: ")
                .AppendLine()
                .Append($@"<Branch Name=""{ci.BranchName}"" VersionName=""{ci.BranchName.Substring( 0, 8 )}"" ... />.")
                .AppendLine();
            }
            else
            {
                ciBuildVersion      = SVersion.Parse(actualBaseTag.ToString(CSVersionFormat.Normalized, ci));
                ciBuildVersionNuGet = SVersion.Parse(actualBaseTag.ToString(CSVersionFormat.NuGetPackage, ci), false);
            }
            Debug.Assert(ciBuildVersion == null || errors.Length == 0);
            return(ciBuildVersion != null
                    ? new CIReleaseInfo(ciBaseTag, info.BelowDepth, ciBuildVersion, ciBuildVersionNuGet, false)
                    : null);
        }
        public void pre_release_with_standard_names_and_fix_number_nugetV2_mappings(string tag, string nuget)
        {
            CSVersion fromShortForm = CSVersion.Parse(nuget);
            CSVersion t             = CSVersion.TryParse(tag);

            Assert.That(t, Is.EqualTo(fromShortForm));

            Assert.That(t.IsValid);
            Assert.That(t.IsPrerelease);
            Assert.That(t.IsPreReleasePatch);
            Assert.That(t.PrereleasePatch, Is.GreaterThan(0));
            Assert.That(t.NormalizedText, Is.EqualTo(tag));
            Assert.That(t.ToString(CSVersionFormat.NuGetPackage), Is.EqualTo(nuget));
            Assert.That(SVersion.Parse(nuget).Prerelease.Length, Is.LessThanOrEqualTo(20));
        }
示例#13
0
        //static int _greatersuccessorCount = 0;

        CSVersion CheckMapping(long v)
        {
            if (v < 0 || v > CSVersion.VeryLastVersion.OrderedVersion)
            {
                Assert.Throws <ArgumentException>(() => CSVersion.Create(v));
                return(null);
            }
            var t = CSVersion.Create(v);

            Assert.That((v == 0) == !t.IsValid);
            Assert.That(t.OrderedVersion, Is.EqualTo(v));
            var sSemVer     = t.NormalizedText;
            var tSemVer     = CSVersion.TryParse(sSemVer);
            var tNormalized = CSVersion.TryParse(t.ToString(CSVersionFormat.Normalized));

            Assert.That(tSemVer.OrderedVersion, Is.EqualTo(v));
            Assert.That(tNormalized.OrderedVersion, Is.EqualTo(v));
            Assert.That(tNormalized.Equals(t));
            Assert.That(tSemVer.Equals(t));
            Assert.That(tNormalized.Equals((object)t));
            Assert.That(tSemVer.Equals((object)t));
            Assert.That(tNormalized.CompareTo(t) == 0);
            Assert.That(tSemVer == t);
            Assert.That(tSemVer.ToString(), Is.EqualTo(t.ToString()));
            Assert.That(tNormalized.ToString(), Is.EqualTo(t.ToString()));
            // Successors/Predecessors check.
            var vSemVer = SVersion.Parse(sSemVer);
            int count   = 0;

            foreach (var succ in t.GetDirectSuccessors(false))
            {
                ++count;
                Assert.That(succ.IsDirectPredecessor(t));
                var vSemVerSucc = SVersion.Parse(succ.NormalizedText);
                Assert.That(vSemVer < vSemVerSucc, "{0} < {1}", vSemVer, vSemVerSucc);
            }
            //if( count > _greatersuccessorCount )
            //{
            //    Console.WriteLine( " -> - found {0} successors for '{1}':", count, t );
            //    Console.WriteLine( "      " + string.Join( ", ", t.GetDirectSuccessors( false ).Select( s => s.ToString() ) ) );
            //    var closest = t.GetDirectSuccessors( true ).Select( s => s.ToString() ).ToList();
            //    Console.WriteLine( "    - {0} closest successors:", closest.Count, t );
            //    Console.WriteLine( "      " + string.Join( ", ", closest ) );
            //    _greatersuccessorCount = count;
            //}
            return(t);
        }
        public void testing_cibuild_timebased()
        {
            var now  = DateTime.UtcNow;
            var more = now.AddSeconds(1);
            {
                var sV = CIBuildDescriptor.CreateSemVerZeroTimed("develop", now);
                var v  = SVersion.Parse(sV);
                v.AsCSVersion.Should().BeNull();

                var vMore = SVersion.Parse(CIBuildDescriptor.CreateSemVerZeroTimed("develop", more));
                vMore.Should().BeGreaterThan(v);
            }
            {
                var sV = CIBuildDescriptor.CreateShortFormZeroTimed("develop", now);
                var v  = SVersion.Parse(sV);
                v.AsCSVersion.Should().BeNull();

                var vMore = SVersion.Parse(CIBuildDescriptor.CreateShortFormZeroTimed("develop", more));
                vMore.Should().BeGreaterThan(v);
            }
        }
        public int Compare(string x, string y)
        {
            var vX = SVersion.Parse(x, handleCSVersion: false);
            var vY = SVersion.Parse(y, handleCSVersion: false);

            CheckValid(x);
            CheckValid(y);
            Assert.That(vX.Prerelease.Length <= 20, "{0} => PreRelease must not contain more than 20 characters (lenght is {1}).", x, x.Length);
            Assert.That(vY.Prerelease.Length <= 20, "{0} => PreRelease must not contain more than 20 characters (lenght is {1}).", y, y.Length);
            int cmp = vX.Major - vY.Major;

            if (cmp != 0)
            {
                return(cmp);
            }
            cmp = vX.Minor - vY.Minor;
            if (cmp != 0)
            {
                return(cmp);
            }
            cmp = vX.Patch - vY.Patch;
            if (cmp != 0)
            {
                return(cmp);
            }
            if (vX.Prerelease.Length == 0 && vY.Prerelease.Length == 0)
            {
                return(0);
            }
            if (vX.Prerelease.Length == 0)
            {
                return(1);
            }
            if (vY.Prerelease.Length == 0)
            {
                return(-1);
            }
            return(StringComparer.InvariantCultureIgnoreCase.Compare(vX.Prerelease, vY.Prerelease));
        }
示例#16
0
        public void pre_release_with_standard_names_and_fix_number_normalized_mappings(string longF, string shortF)
        {
            CSVersion tS = CSVersion.Parse(shortF);
            CSVersion tL = CSVersion.TryParse(longF);

            Assert.That(tL, Is.EqualTo(tS.ToLongForm()));
            Assert.That(tS, Is.EqualTo(tL.ToNormalizedForm()));

            Assert.That(tL.IsValid);
            Assert.That(tL.IsPrerelease);
            Assert.That(tL.IsPreReleasePatch);
            Assert.That(tL.PrereleasePatch, Is.GreaterThan(0));
            Assert.That(tL.ToString(CSVersionFormat.Normalized), Is.EqualTo(shortF));
            Assert.That(tS.ToString(CSVersionFormat.LongForm), Is.EqualTo(longF));
            Assert.That(tS.NormalizedText, Is.EqualTo(shortF));
            Assert.That(tL.NormalizedText, Is.EqualTo(longF));
            var buildInfo = tS.ToString(CSVersionFormat.Normalized, new CIBuildDescriptor()
            {
                BuildIndex = CIBuildDescriptor.MaxBuildIndex, BranchName = "ABCDEFGH"
            });

            Assert.That(SVersion.Parse(buildInfo).Prerelease.Length, Is.LessThanOrEqualTo(20));
        }
        public void display_versions_and_CI_version(string version, string after)
        {
            var buildInfo = new CIBuildDescriptor()
            {
                BranchName = "develop", BuildIndex = 15
            };
            CSVersion v     = CSVersion.TryParse(version);
            string    vCI   = v.ToString(CSVersionFormat.Normalized, buildInfo);
            CSVersion vNext = CSVersion.Create(v.OrderedVersion + 1);

            Console.WriteLine("Version = {0}, CI = {1}, Next = {2}", v, vCI, vNext);

            var vSemVer     = SVersion.Parse(v.ToString(CSVersionFormat.Normalized));
            var vCISemVer   = SVersion.Parse(vCI);
            var vNextSemVer = SVersion.Parse(vNext.ToString(CSVersionFormat.Normalized));

            Assert.That(vSemVer < vCISemVer, "{0} < {1}", vSemVer, vCISemVer);
            Assert.That(vCISemVer < vNextSemVer, "{0} < {1}", vCISemVer, vNextSemVer);

            foreach (var vAfter in after.Split(',').Select(s => SVersion.Parse(s.Trim())))
            {
                Assert.That(vAfter.CompareTo(vCISemVer) > 0, "{0} > {1}", vAfter, vCISemVer);
            }
        }
        public void CIBuildVersion_LastReleaseBased_are_correctely_ordered(string tag)
        {
            var t     = CSVersion.TryParse(tag);
            var v     = SVersion.Parse(t.ToString(CSVersionFormat.Normalized));
            var tNext = CSVersion.Create(t.OrderedVersion + 1);
            var vNext = SVersion.Parse(tNext.ToString(CSVersionFormat.Normalized));
            var tPrev = CSVersion.Create(t.OrderedVersion - 1);
            var vPrev = SVersion.Parse(tPrev.ToString(CSVersionFormat.Normalized));

            void CheckLower(SVersion v1, SVersion v2)
            {
                Assert.That(v1 < v2, "{0} < {1}", v1, v2);
                Assert.That(v2 > v1, "{0} > {1}", v2, v1);

                SVersion v1low = SVersion.Parse(v1.ParsedText.ToLowerInvariant());
                SVersion v2low = SVersion.Parse(v2.ParsedText.ToLowerInvariant());

                Assert.That(v1low < v2low, "{0} < {1} (lowercase)", v1low, v2low);
                Assert.That(v2low > v1low, "{0} > {1} (lowercase)", v2low, v1low);

                SVersion v1up = SVersion.Parse(v1.ParsedText.ToUpperInvariant());
                SVersion v2up = SVersion.Parse(v2.ParsedText.ToUpperInvariant());

                Assert.That(v1up < v2up, "{0} < {1} (uppercase)", v1up, v2up);
                Assert.That(v2up > v1up, "{0} > {1} (uppercase)", v2up, v1up);
            }

            CheckLower(vPrev, v);
            CheckLower(v, vNext);

            var sNuGet     = t.ToString(CSVersionFormat.NuGetPackage);
            var sNuGetPrev = tPrev.ToString(CSVersionFormat.NuGetPackage);
            var sNuGetNext = tNext.ToString(CSVersionFormat.NuGetPackage);

            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetPrev, sNuGet) < 0, "{0} < {1}", sNuGetPrev, sNuGet);
            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGet, sNuGetNext) < 0, "{0} < {1}", sNuGet, sNuGetNext);


            CIBuildDescriptor ci = new CIBuildDescriptor {
                BranchName = "dev", BuildIndex = 1
            };

            string   sCI = t.ToString(CSVersionFormat.Normalized, ci);
            SVersion vCi = SVersion.Parse(sCI);

            CheckLower(v, vCi);
            CheckLower(vCi, vNext);

            var sNuGetCI = t.ToString(CSVersionFormat.NuGetPackage, ci);

            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGet, sNuGetCI) < 0, "{0} < {1}", sNuGet, sNuGetCI);
            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCI, sNuGetNext) < 0, "{0} < {1}", sNuGetCI, sNuGetNext);

            string   sCiNext = tNext.ToString(CSVersionFormat.Normalized, ci);
            SVersion vCiNext = SVersion.Parse(sCiNext);

            CheckLower(vCi, vCiNext);
            CheckLower(vNext, vCiNext);

            var sNuGetCINext = tNext.ToString(CSVersionFormat.NuGetPackage, ci);

            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCINext, sNuGetCI) > 0, "{0} > {1}", sNuGetCINext, sNuGetCI);
            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCINext, sNuGetNext) > 0, "{0} > {1}", sNuGetCINext, sNuGetNext);

            string   sCiPrev = tPrev.ToString(CSVersionFormat.Normalized, ci);
            SVersion vCiPrev = SVersion.Parse(sCiPrev);

            CheckLower(vPrev, vCiPrev);
            CheckLower(vCiPrev, v);
            CheckLower(vCiPrev, vCiNext);

            var sNuGetCIPrev = tPrev.ToString(CSVersionFormat.NuGetPackage, ci);

            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCIPrev, sNuGetPrev) > 0, "{0} > {1}", sNuGetCIPrev, sNuGetPrev);
            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCIPrev, sNuGet) < 0, "{0} < {1}", sNuGetCIPrev, sNuGet);
            Assert.That(NuGetV2StringComparer.DefaultComparer.Compare(sNuGetCIPrev, sNuGetCINext) < 0, "{0} < {1}", sNuGetCIPrev, sNuGetCINext);
        }
示例#19
0
        /// <summary>
        /// Initializes a new <see cref="RepositoryInfo"/> on a <see cref="Repository"/>.
        /// </summary>
        /// <param name="r">The rpository (can be invalid and even null).</param>
        /// <param name="options">Optional options.</param>
        public RepositoryInfo(Repository r, RepositoryInfoOptions options = null)
        {
            Options       = options ?? new RepositoryInfoOptions();
            CommitDateUtc = InformationalVersion.ZeroCommitDate;
            if (r == null)
            {
                RepositoryError = "No Git repository.";
            }
            else
            {
                Commit commit;
                CIBranchVersionMode ciVersionMode;
                string ciBuildName;
                RepositoryError = TryFindCommit(options, r, out commit, out ciVersionMode, out ciBuildName);
                Debug.Assert((ciVersionMode != CIBranchVersionMode.None) == (ciBuildName != null));
                if (commit != null)
                {
                    CommitSha           = commit.Sha;
                    CommitDateUtc       = commit.Author.When.UtcDateTime;
                    IsDirtyExplanations = ComputeIsDirty(r, commit, options);
                    if (!IsDirty || options.IgnoreDirtyWorkingFolder)
                    {
                        StringBuilder errors    = new StringBuilder();
                        TagCollector  collector = new TagCollector(errors,
                                                                   r,
                                                                   options.StartingVersionForCSemVer,
                                                                   options.OverriddenTags,
                                                                   options.SingleMajor);
                        if (errors.Length == 0)
                        {
                            ExistingVersions = collector.ExistingVersions.TagCommits;

                            var info = collector.GetCommitInfo(commit);
                            Debug.Assert(info != null);

                            CommitInfo = info;

                            var rawPossible = info.PossibleVersions;
                            IEnumerable <CSVersion> possibles = rawPossible;
                            if (options.OnlyPatch)
                            {
                                possibles = possibles.Where(v => v.IsPatch);
                            }
                            if (options.SingleMajor.HasValue)
                            {
                                possibles = possibles.Where(v => v.Major == options.SingleMajor.Value);
                            }
                            PossibleVersions = possibles != rawPossible?possibles.ToList() : rawPossible;

                            var rawNextPossible = info.NextPossibleVersions;
                            IEnumerable <CSVersion> nextPossibles = rawNextPossible;
                            if (options.OnlyPatch)
                            {
                                nextPossibles = nextPossibles.Where(v => v.IsPatch);
                            }
                            if (options.SingleMajor.HasValue)
                            {
                                nextPossibles = nextPossibles.Where(v => v.Major == options.SingleMajor.Value);
                            }
                            NextPossibleVersions = nextPossibles != rawNextPossible?nextPossibles.ToList() : rawNextPossible;

                            var thisCommit = info.BasicInfo?.UnfilteredThisCommit;
                            if (info.BasicInfo?.BestCommit?.ThisTag > thisCommit?.ThisTag)
                            {
                                BetterExistingVersion = info.BasicInfo.BestCommit;
                            }
                            if (thisCommit != null)
                            {
                                if (PossibleVersions.Contains(thisCommit.ThisTag))
                                {
                                    ValidReleaseTag = thisCommit.ThisTag;
                                }
                                else
                                {
                                    ReleaseTagIsNotPossibleError = true;
                                    errors.Append("Release tag '")
                                    .Append(thisCommit.ThisTag.ParsedText)
                                    .AppendLine("' is not valid here. ");
                                    errors.Append("Valid tags are: ")
                                    .Append(string.Join(", ", PossibleVersions))
                                    .AppendLine();
                                    if (PossibleVersions != rawPossible &&
                                        rawPossible.Contains(thisCommit.ThisTag))
                                    {
                                        errors.AppendLine("Note: this version is invalid because of <SingleMajor> or <OnlyPatch> setting in RepositoryInfo.xml.");
                                    }
                                }
                            }
                            else
                            {
                                // There is no release tag on the commit point.
                                if (ciBuildName != null)
                                {
                                    CIRelease = CIReleaseInfo.Create(commit, ciVersionMode, ciBuildName, errors, info.BasicInfo);
                                }
                            }
                        }
                        if (errors.Length > 0)
                        {
                            ReleaseTagError = errors.ToString();
                        }
                    }

                    // Conclusion:
                    if (CIRelease != null)
                    {
                        //ContentOrFinalNuGetVersion =
                        FinalNuGetVersion = CIRelease.BuildVersionNuGet;
                        FinalSemVersion   = CIRelease.BuildVersion;
                    }
                    else if (ValidReleaseTag != null)
                    {
                        FinalNuGetVersion = SVersion.Parse(ValidReleaseTag.ToString(CSVersionFormat.NuGetPackage), false);
                        FinalSemVersion   = ValidReleaseTag;
                    }
                }
            }
            // Handles FinalInformationalVersion and SVersion.ZeroVersion for versions if needed.
            if (FinalSemVersion == null)
            {
                FinalSemVersion           = SVersion.ZeroVersion;
                FinalNuGetVersion         = SVersion.ZeroVersion;
                FinalInformationalVersion = InformationalVersion.ZeroInformationalVersion;
            }
            else
            {
                FinalInformationalVersion = InformationalVersion.BuildInformationalVersion(FinalSemVersion.NormalizedText, FinalNuGetVersion.NormalizedText, CommitSha, CommitDateUtc);
            }
        }