@@ -44,7 +44,7 @@ func NewReplicateCommand() *ReplicateCommand {
44
44
}
45
45
46
46
// ParseFlags parses the CLI flags and loads the configuration file.
47
- func (c * ReplicateCommand ) ParseFlags (ctx context.Context , args []string ) (err error ) {
47
+ func (c * ReplicateCommand ) ParseFlags (_ context.Context , args []string ) (err error ) {
48
48
fs := flag .NewFlagSet ("litestream-replicate" , flag .ContinueOnError )
49
49
execFlag := fs .String ("exec" , "" , "execute subcommand" )
50
50
configPath , noExpandEnv := registerConfigFlag (fs )
@@ -54,9 +54,22 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
54
54
}
55
55
56
56
// Load configuration or use CLI args to build db/replica.
57
- if fs .NArg () == 1 {
57
+ switch fs .NArg () {
58
+ case 0 :
59
+ // No arguments provided, use config file
60
+ if * configPath == "" {
61
+ * configPath = DefaultConfigPath ()
62
+ }
63
+ if c .Config , err = ReadConfigFile (* configPath , ! * noExpandEnv ); err != nil {
64
+ return err
65
+ }
66
+
67
+ case 1 :
68
+ // Only database path provided, missing replica URL
58
69
return fmt .Errorf ("must specify at least one replica URL for %s" , fs .Arg (0 ))
59
- } else if fs .NArg () > 1 {
70
+
71
+ default :
72
+ // Database path and replica URLs provided via CLI
60
73
if * configPath != "" {
61
74
return fmt .Errorf ("cannot specify a replica URL and the -config flag" )
62
75
}
@@ -73,14 +86,8 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
73
86
})
74
87
}
75
88
c .Config .DBs = []* DBConfig {dbConfig }
76
- } else {
77
- if * configPath == "" {
78
- * configPath = DefaultConfigPath ()
79
- }
80
- if c .Config , err = ReadConfigFile (* configPath , ! * noExpandEnv ); err != nil {
81
- return err
82
- }
83
89
}
90
+
84
91
c .Config .ConfigPath = * configPath
85
92
86
93
// Override config exec command, if specified.
@@ -92,13 +99,13 @@ func (c *ReplicateCommand) ParseFlags(ctx context.Context, args []string) (err e
92
99
}
93
100
94
101
// Run loads all databases specified in the configuration.
95
- func (c * ReplicateCommand ) Run () (err error ) {
102
+ func (c * ReplicateCommand ) Run (ctx context. Context ) (err error ) {
96
103
// Display version information.
97
104
slog .Info ("litestream" , "version" , Version , "level" , c .Config .Logging .Level )
98
105
99
106
// Start MCP server if enabled
100
107
if c .Config .MCPAddr != "" {
101
- c .MCP , err = NewMCP (context . Background () , c .Config .ConfigPath )
108
+ c .MCP , err = NewMCP (ctx , c .Config .ConfigPath )
102
109
if err != nil {
103
110
return err
104
111
}
@@ -110,7 +117,7 @@ func (c *ReplicateCommand) Run() (err error) {
110
117
slog .Error ("no databases specified in configuration" )
111
118
}
112
119
113
- var dbs []* litestream.DB
120
+ dbs := make ( []* litestream.DB , 0 , len ( c . Config . DBs ))
114
121
for _ , dbConfig := range c .Config .DBs {
115
122
db , err := NewDBFromConfig (dbConfig )
116
123
if err != nil {
@@ -129,30 +136,30 @@ func (c *ReplicateCommand) Run() (err error) {
129
136
if c .Config .Snapshot .Retention != nil {
130
137
c .Store .SnapshotRetention = * c .Config .Snapshot .Retention
131
138
}
132
- if err := c .Store .Open (context . Background () ); err != nil {
139
+ if err := c .Store .Open (ctx ); err != nil {
133
140
return fmt .Errorf ("cannot open store: %w" , err )
134
141
}
135
142
136
143
// Notify user that initialization is done.
137
144
for _ , db := range c .Store .DBs () {
138
145
r := db .Replica
139
146
slog .Info ("initialized db" , "path" , db .Path ())
140
- slog := slog .With ("type" , r .Client .Type (), "sync-interval" , r .SyncInterval )
147
+ slogWith := slog .With ("type" , r .Client .Type (), "sync-interval" , r .SyncInterval )
141
148
switch client := r .Client .(type ) {
142
149
case * file.ReplicaClient :
143
- slog .Info ("replicating to" , "path" , client .Path ())
150
+ slogWith .Info ("replicating to" , "path" , client .Path ())
144
151
case * s3.ReplicaClient :
145
- slog .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path , "region" , client .Region , "endpoint" , client .Endpoint )
152
+ slogWith .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path , "region" , client .Region , "endpoint" , client .Endpoint )
146
153
case * gs.ReplicaClient :
147
- slog .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path )
154
+ slogWith .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path )
148
155
case * abs.ReplicaClient :
149
- slog .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path , "endpoint" , client .Endpoint )
156
+ slogWith .Info ("replicating to" , "bucket" , client .Bucket , "path" , client .Path , "endpoint" , client .Endpoint )
150
157
case * sftp.ReplicaClient :
151
- slog .Info ("replicating to" , "host" , client .Host , "user" , client .User , "path" , client .Path )
158
+ slogWith .Info ("replicating to" , "host" , client .Host , "user" , client .User , "path" , client .Path )
152
159
case * nats.ReplicaClient :
153
- slog .Info ("replicating to" , "bucket" , client .BucketName , "url" , client .URL )
160
+ slogWith .Info ("replicating to" , "bucket" , client .BucketName , "url" , client .URL )
154
161
default :
155
- slog .Info ("replicating to" )
162
+ slogWith .Info ("replicating to" )
156
163
}
157
164
}
158
165
@@ -181,7 +188,7 @@ func (c *ReplicateCommand) Run() (err error) {
181
188
return fmt .Errorf ("cannot parse exec command: %w" , err )
182
189
}
183
190
184
- c .cmd = exec .Command ( execArgs [0 ], execArgs [1 :]... )
191
+ c .cmd = exec .CommandContext ( ctx , execArgs [0 ], execArgs [1 :]... )
185
192
c .cmd .Env = os .Environ ()
186
193
c .cmd .Stdout = os .Stdout
187
194
c .cmd .Stderr = os .Stderr
@@ -195,16 +202,16 @@ func (c *ReplicateCommand) Run() (err error) {
195
202
}
196
203
197
204
// Close closes all open databases.
198
- func (c * ReplicateCommand ) Close () ( err error ) {
199
- if e := c .Store .Close (); e != nil {
200
- slog .Error ("failed to close database" , "error" , e )
205
+ func (c * ReplicateCommand ) Close (ctx context. Context ) error {
206
+ if err := c .Store .Close (ctx ); err != nil {
207
+ slog .Error ("failed to close database" , "error" , err )
201
208
}
202
209
if c .Config .MCPAddr != "" {
203
210
if err := c .MCP .Close (); err != nil {
204
211
slog .Error ("error closing MCP server" , "error" , err )
205
212
}
206
213
}
207
- return err
214
+ return nil
208
215
}
209
216
210
217
// Usage prints the help screen to STDOUT.
0 commit comments