Implement bd-10: Export/import dependencies in JSONL
Added dependency support to export/import workflow:
Changes:
- Added GetDependencyRecords() to Storage interface to get raw dependency records
- Extended Issue struct with Dependencies field (omitempty for backward compat)
- Modified export.go to populate dependencies for each issue
- Modified import.go to process dependencies in second pass after all issues exist
- All tests pass
Benefits:
- JSONL is now self-contained with full dependency information
- Enables proper collision resolution in future (bd-12+)
- Idempotent imports: existing dependencies are not duplicated
- Forward references handled: dependencies created after all issues exist
Example output:
{
"id": "bd-10",
"title": "...",
"dependencies": [{
"issue_id": "bd-10",
"depends_on_id": "bd-9",
"type": "parent-child",
"created_at": "...",
"created_by": "stevey"
}]
}
Closes bd-10
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -48,6 +48,16 @@ Output to stdout by default, or use -o flag for file output.`,
|
||||
return issues[i].ID < issues[j].ID
|
||||
})
|
||||
|
||||
// Populate dependencies for each issue
|
||||
for _, issue := range issues {
|
||||
deps, err := store.GetDependencyRecords(ctx, issue.ID)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error getting dependencies for %s: %v\n", issue.ID, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
issue.Dependencies = deps
|
||||
}
|
||||
|
||||
// Open output
|
||||
out := os.Stdout
|
||||
if output != "" {
|
||||
|
||||
@@ -47,6 +47,7 @@ Behavior:
|
||||
scanner := bufio.NewScanner(in)
|
||||
|
||||
var created, updated, skipped int
|
||||
var allIssues []*types.Issue // Store all issues for dependency processing
|
||||
lineNum := 0
|
||||
|
||||
for scanner.Scan() {
|
||||
@@ -65,6 +66,9 @@ Behavior:
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Store for dependency processing later
|
||||
allIssues = append(allIssues, &issue)
|
||||
|
||||
// Check if issue exists
|
||||
existing, err := store.GetIssue(ctx, issue.ID)
|
||||
if err != nil {
|
||||
@@ -121,11 +125,59 @@ Behavior:
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Second pass: Process dependencies
|
||||
// Do this after all issues are created to handle forward references
|
||||
var depsCreated, depsSkipped int
|
||||
for _, issue := range allIssues {
|
||||
if len(issue.Dependencies) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, dep := range issue.Dependencies {
|
||||
// Check if dependency already exists
|
||||
existingDeps, err := store.GetDependencyRecords(ctx, dep.IssueID)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error checking dependencies for %s: %v\n", dep.IssueID, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Skip if this exact dependency already exists
|
||||
exists := false
|
||||
for _, existing := range existingDeps {
|
||||
if existing.DependsOnID == dep.DependsOnID && existing.Type == dep.Type {
|
||||
exists = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if exists {
|
||||
depsSkipped++
|
||||
continue
|
||||
}
|
||||
|
||||
// Add dependency
|
||||
if err := store.AddDependency(ctx, dep, "import"); err != nil {
|
||||
// Ignore errors for missing target issues or cycles
|
||||
// This can happen if dependencies reference issues not in the import
|
||||
fmt.Fprintf(os.Stderr, "Warning: could not add dependency %s → %s: %v\n",
|
||||
dep.IssueID, dep.DependsOnID, err)
|
||||
continue
|
||||
}
|
||||
depsCreated++
|
||||
}
|
||||
}
|
||||
|
||||
// Print summary
|
||||
fmt.Fprintf(os.Stderr, "Import complete: %d created, %d updated", created, updated)
|
||||
if skipped > 0 {
|
||||
fmt.Fprintf(os.Stderr, ", %d skipped", skipped)
|
||||
}
|
||||
if depsCreated > 0 || depsSkipped > 0 {
|
||||
fmt.Fprintf(os.Stderr, ", %d dependencies added", depsCreated)
|
||||
if depsSkipped > 0 {
|
||||
fmt.Fprintf(os.Stderr, " (%d already existed)", depsSkipped)
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "\n")
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user