fix(update): accept custom types from types.custom config (GH#hq-8hif1z)
The `bd update --type` command was rejecting custom types (like role, agent, rig) even when configured via types.custom. The issue was that type validation used IsValid() which only checks the 5 core types, ignoring custom types. Changes: - CLI (update.go): Use IsValidWithCustom() with types from config - Storage (validators.go): Add validateIssueTypeWithCustom() function - Storage (queries.go, transaction.go): Fetch and pass custom types The error message now dynamically shows all valid types including custom ones. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,9 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/beads/internal/config"
|
||||
"github.com/steveyegge/beads/internal/hooks"
|
||||
"github.com/steveyegge/beads/internal/rpc"
|
||||
"github.com/steveyegge/beads/internal/timeparsing"
|
||||
@@ -113,8 +115,12 @@ create, update, show, or close operation).`,
|
||||
issueType, _ := cmd.Flags().GetString("type")
|
||||
// Normalize aliases (e.g., "enhancement" -> "feature") before validating
|
||||
issueType = util.NormalizeIssueType(issueType)
|
||||
if !types.IssueType(issueType).IsValid() {
|
||||
FatalErrorRespectJSON("invalid issue type %q. Valid types: bug, feature, task, epic, chore, merge-request, molecule, gate, agent, role, rig, convoy, event, slot", issueType)
|
||||
// Get custom types from config to validate non-core types (GH#hq-8hif1z)
|
||||
customTypes := getCustomTypesForValidation()
|
||||
if !types.IssueType(issueType).IsValidWithCustom(customTypes) {
|
||||
validTypes := []string{"bug", "feature", "task", "epic", "chore"}
|
||||
validTypes = append(validTypes, customTypes...)
|
||||
FatalErrorRespectJSON("invalid issue type %q. Valid types: %s", issueType, strings.Join(validTypes, ", "))
|
||||
}
|
||||
updates["issue_type"] = issueType
|
||||
}
|
||||
@@ -643,6 +649,46 @@ create, update, show, or close operation).`,
|
||||
},
|
||||
}
|
||||
|
||||
// getCustomTypesForValidation retrieves custom types for validation.
|
||||
// Works in both daemon and direct modes, with fallback to config.yaml.
|
||||
func getCustomTypesForValidation() []string {
|
||||
ctx := rootCtx
|
||||
|
||||
// Try daemon mode first
|
||||
if daemonClient != nil {
|
||||
resp, err := daemonClient.GetConfig(&rpc.GetConfigArgs{Key: "types.custom"})
|
||||
if err == nil && resp.Value != "" {
|
||||
return parseCustomTypesList(resp.Value)
|
||||
}
|
||||
}
|
||||
|
||||
// Direct mode - use store
|
||||
if store != nil {
|
||||
if ct, err := store.GetCustomTypes(ctx); err == nil && len(ct) > 0 {
|
||||
return ct
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to config.yaml
|
||||
return config.GetCustomTypesFromYAML()
|
||||
}
|
||||
|
||||
// parseCustomTypesList splits a comma-separated string into custom types.
|
||||
func parseCustomTypesList(value string) []string {
|
||||
if value == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(value, ",")
|
||||
result := make([]string, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
trimmed := strings.TrimSpace(p)
|
||||
if trimmed != "" {
|
||||
result = append(result, trimmed)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func init() {
|
||||
updateCmd.Flags().StringP("status", "s", "", "New status")
|
||||
registerPriorityFlag(updateCmd, "")
|
||||
|
||||
Reference in New Issue
Block a user