fix: derive gt- prefix for gastown compound words (gt-m46bb)
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user