From 5ecd09aa2b4f2709d4991cee52a7f13a5962cca9 Mon Sep 17 00:00:00 2001 From: Pasha Sviderski Date: Tue, 5 May 2026 10:41:53 +1000 Subject: [PATCH] fix: return non-exit code when uc commands cancelled by not confirming prompt (fixes #354) --- cmd/uncloud/caddy/deploy.go | 3 +-- cmd/uncloud/deploy.go | 3 +-- cmd/uncloud/machine/add.go | 3 +-- cmd/uncloud/main.go | 10 +++++++++- cmd/uncloud/service/scale.go | 3 +-- internal/cli/errors.go | 15 +++++++++++++++ 6 files changed, 28 insertions(+), 9 deletions(-) create mode 100644 internal/cli/errors.go diff --git a/cmd/uncloud/caddy/deploy.go b/cmd/uncloud/caddy/deploy.go index c3acc4ef..d72ab20d 100644 --- a/cmd/uncloud/caddy/deploy.go +++ b/cmd/uncloud/caddy/deploy.go @@ -175,8 +175,7 @@ func runDeploy(ctx context.Context, uncli *cli.CLI, opts deployOptions) error { return fmt.Errorf("confirm deployment: %w", err) } if !confirmed { - fmt.Println("Cancelled. No changes were made.") - return nil + return cli.Cancelled("Caddy deploy cancelled. No changes were made.") } err = progress.RunWithTitle(ctx, func(ctx context.Context) error { diff --git a/cmd/uncloud/deploy.go b/cmd/uncloud/deploy.go index 2a6bec19..36927a3f 100644 --- a/cmd/uncloud/deploy.go +++ b/cmd/uncloud/deploy.go @@ -222,8 +222,7 @@ func runDeploy(ctx context.Context, uncli *cli.CLI, opts deployOptions) error { return fmt.Errorf("confirm deployment: %w", err) } if !confirmed { - fmt.Println("Cancelled. No changes were made.") - return nil + return cli.Cancelled("Deploy cancelled. No changes were made.") } } diff --git a/cmd/uncloud/machine/add.go b/cmd/uncloud/machine/add.go index 74915b94..0d2a3ca6 100644 --- a/cmd/uncloud/machine/add.go +++ b/cmd/uncloud/machine/add.go @@ -232,8 +232,7 @@ func add(ctx context.Context, uncli *cli.CLI, remoteMachine *cli.RemoteMachine, return fmt.Errorf("confirm deployment: %w", err) } if !confirmed { - fmt.Println("Cancelled. No changes were made.") - return nil + return cli.Cancelled("Caddy deploy cancelled. The machine has been added to the cluster.") } } diff --git a/cmd/uncloud/main.go b/cmd/uncloud/main.go index 1147f46a..686b483e 100644 --- a/cmd/uncloud/main.go +++ b/cmd/uncloud/main.go @@ -2,8 +2,10 @@ package main import ( "context" + "errors" "fmt" "net/netip" + "os" "strings" "charm.land/lipgloss/v2" @@ -152,5 +154,11 @@ func main() { volume.NewRootCommand(), wg.NewRootCommand(), ) - cobra.CheckErr(cmd.Execute()) + if err := cmd.Execute(); err != nil { + if cancelled, ok := errors.AsType[*cli.CancelledError](err); ok { + fmt.Fprintln(os.Stderr, cancelled.Error()) + os.Exit(1) + } + cobra.CheckErr(err) + } } diff --git a/cmd/uncloud/service/scale.go b/cmd/uncloud/service/scale.go index 6c32c0d8..1029fa1b 100644 --- a/cmd/uncloud/service/scale.go +++ b/cmd/uncloud/service/scale.go @@ -155,8 +155,7 @@ func scale(ctx context.Context, uncli *cli.CLI, opts scaleOptions) error { return fmt.Errorf("confirm scaling: %w", err) } if !confirmed { - fmt.Println("Cancelled. No changes were made.") - return nil + return cli.Cancelled("Scaling cancelled. No changes were made.") } } diff --git a/internal/cli/errors.go b/internal/cli/errors.go new file mode 100644 index 00000000..da67dcdf --- /dev/null +++ b/internal/cli/errors.go @@ -0,0 +1,15 @@ +package cli + +// CancelledError signals an interactive command was aborted by the user at a confirmation prompt. +type CancelledError struct { + Message string +} + +func (e *CancelledError) Error() string { + return e.Message +} + +// Cancelled returns a CancelledError carrying the given user-facing message. +func Cancelled(msg string) error { + return &CancelledError{Message: msg} +}