@@ -20,6 +20,9 @@ import (
20
20
"github.com/DefangLabs/defang/src/pkg/cli/client/byoc/gcp"
21
21
"github.com/DefangLabs/defang/src/pkg/cli/compose"
22
22
"github.com/DefangLabs/defang/src/pkg/clouds/aws"
23
+ pcluster "github.com/DefangLabs/defang/src/pkg/cluster"
24
+ "github.com/DefangLabs/defang/src/pkg/dryrun"
25
+ "github.com/DefangLabs/defang/src/pkg/login"
23
26
"github.com/DefangLabs/defang/src/pkg/logs"
24
27
"github.com/DefangLabs/defang/src/pkg/mcp"
25
28
"github.com/DefangLabs/defang/src/pkg/migrate"
@@ -64,19 +67,6 @@ func getCluster() string {
64
67
return org + "@" + cluster
65
68
}
66
69
67
- func prettyError (err error ) error {
68
- // To avoid printing the internal gRPC error code
69
- var cerr * connect.Error
70
- if errors .As (err , & cerr ) {
71
- term .Debug ("Server error:" , cerr )
72
- err = errors .Unwrap (cerr )
73
- }
74
- if cli .IsNetworkError (err ) {
75
- return fmt .Errorf ("%w; please check network settings and try again" , err )
76
- }
77
- return err
78
- }
79
-
80
70
func Execute (ctx context.Context ) error {
81
71
if term .StdoutCanColor () {
82
72
restore := term .EnableANSI ()
@@ -85,10 +75,10 @@ func Execute(ctx context.Context) error {
85
75
86
76
if err := RootCmd .ExecuteContext (ctx ); err != nil {
87
77
if ! (errors .Is (err , context .Canceled ) || errors .Is (err , context .DeadlineExceeded )) {
88
- term .Error ("Error:" , prettyError (err ))
78
+ term .Error ("Error:" , cliClient . PrettyError (err ))
89
79
}
90
80
91
- if err == cli .ErrDryRun {
81
+ if err == dryrun .ErrDryRun {
92
82
return nil
93
83
}
94
84
@@ -169,14 +159,14 @@ func SetupCommands(ctx context.Context, version string) {
169
159
170
160
RootCmd .Version = version
171
161
RootCmd .PersistentFlags ().Var (& colorMode , "color" , fmt .Sprintf (`colorize output; one of %v` , allColorModes ))
172
- RootCmd .PersistentFlags ().StringVarP (& cluster , "cluster" , "s" , cli .DefangFabric , "Defang cluster to connect to" )
162
+ RootCmd .PersistentFlags ().StringVarP (& cluster , "cluster" , "s" , pcluster .DefangFabric , "Defang cluster to connect to" )
173
163
RootCmd .PersistentFlags ().MarkHidden ("cluster" )
174
164
RootCmd .PersistentFlags ().StringVar (& org , "org" , os .Getenv ("DEFANG_ORG" ), "override GitHub organization name (tenant)" )
175
165
RootCmd .PersistentFlags ().VarP (& providerID , "provider" , "P" , fmt .Sprintf (`bring-your-own-cloud provider; one of %v` , cliClient .AllProviders ()))
176
166
// RootCmd.Flag("provider").NoOptDefVal = "auto" NO this will break the "--provider aws"
177
167
RootCmd .PersistentFlags ().BoolVarP (& verbose , "verbose" , "v" , false , "verbose logging" ) // backwards compat: only used by tail
178
168
RootCmd .PersistentFlags ().BoolVar (& doDebug , "debug" , pkg .GetenvBool ("DEFANG_DEBUG" ), "debug logging for troubleshooting the CLI" )
179
- RootCmd .PersistentFlags ().BoolVar (& cli .DoDryRun , "dry-run" , false , "dry run (don't actually change anything)" )
169
+ RootCmd .PersistentFlags ().BoolVar (& dryrun .DoDryRun , "dry-run" , false , "dry run (don't actually change anything)" )
180
170
RootCmd .PersistentFlags ().BoolVarP (& nonInteractive , "non-interactive" , "T" , ! hasTty , "disable interactive prompts / no TTY" )
181
171
RootCmd .PersistentFlags ().StringP ("project-name" , "p" , "" , "project name" )
182
172
RootCmd .PersistentFlags ().StringP ("cwd" , "C" , "" , "change directory before running the command" )
@@ -346,6 +336,7 @@ var RootCmd = &cobra.Command{
346
336
Args : cobra .NoArgs ,
347
337
Short : "Defang CLI is used to take your app from Docker Compose to a secure and scalable deployment on your favorite cloud in minutes." ,
348
338
PersistentPreRunE : func (cmd * cobra.Command , args []string ) (err error ) {
339
+ ctx := cmd .Context ()
349
340
term .SetDebug (doDebug )
350
341
351
342
// Don't track/connect the completion commands
@@ -373,9 +364,9 @@ var RootCmd = &cobra.Command{
373
364
}
374
365
}
375
366
376
- client , err = cli .Connect (cmd . Context () , getCluster ())
367
+ client , err = cli .Connect (ctx , getCluster ())
377
368
378
- if v , err := client .GetVersions (cmd . Context () ); err == nil {
369
+ if v , err := client .GetVersions (ctx ); err == nil {
379
370
version := cmd .Root ().Version // HACK to avoid circular dependency with RootCmd
380
371
term .Debug ("Fabric:" , v .Fabric , "CLI:" , version , "CLI-Min:" , v .CliMin )
381
372
if hasTty && isNewer (version , v .CliMin ) && ! isUpgradeCommand (cmd ) {
@@ -389,40 +380,10 @@ var RootCmd = &cobra.Command{
389
380
return nil
390
381
}
391
382
392
- if err = client .CheckLoginAndToS (cmd .Context ()); err != nil {
393
- if nonInteractive {
394
- return err
395
- }
396
- // Login interactively now; only do this for authorization-related errors
397
- if connect .CodeOf (err ) == connect .CodeUnauthenticated {
398
- term .Debug ("Server error:" , err )
399
- term .Warn ("Please log in to continue." )
400
- term .ResetWarnings () // clear any previous warnings so we don't show them again
401
-
402
- defer func () { track .Cmd (nil , "Login" , P ("reason" , err )) }()
403
- if err = cli .InteractiveLogin (cmd .Context (), client , getCluster ()); err != nil {
404
- return err
405
- }
406
-
407
- // Reconnect with the new token
408
- if client , err = cli .Connect (cmd .Context (), getCluster ()); err != nil {
409
- return err
410
- }
411
-
412
- if err = client .CheckLoginAndToS (cmd .Context ()); err == nil { // recheck (new token = new user)
413
- return nil // success
414
- }
415
- }
416
-
417
- // Check if the user has agreed to the terms of service and show a prompt if needed
418
- if connect .CodeOf (err ) == connect .CodeFailedPrecondition {
419
- term .Warn (prettyError (err ))
420
-
421
- defer func () { track .Cmd (nil , "Terms" , P ("reason" , err )) }()
422
- if err = cli .InteractiveAgreeToS (cmd .Context (), client ); err != nil {
423
- return err // fatal
424
- }
425
- }
383
+ if nonInteractive {
384
+ err = client .CheckLoginAndToS (ctx )
385
+ } else {
386
+ err = login .InteractiveRequireLoginAndToS (ctx , client , getCluster ())
426
387
}
427
388
428
389
return err
@@ -437,11 +398,11 @@ var loginCmd = &cobra.Command{
437
398
trainingOptOut , _ := cmd .Flags ().GetBool ("training-opt-out" )
438
399
439
400
if nonInteractive {
440
- if err := cli .NonInteractiveGitHubLogin (cmd .Context (), client , getCluster ()); err != nil {
401
+ if err := login .NonInteractiveGitHubLogin (cmd .Context (), client , getCluster ()); err != nil {
441
402
return err
442
403
}
443
404
} else {
444
- err := cli .InteractiveLogin (cmd .Context (), client , getCluster ())
405
+ err := login .InteractiveLogin (cmd .Context (), client , getCluster ())
445
406
if err != nil {
446
407
return err
447
408
}
@@ -755,7 +716,7 @@ var configDeleteCmd = &cobra.Command{
755
716
if err := cli .ConfigDelete (cmd .Context (), projectName , provider , names ... ); err != nil {
756
717
// Show a warning (not an error) if the config was not found
757
718
if connect .CodeOf (err ) == connect .CodeNotFound {
758
- term .Warn (prettyError (err ))
719
+ term .Warn (cliClient . PrettyError (err ))
759
720
return nil
760
721
}
761
722
return err
@@ -870,7 +831,7 @@ var deleteCmd = &cobra.Command{
870
831
if err != nil {
871
832
if connect .CodeOf (err ) == connect .CodeNotFound {
872
833
// Show a warning (not an error) if the service was not found
873
- term .Warn (prettyError (err ))
834
+ term .Warn (cliClient . PrettyError (err ))
874
835
return nil
875
836
}
876
837
return err
@@ -998,15 +959,15 @@ var tosCmd = &cobra.Command{
998
959
agree , _ := cmd .Flags ().GetBool ("agree-tos" )
999
960
1000
961
if agree {
1001
- return cli .NonInteractiveAgreeToS (cmd .Context (), client )
962
+ return login .NonInteractiveAgreeToS (cmd .Context (), client )
1002
963
}
1003
964
1004
965
if nonInteractive {
1005
966
printDefangHint ("To agree to the terms of service, do:" , cmd .CalledAs ()+ " --agree-tos" )
1006
967
return nil
1007
968
}
1008
969
1009
- return cli .InteractiveAgreeToS (cmd .Context (), client )
970
+ return login .InteractiveAgreeToS (cmd .Context (), client )
1010
971
},
1011
972
}
1012
973
0 commit comments