fix: ExtractIssuePrefix now handles 3-char base36 hashes (#425)
- Lower minimum hash length from 4 to 3 characters - Update hash validation to support base36 (0-9, a-z) instead of just hex - Require at least one digit to distinguish hashes from English words - Fixes prefix extraction for hyphenated prefixes with 3-char hashes e.g., 'document-intelligence-0sa' now correctly extracts 'document-intelligence' - Add test cases for 3-char hashes with multi-part prefixes - Resolves bd sync failures with 'prefix mismatch detected' errors
This commit is contained in:
@@ -402,6 +402,21 @@ func TestExtractIssuePrefix(t *testing.T) {
|
||||
issueID: "proj-AbCd12",
|
||||
expected: "proj", // Mixed case hash should work
|
||||
},
|
||||
{
|
||||
name: "3-char hash with hyphenated prefix",
|
||||
issueID: "document-intelligence-0sa",
|
||||
expected: "document-intelligence", // 3-char hash (base36) should use last hyphen
|
||||
},
|
||||
{
|
||||
name: "3-char hash with multi-part prefix",
|
||||
issueID: "my-cool-app-1x7",
|
||||
expected: "my-cool-app", // 3-char base36 hash
|
||||
},
|
||||
{
|
||||
name: "3-char all-letters suffix (should fall back to first hyphen)",
|
||||
issueID: "test-proj-abc",
|
||||
expected: "test", // All letters = not a hash, falls back to first hyphen
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -51,19 +51,24 @@ func ExtractIssuePrefix(issueID string) string {
|
||||
}
|
||||
|
||||
// isLikelyHash checks if a string looks like a hash ID suffix.
|
||||
// Returns true for hexadecimal strings of 4-8 characters.
|
||||
// Hash IDs in beads are typically 4-6 characters (progressive length scaling).
|
||||
// Returns true for base36 strings of 3-8 characters (0-9, a-z) that contain at least one digit.
|
||||
// Requires a digit to distinguish hashes from English words (e.g., accept "0sa" but reject "test").
|
||||
// Hash IDs in beads use adaptive length scaling from 3-8 characters.
|
||||
func isLikelyHash(s string) bool {
|
||||
if len(s) < 4 || len(s) > 8 {
|
||||
if len(s) < 3 || len(s) > 8 {
|
||||
return false
|
||||
}
|
||||
// Check if all characters are hexadecimal
|
||||
hasDigit := false
|
||||
// Check if all characters are base36 (0-9, a-z) and at least one is a digit
|
||||
for _, c := range s {
|
||||
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
|
||||
if c >= '0' && c <= '9' {
|
||||
hasDigit = true
|
||||
}
|
||||
if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
return hasDigit
|
||||
}
|
||||
|
||||
// ExtractIssueNumber extracts the number from an issue ID like "bd-123" -> 123
|
||||
|
||||
Reference in New Issue
Block a user