fix: derive gt- prefix for gastown compound words (gt-m46bb)

This commit is contained in:
slit
2026-01-06 23:30:26 -08:00
committed by Steve Yegge
parent c91ab85457
commit 8a8b56e9e6
2 changed files with 117 additions and 0 deletions

View File

@@ -731,6 +731,11 @@ func deriveBeadsPrefix(name string) string {
return r == '-' || r == '_'
})
// If single part, try to detect compound words (e.g., "gastown" -> "gas" + "town")
if len(parts) == 1 {
parts = splitCompoundWord(parts[0])
}
if len(parts) >= 2 {
// Take first letter of each part: "gas-town" -> "gt"
prefix := ""
@@ -749,6 +754,27 @@ func deriveBeadsPrefix(name string) string {
return strings.ToLower(name[:2])
}
// splitCompoundWord attempts to split a compound word into its components.
// Common suffixes like "town", "ville", "port" are detected to split
// compound names (e.g., "gastown" -> ["gas", "town"]).
func splitCompoundWord(word string) []string {
word = strings.ToLower(word)
// Common suffixes for compound place names
suffixes := []string{"town", "ville", "port", "place", "land", "field", "wood", "ford"}
for _, suffix := range suffixes {
if strings.HasSuffix(word, suffix) && len(word) > len(suffix) {
prefix := word[:len(word)-len(suffix)]
if len(prefix) > 0 {
return []string{prefix, suffix}
}
}
}
return []string{word}
}
// detectBeadsPrefixFromConfig reads the issue prefix from a beads config.yaml file.
// Returns empty string if the file doesn't exist or doesn't contain a prefix.
// Falls back to detecting prefix from existing issues in issues.jsonl.

View File

@@ -485,3 +485,94 @@ func TestInitBeadsRejectsInvalidPrefix(t *testing.T) {
})
}
}
func TestDeriveBeadsPrefix(t *testing.T) {
tests := []struct {
name string
want string
}{
// Compound words with common suffixes should split
{"gastown", "gt"}, // gas + town
{"nashville", "nv"}, // nash + ville
{"bridgeport", "bp"}, // bridge + port
{"someplace", "sp"}, // some + place
{"greenland", "gl"}, // green + land
{"springfield", "sf"}, // spring + field
{"hollywood", "hw"}, // holly + wood
{"oxford", "of"}, // ox + ford
// Hyphenated names
{"my-project", "mp"},
{"gas-town", "gt"},
{"some-long-name", "sln"},
// Underscored names
{"my_project", "mp"},
// Short single words (use the whole name)
{"foo", "foo"},
{"bar", "bar"},
{"ab", "ab"},
// Longer single words without known suffixes (first 2 chars)
{"myrig", "my"},
{"awesome", "aw"},
{"coolrig", "co"},
// With language suffixes stripped
{"myproject-py", "my"},
{"myproject-go", "my"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := deriveBeadsPrefix(tt.name)
if got != tt.want {
t.Errorf("deriveBeadsPrefix(%q) = %q, want %q", tt.name, got, tt.want)
}
})
}
}
func TestSplitCompoundWord(t *testing.T) {
tests := []struct {
word string
want []string
}{
// Known suffixes
{"gastown", []string{"gas", "town"}},
{"nashville", []string{"nash", "ville"}},
{"bridgeport", []string{"bridge", "port"}},
{"someplace", []string{"some", "place"}},
{"greenland", []string{"green", "land"}},
{"springfield", []string{"spring", "field"}},
{"hollywood", []string{"holly", "wood"}},
{"oxford", []string{"ox", "ford"}},
// Just the suffix (should not split)
{"town", []string{"town"}},
{"ville", []string{"ville"}},
// No known suffix
{"myrig", []string{"myrig"}},
{"awesome", []string{"awesome"}},
// Empty prefix would result (should not split)
// Note: "town" itself shouldn't split to ["", "town"]
}
for _, tt := range tests {
t.Run(tt.word, func(t *testing.T) {
got := splitCompoundWord(tt.word)
if len(got) != len(tt.want) {
t.Errorf("splitCompoundWord(%q) = %v, want %v", tt.word, got, tt.want)
return
}
for i := range got {
if got[i] != tt.want[i] {
t.Errorf("splitCompoundWord(%q)[%d] = %q, want %q", tt.word, i, got[i], tt.want[i])
}
}
})
}
}