fix(orphans): honor --db flag for cross-repo orphan detection (#1200)
* fix(orphans): honor --db flag for cross-repo orphan detection Problem: - `bd orphans --db /path` ignored the --db flag entirely - FindOrphanedIssues() hardcoded local .beads/ directory Solution: - Introduce IssueProvider interface for abstract issue lookup - Add StorageProvider adapter wrapping Storage instances - Update FindOrphanedIssues to accept provider instead of path - Wire orphans command to create provider from --db flag Closes: steveyegge/beads#1196 * test(orphans): add cross-repo and provider tests for --db flag fix - Add TestFindOrphanedIssues_WithMockProvider (table-driven, UT-01 through UT-09) - Add TestFindOrphanedIssues_CrossRepo (validates --db flag honored) - Add TestFindOrphanedIssues_LocalProvider (backward compat RT-01) - Add TestFindOrphanedIssues_ProviderError (error handling UT-07) - Add TestFindOrphanedIssues_IntegrationCrossRepo (IT-02 full) - Add TestLocalProvider_* unit tests Coverage for IssueProvider interface and cross-repo orphan detection. * docs: add bd orphans command to CLI reference Document the orphan detection command including the cross-repo workflow enabled by the --db flag fix in this PR.
This commit is contained in:
committed by
GitHub
parent
a0dac11e42
commit
c11fa799be
+35
-2
@@ -9,9 +9,13 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/steveyegge/beads/cmd/bd/doctor"
|
||||
"github.com/steveyegge/beads/internal/storage"
|
||||
"github.com/steveyegge/beads/internal/types"
|
||||
"github.com/steveyegge/beads/internal/ui"
|
||||
)
|
||||
|
||||
// doctorFindOrphanedIssues is the function used to find orphaned issues.
|
||||
// It accepts a git path and an IssueProvider for flexibility (cross-repo, mock testing).
|
||||
var doctorFindOrphanedIssues = doctor.FindOrphanedIssues
|
||||
|
||||
var closeIssueRunner = func(issueID string) error {
|
||||
@@ -103,9 +107,38 @@ type orphanIssueOutput struct {
|
||||
LatestCommitMessage string `json:"latest_commit_message,omitempty"`
|
||||
}
|
||||
|
||||
// findOrphanedIssues wraps the shared doctor package function and converts to output format
|
||||
// getIssueProvider returns an IssueProvider based on the current configuration.
|
||||
// If --db flag is set, it creates a provider from that database path.
|
||||
// Otherwise, it uses the global store (already opened in PersistentPreRun).
|
||||
func getIssueProvider() (types.IssueProvider, func(), error) {
|
||||
// If --db flag is set and we have a dbPath, create a provider from that path
|
||||
if dbPath != "" {
|
||||
provider, err := doctor.NewLocalProvider(dbPath)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to open database at %s: %w", dbPath, err)
|
||||
}
|
||||
return provider, func() { provider.Close() }, nil
|
||||
}
|
||||
|
||||
// Use the global store (already opened by PersistentPreRun)
|
||||
if store != nil {
|
||||
provider := storage.NewStorageProvider(store)
|
||||
return provider, func() {}, nil // No cleanup needed for global store
|
||||
}
|
||||
|
||||
return nil, nil, fmt.Errorf("no database available")
|
||||
}
|
||||
|
||||
// findOrphanedIssues wraps the shared doctor package function and converts to output format.
|
||||
// It respects the --db flag for cross-repo orphan detection.
|
||||
func findOrphanedIssues(path string) ([]orphanIssueOutput, error) {
|
||||
orphans, err := doctorFindOrphanedIssues(path)
|
||||
provider, cleanup, err := getIssueProvider()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find orphaned issues: %w", err)
|
||||
}
|
||||
defer cleanup()
|
||||
|
||||
orphans, err := doctorFindOrphanedIssues(path, provider)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to find orphaned issues: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user