Ejemplo n.º 1
0
 internal RepositoryVersions( IEnumerable<TagCommit> collected, StringBuilder errors, ReleaseTagVersion startingVersionForCSemVer, bool checkCompactExistingVersions )
 {
     Debug.Assert( collected.All( c => c.ThisTag != null ) );
     _versions = collected.OrderBy( t => t.ThisTag ).ToList();
     if( _versions.Count > 0 )
     {
         var first = _versions[0].ThisTag;
         if( checkCompactExistingVersions && startingVersionForCSemVer == null && !first.IsDirectPredecessor( null ) )
         {
             errors.AppendFormat( "First existing version is '{0}' (on '{1}'). One or more previous versions are missing.", first, _versions[0].CommitSha )
                     .AppendLine();
         }
         for( int i = 0; i < _versions.Count - 1; ++i )
         {
             var prev = _versions[i].ThisTag;
             var next = _versions[i + 1].ThisTag;
             if( next.Equals( prev ) )
             {
                 errors.AppendFormat( "Version '{0}' is defined on '{1}' and '{2}'.", prev, _versions[i].CommitSha, _versions[i + 1].CommitSha )
                         .AppendLine();
             }
             else if( checkCompactExistingVersions && !next.IsDirectPredecessor( prev ) )
             {
                 errors.AppendFormat( "Missing one or more version(s) between '{0}' and '{1}'.", prev, next )
                         .AppendLine();
             }
         }
     }
 }
Ejemplo n.º 2
0
 internal CIReleaseInfo( ReleaseTagVersion ciBaseTag, int ciBaseDepth, string ciBuildVersion, string ciBuildVersionNuGet )
 {
     BaseTag = ciBaseTag;
     Depth = ciBaseDepth;
     BuildVersion = ciBuildVersion;
     BuildVersionNuGet = ciBuildVersionNuGet;
 }
Ejemplo n.º 3
0
 public TagCommit( Commit c, ReleaseTagVersion first )
 {
     Debug.Assert( c != null && first != null && first.IsValid );
     _commitSha = c.Sha;
     _contentSha = c.Tree.Sha;
     _thisTag = first;
 }
Ejemplo n.º 4
0
        internal static CIReleaseInfo Create(Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, CommitVersionInfo info)
        {
            var actualBaseTag = info.PreviousMaxTag;
            ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion;
            string            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;
                ciBuildVersion      = CreateSemVerZeroTimed(ciBuildName, timeRelease, actualBaseTag?.ToString());
                ciBuildVersionNuGet = CreateNuGetZeroTimed(ciBuildName, timeRelease);
            }
            else
            {
                Debug.Assert(ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null);
                CIBuildDescriptor ci = new CIBuildDescriptor {
                    BranchName = ciBuildName, BuildIndex = info.PreviousMaxCommitDepth
                };
                if (!ci.IsValidForNuGetV2)
                {
                    errors.AppendLine("Due to NuGet V2 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: ")
                    .AppendFormat(@"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring(0, 8))
                    .AppendLine();
                }
                else
                {
                    ciBuildVersion      = actualBaseTag.ToString(ReleaseTagFormat.SemVer, ci);
                    ciBuildVersionNuGet = actualBaseTag.ToString(ReleaseTagFormat.NuGetPackage, ci);
                }
            }
            Debug.Assert(ciBuildVersion == null || errors.Length == 0);
            return(ciBuildVersion != null ? new CIReleaseInfo(ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet) : null);
        }
Ejemplo n.º 5
0
 internal CIReleaseInfo(ReleaseTagVersion ciBaseTag, int ciBaseDepth, string ciBuildVersion, string ciBuildVersionNuGet)
 {
     BaseTag           = ciBaseTag;
     Depth             = ciBaseDepth;
     BuildVersion      = ciBuildVersion;
     BuildVersionNuGet = ciBuildVersionNuGet;
 }
Ejemplo n.º 6
0
 public TagCommit(Commit c, ReleaseTagVersion first)
 {
     Debug.Assert(c != null && first != null && first.IsValid);
     _commitSha  = c.Sha;
     _contentSha = c.Tree.Sha;
     _thisTag    = first;
 }
 /// <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(ReleaseTagVersion other)
 {
     if (other == null)
     {
         return(1);
     }
     return(_orderedVersion.Number.CompareTo(other._orderedVersion.Number));
 }
 /// <summary>
 /// Tags are equal it their <see cref="OrderedVersion"/> are equals.
 /// No other members are used for equality and comparison.
 /// </summary>
 /// <param name="other">Other release tag.</param>
 /// <returns>True if they have the same OrderedVersion.</returns>
 public bool Equals(ReleaseTagVersion other)
 {
     if (other == null)
     {
         return(false);
     }
     return(_orderedVersion.Number == other._orderedVersion.Number);
 }
Ejemplo n.º 9
0
 void SetNumericalVersionValues(ReleaseTagVersion t, bool isCIBuild)
 {
     Major            = t.Major;
     Minor            = t.Minor;
     Patch            = t.Patch;
     PreReleaseName   = t.PreReleaseName;
     PreReleaseNumber = t.PreReleaseNumber;
     PreReleaseFix    = t.PreReleasePatch;
     FileVersion      = t.ToStringFileVersion(isCIBuild);
     OrderedVersion   = t.OrderedVersion;
 }
Ejemplo n.º 10
0
        /// <summary>
        /// Computes the final release tag: +invalid hides any other version tags.
        /// If multiple versions exist on this commit, an error is raised.
        /// </summary>
        /// <param name="errors">Errors collector.</param>
        /// <returns>False it this tag is invalid.</returns>
        public bool CloseCollect(StringBuilder errors)
        {
            var t = DoCloseCollect(errors);

            if (t != null && t.IsValid)
            {
                _thisTag = t;
                return(true);
            }
            _thisTag = null;
            return(false);
        }
Ejemplo n.º 11
0
 public void AddCollectedTag( ReleaseTagVersion t )
 {
     Debug.Assert( t != null );
     if( t.Equals( _thisTag ) )
     {
         if( t.DefinitionStrength > _thisTag.DefinitionStrength ) _thisTag = t;
     }
     else
     {
         if( _extraCollectedTags == null ) _extraCollectedTags = new List<ReleaseTagVersion>();
         _extraCollectedTags.Add( t );
     }
 }
 static IReadOnlyList<ReleaseTagVersion> BuildFirstPossibleVersions()
 {
     var versions = new ReleaseTagVersion[3 * 9];
     long v = 1L;
     int i = 0;
     while( i < 3 * 9 )
     {
         versions[i++] = new ReleaseTagVersion( v, true );
         if( (i % 18) == 0 ) v += MulMajor - MulMinor - MulPatch + 1;
         else if( (i % 9) == 0 ) v += MulMinor - MulPatch + 1;
         else v += MulName;
     }
     return versions;
 }
        /// <summary>
        /// Tags are equal it their <see cref="OrderedVersion"/> are equals.
        /// No other members are used for equality and comparison.
        /// </summary>
        /// <param name="obj">Other release tag.</param>
        /// <returns>True if obj is a tag that has the same OrderedVersion as this.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }
            ReleaseTagVersion other = obj as ReleaseTagVersion;

            if (other == null)
            {
                throw new ArgumentException();
            }
            return(Equals(other));
        }
Ejemplo n.º 14
0
        void RegisterOneTag(StringBuilder errors, Commit c, string tagName, Func <Commit, ReleaseTagParsingMode> analyseInvalidTagSyntax, ref bool startingVersionForCSemVerFound)
        {
            ReleaseTagParsingMode mode = analyseInvalidTagSyntax == null ? ReleaseTagParsingMode.IgnoreMalformedTag : analyseInvalidTagSyntax(c);
            ReleaseTagVersion     v    = ReleaseTagVersion.TryParse(tagName, mode == ReleaseTagParsingMode.RaiseErrorOnMalformedTag);

            if (v.IsMalformed)
            {
                // Parsing in strict mode can result in malformed tag. We can not assume that here:
                // Debug.Assert( mode == ReleaseTagParsingMode.RaiseErrorOnMalformedTag );
                if (mode == ReleaseTagParsingMode.RaiseErrorOnMalformedTag)
                {
                    errors.AppendFormat("Malformed {0} on commit '{1}'.", v.ParseErrorMessage, c.Sha).AppendLine();
                }
                return;
            }
            if (v.IsValid)
            {
                if (_startingVersionForCSemVer != null)
                {
                    int cmp = _startingVersionForCSemVer.CompareTo(v);
                    if (cmp == 0)
                    {
                        startingVersionForCSemVerFound = true;
                    }
                    else if (cmp > 0)
                    {
                        // This version is smaller than the StartingVersionForCSemVer:
                        // we ignore it.
                        return;
                    }
                }
                if (mode == ReleaseTagParsingMode.RaiseErrorOnMalformedTagAndNonStandardPreReleaseName && v.IsPreRelease && !v.IsPreReleaseNameStandard)
                {
                    errors.AppendFormat("Invalid PreRelease name in '{0}' on commit '{1}'.", v.OriginalTagText, c.Sha).AppendLine();
                    return;
                }
                TagCommit tagCommit;
                if (_collector.TryGetValue(c.Sha, out tagCommit))
                {
                    tagCommit.AddCollectedTag(v);
                }
                else
                {
                    _collector.Add(c.Sha, tagCommit = new TagCommit(c, v));
                }
            }
        }
Ejemplo n.º 15
0
 public void AddCollectedTag(ReleaseTagVersion t)
 {
     Debug.Assert(t != null);
     if (t.Equals(_thisTag))
     {
         if (t.DefinitionStrength > _thisTag.DefinitionStrength)
         {
             _thisTag = t;
         }
     }
     else
     {
         if (_extraCollectedTags == null)
         {
             _extraCollectedTags = new List <ReleaseTagVersion>();
         }
         _extraCollectedTags.Add(t);
     }
 }
Ejemplo n.º 16
0
        void ComputePossibleVersions()
        {
            var allVersions = _tagCollector.ExistingVersions.Versions;

            // Special case: there is no existing versions (other than this that is skipped if it exists) but
            // there is a startingVersionForCSemVer, every commit may be the first one.
            if (_tagCollector.StartingVersionForCSemVer != null &&
                (allVersions.Count == 0 || (allVersions.Count == 1 && ThisTag != null)))
            {
                _possibleVersionsStrict = _possibleVersions = new[] { _tagCollector.StartingVersionForCSemVer };
            }
            else
            {
                var versions = allVersions.Where(c => c != _thisCommit);

                List <ReleaseTagVersion> possible       = new List <ReleaseTagVersion>();
                List <ReleaseTagVersion> possibleStrict = new List <ReleaseTagVersion>();
                foreach (ReleaseTagVersion b in GetBaseVersions())
                {
                    // The base version b can be null here: a null version tag correctly generates
                    // the very first possible versions (and the comparison operators handle null).
                    var nextReleased = versions.FirstOrDefault(c => c.ThisTag > b);
                    var successors   = ReleaseTagVersion.GetDirectSuccessors(false, b);
                    foreach (var v in successors.Where(v => v > _tagCollector.StartingVersionForCSemVer &&
                                                       (nextReleased == null || v < nextReleased.ThisTag)))
                    {
                        if (!possible.Contains(v))
                        {
                            possible.Add(v);
                            if (nextReleased == null || v.IsPatch)
                            {
                                possibleStrict.Add(v);
                            }
                        }
                    }
                }
                _possibleVersions       = possible;
                _possibleVersionsStrict = possibleStrict;
            }
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Initializes a new <see cref="TagCollector"/>.
        /// Errors may be appended to the collector that can be syntaxic errors or multiple different versions applied to the same commit point.
        /// </summary>
        /// <param name="errors">A collector of errors. One line per error.</param>
        /// <param name="repo">The Git repository.</param>
        /// <param name="startingVersionForCSemVer">Vesion tags lower than this version will be ignored.</param>
        /// <param name="analyseInvalidTagSyntax">
        /// Optional function that drives the behavior regarding malformed tags of commits.
        /// When null, <see cref="ReleaseTagParsingMode.IgnoreMalformedTag">IgnoreMalformedTag</see> is used for all tags.
        /// </param>
        /// <param name="OverriddenTags">Optional commits with associated tags that are applied as if they exist in the repository.</param>
        /// <param name="checkValidExistingVersions">
        /// When true, existing versions are checked: one of the valid first version must exist and exisitng versions
        /// must be compact.
        /// </param>
        public TagCollector(
            StringBuilder errors,
            Repository repo,
            string startingVersionForCSemVer = null,
            Func <Commit, ReleaseTagParsingMode> analyseInvalidTagSyntax = null,
            IEnumerable <KeyValuePair <string, IReadOnlyList <string> > > OverriddenTags = null,
            bool checkValidExistingVersions = false)
        {
            Debug.Assert(errors != null && repo != null);

            _collector     = new Dictionary <string, TagCommit>();
            _versionsCache = new Dictionary <string, CommitVersionInfo>();

            if (startingVersionForCSemVer != null)
            {
                _startingVersionForCSemVer = ReleaseTagVersion.TryParse(startingVersionForCSemVer, true);
                if (!_startingVersionForCSemVer.IsValid)
                {
                    errors.Append("Invalid StartingVersionForCSemVer. ").Append(_startingVersionForCSemVer.ParseErrorMessage).AppendLine();
                    return;
                }
            }
            // Register all tags.
            RegisterAllTags(errors, repo, analyseInvalidTagSyntax, OverriddenTags);

            // Resolves multiple tags on the same commit.
            CloseCollect(errors);

            // Sorts TagCommit, optionally checking the existing versions.
            _repoVersions = new RepositoryVersions(_collector.Values, errors, _startingVersionForCSemVer, checkValidExistingVersions);

            // Register content.
            if (errors.Length == 0)
            {
                foreach (var tc in _repoVersions.TagCommits)
                {
                    RegisterContent(tc);
                }
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Initializes a new <see cref="TagCollector"/>.
        /// Errors may be appended to the collector that can be syntaxic errors or multiple different versions applied to the same commit point.
        /// </summary>
        /// <param name="errors">A collector of errors. One line per error.</param>
        /// <param name="repo">The Git repository.</param>
        /// <param name="startingVersionForCSemVer">Vesion tags lower than this version will be ignored.</param>
        /// <param name="analyseInvalidTagSyntax">
        /// Optional function that drives the behavior regarding malformed tags of commits.
        /// When null, <see cref="ReleaseTagParsingMode.IgnoreMalformedTag">IgnoreMalformedTag</see> is used for all tags.
        /// </param>
        /// <param name="OverriddenTags">Optional commits with associated tags that are applied as if they exist in the repository.</param>
        /// <param name="checkValidExistingVersions">
        /// When true, existing versions are checked: one of the valid first version must exist and exisitng versions
        /// must be compact.
        /// </param>
        public TagCollector(
            StringBuilder errors,
            Repository repo,
            string startingVersionForCSemVer = null,
            Func<Commit, ReleaseTagParsingMode> analyseInvalidTagSyntax = null,
            IEnumerable<KeyValuePair<string, IReadOnlyList<string>>> OverriddenTags = null,
            bool checkValidExistingVersions = false )
        {
            Debug.Assert( errors != null && repo != null );

            _collector = new Dictionary<string, TagCommit>();
            _versionsCache = new Dictionary<string, CommitVersionInfo>();

            if( startingVersionForCSemVer != null )
            {
                _startingVersionForCSemVer = ReleaseTagVersion.TryParse( startingVersionForCSemVer, true );
                if( !_startingVersionForCSemVer.IsValid )
                {
                    errors.Append( "Invalid StartingVersionForCSemVer. " ).Append( _startingVersionForCSemVer.ParseErrorMessage ).AppendLine();
                    return;
                }
            }
            // Register all tags.
            RegisterAllTags( errors, repo, analyseInvalidTagSyntax, OverriddenTags );

            // Resolves multiple tags on the same commit.
            CloseCollect( errors );

            // Sorts TagCommit, optionally checking the existing versions. 
            _repoVersions = new RepositoryVersions( _collector.Values, errors, _startingVersionForCSemVer, checkValidExistingVersions );

            // Register content.
            if( errors.Length == 0 )
            {
                foreach( var tc in _repoVersions.TagCommits )
                {
                    RegisterContent( tc );
                }
            }
        }
        static IReadOnlyList <ReleaseTagVersion> BuildFirstPossibleVersions()
        {
            var  versions = new ReleaseTagVersion[3 * 9];
            long v        = 1L;
            int  i        = 0;

            while (i < 3 * 9)
            {
                versions[i++] = new ReleaseTagVersion(v, true);
                if ((i % 18) == 0)
                {
                    v += MulMajor - MulMinor - MulPatch + 1;
                }
                else if ((i % 9) == 0)
                {
                    v += MulMinor - MulPatch + 1;
                }
                else
                {
                    v += MulName;
                }
            }
            return(versions);
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Standard TryParse pattern that returns a boolean rather than the resulting <see cref="ReleaseTagVersion"/>. See <see cref="TryParse(string,bool)"/>.
 /// </summary>
 /// <param name="s">String to parse.</param>
 /// <param name="v">Resulting version.</param>
 /// <returns>True on success, false otherwise.</returns>
 public static bool TryParse(string s, out ReleaseTagVersion v)
 {
     v = TryParse(s, analyseInvalidTag: false);
     return(v.IsValid);
 }
 void SetNumericalVersionValues( ReleaseTagVersion t, bool isCIBuild )
 {
     Major = t.Major;
     Minor = t.Minor;
     Patch = t.Patch;
     PreReleaseName = t.PreReleaseName;
     PreReleaseNumber = t.PreReleaseNumber;
     PreReleaseFix = t.PreReleasePatch;
     FileVersion = t.ToStringFileVersion( isCIBuild );
     OrderedVersion = t.OrderedVersion;
 }
 /// <summary>
 /// Tags are equal it their <see cref="OrderedVersion"/> are equals.
 /// No other members are used for equality and comparison.
 /// </summary>
 /// <param name="other">Other release tag.</param>
 /// <returns>True if they have the same OrderedVersion.</returns>
 public bool Equals( ReleaseTagVersion other )
 {
     if( other == null ) return false;
     return _orderedVersion.Number == other._orderedVersion.Number;
 }
 /// <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( ReleaseTagVersion other )
 {
     if( other == null ) return 1;
     return _orderedVersion.Number.CompareTo( other._orderedVersion.Number );
 }
Ejemplo n.º 24
0
 /// <summary>
 /// Standard TryParse pattern that returns a boolean rather than the resulting <see cref="ReleaseTagVersion"/>. See <see cref="TryParse(string,bool)"/>.
 /// </summary>
 /// <param name="s">String to parse.</param>
 /// <param name="v">Resulting version.</param>
 /// <returns>True on success, false otherwise.</returns>
 public static bool TryParse( string s, out ReleaseTagVersion v )
 {
     v = TryParse( s, analyseInvalidTag: false );
     return v.IsValid;
 }
Ejemplo n.º 25
0
 /// <summary>
 /// Computes the final release tag: +invalid hides any other version tags.
 /// If multiple versions exist on this commit, an error is raised.
 /// </summary>
 /// <param name="errors">Errors collector.</param>
 /// <returns>False it this tag is invalid.</returns>
 public bool CloseCollect( StringBuilder errors )
 {
     var t = DoCloseCollect( errors );
     if( t != null && t.IsValid )
     {
         _thisTag = t;
         return true;
     }
     _thisTag = null;
     return false;
 }
Ejemplo n.º 26
0
 RepositoryInfo( Repository r, RepositoryInfoOptions options, string gitSolutionDir )
     : this()
 {
     if( options == null ) options = new RepositoryInfoOptions();
     Options = options;
     if( r == null ) RepositoryError = "No Git repository.";
     else
     {
         Debug.Assert( gitSolutionDir != null && gitSolutionDir[gitSolutionDir.Length-1] == Path.DirectorySeparatorChar );
         GitSolutionDirectory = gitSolutionDir;
         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.ToUniversalTime().DateTime;
             IsDirtyExplanations = ComputeIsDirty( r, commit, options );
             if( !IsDirty || options.IgnoreDirtyWorkingFolder )
             {
                 StringBuilder errors = new StringBuilder();
                 TagCollector collector = new TagCollector( errors,
                                                             r,
                                                             options.StartingVersionForCSemVer,
                                                             c => c.Sha == CommitSha ? ReleaseTagParsingMode.RaiseErrorOnMalformedTag : ReleaseTagParsingMode.IgnoreMalformedTag,
                                                             options.OverriddenTags );
                 if( errors.Length == 0 )
                 {
                     CommitVersionInfo info = collector.GetVersionInfo( commit );
                     ExistingVersions = collector.ExistingVersions.TagCommits;
                     PossibleVersions = info.PossibleVersions;
                     PossibleVersionsStrict = info.PossibleVersionsStrict;
                     PreviousRelease = info.PreviousCommit;
                     PreviousMaxRelease = info.PreviousMaxCommit;
                     if( info.ThisCommit != null )
                     {
                         bool strictMode = options.PossibleVersionsMode.IsStrict();
                         var possibleSet = strictMode ? info.PossibleVersionsStrict : info.PossibleVersions;
                         if( possibleSet.Contains( info.ThisCommit.ThisTag ) )
                         {
                             ValidReleaseTag = info.ThisCommit.ThisTag;
                         }
                         else
                         {
                             ReleaseTagIsNotPossibleError = true;
                             errors.Append( "Release tag '" )
                                    .Append( info.ThisCommit.ThisTag.OriginalTagText )
                                    .Append( "' is not valid here. Valid tags are: " )
                                    .Append( string.Join( ", ", possibleSet ) )
                                    .AppendLine();
                             if( strictMode && info.PossibleVersions.Contains( info.ThisCommit.ThisTag ))
                             {
                                 if( options.PossibleVersionsMode == PossibleVersionsMode.Default )
                                 {
                                     errors.Append( "Consider setting <PossibleVersionsMode>AllSuccessors</PossibleVersionsMode> in RepositoryInfo.xml to allow this version." );
                                 }
                                 else
                                 {
                                     errors.Append( "Current <PossibleVersionsMode>Restricted</PossibleVersionsMode> in RepositoryInfo.xml forbids this version." );
                                 }
                             }
                         }
                     }
                     else
                     {
                         if( ciBuildName != null )
                         {
                             CIRelease = CIReleaseInfo.Create( commit, ciVersionMode, ciBuildName, errors, info );
                         }
                     }
                 }
                 if( errors.Length > 0 ) SetError( errors, out ReleaseTagErrorLines, out ReleaseTagErrorText );
             }
         }
     }
 }
Ejemplo n.º 27
0
 internal RepositoryVersions(IEnumerable <TagCommit> collected, StringBuilder errors, ReleaseTagVersion startingVersionForCSemVer, bool checkCompactExistingVersions)
 {
     Debug.Assert(collected.All(c => c.ThisTag != null));
     _versions = collected.OrderBy(t => t.ThisTag).ToList();
     if (_versions.Count > 0)
     {
         var first = _versions[0].ThisTag;
         if (checkCompactExistingVersions && startingVersionForCSemVer == null && !first.IsDirectPredecessor(null))
         {
             errors.AppendFormat("First existing version is '{0}' (on '{1}'). One or more previous versions are missing.", first, _versions[0].CommitSha)
             .AppendLine();
         }
         for (int i = 0; i < _versions.Count - 1; ++i)
         {
             var prev = _versions[i].ThisTag;
             var next = _versions[i + 1].ThisTag;
             if (next.Equals(prev))
             {
                 errors.AppendFormat("Version '{0}' is defined on '{1}' and '{2}'.", prev, _versions[i].CommitSha, _versions[i + 1].CommitSha)
                 .AppendLine();
             }
             else if (checkCompactExistingVersions && !next.IsDirectPredecessor(prev))
             {
                 errors.AppendFormat("Missing one or more version(s) between '{0}' and '{1}'.", prev, next)
                 .AppendLine();
             }
         }
     }
 }
Ejemplo n.º 28
0
 RepositoryInfo(Repository r, RepositoryInfoOptions options, string gitSolutionDir)
     : this()
 {
     if (options == null)
     {
         options = new RepositoryInfoOptions();
     }
     Options = options;
     if (r == null)
     {
         RepositoryError = "No Git repository.";
     }
     else
     {
         Debug.Assert(gitSolutionDir != null && gitSolutionDir[gitSolutionDir.Length - 1] == Path.DirectorySeparatorChar);
         GitSolutionDirectory = gitSolutionDir;
         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.ToUniversalTime().DateTime;
             IsDirtyExplanations = ComputeIsDirty(r, commit, options);
             if (!IsDirty || options.IgnoreDirtyWorkingFolder)
             {
                 StringBuilder errors    = new StringBuilder();
                 TagCollector  collector = new TagCollector(errors,
                                                            r,
                                                            options.StartingVersionForCSemVer,
                                                            c => c.Sha == CommitSha ? ReleaseTagParsingMode.RaiseErrorOnMalformedTag : ReleaseTagParsingMode.IgnoreMalformedTag,
                                                            options.OverriddenTags);
                 if (errors.Length == 0)
                 {
                     CommitVersionInfo info = collector.GetVersionInfo(commit);
                     ExistingVersions       = collector.ExistingVersions.TagCommits;
                     PossibleVersions       = info.PossibleVersions;
                     PossibleVersionsStrict = info.PossibleVersionsStrict;
                     PreviousRelease        = info.PreviousCommit;
                     PreviousMaxRelease     = info.PreviousMaxCommit;
                     if (info.ThisCommit != null)
                     {
                         bool strictMode  = options.PossibleVersionsMode.IsStrict();
                         var  possibleSet = strictMode ? info.PossibleVersionsStrict : info.PossibleVersions;
                         if (possibleSet.Contains(info.ThisCommit.ThisTag))
                         {
                             ValidReleaseTag = info.ThisCommit.ThisTag;
                         }
                         else
                         {
                             ReleaseTagIsNotPossibleError = true;
                             errors.Append("Release tag '")
                             .Append(info.ThisCommit.ThisTag.OriginalTagText)
                             .Append("' is not valid here. Valid tags are: ")
                             .Append(string.Join(", ", possibleSet))
                             .AppendLine();
                             if (strictMode && info.PossibleVersions.Contains(info.ThisCommit.ThisTag))
                             {
                                 if (options.PossibleVersionsMode == PossibleVersionsMode.Default)
                                 {
                                     errors.Append("Consider setting <PossibleVersionsMode>AllSuccessors</PossibleVersionsMode> in RepositoryInfo.xml to allow this version.");
                                 }
                                 else
                                 {
                                     errors.Append("Current <PossibleVersionsMode>Restricted</PossibleVersionsMode> in RepositoryInfo.xml forbids this version.");
                                 }
                             }
                         }
                     }
                     else
                     {
                         if (ciBuildName != null)
                         {
                             CIRelease = CIReleaseInfo.Create(commit, ciVersionMode, ciBuildName, errors, info);
                         }
                     }
                 }
                 if (errors.Length > 0)
                 {
                     SetError(errors, out ReleaseTagErrorLines, out ReleaseTagErrorText);
                 }
             }
         }
     }
 }