Files
beads/internal/beads/beads_multidb_test.go
Steve Yegge 42ac923ea8 fix(beads): stop searching upward when .beads found (gt-bzd)
In multi-workspace setups like Gas Town, nested .beads directories are
intentional and separate:
- Town level: ~/gt/.beads
- Rig level: ~/gt/gastown/.beads

Previously, FindAllDatabases() walked up the entire directory tree
and warned about "multiple databases detected" even though these are
unrelated beads instances for different scopes.

Now FindAllDatabases() stops as soon as it finds the first (closest)
.beads directory. Parent directories are out of scope.

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

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

142 lines
3.6 KiB
Go

//go:build integration
// +build integration
package beads
import (
"os"
"path/filepath"
"testing"
)
func TestFindAllDatabases(t *testing.T) {
// Create a temporary directory structure with multiple .beads databases
tmpDir, err := os.MkdirTemp("", "beads-multidb-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// Resolve symlinks (macOS /var -> /private/var)
tmpDir, err = filepath.EvalSymlinks(tmpDir)
if err != nil {
t.Fatal(err)
}
// Create nested directory structure:
// tmpDir/
// .beads/test.db
// project1/
// .beads/project1.db
// subdir/
// (working directory here)
// Root .beads
rootBeads := filepath.Join(tmpDir, ".beads")
if err := os.MkdirAll(rootBeads, 0750); err != nil {
t.Fatal(err)
}
rootDB := filepath.Join(rootBeads, "test.db")
if err := os.WriteFile(rootDB, []byte("fake db"), 0600); err != nil {
t.Fatal(err)
}
// Project1 .beads
project1Dir := filepath.Join(tmpDir, "project1")
project1Beads := filepath.Join(project1Dir, ".beads")
if err := os.MkdirAll(project1Beads, 0750); err != nil {
t.Fatal(err)
}
project1DB := filepath.Join(project1Beads, "project1.db")
if err := os.WriteFile(project1DB, []byte("fake db"), 0600); err != nil {
t.Fatal(err)
}
// Subdir for working directory
subdir := filepath.Join(project1Dir, "subdir")
if err := os.MkdirAll(subdir, 0750); err != nil {
t.Fatal(err)
}
// Change to subdir and test FindAllDatabases
t.Chdir(subdir)
databases := FindAllDatabases()
// Should find only the closest database (gt-bzd: stop searching when .beads found)
// Parent .beads directories are out of scope in multi-workspace setups like Gas Town
if len(databases) != 1 {
t.Fatalf("expected 1 database (closest only), got %d", len(databases))
}
// Database should be project1 (closest to CWD)
if databases[0].Path != project1DB {
t.Errorf("expected database to be %s, got %s", project1DB, databases[0].Path)
}
if databases[0].BeadsDir != project1Beads {
t.Errorf("expected beads dir to be %s, got %s", project1Beads, databases[0].BeadsDir)
}
// Root database should NOT be found - it's out of scope (parent of closest .beads)
_ = rootDB // referenced but not expected in results
_ = rootBeads // referenced but not expected in results
}
func TestFindAllDatabases_Single(t *testing.T) {
// Create a temporary directory with only one database
tmpDir, err := os.MkdirTemp("", "beads-single-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// Resolve symlinks (macOS /var -> /private/var)
tmpDir, err = filepath.EvalSymlinks(tmpDir)
if err != nil {
t.Fatal(err)
}
// Create .beads directory with database
beadsDir := filepath.Join(tmpDir, ".beads")
if err := os.MkdirAll(beadsDir, 0750); err != nil {
t.Fatal(err)
}
dbPath := filepath.Join(beadsDir, "test.db")
if err := os.WriteFile(dbPath, []byte("fake db"), 0600); err != nil {
t.Fatal(err)
}
// Change to tmpDir and test
t.Chdir(tmpDir)
databases := FindAllDatabases()
// Should find exactly one database
if len(databases) != 1 {
t.Fatalf("expected 1 database, got %d", len(databases))
}
if databases[0].Path != dbPath {
t.Errorf("expected database path %s, got %s", dbPath, databases[0].Path)
}
}
func TestFindAllDatabases_None(t *testing.T) {
// Create a temporary directory with no databases
tmpDir, err := os.MkdirTemp("", "beads-none-test")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(tmpDir)
// Change to tmpDir and test
t.Chdir(tmpDir)
databases := FindAllDatabases()
// Should find no databases
if len(databases) != 0 {
t.Fatalf("expected 0 databases, got %d", len(databases))
}
}