fix: bd --no-db dep tree now shows complete tree (GH#836)
The memory storage GetDependencyTree was missing the root node at depth 0, causing --no-db mode to only show dependencies without the root issue. Fixed by: - Adding root node at depth 0 before listing dependencies - Setting ParentID on child nodes for proper tree rendering 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
edc0fea02f
commit
95f14fa827
@@ -887,19 +887,43 @@ func (m *MemoryStorage) SetJSONLFileHash(ctx context.Context, fileHash string) e
|
||||
|
||||
// GetDependencyTree gets the dependency tree for an issue
|
||||
func (m *MemoryStorage) GetDependencyTree(ctx context.Context, issueID string, maxDepth int, showAllPaths bool, reverse bool) ([]*types.TreeNode, error) {
|
||||
// Simplified implementation - just return direct dependencies
|
||||
// Note: reverse parameter is accepted for interface compatibility but not fully implemented in memory storage
|
||||
// Get the root issue first
|
||||
root, err := m.GetIssue(ctx, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if root == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var nodes []*types.TreeNode
|
||||
|
||||
// Add root node at depth 0
|
||||
rootNode := &types.TreeNode{
|
||||
Depth: 0,
|
||||
ParentID: issueID, // Root's parent is itself
|
||||
}
|
||||
rootNode.ID = root.ID
|
||||
rootNode.Title = root.Title
|
||||
rootNode.Description = root.Description
|
||||
rootNode.Status = root.Status
|
||||
rootNode.Priority = root.Priority
|
||||
rootNode.IssueType = root.IssueType
|
||||
nodes = append(nodes, rootNode)
|
||||
|
||||
// Get dependencies (or dependents if reverse)
|
||||
// Note: reverse mode not fully implemented - uses same logic for now
|
||||
deps, err := m.GetDependencies(ctx, issueID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var nodes []*types.TreeNode
|
||||
// Add dependencies at depth 1
|
||||
for _, dep := range deps {
|
||||
node := &types.TreeNode{
|
||||
Depth: 1,
|
||||
Depth: 1,
|
||||
ParentID: issueID, // Parent is the root
|
||||
}
|
||||
// Copy issue fields
|
||||
node.ID = dep.ID
|
||||
node.Title = dep.Title
|
||||
node.Description = dep.Description
|
||||
|
||||
@@ -223,8 +223,12 @@ func TestMemoryStorage_DependencyCounts_Records_Tree_Cycles(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("GetDependencyTree: %v", err)
|
||||
}
|
||||
if len(nodes) != 2 || nodes[0].Depth != 1 {
|
||||
t.Fatalf("unexpected tree: %+v", nodes)
|
||||
// Expect 3 nodes: root (A) at depth 0, plus 2 dependencies (B, C) at depth 1
|
||||
if len(nodes) != 3 {
|
||||
t.Fatalf("expected 3 nodes (root + 2 deps), got %d", len(nodes))
|
||||
}
|
||||
if nodes[0].ID != a.ID || nodes[0].Depth != 0 {
|
||||
t.Fatalf("expected root node %s at depth 0, got %s at depth %d", a.ID, nodes[0].ID, nodes[0].Depth)
|
||||
}
|
||||
|
||||
cycles, err := store.DetectCycles(ctx)
|
||||
|
||||
66
internal/storage/memory/tree_test.go
Normal file
66
internal/storage/memory/tree_test.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package memory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/steveyegge/beads/internal/types"
|
||||
)
|
||||
|
||||
func TestGetDependencyTree_IncludesRoot(t *testing.T) {
|
||||
m := New("")
|
||||
|
||||
// Create parent and child issues
|
||||
parent := &types.Issue{
|
||||
ID: "bd-7zka",
|
||||
Title: "Parent issue",
|
||||
Status: types.StatusOpen,
|
||||
Priority: 3,
|
||||
}
|
||||
child := &types.Issue{
|
||||
ID: "bd-7zka.2",
|
||||
Title: "Child issue",
|
||||
Status: types.StatusOpen,
|
||||
Priority: 3,
|
||||
Dependencies: []*types.Dependency{
|
||||
{IssueID: "bd-7zka.2", DependsOnID: "bd-7zka", Type: "blocks"},
|
||||
},
|
||||
}
|
||||
|
||||
if err := m.LoadFromIssues([]*types.Issue{parent, child}); err != nil {
|
||||
t.Fatalf("LoadFromIssues failed: %v", err)
|
||||
}
|
||||
|
||||
tree, err := m.GetDependencyTree(context.Background(), "bd-7zka.2", 50, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("GetDependencyTree failed: %v", err)
|
||||
}
|
||||
|
||||
// Should have 2 nodes: root at depth 0, dependency at depth 1
|
||||
if len(tree) != 2 {
|
||||
t.Errorf("Expected 2 nodes, got %d", len(tree))
|
||||
for i, node := range tree {
|
||||
t.Logf(" [%d] ID=%s, Depth=%d, ParentID=%s", i, node.ID, node.Depth, node.ParentID)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// First node should be root at depth 0
|
||||
if tree[0].ID != "bd-7zka.2" {
|
||||
t.Errorf("Expected root ID 'bd-7zka.2', got '%s'", tree[0].ID)
|
||||
}
|
||||
if tree[0].Depth != 0 {
|
||||
t.Errorf("Expected root depth 0, got %d", tree[0].Depth)
|
||||
}
|
||||
|
||||
// Second node should be dependency at depth 1
|
||||
if tree[1].ID != "bd-7zka" {
|
||||
t.Errorf("Expected dependency ID 'bd-7zka', got '%s'", tree[1].ID)
|
||||
}
|
||||
if tree[1].Depth != 1 {
|
||||
t.Errorf("Expected dependency depth 1, got %d", tree[1].Depth)
|
||||
}
|
||||
if tree[1].ParentID != "bd-7zka.2" {
|
||||
t.Errorf("Expected dependency ParentID 'bd-7zka.2', got '%s'", tree[1].ParentID)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user