refactor: deduplicate FindJSONLInDir function (bd-8a5)

Extract shared JSONL file discovery logic to internal/utils/path.go.
Both autoimport and beads packages now use this shared implementation.

Changes:
- Add utils.FindJSONLInDir with common logic
- Update autoimport.go to use utils.FindJSONLInDir
- Update beads.go to delegate to utils.FindJSONLInDir
- Update server_export_import_auto.go to use utils.FindJSONLInDir
- Move FindJSONLInDir test to utils/path_test.go
- Fix pre-existing duplicate countIssuesInJSONLFile in init.go

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-11-28 23:07:53 -08:00
parent 52fe60859a
commit 40b07045c7
8 changed files with 201 additions and 256 deletions

View File

@@ -15,6 +15,7 @@ import (
"github.com/steveyegge/beads/internal/debug"
"github.com/steveyegge/beads/internal/storage"
"github.com/steveyegge/beads/internal/types"
"github.com/steveyegge/beads/internal/utils"
)
// Notifier handles user notifications during import
@@ -65,9 +66,9 @@ func AutoImportIfNewer(ctx context.Context, store storage.Storage, dbPath string
notify = NewStderrNotifier(debug.Enabled())
}
// Find JSONL using database directory (same logic as beads.FindJSONLPath)
// Find JSONL using database directory
dbDir := filepath.Dir(dbPath)
jsonlPath := FindJSONLInDir(dbDir)
jsonlPath := utils.FindJSONLInDir(dbDir)
if jsonlPath == "" {
notify.Debugf("auto-import skipped, JSONL not found")
return nil
@@ -282,7 +283,7 @@ func CheckStaleness(ctx context.Context, store storage.Storage, dbPath string) (
// Find JSONL using database directory
dbDir := filepath.Dir(dbPath)
jsonlPath := FindJSONLInDir(dbDir)
jsonlPath := utils.FindJSONLInDir(dbDir)
stat, err := os.Stat(jsonlPath)
if err != nil {
@@ -297,46 +298,3 @@ func CheckStaleness(ctx context.Context, store storage.Storage, dbPath string) (
return stat.ModTime().After(lastImportTime), nil
}
// FindJSONLInDir finds the JSONL file in the given directory.
// It prefers issues.jsonl over other .jsonl files to prevent accidentally
// reading/writing to deletions.jsonl or merge artifacts (bd-tqo fix).
// Always returns a path (defaults to issues.jsonl if nothing suitable found).
func FindJSONLInDir(dbDir string) string {
pattern := filepath.Join(dbDir, "*.jsonl")
matches, err := filepath.Glob(pattern)
if err != nil || len(matches) == 0 {
// Default to issues.jsonl if glob fails or no matches
return filepath.Join(dbDir, "issues.jsonl")
}
// Prefer issues.jsonl over other .jsonl files (bd-tqo fix)
// This prevents accidentally using deletions.jsonl or merge artifacts
for _, match := range matches {
if filepath.Base(match) == "issues.jsonl" {
return match
}
}
// Fall back to beads.jsonl for legacy support
for _, match := range matches {
if filepath.Base(match) == "beads.jsonl" {
return match
}
}
// Last resort: use first match (but skip deletions.jsonl and merge artifacts)
for _, match := range matches {
base := filepath.Base(match)
// Skip deletions manifest and merge artifacts
if base == "deletions.jsonl" ||
base == "beads.base.jsonl" ||
base == "beads.left.jsonl" ||
base == "beads.right.jsonl" {
continue
}
return match
}
// If only deletions/merge files exist, default to issues.jsonl
return filepath.Join(dbDir, "issues.jsonl")
}