feat: generate compare links for changelog references
This commit is contained in:
@@ -9,6 +9,7 @@ package vociferate
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -16,9 +17,9 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
defaultVersionFile = "release-version"
|
||||
defaultVersionExpr = `^\s*([^\r\n]+)\s*$`
|
||||
defaultChangelog = "changelog.md"
|
||||
defaultVersionFile = "release-version"
|
||||
defaultVersionExpr = `^\s*([^\r\n]+)\s*$`
|
||||
defaultChangelog = "changelog.md"
|
||||
defaultUnreleasedTemplate = "### Breaking\n\n### Added\n\n### Changed\n\n### Removed\n\n### Fixed\n"
|
||||
)
|
||||
|
||||
@@ -246,7 +247,7 @@ func updateChangelog(rootDir, version, releaseDate, changelogPath string) error
|
||||
updated := text[:afterHeader] + "\n" + defaultUnreleasedTemplate + "\n" + newSection + text[nextSectionStart:]
|
||||
repoURL, ok := deriveRepositoryURL(rootDir)
|
||||
if ok {
|
||||
updated = addChangelogLinks(updated, repoURL)
|
||||
updated = addChangelogLinks(updated, repoURL, rootDir)
|
||||
}
|
||||
if err := os.WriteFile(path, []byte(updated), 0o644); err != nil {
|
||||
return fmt.Errorf("write changelog: %w", err)
|
||||
@@ -426,7 +427,7 @@ func normalizeRepoURL(remoteURL string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func addChangelogLinks(text, repoURL string) string {
|
||||
func addChangelogLinks(text, repoURL, rootDir string) string {
|
||||
repoURL = strings.TrimSuffix(strings.TrimSpace(repoURL), "/")
|
||||
if repoURL == "" {
|
||||
return text
|
||||
@@ -456,16 +457,60 @@ func addChangelogLinks(text, repoURL string) string {
|
||||
text = strings.Join(lines[:cutAt], "\n") + "\n"
|
||||
|
||||
// Build and append reference link definitions.
|
||||
linkDefs := []string{fmt.Sprintf("[Unreleased]: %s/src/branch/main", repoURL)}
|
||||
for _, match := range releasedSectionRe.FindAllStringSubmatch(text, -1) {
|
||||
releasedMatches := releasedSectionRe.FindAllStringSubmatch(text, -1)
|
||||
releasedVersions := make([]string, 0, len(releasedMatches))
|
||||
for _, match := range releasedMatches {
|
||||
if len(match) >= 2 {
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[%s]: %s/releases/tag/v%s", match[1], repoURL, match[1]))
|
||||
releasedVersions = append(releasedVersions, match[1])
|
||||
}
|
||||
}
|
||||
|
||||
linkDefs := make([]string, 0, len(releasedVersions)+1)
|
||||
if len(releasedVersions) > 0 {
|
||||
latest := releasedVersions[0]
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[Unreleased]: %s/compare/v%s...main", repoURL, latest))
|
||||
} else {
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[Unreleased]: %s/src/branch/main", repoURL))
|
||||
}
|
||||
|
||||
firstCommitShort, hasFirstCommit := firstCommitShortHash(rootDir)
|
||||
for i, version := range releasedVersions {
|
||||
if i+1 < len(releasedVersions) {
|
||||
previousVersion := releasedVersions[i+1]
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[%s]: %s/compare/v%s...v%s", version, repoURL, previousVersion, version))
|
||||
continue
|
||||
}
|
||||
|
||||
if hasFirstCommit {
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[%s]: %s/compare/%s...v%s", version, repoURL, firstCommitShort, version))
|
||||
continue
|
||||
}
|
||||
|
||||
linkDefs = append(linkDefs, fmt.Sprintf("[%s]: %s/compare/v%s...main", version, repoURL, version))
|
||||
}
|
||||
|
||||
return strings.TrimRight(text, "\n") + "\n\n" + strings.Join(linkDefs, "\n") + "\n"
|
||||
}
|
||||
|
||||
func firstCommitShortHash(rootDir string) (string, bool) {
|
||||
command := exec.Command("git", "-C", rootDir, "rev-list", "--max-parents=0", "--abbrev-commit", "HEAD")
|
||||
output, err := command.Output()
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
|
||||
commit := strings.TrimSpace(string(output))
|
||||
if commit == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if strings.Contains(commit, "\n") {
|
||||
commit = strings.SplitN(commit, "\n", 2)[0]
|
||||
}
|
||||
|
||||
return commit, true
|
||||
}
|
||||
|
||||
func parseSemver(version string) (semver, error) {
|
||||
parts := strings.Split(strings.TrimSpace(version), ".")
|
||||
if len(parts) != 3 {
|
||||
|
||||
Reference in New Issue
Block a user