99 "github.com/spf13/cobra"
1010 "github.com/steveyegge/wasteland/internal/commons"
1111 "github.com/steveyegge/wasteland/internal/federation"
12+ "github.com/steveyegge/wasteland/internal/remote"
1213 "github.com/steveyegge/wasteland/internal/style"
1314)
1415
@@ -17,6 +18,9 @@ func newJoinCmd(stdout, stderr io.Writer) *cobra.Command {
1718 handle string
1819 displayName string
1920 email string
21+ forkOrg string
22+ remoteBase string
23+ gitRemote string
2024 )
2125
2226 cmd := & cobra.Command {
@@ -25,53 +29,55 @@ func newJoinCmd(stdout, stderr io.Writer) *cobra.Command {
2529 Long : `Join a wasteland community by forking its shared commons database.
2630
2731This command:
28- 1. Forks the upstream commons to your DoltHub org
32+ 1. Forks the upstream commons to your org
2933 2. Clones the fork locally
3034 3. Registers your rig in the rigs table
3135 4. Pushes the registration to your fork
3236 5. Saves wasteland configuration locally
3337
34- The upstream argument is a DoltHub path like 'steveyegge/wl-commons'.
38+ The upstream argument is an org/database path like 'steveyegge/wl-commons'.
3539
36- Required environment variables:
37- DOLTHUB_TOKEN - Your DoltHub API token
38- DOLTHUB_ORG - Your DoltHub organization name
40+ DoltHub mode (default):
41+ Requires DOLTHUB_TOKEN and DOLTHUB_ORG (or --fork-org).
42+ Forks and clones via DoltHub.
43+
44+ Offline file mode (--remote-base):
45+ Uses file:// dolt remotes. No DoltHub credentials needed.
46+ Requires --fork-org (or DOLTHUB_ORG).
47+
48+ Git remote mode (--git-remote):
49+ Uses bare git repos as dolt remotes. No DoltHub credentials needed.
50+ Requires --fork-org (or DOLTHUB_ORG).
3951
4052Examples:
4153 wl join steveyegge/wl-commons
4254 wl join steveyegge/wl-commons --handle my-rig
43- wl join steveyegge/wl-commons --display-name "Alice's Workshop"` ,
55+ wl join test-org/wl-commons --remote-base /tmp/remotes --fork-org my-fork
56+ wl join test-org/wl-commons --git-remote /tmp/git-remotes --fork-org my-fork` ,
4457 Args : cobra .ExactArgs (1 ),
4558 RunE : func (cmd * cobra.Command , args []string ) error {
46- return runJoin (stdout , stderr , args [0 ], handle , displayName , email )
59+ return runJoin (stdout , stderr , args [0 ], handle , displayName , email , forkOrg , remoteBase , gitRemote )
4760 },
4861 }
4962
50- cmd .Flags ().StringVar (& handle , "handle" , "" , "Rig handle for registration (default: DoltHub org)" )
63+ cmd .Flags ().StringVar (& handle , "handle" , "" , "Rig handle for registration (default: fork org)" )
5164 cmd .Flags ().StringVar (& displayName , "display-name" , "" , "Display name for the rig registry" )
5265 cmd .Flags ().StringVar (& email , "email" , "" , "Registration email (default: git config user.email)" )
66+ cmd .Flags ().StringVar (& forkOrg , "fork-org" , "" , "Fork organization (default: DOLTHUB_ORG)" )
67+ cmd .Flags ().StringVar (& remoteBase , "remote-base" , "" , "Base directory for file:// remotes (offline mode)" )
68+ cmd .Flags ().StringVar (& gitRemote , "git-remote" , "" , "Base directory for bare git remotes" )
69+ cmd .MarkFlagsMutuallyExclusive ("remote-base" , "git-remote" )
5370
5471 return cmd
5572}
5673
57- func runJoin (stdout , stderr io.Writer , upstream , handle , displayName , email string ) error {
74+ func runJoin (stdout , stderr io.Writer , upstream , handle , displayName , email , forkOrg , remoteBase , gitRemote string ) error {
5875 // Parse upstream path (validate early)
5976 _ , _ , err := federation .ParseUpstream (upstream )
6077 if err != nil {
6178 return err
6279 }
6380
64- // Require DoltHub credentials
65- token := commons .DoltHubToken ()
66- if token == "" {
67- return fmt .Errorf ("DOLTHUB_TOKEN environment variable is required\n \n Get your token from https://www.dolthub.com/settings/tokens" )
68- }
69-
70- forkOrg := commons .DoltHubOrg ()
71- if forkOrg == "" {
72- return fmt .Errorf ("DOLTHUB_ORG environment variable is required\n \n Set this to your DoltHub organization name" )
73- }
74-
7581 // Fast path: check if already joined
7682 if existing , loadErr := federation .LoadConfig (); loadErr == nil {
7783 if existing .Upstream == upstream {
@@ -84,6 +90,40 @@ func runJoin(stdout, stderr io.Writer, upstream, handle, displayName, email stri
8490 return fmt .Errorf ("already joined to %s; run wl leave first" , existing .Upstream )
8591 }
8692
93+ // Resolve fork org: flag > env var
94+ if forkOrg == "" {
95+ forkOrg = commons .DoltHubOrg ()
96+ }
97+
98+ var provider remote.Provider
99+
100+ switch {
101+ case remoteBase != "" :
102+ // Offline file mode — file:// dolt remotes, no DoltHub credentials needed.
103+ if forkOrg == "" {
104+ return fmt .Errorf ("--fork-org is required in offline mode (or set DOLTHUB_ORG)" )
105+ }
106+ provider = remote .NewFileProvider (remoteBase )
107+
108+ case gitRemote != "" :
109+ // Git remote mode — bare git repos as dolt remotes, no DoltHub credentials needed.
110+ if forkOrg == "" {
111+ return fmt .Errorf ("--fork-org is required in git remote mode (or set DOLTHUB_ORG)" )
112+ }
113+ provider = remote .NewGitProvider (gitRemote )
114+
115+ default :
116+ // DoltHub mode — requires token and org.
117+ token := commons .DoltHubToken ()
118+ if token == "" {
119+ return fmt .Errorf ("DOLTHUB_TOKEN environment variable is required\n \n Get your token from https://www.dolthub.com/settings/tokens" )
120+ }
121+ if forkOrg == "" {
122+ return fmt .Errorf ("DOLTHUB_ORG environment variable is required\n \n Set this to your DoltHub organization name" )
123+ }
124+ provider = remote .NewDoltHubProvider (token )
125+ }
126+
87127 // Determine handle
88128 if handle == "" {
89129 handle = forkOrg
@@ -101,13 +141,14 @@ func runJoin(stdout, stderr io.Writer, upstream, handle, displayName, email stri
101141
102142 wlVersion := "dev"
103143
104- svc := federation .NewService ()
144+ svc := federation .NewService (provider )
105145 svc .OnProgress = func (step string ) {
106146 fmt .Fprintf (stdout , " %s\n " , step )
107147 }
108148
109- fmt .Fprintf (stdout , "Joining wasteland %s (fork to %s/%s)...\n " , upstream , forkOrg , upstream [strings .Index (upstream , "/" )+ 1 :])
110- cfg , err := svc .Join (upstream , forkOrg , token , handle , displayName , email , wlVersion )
149+ dbName := upstream [strings .Index (upstream , "/" )+ 1 :]
150+ fmt .Fprintf (stdout , "Joining wasteland %s (fork to %s/%s)...\n " , upstream , forkOrg , dbName )
151+ cfg , err := svc .Join (upstream , forkOrg , handle , displayName , email , wlVersion )
111152 if err != nil {
112153 return err
113154 }
0 commit comments