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 == '_'
|
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 {
|
if len(parts) >= 2 {
|
||||||
// Take first letter of each part: "gas-town" -> "gt"
|
// Take first letter of each part: "gas-town" -> "gt"
|
||||||
prefix := ""
|
prefix := ""
|
||||||
@@ -749,6 +754,27 @@ func deriveBeadsPrefix(name string) string {
|
|||||||
return strings.ToLower(name[:2])
|
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.
|
// 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.
|
// 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.
|
// 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