()
| 38 | ) |
| 39 | |
| 40 | func updateCmd() *cobra.Command { |
| 41 | cmd := &cobra.Command{ |
| 42 | Use: "update", |
| 43 | Short: "Updates CHANGELOG.MD to include all new changes", |
| 44 | RunE: func(cmd *cobra.Command, _ []string) error { |
| 45 | entriesByChangelog, err := chlog.ReadEntries(globalCfg) |
| 46 | if err != nil { |
| 47 | return err |
| 48 | } |
| 49 | |
| 50 | // Validate before rendering/deleting so an invalid entry is never |
| 51 | // silently dropped from the summary and then lost when its source |
| 52 | // file is deleted. |
| 53 | if err = chlog.ValidateEntries(globalCfg, entriesByChangelog); err != nil { |
| 54 | return err |
| 55 | } |
| 56 | |
| 57 | // Backfill empty 'issues' from git here, not in validate, so the PR-CI |
| 58 | // validation of an unmerged entry doesn't depend on git history. Dedupe |
| 59 | // by pointer: one entry can appear under several changelogs, and a |
| 60 | // failed backfill would otherwise re-spawn git for it each time. |
| 61 | backfilled := make(map[*chlog.Entry]bool) |
| 62 | for _, entries := range entriesByChangelog { |
| 63 | for _, e := range entries { |
| 64 | if backfilled[e] { |
| 65 | continue |
| 66 | } |
| 67 | backfilled[e] = true |
| 68 | e.BackfillIssues() |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | // Never render an entry without a PR link: fail, listing all of them. |
| 73 | if missing := chlog.MissingIssues(entriesByChangelog); len(missing) > 0 { |
| 74 | noun := "entry" |
| 75 | if len(missing) > 1 { |
| 76 | noun = "entries" |
| 77 | } |
| 78 | return fmt.Errorf("could not determine a PR number for %d changelog %s; set 'issues' explicitly in:\n %s", |
| 79 | len(missing), noun, strings.Join(missing, "\n ")) |
| 80 | } |
| 81 | |
| 82 | for changeLogKey, entries := range entriesByChangelog { |
| 83 | |
| 84 | slices.SortFunc(entries, func(a, b *chlog.Entry) int { |
| 85 | return strings.Compare(a.Component, b.Component) |
| 86 | }) |
| 87 | |
| 88 | if componentFilter != "" { |
| 89 | filteredEntries := make([]*chlog.Entry, 0, len(entries)) |
| 90 | for _, e := range entries { |
| 91 | if e.Component == componentFilter { |
| 92 | filteredEntries = append(filteredEntries, e) |
| 93 | } |
| 94 | } |
| 95 | entries = filteredEntries |
| 96 | } |
| 97 | chlogUpdate, err := chlog.GenerateSummary(version, entries, globalCfg) |
no test coverage detected