fix(beads): Use conditional routing based on source repo beads location
Route to the correct beads location based on whether the source repo has .beads/ tracked in git: - If source has .beads/ tracked: route to mayor/rig/.beads - Otherwise: route to rig root .beads/ (created by initBeads) Updates both route registration in rig.go and polecat manager's NewManager/setupSharedBeads to use consistent conditional logic.
This commit is contained in:
@@ -317,11 +317,22 @@ func runRigAdd(cmd *cobra.Command, args []string) error {
|
|||||||
return fmt.Errorf("saving rigs config: %w", err)
|
return fmt.Errorf("saving rigs config: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add route to town-level routes.jsonl for prefix-based routing
|
// Add route to town-level routes.jsonl for prefix-based routing.
|
||||||
|
// Route points to the canonical beads location:
|
||||||
|
// - If source repo has .beads/ tracked in git, route to mayor/rig
|
||||||
|
// - Otherwise route to rig root (where initBeads creates the database)
|
||||||
|
// The conditional routing is necessary because initBeads creates the database at
|
||||||
|
// "<rig>/.beads", while repos with tracked beads have their database at mayor/rig/.beads.
|
||||||
if newRig.Config.Prefix != "" {
|
if newRig.Config.Prefix != "" {
|
||||||
|
routePath := name
|
||||||
|
mayorRigBeads := filepath.Join(townRoot, name, "mayor", "rig", ".beads")
|
||||||
|
if _, err := os.Stat(mayorRigBeads); err == nil {
|
||||||
|
// Source repo has .beads/ tracked - route to mayor/rig
|
||||||
|
routePath = name + "/mayor/rig"
|
||||||
|
}
|
||||||
route := beads.Route{
|
route := beads.Route{
|
||||||
Prefix: newRig.Config.Prefix + "-",
|
Prefix: newRig.Config.Prefix + "-",
|
||||||
Path: name + "/mayor/rig",
|
Path: routePath,
|
||||||
}
|
}
|
||||||
if err := beads.AppendRoute(townRoot, route); err != nil {
|
if err := beads.AppendRoute(townRoot, route); err != nil {
|
||||||
// Non-fatal: routing will still work, just not from town root
|
// Non-fatal: routing will still work, just not from town root
|
||||||
|
|||||||
@@ -47,8 +47,16 @@ type Manager struct {
|
|||||||
|
|
||||||
// NewManager creates a new polecat manager.
|
// NewManager creates a new polecat manager.
|
||||||
func NewManager(r *rig.Rig, g *git.Git) *Manager {
|
func NewManager(r *rig.Rig, g *git.Git) *Manager {
|
||||||
// Use the rig root for beads operations (rig-level beads at .beads/)
|
// Determine the canonical beads location:
|
||||||
rigPath := r.Path
|
// - If mayor/rig/.beads exists (source repo has beads tracked), use that
|
||||||
|
// - Otherwise use rig root .beads/ (created by initBeads during gt rig add)
|
||||||
|
// This matches the conditional logic in setupSharedBeads and route registration.
|
||||||
|
// For repos that have .beads/ tracked in git, the canonical database lives in mayor/rig/.
|
||||||
|
mayorRigBeads := filepath.Join(r.Path, "mayor", "rig", ".beads")
|
||||||
|
beadsPath := r.Path
|
||||||
|
if _, err := os.Stat(mayorRigBeads); err == nil {
|
||||||
|
beadsPath = filepath.Join(r.Path, "mayor", "rig")
|
||||||
|
}
|
||||||
|
|
||||||
// Try to load rig settings for namepool config
|
// Try to load rig settings for namepool config
|
||||||
settingsPath := filepath.Join(r.Path, "settings", "config.json")
|
settingsPath := filepath.Join(r.Path, "settings", "config.json")
|
||||||
@@ -73,7 +81,7 @@ func NewManager(r *rig.Rig, g *git.Git) *Manager {
|
|||||||
return &Manager{
|
return &Manager{
|
||||||
rig: r,
|
rig: r,
|
||||||
git: g,
|
git: g,
|
||||||
beads: beads.New(rigPath),
|
beads: beads.New(beadsPath),
|
||||||
namePool: pool,
|
namePool: pool,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -763,15 +771,41 @@ func (m *Manager) loadFromBeads(name string) (*Polecat, error) {
|
|||||||
// polecats/
|
// polecats/
|
||||||
// <name>/
|
// <name>/
|
||||||
// .beads/
|
// .beads/
|
||||||
// redirect <- Contains "../../.beads"
|
// redirect <- Contains "../../.beads" or "../../mayor/rig/.beads"
|
||||||
//
|
//
|
||||||
// IMPORTANT: If the polecat was created from a branch that had .beads/ tracked in git,
|
// IMPORTANT: If the polecat was created from a branch that had .beads/ tracked in git,
|
||||||
// those files will be present. We must clean them out and replace with just the redirect.
|
// those files will be present. We must clean them out and replace with just the redirect.
|
||||||
|
//
|
||||||
|
// The redirect target is conditional: repos with .beads/ tracked in git have their canonical
|
||||||
|
// database at mayor/rig/.beads, while fresh rigs use the database at rig root .beads/.
|
||||||
func (m *Manager) setupSharedBeads(polecatPath string) error {
|
func (m *Manager) setupSharedBeads(polecatPath string) error {
|
||||||
// Ensure rig root has .beads/ directory
|
// Determine the shared beads location:
|
||||||
rigBeadsDir := filepath.Join(m.rig.Path, ".beads")
|
// - If mayor/rig/.beads exists (source repo has beads tracked in git), use that
|
||||||
if err := os.MkdirAll(rigBeadsDir, 0755); err != nil {
|
// - Otherwise fall back to rig/.beads (created by initBeads during gt rig add)
|
||||||
return fmt.Errorf("creating rig .beads dir: %w", err)
|
// This matches the crew manager's logic for consistency.
|
||||||
|
mayorRigBeads := filepath.Join(m.rig.Path, "mayor", "rig", ".beads")
|
||||||
|
rigRootBeads := filepath.Join(m.rig.Path, ".beads")
|
||||||
|
|
||||||
|
var sharedBeadsPath string
|
||||||
|
var redirectContent string
|
||||||
|
|
||||||
|
if _, err := os.Stat(mayorRigBeads); err == nil {
|
||||||
|
// Source repo has .beads/ tracked - use mayor/rig/.beads
|
||||||
|
sharedBeadsPath = mayorRigBeads
|
||||||
|
redirectContent = "../../mayor/rig/.beads\n"
|
||||||
|
} else {
|
||||||
|
// No beads in source repo - use rig root .beads (from initBeads)
|
||||||
|
sharedBeadsPath = rigRootBeads
|
||||||
|
redirectContent = "../../.beads\n"
|
||||||
|
// Ensure rig root has .beads/ directory
|
||||||
|
if err := os.MkdirAll(rigRootBeads, 0755); err != nil {
|
||||||
|
return fmt.Errorf("creating rig .beads dir: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify shared beads exists
|
||||||
|
if _, err := os.Stat(sharedBeadsPath); os.IsNotExist(err) {
|
||||||
|
return fmt.Errorf("no shared beads database found at %s", sharedBeadsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up any existing .beads/ contents from the branch
|
// Clean up any existing .beads/ contents from the branch
|
||||||
@@ -790,12 +824,8 @@ func (m *Manager) setupSharedBeads(polecatPath string) error {
|
|||||||
return fmt.Errorf("creating polecat .beads dir: %w", err)
|
return fmt.Errorf("creating polecat .beads dir: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create redirect file pointing to mayor/rig/.beads (the canonical beads location)
|
// Create redirect file pointing to the shared beads location
|
||||||
// Path is relative from polecats/<name>/.beads/ to mayor/rig/.beads/
|
|
||||||
// We go directly to mayor/rig/.beads, not through rig root, to match crew workers
|
|
||||||
redirectPath := filepath.Join(polecatBeadsDir, "redirect")
|
redirectPath := filepath.Join(polecatBeadsDir, "redirect")
|
||||||
redirectContent := "../../mayor/rig/.beads\n"
|
|
||||||
|
|
||||||
if err := os.WriteFile(redirectPath, []byte(redirectContent), 0644); err != nil {
|
if err := os.WriteFile(redirectPath, []byte(redirectContent), 0644); err != nil {
|
||||||
return fmt.Errorf("creating redirect file: %w", err)
|
return fmt.Errorf("creating redirect file: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user