IEnumerable <ReleaseProposal> IBatchCriterion.GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);
            var pendingChangesByApi = GitHelpers.GetPendingChangesByApi(repo, catalog);

            foreach (var api in catalog.Apis)
            {
                // Don't even bother proposing package groups at the moment.
                if (api.PackageGroup is object)
                {
                    continue;
                }
                // Don't propose packages that haven't changed.
                // Note that this will also not propose a release for APIs that haven't
                // yet *been* released - which is probably fine. (We don't want to accidentally
                // launch something due to not paying attention.)
                if (pendingChangesByApi[api].Commits.Count == 0)
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();

                yield return(ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion));
            }
        }
        IEnumerable <ReleaseProposal> IBatchCriterion.GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);
            var pendingChangesByApi = GitHelpers.GetPendingChangesByApi(repo, catalog);

            foreach (var api in catalog.Apis)
            {
                var pendingChanges = pendingChangesByApi[api];
                var pendingCommits = pendingChanges.Commits.Select(commit => commit.HashPrefix);
                if (!Commits.SetEquals(pendingCommits))
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();
                var proposal   = ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion);

                // Potentially replace the natural history with an override
                if (!string.IsNullOrEmpty(HistoryOverride) && proposal.NewHistorySection is HistoryFile.Section newSection)
                {
                    var naturalLines  = newSection.Lines;
                    var overrideLines = HistoryOverride.Split('\n');
                    var lines         = naturalLines.Take(2).Concat(overrideLines).ToList();
                    // We always add a blank line at the end of each section.
                    lines.Add("");
                    proposal.NewHistorySection = new HistoryFile.Section(newVersion, lines);
                }
                yield return(proposal);
            }
        }
        public IEnumerable <ReleaseProposal> GetProposals(ApiCatalog catalog)
        {
            var root = DirectoryLayout.DetermineRootDirectory();

            using var repo = new Repository(root);

            foreach (var api in catalog.Apis)
            {
                if (!_apis.Contains(api.Id))
                {
                    continue;
                }
                var newVersion = api.StructuredVersion.AfterIncrement();

                yield return(ReleaseProposal.CreateFromHistory(repo, api.Id, newVersion));
            }
        }