Skip to content

Commit 573bdd1

Browse files
committed
feat(dolt): add 'bd dolt remote' subcommands (add/list/remove)
Expose the existing DoltStore remote management methods through CLI commands so users never need the dolt CLI for basic replication setup. Closes: bd-fhh Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Executed-By: beads/polecats/quartz Rig: beads Role: polecats
1 parent e688ea7 commit 573bdd1

1 file changed

Lines changed: 117 additions & 0 deletions

File tree

cmd/bd/dolt.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ Version control:
4747
bd dolt push Push commits to Dolt remote
4848
bd dolt pull Pull commits from Dolt remote
4949
50+
Remote management:
51+
bd dolt remote add <name> <url> Add a Dolt remote
52+
bd dolt remote list List configured remotes
53+
bd dolt remote remove <name> Remove a Dolt remote
54+
5055
Configuration keys for 'bd dolt set':
5156
database Database name (default: issue prefix or "beads")
5257
host Server host (default: 127.0.0.1)
@@ -539,6 +544,114 @@ Use --dry-run to see what would be dropped without actually dropping.`,
539544
},
540545
}
541546

547+
// --- Dolt remote management commands ---
548+
549+
var doltRemoteCmd = &cobra.Command{
550+
Use: "remote",
551+
Short: "Manage Dolt remotes",
552+
Long: `Manage Dolt remotes for push/pull replication.
553+
554+
Subcommands:
555+
add <name> <url> Add a new remote
556+
list List all configured remotes
557+
remove <name> Remove a remote`,
558+
}
559+
560+
var doltRemoteAddCmd = &cobra.Command{
561+
Use: "add <name> <url>",
562+
Short: "Add a Dolt remote",
563+
Args: cobra.ExactArgs(2),
564+
Run: func(cmd *cobra.Command, args []string) {
565+
ctx := context.Background()
566+
st := getStore()
567+
if st == nil {
568+
fmt.Fprintf(os.Stderr, "Error: no store available\n")
569+
os.Exit(1)
570+
}
571+
name, url := args[0], args[1]
572+
if err := st.AddRemote(ctx, name, url); err != nil {
573+
if jsonOutput {
574+
outputJSONError(err, "remote_add_failed")
575+
} else {
576+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
577+
}
578+
os.Exit(1)
579+
}
580+
if jsonOutput {
581+
outputJSON(map[string]interface{}{
582+
"name": name,
583+
"url": url,
584+
})
585+
} else {
586+
fmt.Printf("Added remote %q → %s\n", name, url)
587+
}
588+
},
589+
}
590+
591+
var doltRemoteListCmd = &cobra.Command{
592+
Use: "list",
593+
Short: "List configured Dolt remotes",
594+
Run: func(cmd *cobra.Command, args []string) {
595+
ctx := context.Background()
596+
st := getStore()
597+
if st == nil {
598+
fmt.Fprintf(os.Stderr, "Error: no store available\n")
599+
os.Exit(1)
600+
}
601+
remotes, err := st.ListRemotes(ctx)
602+
if err != nil {
603+
if jsonOutput {
604+
outputJSONError(err, "remote_list_failed")
605+
} else {
606+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
607+
}
608+
os.Exit(1)
609+
}
610+
if jsonOutput {
611+
outputJSON(remotes)
612+
return
613+
}
614+
if len(remotes) == 0 {
615+
fmt.Println("No remotes configured.")
616+
return
617+
}
618+
for _, r := range remotes {
619+
fmt.Printf("%-20s %s\n", r.Name, r.URL)
620+
}
621+
},
622+
}
623+
624+
var doltRemoteRemoveCmd = &cobra.Command{
625+
Use: "remove <name>",
626+
Short: "Remove a Dolt remote",
627+
Args: cobra.ExactArgs(1),
628+
Run: func(cmd *cobra.Command, args []string) {
629+
ctx := context.Background()
630+
st := getStore()
631+
if st == nil {
632+
fmt.Fprintf(os.Stderr, "Error: no store available\n")
633+
os.Exit(1)
634+
}
635+
name := args[0]
636+
if err := st.RemoveRemote(ctx, name); err != nil {
637+
if jsonOutput {
638+
outputJSONError(err, "remote_remove_failed")
639+
} else {
640+
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
641+
}
642+
os.Exit(1)
643+
}
644+
if jsonOutput {
645+
outputJSON(map[string]interface{}{
646+
"name": name,
647+
"removed": true,
648+
})
649+
} else {
650+
fmt.Printf("Removed remote %q\n", name)
651+
}
652+
},
653+
}
654+
542655
// isTimeoutError checks if an error is a context deadline exceeded or timeout.
543656
func isTimeoutError(err error) bool {
544657
if err == nil {
@@ -563,6 +676,9 @@ func init() {
563676
doltCommitCmd.Flags().StringP("message", "m", "", "Commit message (default: auto-generated)")
564677
doltIdleMonitorCmd.Flags().String("beads-dir", "", "Path to .beads directory")
565678
doltCleanDatabasesCmd.Flags().Bool("dry-run", false, "Show what would be dropped without dropping")
679+
doltRemoteCmd.AddCommand(doltRemoteAddCmd)
680+
doltRemoteCmd.AddCommand(doltRemoteListCmd)
681+
doltRemoteCmd.AddCommand(doltRemoteRemoveCmd)
566682
doltCmd.AddCommand(doltShowCmd)
567683
doltCmd.AddCommand(doltSetCmd)
568684
doltCmd.AddCommand(doltTestCmd)
@@ -575,6 +691,7 @@ func init() {
575691
doltCmd.AddCommand(doltIdleMonitorCmd)
576692
doltCmd.AddCommand(doltKillallCmd)
577693
doltCmd.AddCommand(doltCleanDatabasesCmd)
694+
doltCmd.AddCommand(doltRemoteCmd)
578695
rootCmd.AddCommand(doltCmd)
579696
}
580697

0 commit comments

Comments
 (0)