Skip to content

Commit 94a5524

Browse files
osamu2001steveyegge
authored andcommitted
fix(doctor): use effective beads dir for shared-server checks (beads-9f74-385)
1 parent 65ed43f commit 94a5524

3 files changed

Lines changed: 96 additions & 6 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package doctor
2+
3+
import (
4+
"os"
5+
"os/exec"
6+
"path/filepath"
7+
"strings"
8+
"testing"
9+
10+
"github.com/steveyegge/beads/internal/utils"
11+
)
12+
13+
func TestResolveBeadsDirForRepo_BareParentWorktreeFallback(t *testing.T) {
14+
bareDir, featureWorktreeDir := setupBareParentWorktreeForDoctorTest(t)
15+
bareBeadsDir := filepath.Join(bareDir, ".beads")
16+
if err := os.MkdirAll(bareBeadsDir, 0o750); err != nil {
17+
t.Fatal(err)
18+
}
19+
20+
resolved := ResolveBeadsDirForRepo(featureWorktreeDir)
21+
if resolved != utils.CanonicalizePath(bareBeadsDir) {
22+
t.Fatalf("ResolveBeadsDirForRepo() = %q, want %q", resolved, utils.CanonicalizePath(bareBeadsDir))
23+
}
24+
}
25+
26+
func TestCheckMetadataVersionTracking_BareParentWorktreeFallback(t *testing.T) {
27+
bareDir, featureWorktreeDir := setupBareParentWorktreeForDoctorTest(t)
28+
bareBeadsDir := filepath.Join(bareDir, ".beads")
29+
if err := os.MkdirAll(bareBeadsDir, 0o750); err != nil {
30+
t.Fatal(err)
31+
}
32+
if err := os.WriteFile(filepath.Join(bareBeadsDir, ".local_version"), []byte("0.60.0\n"), 0o600); err != nil {
33+
t.Fatal(err)
34+
}
35+
36+
check := CheckMetadataVersionTracking(featureWorktreeDir, "0.60.0")
37+
if check.Status != StatusOK {
38+
t.Fatalf("expected ok, got %s: %s", check.Status, check.Message)
39+
}
40+
}
41+
42+
func TestCheckLockHealth_BareParentWorktreeFallback(t *testing.T) {
43+
bareDir, featureWorktreeDir := setupBareParentWorktreeForDoctorTest(t)
44+
bareBeadsDir := filepath.Join(bareDir, ".beads")
45+
if err := os.MkdirAll(filepath.Join(bareBeadsDir, "dolt"), 0o750); err != nil {
46+
t.Fatal(err)
47+
}
48+
if err := os.WriteFile(filepath.Join(bareBeadsDir, "metadata.json"), []byte(`{"backend":"dolt"}`), 0o600); err != nil {
49+
t.Fatal(err)
50+
}
51+
52+
check := CheckLockHealth(featureWorktreeDir)
53+
if check.Status != StatusOK {
54+
t.Fatalf("expected ok, got %s: %s", check.Status, check.Message)
55+
}
56+
}
57+
58+
func setupBareParentWorktreeForDoctorTest(t *testing.T) (string, string) {
59+
t.Helper()
60+
61+
tmpDir := t.TempDir()
62+
bareDir := filepath.Join(tmpDir, "repo.git")
63+
mainWorktreeDir := filepath.Join(tmpDir, "main")
64+
featureWorktreeDir := filepath.Join(tmpDir, "feature")
65+
66+
runGitInDirForDoctorTest(t, tmpDir, "init", "--bare", bareDir)
67+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "symbolic-ref", "HEAD", "refs/heads/main")
68+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "config", "user.email", "test@example.com")
69+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "config", "user.name", "Test User")
70+
emptyTree := runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "hash-object", "-t", "tree", "/dev/null")
71+
initCommit := runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "commit-tree", "-m", "Initial commit", emptyTree)
72+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "update-ref", "HEAD", initCommit)
73+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "worktree", "add", mainWorktreeDir, "main")
74+
runGitInDirForDoctorTest(t, mainWorktreeDir, "branch", "feature")
75+
runGitInDirForDoctorTest(t, tmpDir, "--git-dir", bareDir, "worktree", "add", featureWorktreeDir, "feature")
76+
77+
return bareDir, featureWorktreeDir
78+
}
79+
80+
func runGitInDirForDoctorTest(t *testing.T, dir string, args ...string) string {
81+
t.Helper()
82+
83+
cmd := exec.Command("git", args...)
84+
cmd.Dir = dir
85+
output, err := cmd.CombinedOutput()
86+
if err != nil {
87+
t.Fatalf("git %v failed in %s: %v\n%s", args, dir, err, output)
88+
}
89+
90+
return strings.TrimSpace(string(output))
91+
}

cmd/bd/doctor/dolt.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ func RunDoltHealthChecks(path string) []DoctorCheck {
126126
// CheckLockHealth before any checks that open embedded Dolt databases,
127127
// avoiding false positives from doctor's own noms LOCK files (GH#1981).
128128
func RunDoltHealthChecksWithLock(path string, lockCheck DoctorCheck) []DoctorCheck {
129-
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
129+
beadsDir := ResolveBeadsDirForRepo(path)
130130

131131
if !IsDoltBackend(beadsDir) {
132132
return []DoctorCheck{
@@ -199,7 +199,7 @@ func checkConnectionWithDB(conn *doltConn) DoctorCheck {
199199
// This is the standalone entry point; RunDoltHealthChecks is preferred
200200
// for coordinated access.
201201
func CheckDoltConnection(path string) DoctorCheck {
202-
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
202+
beadsDir := ResolveBeadsDirForRepo(path)
203203

204204
// Only run this check for Dolt backend
205205
if !IsDoltBackend(beadsDir) {
@@ -463,7 +463,7 @@ func checkStatusWithDB(conn *doltConn) DoctorCheck {
463463
// This is the standalone entry point; RunDoltHealthChecks is preferred
464464
// for coordinated access.
465465
func CheckDoltStatus(path string) DoctorCheck {
466-
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
466+
beadsDir := ResolveBeadsDirForRepo(path)
467467

468468
// Only run for Dolt backend
469469
if !IsDoltBackend(beadsDir) {
@@ -494,7 +494,7 @@ func CheckDoltStatus(path string) DoctorCheck {
494494
// It probes for stale noms LOCK files and checks whether the advisory lock
495495
// is currently held, providing actionable guidance when issues are found.
496496
func CheckLockHealth(path string) DoctorCheck {
497-
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
497+
beadsDir := ResolveBeadsDirForRepo(path)
498498

499499
if !IsDoltBackend(beadsDir) {
500500
return DoctorCheck{

cmd/bd/doctor/version.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ const localVersionFile = ".local_version"
9797
// GH#662: This was updated to check .local_version instead of metadata.json:LastBdVersion,
9898
// which is now deprecated.
9999
func CheckMetadataVersionTracking(path string, currentVersion string) DoctorCheck {
100-
// Follow redirect to resolve actual beads directory (bd-tvus fix)
101-
beadsDir := resolveBeadsDir(filepath.Join(path, ".beads"))
100+
beadsDir := ResolveBeadsDirForRepo(path)
102101
localVersionPath := filepath.Join(beadsDir, localVersionFile)
103102

104103
// Read .local_version file

0 commit comments

Comments
 (0)