Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions scripts/changelog/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,18 +255,13 @@ func MergeNotes(manual, generated, fallback string) string {
// reMarker matches the [hash:...][type:...] prefix emitted by cliff.toml.
var reMarker = regexp.MustCompile(`^\- \[hash:([a-f0-9]+)\]\[type:([^\]]+)\] (.+)$`)

// areaMapping maps file path prefixes to human-readable area names.
// An empty area name means the file is internal and excluded from the changelog.
// areaMapping maps file path prefixes to user-facing area names.
// Files not matching any prefix are ignored — commits that only touch
// unrecognised paths are excluded from the changelog.
var areaMapping = []struct {
prefix string
area string
}{
// Internal paths — excluded from changelog.
{"scripts/", ""},
{".github/", ""},
{".golangci", ""},
{".gitignore", ""},
// User-facing areas.
{"cmd/aitaskbuilder/", "AI Task Builder"},
{"cmd/study/", "Study"},
{"cmd/bonus/", "Bonus Payments"},
Expand Down Expand Up @@ -305,24 +300,17 @@ func ParseMarkerLine(line string) (parsedEntry, bool) {
}

// AreaForFiles determines the primary area for a set of changed file paths.
// Unrecognised files count toward "Other". Internal files (empty area in
// areaMapping) are ignored. Returns "" when there are no non-internal files.
// Only files matching a prefix in areaMapping are counted. Returns "" when
// no files match any known area.
func AreaForFiles(files []string) string {
counts := make(map[string]int)
for _, f := range files {
matched := false
for _, am := range areaMapping {
if strings.HasPrefix(f, am.prefix) {
if am.area != "" {
counts[am.area]++
}
matched = true
counts[am.area]++
break
}
}
if !matched {
counts["Other"]++
}
}
if len(counts) == 0 {
return ""
Expand Down Expand Up @@ -382,7 +370,6 @@ var areaOrder = []string{
"Requirements",
"User",
"Core",
"Other",
}

// TransformChangelog takes cliff-generated markdown with [hash:...][type:...]
Expand Down
10 changes: 6 additions & 4 deletions scripts/changelog/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,8 @@ func TestAreaForFiles(t *testing.T) {
{"majority wins", []string{"cmd/study/list.go", "cmd/study/get.go", "cmd/workspace/list.go"}, "Study"},
{"model and client map to Core", []string{"model/study.go", "client/client.go"}, "Core"},
{"filters and filtersets both map to Filters", []string{"cmd/filters/list.go", "cmd/filtersets/list.go"}, "Filters"},
{"unknown files fall back to Other", []string{"README.md", "Makefile"}, "Other"},
{"internal-only returns empty", []string{"scripts/changelog/main.go", ".github/workflows/ci.yml"}, ""},
{"mixed internal and user-facing keeps user-facing", []string{"scripts/foo.sh", "cmd/study/list.go"}, "Study"},
{"unrecognised files return empty", []string{"README.md", "Makefile"}, ""},
{"mixed unrecognised and user-facing keeps user-facing", []string{"scripts/foo.sh", "cmd/study/list.go"}, "Study"},
{"empty file list returns empty", []string{}, ""},
}

Expand Down Expand Up @@ -386,14 +385,17 @@ func TestTransformChangelog(t *testing.T) {
got := TransformChangelog(input, func(h string) ([]string, error) { return filesByHash[h], nil })

// Area headings present, markers stripped.
for _, heading := range []string{"### AI Task Builder", "### Study", "### Workspaces", "### Other"} {
for _, heading := range []string{"### AI Task Builder", "### Study", "### Workspaces"} {
if !strings.Contains(got, heading) {
t.Errorf("missing heading %q", heading)
}
}
if strings.Contains(got, "[hash:") || strings.Contains(got, "[type:") {
t.Error("markers should be stripped from output")
}
if strings.Contains(got, "Update README") {
t.Error("unrecognised-only commit should be excluded")
}

// AI Task Builder before Study (per areaOrder).
if strings.Index(got, "### AI Task Builder") > strings.Index(got, "### Study") {
Expand Down
Loading