8
8
"bytes"
9
9
"context"
10
10
"errors"
11
+ "fmt"
11
12
"io/fs"
12
13
"io/ioutil"
13
14
"os"
@@ -54,7 +55,7 @@ migration, Atlas will print the migration plan and prompt the user for approval.
54
55
55
56
If run with the "--dry-run" flag, atlas will exit after printing out the planned
56
57
migration.` ,
57
- Run : CmdApplyRun ,
58
+ RunE : CmdApplyRun ,
58
59
Example : ` atlas schema apply -u "mysql://user:pass@localhost/dbname" -f atlas.hcl
59
60
atlas schema apply -u "mysql://localhost" -f atlas.hcl --schema prod --schema staging
60
61
atlas schema apply -u "mysql://user:pass@localhost:3306/dbname" -f atlas.hcl --dry-run
@@ -114,6 +115,14 @@ const (
114
115
answerAbort = "Abort"
115
116
)
116
117
118
+ // selectEnv selects the environment config from the current directory project file.
119
+ func selectEnv (args []string ) (* Env , error ) {
120
+ if len (args ) == 0 {
121
+ return nil , nil
122
+ }
123
+ return LoadEnv (projectFileName , args [0 ])
124
+ }
125
+
117
126
func init () {
118
127
// Schema apply flags.
119
128
schemaCmd .AddCommand (SchemaApply )
@@ -129,8 +138,7 @@ func init() {
129
138
SchemaApply .Flags ().BoolVarP (& ApplyFlags .Verbose , migrateDiffFlagVerbose , "" , false , "enable verbose logging" )
130
139
SchemaApply .Flags ().StringToStringVarP (& ApplyFlags .Vars , "var" , "" , nil , "input variables" )
131
140
cobra .CheckErr (SchemaApply .MarkFlagRequired ("url" ))
132
- cobra .CheckErr (SchemaApply .MarkFlagRequired ("file" ))
133
- dsn2url (SchemaApply , & ApplyFlags .URL )
141
+ fixURLFlag (SchemaApply , & ApplyFlags .URL )
134
142
135
143
// Schema inspect flags.
136
144
schemaCmd .AddCommand (SchemaInspect )
@@ -139,14 +147,14 @@ func init() {
139
147
SchemaInspect .Flags ().StringVarP (& InspectFlags .Addr , "addr" , "" , ":5800" , "Used with -w, local address to bind the server to" )
140
148
SchemaInspect .Flags ().StringSliceVarP (& InspectFlags .Schema , "schema" , "s" , nil , "Set schema name" )
141
149
cobra .CheckErr (SchemaInspect .MarkFlagRequired ("url" ))
142
- dsn2url (SchemaInspect , & InspectFlags .URL )
150
+ fixURLFlag (SchemaInspect , & InspectFlags .URL )
143
151
144
152
// Schema fmt.
145
153
schemaCmd .AddCommand (SchemaFmt )
146
154
}
147
155
148
156
// CmdInspectRun is the command used when running CLI.
149
- func CmdInspectRun (cmd * cobra.Command , _ []string ) {
157
+ func CmdInspectRun (cmd * cobra.Command , args []string ) {
150
158
if InspectFlags .Web {
151
159
schemaCmd .PrintErrln ("The Alas UI is not available in this release." )
152
160
return
@@ -155,6 +163,11 @@ func CmdInspectRun(cmd *cobra.Command, _ []string) {
155
163
cobra .CheckErr (err )
156
164
defer client .Close ()
157
165
schemas := InspectFlags .Schema
166
+ activeEnv , err := selectEnv (args )
167
+ cobra .CheckErr (err )
168
+ if activeEnv != nil && len (activeEnv .Schemas ) > 0 {
169
+ schemas = activeEnv .Schemas
170
+ }
158
171
if client .URL .Schema != "" {
159
172
schemas = append (schemas , client .URL .Schema )
160
173
}
@@ -168,15 +181,37 @@ func CmdInspectRun(cmd *cobra.Command, _ []string) {
168
181
}
169
182
170
183
// CmdApplyRun is the command used when running CLI.
171
- func CmdApplyRun (cmd * cobra.Command , _ []string ) {
184
+ func CmdApplyRun (cmd * cobra.Command , args []string ) error {
172
185
if ApplyFlags .Web {
173
- schemaCmd . PrintErrln ("The Atlas UI is not available in this release." )
174
- return
186
+ cmd . Println ("The Atlas UI is not available in this release." )
187
+ return errors . New ( "unavailable" )
175
188
}
176
189
c , err := sqlclient .Open (cmd .Context (), ApplyFlags .URL )
177
- cobra .CheckErr (err )
190
+ if err != nil {
191
+ return err
192
+ }
178
193
defer c .Close ()
179
- applyRun (cmd .Context (), c , ApplyFlags .File , ApplyFlags .DryRun , ApplyFlags .AutoApprove , ApplyFlags .Vars )
194
+ devURL := ApplyFlags .DevURL
195
+ activeEnv , err := selectEnv (args )
196
+ if err != nil {
197
+ return err
198
+ }
199
+ if activeEnv != nil && activeEnv .DevURL != "" {
200
+ devURL = activeEnv .DevURL
201
+ }
202
+ var file string
203
+ switch {
204
+ case activeEnv != nil && activeEnv .Source != "" :
205
+ file = activeEnv .Source
206
+ case ApplyFlags .File != "" :
207
+ file = ApplyFlags .File
208
+ default :
209
+ return fmt .Errorf ("source file must be set via -f or project file" )
210
+ }
211
+ if activeEnv != nil && activeEnv .Source != "" {
212
+ file = activeEnv .Source
213
+ }
214
+ return applyRun (cmd .Context (), c , devURL , file , ApplyFlags .DryRun , ApplyFlags .AutoApprove , ApplyFlags .Vars )
180
215
}
181
216
182
217
// CmdFmtRun formats all HCL files in a given directory using canonical HCL formatting
@@ -190,19 +225,25 @@ func CmdFmtRun(cmd *cobra.Command, args []string) {
190
225
}
191
226
}
192
227
193
- func applyRun (ctx context.Context , client * sqlclient.Client , file string , dryRun , autoApprove bool , input map [string ]string ) {
228
+ func applyRun (ctx context.Context , client * sqlclient.Client , devURL string , file string , dryRun , autoApprove bool , input map [string ]string ) error {
194
229
schemas := ApplyFlags .Schema
195
230
if client .URL .Schema != "" {
196
231
schemas = append (schemas , client .URL .Schema )
197
232
}
198
233
realm , err := client .InspectRealm (ctx , & schema.InspectRealmOption {
199
234
Schemas : schemas ,
200
235
})
201
- cobra .CheckErr (err )
236
+ if err != nil {
237
+ return err
238
+ }
202
239
f , err := ioutil .ReadFile (file )
203
- cobra .CheckErr (err )
240
+ if err != nil {
241
+ return err
242
+ }
204
243
desired := & schema.Realm {}
205
- cobra .CheckErr (client .Eval (f , desired , input ))
244
+ if err := client .Eval (f , desired , input ); err != nil {
245
+ return err
246
+ }
206
247
if len (schemas ) > 0 {
207
248
// Validate all schemas in file were selected by user.
208
249
sm := make (map [string ]bool , len (schemas ))
@@ -211,26 +252,33 @@ func applyRun(ctx context.Context, client *sqlclient.Client, file string, dryRun
211
252
}
212
253
for _ , s := range desired .Schemas {
213
254
if ! sm [s .Name ] {
214
- schemaCmd .Printf ("schema %q from file %q was not selected %q, all schemas defined in file must be selected\n " , s .Name , file , schemas )
215
- return
255
+ return fmt .Errorf ("schema %q from file %q was not selected %q, all schemas defined in file must be selected" , s .Name , file , schemas )
216
256
}
217
257
}
218
258
}
219
- if _ , ok := client .Driver .(schema.Normalizer ); ok && ApplyFlags . DevURL != "" {
259
+ if _ , ok := client .Driver .(schema.Normalizer ); ok && devURL != "" {
220
260
dev , err := sqlclient .Open (ctx , ApplyFlags .DevURL )
221
- cobra .CheckErr (err )
261
+ if err != nil {
262
+ return err
263
+ }
222
264
defer dev .Close ()
223
265
desired , err = dev .Driver .(schema.Normalizer ).NormalizeRealm (ctx , desired )
224
- cobra .CheckErr (err )
266
+ if err != nil {
267
+ return err
268
+ }
225
269
}
226
270
changes , err := client .RealmDiff (realm , desired )
227
- cobra .CheckErr (err )
271
+ if err != nil {
272
+ return err
273
+ }
228
274
if len (changes ) == 0 {
229
275
schemaCmd .Println ("Schema is synced, no changes to be made" )
230
- return
276
+ return nil
231
277
}
232
278
p , err := client .PlanChanges (ctx , "plan" , changes )
233
- cobra .CheckErr (err )
279
+ if err != nil {
280
+ return err
281
+ }
234
282
schemaCmd .Println ("-- Planned Changes:" )
235
283
for _ , c := range p .Changes {
236
284
if c .Comment != "" {
@@ -239,11 +287,14 @@ func applyRun(ctx context.Context, client *sqlclient.Client, file string, dryRun
239
287
schemaCmd .Println (c .Cmd )
240
288
}
241
289
if dryRun {
242
- return
290
+ return nil
243
291
}
244
292
if autoApprove || promptUser () {
245
- cobra .CheckErr (client .ApplyChanges (ctx , changes ))
293
+ if err := client .ApplyChanges (ctx , changes ); err != nil {
294
+ return err
295
+ }
246
296
}
297
+ return nil
247
298
}
248
299
249
300
func promptUser () bool {
@@ -256,12 +307,23 @@ func promptUser() bool {
256
307
return result == answerApply
257
308
}
258
309
259
- func dsn2url (cmd * cobra.Command , p * string ) {
310
+ // fixURLFlag fixes the url flag by pulling its value either from the flag itself,
311
+ // the (deprecated) dsn flag, or from the active environment.
312
+ func fixURLFlag (cmd * cobra.Command , p * string ) {
260
313
cmd .Flags ().StringVarP (p , "dsn" , "d" , "" , "" )
261
314
cobra .CheckErr (cmd .Flags ().MarkHidden ("dsn" ))
262
315
cmd .PreRunE = func (cmd * cobra.Command , args []string ) error {
316
+ activeEnv , err := selectEnv (args )
317
+ if err != nil {
318
+ return err
319
+ }
263
320
dsnF , urlF := cmd .Flag ("dsn" ), cmd .Flag ("url" )
264
321
switch {
322
+ case activeEnv != nil && activeEnv .URL != "" :
323
+ urlF .Changed = true
324
+ if err := urlF .Value .Set (activeEnv .URL ); err != nil {
325
+ return err
326
+ }
265
327
case ! dsnF .Changed && ! urlF .Changed :
266
328
return errors .New (`required flag "url" was not set` )
267
329
case dsnF .Changed && urlF .Changed :
0 commit comments