Files
beads/cmd/bd/show_unit_helpers.go
Steve Yegge 643a162f0e Centralize validation patterns with composable validators (bd-jbqx)
Add composable issue validators to internal/validation package:
- IssueValidator type with Chain() composition function
- Exists(), NotTemplate(), NotPinned(), NotClosed(), NotHooked() validators
- HasStatus(), HasType() for checking allowed values
- ForUpdate(), ForClose(), ForDelete(), ForReopen() convenience chains

Update cmd/bd/show_unit_helpers.go to use centralized validators instead
of duplicated inline validation logic. This enables consistent validation
across all commands with a single source of truth.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-30 16:00:22 -08:00

65 lines
1.8 KiB
Go

package main
import (
"context"
"github.com/steveyegge/beads/internal/storage"
"github.com/steveyegge/beads/internal/types"
"github.com/steveyegge/beads/internal/validation"
)
// validateIssueUpdatable checks if an issue can be updated.
// Uses the centralized validation package for consistency.
func validateIssueUpdatable(id string, issue *types.Issue) error {
// Note: We use NotTemplate() directly instead of ForUpdate() to maintain
// backward compatibility - the original didn't check for nil issues.
return validation.NotTemplate()(id, issue)
}
// validateIssueClosable checks if an issue can be closed.
// Uses the centralized validation package for consistency.
func validateIssueClosable(id string, issue *types.Issue, force bool) error {
// Note: We use individual validators instead of ForClose() to maintain
// backward compatibility - the original didn't check for nil issues.
return validation.Chain(
validation.NotTemplate(),
validation.NotPinned(force),
)(id, issue)
}
func applyLabelUpdates(ctx context.Context, st storage.Storage, issueID, actor string, setLabels, addLabels, removeLabels []string) error {
// Set labels (replaces all existing labels)
if len(setLabels) > 0 {
currentLabels, err := st.GetLabels(ctx, issueID)
if err != nil {
return err
}
for _, label := range currentLabels {
if err := st.RemoveLabel(ctx, issueID, label, actor); err != nil {
return err
}
}
for _, label := range setLabels {
if err := st.AddLabel(ctx, issueID, label, actor); err != nil {
return err
}
}
}
// Add labels
for _, label := range addLabels {
if err := st.AddLabel(ctx, issueID, label, actor); err != nil {
return err
}
}
// Remove labels
for _, label := range removeLabels {
if err := st.RemoveLabel(ctx, issueID, label, actor); err != nil {
return err
}
}
return nil
}