SimpleVersion GetVersionInternal(SimpleCommit commit)
        {
            // We do this to avoid recursing too many stack frames
            if (_calculatedVersions.TryGetValue(commit, out var alreadyCalculatedVersion))
            {
                return(alreadyCalculatedVersion);
            }

            var taggedVersion = commit
                                .TaggedWithVersions
                                .OrderByDescending(v => v)
                                .FirstOrDefault();

            if (taggedVersion != null)
            {
                return(taggedVersion);
            }

            var maxParentVersion = commit.Parents
                                   .Select(GetVersionInternal)
                                   .OrderByDescending(v => v)
                                   .FirstOrDefault()
                                   ?? new SimpleVersion(0, 0, 0);

            SimpleVersion version;

            if (commit.BumpsMajorVersion)
            {
                version = new SimpleVersion(maxParentVersion.Major + 1, 0, 0);
            }
            else if (commit.BumpsMinorVersion)
            {
                version = new SimpleVersion(maxParentVersion.Major, maxParentVersion.Minor + 1, 0);
            }
            else
            {
                version = new SimpleVersion(maxParentVersion.Major,
                                            maxParentVersion.Minor,
                                            maxParentVersion.Patch + 1);
            }
            _calculatedVersions[commit] = version;

            return(version);
        }
Exemple #2
0
        public VersionCalculator Create()
        {
            Commit[] allCommits;
            using (_logger.BeginTimedOperation("Loading commits"))
            {
                allCommits = _repository.Commits.ToArray();
                _logger.Debug("Repository contains {NumberOfCommits} commits", allCommits.Length);
            }

            Dictionary <string, SimpleCommit> commits;

            using (_logger.BeginTimedOperation("Mapping commits into internal representation"))
            {
                commits = allCommits
                          .Select(SimpleCommit.FromCommit)
                          .ToDictionary(c => c.Hash, c => c);
            }

            // Establish parent/child relationships
            using (_logger.BeginTimedOperation("Establishing parent/child relationships"))
            {
                foreach (var commit in allCommits)
                {
                    if (!commit.Parents.Any())
                    {
                        continue;
                    }

                    var simpleCommit = commits[commit.Sha];
                    foreach (var parent in commit.Parents)
                    {
                        var simpleParent = commits[parent.Sha];
                        simpleCommit.AddParent(simpleParent);
                    }
                }
            }

            Tag[] allTags;
            using (_logger.BeginTimedOperation("Loading tags"))
            {
                allTags = _repository.Tags.ToArray();
                _logger.Debug("Repository contains {NumberOfTags} tags", allTags.Length);
            }

            using (_logger.BeginTimedOperation("Applying relevant version tags to each commit"))
            {
                foreach (var tag in allTags)
                {
                    var version = SimpleVersion.TryParse(tag.FriendlyName);
                    if (version == null)
                    {
                        continue;
                    }

                    // tags can reference to commits which have been removed. In this case we don't care.
                    if (!commits.TryGetValue(tag.Target.Sha, out var commit))
                    {
                        continue;
                    }

                    _logger.Verbose("{CommitHash} is tagged with {VersionTag}", commit.Hash, version);
                    commit.TagWith(version);
                }
            }

            var currentCommitHash = allCommits.First().Sha;
            var calculator        = new VersionCalculator(commits.Values.ToArray(), currentCommitHash);

            return(calculator);
        }
 public void TagWith(SimpleVersion version)
 {
     TaggedWithVersions.Add(version);
 }