From c13dc4fd29b3bb54f987f554e531f48a05009237 Mon Sep 17 00:00:00 2001 From: Tim Thacker Date: Tue, 26 May 2026 20:10:53 +1000 Subject: [PATCH 1/2] refactor(cli): RunE migration, auth dedup, TTY-aware spinner, non-interactive guards Command hygiene refactor for the hand-written CLI commands. Behavior (including exit codes and output streams) is preserved. - os.Exit -> RunE: convert bespoke command bodies (auth, fix, status, findings, ci, open, whoami, init, mcp, pentest, repos, update) to return errors instead of calling os.Exit mid-body, so deferred logger.Close runs and the commands are testable. Centralize error->exit-code mapping in main.go via a typed exitCodeError and ExitCodeForError; preserves ExitAuthError(2), ExitNetworkError(3), and ExitFindings(1). Set rootCmd.SilenceUsage=true / SilenceErrors=false so cobra prints each error once. - Auth boilerplate dedup: route fix/status/findings/ci through the existing resolveCommandAuth helper (now error-returning) instead of repeating resolveHost->GetNullifyToken->NewNullifyClient-> LoadCredentials. Added commandAuthContext.Client(). - TTY-aware spinner: NewSpinner stays silent when stderr is not a terminal, avoiding ANSI/braille noise in CI logs. - Non-interactive guards: auth login host prompt and the init wizard domain step now fail fast with a clear error when stdin is not a TTY instead of blocking on a read. The generated `api` commands and their getAPIClient factory are unchanged (resolveHost retains its os.Exit wrapper for that path). Co-Authored-By: Claude Opus 4.7 (1M context) --- cmd/cli/cmd/auth.go | 88 ++++++++++++++++++----------------- cmd/cli/cmd/ci.go | 74 +++++++++++------------------ cmd/cli/cmd/exitcodes.go | 67 ++++++++++++++++++++++++++ cmd/cli/cmd/exitcodes_test.go | 40 ++++++++++++++++ cmd/cli/cmd/findings.go | 32 ++++--------- cmd/cli/cmd/fix.go | 35 ++++---------- cmd/cli/cmd/init.go | 7 ++- cmd/cli/cmd/mcp.go | 25 +++------- cmd/cli/cmd/open.go | 12 +++-- cmd/cli/cmd/pentest.go | 19 ++++---- cmd/cli/cmd/repos.go | 6 +-- cmd/cli/cmd/root.go | 55 ++++++++++++++-------- cmd/cli/cmd/runtime_auth.go | 28 ++++++++++- cmd/cli/cmd/status.go | 39 ++++------------ cmd/cli/cmd/update.go | 9 ++-- cmd/cli/cmd/whoami.go | 12 +++-- cmd/cli/main.go | 4 +- internal/output/spinner.go | 14 +++++- internal/wizard/steps.go | 14 ++++++ 19 files changed, 339 insertions(+), 241 deletions(-) create mode 100644 cmd/cli/cmd/exitcodes_test.go diff --git a/cmd/cli/cmd/auth.go b/cmd/cli/cmd/auth.go index a6fa5a8..518bfde 100644 --- a/cmd/cli/cmd/auth.go +++ b/cmd/cli/cmd/auth.go @@ -1,7 +1,6 @@ package cmd import ( - "context" "encoding/json" "fmt" "os" @@ -25,7 +24,7 @@ var loginCmd = &cobra.Command{ Use: "login", Short: "Log in to Nullify", Long: "Authenticate with your Nullify instance. Opens your browser to log in with your identity provider.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) @@ -43,23 +42,24 @@ var loginCmd = &cobra.Command{ } } - // If still no host, prompt + // If still no host, prompt (only when running interactively). if loginHost == "" { + if !stdinIsTTY() { + return fmt.Errorf("not a terminal; pass --host .nullify.ai") + } fmt.Print("Enter your Nullify instance (e.g., acme.nullify.ai): ") _, _ = fmt.Scanln(&loginHost) } sanitizedHost, err := lib.SanitizeNullifyHost(loginHost) if err != nil { - fmt.Fprintf(os.Stderr, "Error: invalid host %q - must be in the format .nullify.ai\n", loginHost) - os.Exit(1) + return fmt.Errorf("invalid host %q - must be in the format .nullify.ai", loginHost) } - err = auth.Login(ctx, sanitizedHost) - if err != nil { - fmt.Fprintf(os.Stderr, "Error: login failed: %v\n", err) - os.Exit(1) + if err := auth.Login(ctx, sanitizedHost); err != nil { + return fmt.Errorf("login failed: %w", err) } + return nil }, } @@ -67,19 +67,21 @@ var logoutCmd = &cobra.Command{ Use: "logout", Short: "Log out of Nullify", Long: "Clear stored credentials for the current or specified host.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - logoutHost := resolveHostForAuth(ctx) - - err := auth.Logout(logoutHost) + logoutHost, err := resolveHostForAuth() if err != nil { - fmt.Fprintf(os.Stderr, "Error: logout failed: %v\n", err) - os.Exit(1) + return err + } + + if err := auth.Logout(logoutHost); err != nil { + return fmt.Errorf("logout failed: %w", err) } fmt.Printf("Logged out from %s\n", logoutHost) + return nil }, } @@ -87,16 +89,16 @@ var statusCmd = &cobra.Command{ Use: "status", Short: "Show authentication status", Long: "Display the current authentication state including host, user, and token expiry.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { cfg, err := auth.LoadConfig() if err != nil { fmt.Println("Not configured. Run 'nullify auth login --host .nullify.ai' to get started.") - return + return nil } if cfg.Host == "" { fmt.Println("No host configured. Run 'nullify auth login --host .nullify.ai'") - return + return nil } fmt.Printf("Host: %s\n", cfg.Host) @@ -104,13 +106,13 @@ var statusCmd = &cobra.Command{ creds, err := auth.LoadCredentials() if err != nil { fmt.Println("Status: not authenticated") - return + return nil } hostCreds, ok := creds[auth.CredentialKey(cfg.Host)] if !ok { fmt.Println("Status: not authenticated") - return + return nil } if hostCreds.ExpiresAt > 0 { @@ -123,6 +125,7 @@ var statusCmd = &cobra.Command{ } else { fmt.Println("Status: authenticated") } + return nil }, } @@ -130,19 +133,22 @@ var tokenCmd = &cobra.Command{ Use: "token", Short: "Print access token to stdout", Long: "Print the current access token. Useful for piping to other tools.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - hostForToken := resolveHostForAuth(ctx) + hostForToken, err := resolveHostForAuth() + if err != nil { + return err + } token, err := auth.GetValidToken(ctx, hostForToken) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) + return err } fmt.Println(token) + return nil }, } @@ -150,7 +156,7 @@ var switchCmd = &cobra.Command{ Use: "switch", Short: "Switch between configured hosts", Long: "Switch the default host when multiple Nullify instances are configured.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { switchHost, _ := cmd.Flags().GetString("host") if switchHost == "" && host != "" { switchHost = host @@ -161,7 +167,7 @@ var switchCmd = &cobra.Command{ creds, err := auth.LoadCredentials() if err != nil || len(creds) == 0 { fmt.Println("No configured hosts. Run 'nullify auth login --host .nullify.ai'") - return + return nil } cfg, _ := auth.LoadConfig() @@ -174,13 +180,12 @@ var switchCmd = &cobra.Command{ fmt.Printf("%s%s\n", marker, h) } fmt.Println("\nUse 'nullify auth switch --host ' to switch.") - return + return nil } sanitizedHost, err := lib.SanitizeNullifyHost(switchHost) if err != nil { - fmt.Fprintf(os.Stderr, "Error: invalid host %q\n", switchHost) - os.Exit(1) + return fmt.Errorf("invalid host %q", switchHost) } cfg, err := auth.LoadConfig() @@ -189,13 +194,12 @@ var switchCmd = &cobra.Command{ } cfg.Host = sanitizedHost - err = auth.SaveConfig(cfg) - if err != nil { - fmt.Fprintf(os.Stderr, "Error: failed to save config: %v\n", err) - os.Exit(1) + if err := auth.SaveConfig(cfg); err != nil { + return fmt.Errorf("failed to save config: %w", err) } fmt.Printf("Switched to %s\n", sanitizedHost) + return nil }, } @@ -203,15 +207,16 @@ var configShowCmd = &cobra.Command{ Use: "config", Short: "Show current configuration", Long: "Display the current CLI configuration as JSON.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { cfg, err := auth.LoadConfig() if err != nil { fmt.Fprintf(os.Stderr, "No config found. Run 'nullify init' to set up.\n") - return + return nil } data, _ := json.MarshalIndent(cfg, "", " ") fmt.Println(string(data)) + return nil }, } @@ -225,25 +230,22 @@ func init() { authCmd.AddCommand(configShowCmd) } -func resolveHostForAuth(ctx context.Context) string { +func resolveHostForAuth() (string, error) { if host != "" { sanitized, err := lib.SanitizeNullifyHost(host) if err != nil { - fmt.Fprintf(os.Stderr, "Error: invalid host %q\n", host) - os.Exit(1) + return "", fmt.Errorf("invalid host %q", host) } - return sanitized + return sanitized, nil } cfg, err := auth.LoadConfig() if err == nil && cfg.Host != "" { sanitized, sErr := lib.SanitizeNullifyHost(cfg.Host) if sErr == nil { - return sanitized + return sanitized, nil } } - fmt.Fprintln(os.Stderr, "Error: no host configured. Use --host or run 'nullify auth login'") - os.Exit(1) - return "" + return "", fmt.Errorf("no host configured. Use --host or run 'nullify auth login'") } diff --git a/cmd/cli/cmd/ci.go b/cmd/cli/cmd/ci.go index 84e2ab6..cff79f5 100644 --- a/cmd/cli/cmd/ci.go +++ b/cmd/cli/cmd/ci.go @@ -2,14 +2,11 @@ package cmd import ( "encoding/json" - "errors" "fmt" "os" "sync" "sync/atomic" - "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" "github.com/nullify-platform/cli/internal/logger" "github.com/spf13/cobra" @@ -41,30 +38,22 @@ Exit codes: # Check a specific repo nullify ci gate --repo my-org/my-repo`, - Run: func(cmd *cobra.Command, args []string) { + // SilenceErrors: this command writes its own gate-failure summary to + // stdout and must not have cobra echo the sentinel error to stderr. + // Auth/network errors are printed explicitly below to preserve the + // original stderr output. + SilenceErrors: true, + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - ciHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, ciHost, nullifyToken, githubToken) + authCtx, err := resolveCommandAuth(ctx) if err != nil { - if errors.Is(err, lib.ErrNoToken) { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - } else { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - } - os.Exit(ExitAuthError) - } - - nullifyClient := client.NewNullifyClient(ciHost, token) - - creds, err := auth.LoadCredentials() - queryParams := map[string]string{} - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(ciHost)]; ok && hostCreds.QueryParameters != nil { - queryParams = hostCreds.QueryParameters - } + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + return err } + nullifyClient := authCtx.Client() + queryParams := authCtx.QueryParams severityThreshold, _ := cmd.Flags().GetString("severity-threshold") findingType, _ := cmd.Flags().GetString("type") @@ -79,8 +68,9 @@ Exit codes: } } if !validThreshold { - fmt.Fprintf(os.Stderr, "Error: invalid --severity-threshold %q. Valid values: critical, high, medium, low\n", severityThreshold) - os.Exit(1) + err := fmt.Errorf("invalid --severity-threshold %q. Valid values: critical, high, medium, low", severityThreshold) + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + return withExitCode(1, err) } if repo == "" { @@ -138,16 +128,18 @@ Exit codes: _ = g.Wait() if apiErrors > 0 && apiErrors == totalRequests { - fmt.Fprintf(os.Stderr, "Error: all API requests failed, cannot determine gate status\n") - os.Exit(ExitNetworkError) + err := fmt.Errorf("all API requests failed, cannot determine gate status") + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + return withExitCode(ExitNetworkError, err) } if totalFindings > 0 { fmt.Printf("\nGate failed: %d findings at or above %s severity\n", totalFindings, severityThreshold) - os.Exit(ExitFindings) + return withExitCode(ExitFindings, fmt.Errorf("gate failed: %d findings at or above %s severity", totalFindings, severityThreshold)) } fmt.Println("Gate passed: no findings above threshold") + return nil }, } @@ -157,30 +149,16 @@ var ciReportCmd = &cobra.Command{ Long: "Output a markdown summary of security findings suitable for PR comments. Shows counts by type and severity.", Example: ` nullify ci report nullify ci report --repo my-org/my-repo`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - ciHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, ciHost, nullifyToken, githubToken) + authCtx, err := resolveCommandAuth(ctx) if err != nil { - if errors.Is(err, lib.ErrNoToken) { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - } else { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - } - os.Exit(ExitAuthError) - } - - nullifyClient := client.NewNullifyClient(ciHost, token) - - creds, err := auth.LoadCredentials() - queryParams := map[string]string{} - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(ciHost)]; ok && hostCreds.QueryParameters != nil { - queryParams = hostCreds.QueryParameters - } + return err } + nullifyClient := authCtx.Client() + queryParams := authCtx.QueryParams repo, _ := cmd.Flags().GetString("repo") if repo == "" { @@ -235,8 +213,7 @@ var ciReportCmd = &cobra.Command{ _ = g.Wait() if successCount == 0 { - fmt.Fprintln(os.Stderr, "Error: all API requests failed, cannot generate report") - os.Exit(ExitNetworkError) + return networkError("all API requests failed, cannot generate report") } if apiErrors > 0 { fmt.Fprintf(os.Stderr, "Warning: %d API requests failed while generating the report\n", apiErrors) @@ -255,6 +232,7 @@ var ciReportCmd = &cobra.Command{ fmt.Println() fmt.Println("*Generated by [Nullify CLI](https://github.com/nullify-platform/cli)*") + return nil }, } diff --git a/cmd/cli/cmd/exitcodes.go b/cmd/cli/cmd/exitcodes.go index dc02b3d..9c0b84e 100644 --- a/cmd/cli/cmd/exitcodes.go +++ b/cmd/cli/cmd/exitcodes.go @@ -1,5 +1,10 @@ package cmd +import ( + "errors" + "fmt" +) + // Exit codes for the CLI. const ( ExitSuccess = 0 @@ -7,3 +12,65 @@ const ( ExitAuthError = 2 ExitNetworkError = 3 ) + +// exitCodeError wraps an error with a specific process exit code. RunE handlers +// return these so that exit-code mapping happens in exactly one place +// (main.go), instead of scattered os.Exit calls that would skip deferred +// cleanup such as logger.Close. +type exitCodeError struct { + code int + err error +} + +func (e *exitCodeError) Error() string { + if e.err == nil { + return "" + } + return e.err.Error() +} + +func (e *exitCodeError) Unwrap() error { + return e.err +} + +// ExitCode returns the process exit code associated with the error. +func (e *exitCodeError) ExitCode() int { + return e.code +} + +// withExitCode wraps err so that the CLI exits with the given code. The +// underlying error is preserved (and printed once by cobra). +func withExitCode(code int, err error) error { + if err == nil { + return nil + } + return &exitCodeError{code: code, err: err} +} + +// authError builds an exit-code error for authentication failures. +func authError(format string, args ...any) error { + return withExitCode(ExitAuthError, fmt.Errorf(format, args...)) +} + +// networkError builds an exit-code error for network/API failures. +func networkError(format string, args ...any) error { + return withExitCode(ExitNetworkError, fmt.Errorf(format, args...)) +} + +// findingsError builds an exit-code error indicating findings exceeded the gate. +func findingsError(format string, args ...any) error { + return withExitCode(ExitFindings, fmt.Errorf(format, args...)) +} + +// ExitCodeForError resolves the process exit code for a top-level error. +// Plain errors map to exit code 1; coded errors use their embedded code. +func ExitCodeForError(err error) int { + if err == nil { + return ExitSuccess + } + var coded *exitCodeError + if errors.As(err, &coded) { + return coded.code + } + return 1 +} diff --git a/cmd/cli/cmd/exitcodes_test.go b/cmd/cli/cmd/exitcodes_test.go new file mode 100644 index 0000000..e603289 --- /dev/null +++ b/cmd/cli/cmd/exitcodes_test.go @@ -0,0 +1,40 @@ +package cmd + +import ( + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestExitCodeForError(t *testing.T) { + tests := []struct { + name string + err error + want int + }{ + {"nil", nil, ExitSuccess}, + {"plain error", errors.New("boom"), 1}, + {"auth error", authError("nope"), ExitAuthError}, + {"network error", networkError("nope"), ExitNetworkError}, + {"findings error", findingsError("nope"), ExitFindings}, + {"explicit code 1", withExitCode(1, errors.New("x")), 1}, + {"wrapped coded error", fmt.Errorf("ctx: %w", authError("nope")), ExitAuthError}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, ExitCodeForError(tt.err)) + }) + } +} + +func TestWithExitCodePreservesMessage(t *testing.T) { + err := withExitCode(ExitNetworkError, errors.New("fetching metrics: timeout")) + require.Equal(t, "fetching metrics: timeout", err.Error()) + + var coded *exitCodeError + require.True(t, errors.As(err, &coded)) + require.Equal(t, ExitNetworkError, coded.ExitCode()) +} diff --git a/cmd/cli/cmd/findings.go b/cmd/cli/cmd/findings.go index 11268bc..dd27f8c 100644 --- a/cmd/cli/cmd/findings.go +++ b/cmd/cli/cmd/findings.go @@ -7,8 +7,6 @@ import ( "os" "strings" - "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" @@ -33,26 +31,16 @@ Results are paginated automatically up to --limit total findings.`, # Fetch up to 500 findings nullify findings --limit 500`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - findingsHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, findingsHost, nullifyToken, githubToken) + authCtx, err := resolveCommandAuth(ctx) if err != nil { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - os.Exit(ExitAuthError) - } - - nullifyClient := client.NewNullifyClient(findingsHost, token) - - creds, err := auth.LoadCredentials() - queryParams := map[string]string{} - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(findingsHost)]; ok && hostCreds.QueryParameters != nil { - queryParams = hostCreds.QueryParameters - } + return err } + nullifyClient := authCtx.Client() + queryParams := authCtx.QueryParams severity, _ := cmd.Flags().GetString("severity") status, _ := cmd.Flags().GetString("status") @@ -136,8 +124,7 @@ Results are paginated automatically up to --limit total findings.`, reqBody := map[string]any{"query": query} bodyBytes, err := json.Marshal(reqBody) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(ExitNetworkError) + return networkError("%w", err) } if debug { @@ -147,8 +134,7 @@ Results are paginated automatically up to --limit total findings.`, respBody, err := lib.DoPostJSON(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, path, bytes.NewReader(bodyBytes)) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(ExitNetworkError) + return networkError("%w", err) } if debug { @@ -161,8 +147,7 @@ Results are paginated automatically up to --limit total findings.`, var resp unifiedResponse if err := json.Unmarshal([]byte(respBody), &resp); err != nil { - fmt.Fprintf(os.Stderr, "Error parsing response: %v\n", err) - os.Exit(ExitNetworkError) + return networkError("parsing response: %w", err) } allFindings = append(allFindings, resp.Findings...) @@ -190,6 +175,7 @@ Results are paginated automatically up to --limit total findings.`, if err := output.Print(cmd, out); err != nil { fmt.Fprintln(os.Stderr, string(out)) } + return nil }, } diff --git a/cmd/cli/cmd/fix.go b/cmd/cli/cmd/fix.go index d60ef8b..427ebb3 100644 --- a/cmd/cli/cmd/fix.go +++ b/cmd/cli/cmd/fix.go @@ -6,8 +6,6 @@ import ( "net/url" "os" - "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" @@ -29,28 +27,18 @@ Supports SAST and SCA dependency findings.`, # Fix an SCA dependency finding nullify fix def456 --type sca`, Args: cobra.ExactArgs(1), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) findingID := args[0] - fixHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, fixHost, nullifyToken, githubToken) + authCtx, err := resolveCommandAuth(ctx) if err != nil { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - os.Exit(ExitAuthError) - } - - nullifyClient := client.NewNullifyClient(fixHost, token) - - creds, err := auth.LoadCredentials() - queryParams := map[string]string{} - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(fixHost)]; ok && hostCreds.QueryParameters != nil { - queryParams = hostCreds.QueryParameters - } + return err } + nullifyClient := authCtx.Client() + queryParams := authCtx.QueryParams findingType, _ := cmd.Flags().GetString("type") createPR, _ := cmd.Flags().GetBool("create-pr") @@ -62,8 +50,7 @@ Supports SAST and SCA dependency findings.`, case "sca": basePath = "/sca/dependencies/findings" default: - fmt.Fprintf(os.Stderr, "Error: --type must be 'sast' or 'sca'\n") - os.Exit(1) + return fmt.Errorf("--type must be 'sast' or 'sca'") } qs := lib.BuildQueryString(queryParams) @@ -75,16 +62,14 @@ Supports SAST and SCA dependency findings.`, _, err = lib.DoPost(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/fix%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - fmt.Fprintf(os.Stderr, "Error generating fix: %v\n", err) - os.Exit(1) + return fmt.Errorf("generating fix: %w", err) } // Step 2: Get diff diffBody, err := lib.DoGet(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/cache/diff%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - fmt.Fprintf(os.Stderr, "Error getting diff: %v\n", err) - os.Exit(1) + return fmt.Errorf("getting diff: %w", err) } result := map[string]any{ @@ -101,8 +86,7 @@ Supports SAST and SCA dependency findings.`, prBody, err := lib.DoPost(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/cache/create_pr%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - fmt.Fprintf(os.Stderr, "Error creating PR: %v\n", err) - os.Exit(1) + return fmt.Errorf("creating PR: %w", err) } result["pr"] = json.RawMessage(prBody) } @@ -111,6 +95,7 @@ Supports SAST and SCA dependency findings.`, if err := output.Print(cmd, out); err != nil { fmt.Fprintln(os.Stderr, string(out)) } + return nil }, } diff --git a/cmd/cli/cmd/init.go b/cmd/cli/cmd/init.go index d908c8f..2eab8c5 100644 --- a/cmd/cli/cmd/init.go +++ b/cmd/cli/cmd/init.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "os" "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/wizard" @@ -13,7 +12,7 @@ var initCmd = &cobra.Command{ Use: "init", Short: "Set up Nullify CLI for the first time", Long: "Interactive setup wizard that configures your Nullify domain, authentication, repository detection, and MCP integration.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) @@ -31,9 +30,9 @@ var initCmd = &cobra.Command{ } if err := wizard.Run(ctx, steps); err != nil { - logger.L(ctx).Error("setup wizard failed", logger.Err(err)) - os.Exit(1) + return fmt.Errorf("setup wizard failed: %w", err) } + return nil }, } diff --git a/cmd/cli/cmd/mcp.go b/cmd/cli/cmd/mcp.go index f9cc7ac..6cbde2a 100644 --- a/cmd/cli/cmd/mcp.go +++ b/cmd/cli/cmd/mcp.go @@ -1,10 +1,7 @@ package cmd import ( - "errors" "fmt" - "os" - "strings" "github.com/nullify-platform/cli/internal/client" @@ -24,18 +21,13 @@ var mcpServeCmd = &cobra.Command{ Use: "serve", Short: "Start the MCP server", Long: "Start the Nullify MCP server over stdio. Configure your AI tool to run 'nullify mcp serve'.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) authCtx, err := resolveCommandAuth(ctx) if err != nil { - if errors.Is(err, lib.ErrNoToken) { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - } else { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - } - os.Exit(ExitAuthError) + return err } queryParams := authCtx.QueryParams @@ -59,8 +51,7 @@ var mcpServeCmd = &cobra.Command{ } } if !validSet { - fmt.Fprintf(os.Stderr, "Error: invalid --tools value %q. Valid values: %s\n", toolsFlag, strings.Join(validSets, ", ")) - os.Exit(1) + return fmt.Errorf("invalid --tools value %q. Valid values: %s", toolsFlag, strings.Join(validSets, ", ")) } // Create a refreshing client for long-running MCP sessions @@ -69,15 +60,13 @@ var mcpServeCmd = &cobra.Command{ } nullifyClient, clientErr := client.NewRefreshingNullifyClient(authCtx.Host, tokenProvider) if clientErr != nil { - fmt.Fprintf(os.Stderr, "Error: failed to create client: %v\n", clientErr) - os.Exit(1) + return fmt.Errorf("failed to create client: %w", clientErr) } - err = mcp.ServeWithClient(ctx, nullifyClient, queryParams, toolSet) - if err != nil { - logger.L(ctx).Error("MCP server error", logger.Err(err)) - os.Exit(1) + if err := mcp.ServeWithClient(ctx, nullifyClient, queryParams, toolSet); err != nil { + return fmt.Errorf("MCP server error: %w", err) } + return nil }, } diff --git a/cmd/cli/cmd/open.go b/cmd/cli/cmd/open.go index e3db4ae..07f3f02 100644 --- a/cmd/cli/cmd/open.go +++ b/cmd/cli/cmd/open.go @@ -13,11 +13,14 @@ import ( var openCmd = &cobra.Command{ Use: "open", Short: "Open the Nullify dashboard in your browser", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - openHost := resolveHost(ctx) + openHost, err := resolveHostE(ctx) + if err != nil { + return err + } // Strip "api." prefix to get the dashboard URL dashboardHost := strings.TrimPrefix(openHost, "api.") url := "https://" + dashboardHost @@ -27,9 +30,10 @@ var openCmd = &cobra.Command{ } if err := auth.OpenBrowser(url); err != nil { - fmt.Fprintf(os.Stderr, "Error: could not open browser: %v\nVisit %s manually.\n", err, url) - os.Exit(1) + fmt.Fprintf(os.Stderr, "Visit %s manually.\n", url) + return fmt.Errorf("could not open browser: %w", err) } + return nil }, } diff --git a/cmd/cli/cmd/pentest.go b/cmd/cli/cmd/pentest.go index cf30865..3ce2d97 100644 --- a/cmd/cli/cmd/pentest.go +++ b/cmd/cli/cmd/pentest.go @@ -1,7 +1,7 @@ package cmd import ( - "os" + "fmt" "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/pentest" @@ -12,21 +12,20 @@ var pentestCmd = &cobra.Command{ Use: "pentest", Short: "Run a pentest scan against your API endpoints", Long: "Run pentest scans against your API endpoints. Supports local Docker-based scanning and cloud-based scanning.", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) pentestArgs := getPentestArgs(cmd) - nullifyClient := getNullifyClient(ctx) - - err := pentest.RunPentestScan(ctx, pentestArgs, nullifyClient, getLogLevel()) + nullifyClient, err := getNullifyClientE(ctx) if err != nil { - logger.L(ctx).Error( - "failed to run pentest scan", - logger.Err(err), - ) - os.Exit(1) + return err + } + + if err := pentest.RunPentestScan(ctx, pentestArgs, nullifyClient, getLogLevel()); err != nil { + return fmt.Errorf("failed to run pentest scan: %w", err) } + return nil }, } diff --git a/cmd/cli/cmd/repos.go b/cmd/cli/cmd/repos.go index 551ee08..b9fa9b1 100644 --- a/cmd/cli/cmd/repos.go +++ b/cmd/cli/cmd/repos.go @@ -14,7 +14,7 @@ var reposCmd = &cobra.Command{ Use: "repos", Short: "List monitored repositories", Example: " nullify repos\n nullify repos -o table", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) @@ -22,13 +22,13 @@ var reposCmd = &cobra.Command{ result, err := apiClient.ListContextRepositories(ctx, url.Values{}) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) + return err } if err := output.Print(cmd, result); err != nil { fmt.Fprintln(os.Stderr, string(result)) } + return nil }, } diff --git a/cmd/cli/cmd/root.go b/cmd/cli/cmd/root.go index 3691769..e8f2578 100644 --- a/cmd/cli/cmd/root.go +++ b/cmd/cli/cmd/root.go @@ -2,6 +2,7 @@ package cmd import ( "context" + "fmt" "net/http" "os" "time" @@ -47,6 +48,10 @@ var rootCmd = &cobra.Command{ } func Execute() error { + // Silence cobra's automatic usage dump on errors (it's noisy for runtime + // failures), but let cobra print the error message itself exactly once. + rootCmd.SilenceUsage = true + rootCmd.SilenceErrors = false return rootCmd.Execute() } @@ -137,25 +142,25 @@ func getLogLevel() string { return "warn" } -func resolveHost(ctx context.Context) string { +// resolveHostE resolves the Nullify host from flag, env var, or config file. +// It returns a coded error (exit code 1 for a malformed host, ExitAuthError +// when no host is configured) instead of calling os.Exit, so callers in RunE +// handlers can return it up the stack and let deferred cleanup run. +func resolveHostE(ctx context.Context) (string, error) { // 1. Flag takes priority if host != "" { sanitized, err := lib.SanitizeNullifyHost(host) if err != nil { - logger.L(ctx).Error( - "invalid host, must be in the format .nullify.ai", - logger.String("host", host), - ) - os.Exit(1) + return "", withExitCode(1, fmt.Errorf("invalid host %q, must be in the format .nullify.ai", host)) } - return sanitized + return sanitized, nil } // 2. Env var (takes precedence over config file) if envHost := os.Getenv("NULLIFY_HOST"); envHost != "" { sanitized, err := lib.SanitizeNullifyHost(envHost) if err == nil { - return sanitized + return sanitized, nil } logger.L(ctx).Warn("NULLIFY_HOST env var is invalid, falling through to config", logger.String("host", envHost), logger.Err(err)) } @@ -165,27 +170,37 @@ func resolveHost(ctx context.Context) string { if err == nil && cfg.Host != "" { sanitized, err := lib.SanitizeNullifyHost(cfg.Host) if err == nil { - return sanitized + return sanitized, nil } logger.L(ctx).Warn("config file host is invalid, ignoring", logger.String("host", cfg.Host), logger.Err(err)) } - logger.L(ctx).Error("no host configured. Run 'nullify init' to set up, or 'nullify auth login --host .nullify.ai' to configure.") - os.Exit(ExitAuthError) - return "" + return "", authError("no host configured. Run 'nullify init' to set up, or 'nullify auth login --host .nullify.ai' to configure.") +} + +// resolveHost is the os.Exit-on-error variant retained for the generated API +// commands' getAPIClient factory, which cannot easily thread errors back up. +func resolveHost(ctx context.Context) string { + nullifyHost, err := resolveHostE(ctx) + if err != nil { + logger.L(ctx).Error("failed to resolve host", logger.Err(err)) + os.Exit(ExitCodeForError(err)) + } + return nullifyHost } -func getNullifyClient(ctx context.Context) *client.NullifyClient { - nullifyHost := resolveHost(ctx) +// getNullifyClientE builds a NullifyClient, returning a coded error on auth +// failure instead of calling os.Exit. +func getNullifyClientE(ctx context.Context) (*client.NullifyClient, error) { + nullifyHost, err := resolveHostE(ctx) + if err != nil { + return nil, err + } token, err := lib.GetNullifyToken(ctx, nullifyHost, nullifyToken, githubToken) if err != nil { - logger.L(ctx).Error( - "failed to get token. Run 'nullify auth login' to authenticate.", - logger.Err(err), - ) - os.Exit(ExitAuthError) + return nil, authError("failed to get token. Run 'nullify auth login' to authenticate: %w", err) } - return client.NewNullifyClient(nullifyHost, token) + return client.NewNullifyClient(nullifyHost, token), nil } diff --git a/cmd/cli/cmd/runtime_auth.go b/cmd/cli/cmd/runtime_auth.go index 7725530..e663223 100644 --- a/cmd/cli/cmd/runtime_auth.go +++ b/cmd/cli/cmd/runtime_auth.go @@ -2,24 +2,48 @@ package cmd import ( "context" + "errors" "os" "github.com/nullify-platform/cli/internal/auth" + "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" ) +// stdinIsTTY reports whether stdin is connected to an interactive terminal. +// Commands that prompt for input use this to fail fast in non-interactive +// environments (CI, pipes) instead of blocking forever on a read. +func stdinIsTTY() bool { + info, err := os.Stdin.Stat() + if err != nil { + return false + } + return info.Mode()&os.ModeCharDevice != 0 +} + type commandAuthContext struct { Host string Token string QueryParams map[string]string } +// Client builds a NullifyClient for the resolved host and token. +func (c *commandAuthContext) Client() *client.NullifyClient { + return client.NewNullifyClient(c.Host, c.Token) +} + func resolveCommandAuth(ctx context.Context) (*commandAuthContext, error) { - commandHost := resolveHost(ctx) + commandHost, err := resolveHostE(ctx) + if err != nil { + return nil, err + } token, err := lib.GetNullifyToken(ctx, commandHost, nullifyToken, githubToken) if err != nil { - return nil, err + if errors.Is(err, lib.ErrNoToken) { + return nil, authError("not authenticated. Run 'nullify auth login' first") + } + return nil, authError("%w", err) } queryParams := map[string]string{} diff --git a/cmd/cli/cmd/status.go b/cmd/cli/cmd/status.go index 670253f..743ac67 100644 --- a/cmd/cli/cmd/status.go +++ b/cmd/cli/cmd/status.go @@ -2,15 +2,12 @@ package cmd import ( "encoding/json" - "errors" "fmt" "os" "sort" "strings" "text/tabwriter" - "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" @@ -24,38 +21,23 @@ var securityStatusCmd = &cobra.Command{ Long: "Display a summary of your security posture across all scanner types. Quick morning check-in command.", Example: ` nullify status nullify status -o table`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - statusHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, statusHost, nullifyToken, githubToken) + authCtx, err := resolveCommandAuth(ctx) if err != nil { - if errors.Is(err, lib.ErrNoToken) { - fmt.Fprintf(os.Stderr, "Error: not authenticated. Run 'nullify auth login' first.\n") - } else { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - } - os.Exit(ExitAuthError) - } - - nullifyClient := client.NewNullifyClient(statusHost, token) - - creds, err := auth.LoadCredentials() - queryParams := map[string]string{} - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(statusHost)]; ok && hostCreds.QueryParameters != nil { - queryParams = hostCreds.QueryParameters - } + return err } + nullifyClient := authCtx.Client() + queryParams := authCtx.QueryParams // Fetch metrics overview qs := lib.BuildQueryString(queryParams) overviewBody, err := lib.DoPostJSON(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, "/admin/metrics/overview"+qs, strings.NewReader(`{"query":{}}`)) if err != nil { - fmt.Fprintf(os.Stderr, "Error fetching metrics: %v\n", err) - os.Exit(ExitNetworkError) + return networkError("fetching metrics: %w", err) } var overview any @@ -106,20 +88,19 @@ var securityStatusCmd = &cobra.Command{ if format == "table" || !outputExplicit { if err := printStatusTable(statusOutput); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) + return err } - return + return nil } out, err := json.Marshal(statusOutput) if err != nil { - fmt.Fprintf(os.Stderr, "Error: failed to encode status output: %v\n", err) - os.Exit(1) + return fmt.Errorf("failed to encode status output: %w", err) } if err := output.Print(cmd, out); err != nil { fmt.Fprintln(os.Stderr, string(out)) } + return nil }, } diff --git a/cmd/cli/cmd/update.go b/cmd/cli/cmd/update.go index e3e16ef..1693509 100644 --- a/cmd/cli/cmd/update.go +++ b/cmd/cli/cmd/update.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "os" "runtime" "strings" @@ -14,14 +13,13 @@ import ( var updateCmd = &cobra.Command{ Use: "update", Short: "Check for CLI updates", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() ghClient := github.NewClient(nil) release, _, err := ghClient.Repositories.GetLatestRelease(ctx, "Nullify-Platform", "cli") if err != nil { - fmt.Fprintf(os.Stderr, "Error checking for updates: %v\n", err) - os.Exit(1) + return fmt.Errorf("checking for updates: %w", err) } latestVersion := strings.TrimPrefix(release.GetTagName(), "v") @@ -29,7 +27,7 @@ var updateCmd = &cobra.Command{ if latestVersion == currentVersion || currentVersion == "dev" { fmt.Printf("You are running the latest version (%s)\n", logger.Version) - return + return nil } fmt.Printf("A new version is available: %s (current: %s)\n\n", latestVersion, logger.Version) @@ -46,6 +44,7 @@ var updateCmd = &cobra.Command{ fmt.Println(" # Direct download") fmt.Printf(" curl -sSL https://github.com/Nullify-Platform/cli/releases/download/v%s/nullify_%s_%s.tar.gz | tar xz\n", latestVersion, runtime.GOOS, runtime.GOARCH) + return nil }, } diff --git a/cmd/cli/cmd/whoami.go b/cmd/cli/cmd/whoami.go index cbde7c9..180892a 100644 --- a/cmd/cli/cmd/whoami.go +++ b/cmd/cli/cmd/whoami.go @@ -3,7 +3,6 @@ package cmd import ( "encoding/json" "fmt" - "os" "github.com/nullify-platform/cli/internal/auth" "github.com/nullify-platform/cli/internal/logger" @@ -14,11 +13,14 @@ import ( var whoamiCmd = &cobra.Command{ Use: "whoami", Short: "Show current authentication status", - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { ctx := setupLogger(cmd.Context()) defer logger.Close(ctx) - whoamiHost := resolveHost(ctx) + whoamiHost, err := resolveHostE(ctx) + if err != nil { + return err + } info := map[string]any{ "host": whoamiHost, @@ -44,9 +46,9 @@ var whoamiCmd = &cobra.Command{ out, _ := json.MarshalIndent(info, "", " ") if err := output.Print(cmd, out); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) + return err } + return nil }, } diff --git a/cmd/cli/main.go b/cmd/cli/main.go index b9876ca..a4fd15f 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -8,6 +8,8 @@ import ( func main() { if err := cmd.Execute(); err != nil { - os.Exit(1) + // cobra has already printed the error (SilenceErrors is false). + // Map it to the appropriate process exit code in one place. + os.Exit(cmd.ExitCodeForError(err)) } } diff --git a/internal/output/spinner.go b/internal/output/spinner.go index fc204d3..13e5c8b 100644 --- a/internal/output/spinner.go +++ b/internal/output/spinner.go @@ -14,14 +14,26 @@ type Spinner struct { once sync.Once } +// stderrIsTTY reports whether stderr is connected to a terminal. When it is +// not (e.g. CI logs, redirected output), the spinner stays silent to avoid +// polluting logs with ANSI escape sequences and braille frames. +func stderrIsTTY() bool { + info, err := os.Stderr.Stat() + if err != nil { + return false + } + return info.Mode()&os.ModeCharDevice != 0 +} + // NewSpinner starts a spinner with the given message. Call Stop() when done. // If quiet is true, no spinner is displayed but Stop() is still safe to call. +// The spinner is also suppressed when stderr is not a terminal. func NewSpinner(msg string, quiet bool) *Spinner { s := &Spinner{ msg: msg, done: make(chan struct{}), } - if quiet { + if quiet || !stderrIsTTY() { return s } diff --git a/internal/wizard/steps.go b/internal/wizard/steps.go index 78a0069..d903386 100644 --- a/internal/wizard/steps.go +++ b/internal/wizard/steps.go @@ -14,6 +14,17 @@ import ( "github.com/nullify-platform/cli/internal/logger" ) +// stdinIsTTY reports whether stdin is connected to an interactive terminal. +// Steps that prompt for input use this to fail fast in non-interactive +// environments (CI, pipes) instead of blocking forever on a read. +func stdinIsTTY() bool { + info, err := os.Stdin.Stat() + if err != nil { + return false + } + return info.Mode()&os.ModeCharDevice != 0 +} + // DomainStep checks if a valid host is configured and prompts the user if not. func DomainStep() Step { return Step{ @@ -23,6 +34,9 @@ func DomainStep() Step { return err == nil && cfg.Host != "" }, Execute: func(ctx context.Context) error { + if !stdinIsTTY() { + return fmt.Errorf("not a terminal; configure a host non-interactively with 'nullify auth login --host .nullify.ai'") + } reader := bufio.NewReader(os.Stdin) fmt.Print(" Enter your Nullify customer name (e.g., 'acme'): ") input, err := reader.ReadString('\n') From d2fc96685ff47e16708fb1dc654b0f838fd6d6ce Mon Sep 17 00:00:00 2001 From: Tim Thacker Date: Fri, 31 Jul 2026 16:02:20 -0400 Subject: [PATCH 2/2] fix(cli): address command lifecycle review feedback --- cmd/cli/cmd/auth.go | 12 +- cmd/cli/cmd/ci.go | 20 +- cmd/cli/cmd/errors.go | 18 + cmd/cli/cmd/exitcodes.go | 21 +- cmd/cli/cmd/exitcodes_test.go | 8 +- cmd/cli/cmd/findings.go | 11 +- cmd/cli/cmd/fix.go | 25 +- cmd/cli/cmd/init.go | 4 +- cmd/cli/cmd/mcp.go | 4 +- cmd/cli/cmd/open.go | 12 +- cmd/cli/cmd/pentest.go | 4 +- cmd/cli/cmd/repos.go | 4 +- cmd/cli/cmd/root.go | 153 +++-- cmd/cli/cmd/root_behavior_test.go | 182 ++++++ cmd/cli/cmd/runtime_auth.go | 10 +- cmd/cli/cmd/runtime_auth_test.go | 4 +- cmd/cli/cmd/sbom.go | 4 +- cmd/cli/cmd/scan.go | 10 +- cmd/cli/cmd/status.go | 11 +- cmd/cli/cmd/threat.go | 10 +- cmd/cli/cmd/whoami.go | 4 +- cmd/cli/main.go | 10 +- go.mod | 1 + go.sum | 2 + internal/commands/admin.go | 772 +++++++++++++++++++++---- internal/commands/asset-graph.go | 30 +- internal/commands/behavior.go | 17 + internal/commands/bughunt_bridge.go | 3 +- internal/commands/client_factory.go | 10 + internal/commands/context.go | 611 ++++++++++++++++--- internal/commands/context_defaults.go | 14 +- internal/commands/context_push.go | 9 +- internal/commands/cspm.go | 72 ++- internal/commands/dast.go | 415 +++++++++++-- internal/commands/deps_analyze.go | 30 +- internal/commands/deps_analyze_test.go | 28 +- internal/commands/infrastructure.go | 51 +- internal/commands/manager.go | 401 +++++++++++-- internal/commands/orchestrator.go | 65 ++- internal/commands/pentest_bridge.go | 3 +- internal/commands/sast.go | 149 ++++- internal/commands/sca.go | 254 ++++++-- internal/commands/scpm.go | 170 +++++- internal/commands/secrets.go | 240 ++++++-- internal/output/spinner.go | 32 +- internal/output/spinner_test.go | 29 + internal/terminal/terminal.go | 12 + internal/terminal/terminal_test.go | 18 + internal/wizard/steps.go | 10 +- scripts/generate/main.go | 10 +- 50 files changed, 3292 insertions(+), 707 deletions(-) create mode 100644 cmd/cli/cmd/errors.go create mode 100644 cmd/cli/cmd/root_behavior_test.go create mode 100644 internal/commands/behavior.go create mode 100644 internal/commands/client_factory.go create mode 100644 internal/output/spinner_test.go create mode 100644 internal/terminal/terminal.go create mode 100644 internal/terminal/terminal_test.go diff --git a/cmd/cli/cmd/auth.go b/cmd/cli/cmd/auth.go index 518bfde..fd46259 100644 --- a/cmd/cli/cmd/auth.go +++ b/cmd/cli/cmd/auth.go @@ -10,7 +10,6 @@ import ( "github.com/nullify-platform/cli/internal/auth" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/spf13/cobra" ) @@ -25,10 +24,7 @@ var loginCmd = &cobra.Command{ Short: "Log in to Nullify", Long: "Authenticate with your Nullify instance. Opens your browser to log in with your identity provider.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) - - // Wrap context with signal handling so Ctrl+C triggers graceful cancellation + ctx := cmd.Context() ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM) defer stop() @@ -68,9 +64,6 @@ var logoutCmd = &cobra.Command{ Short: "Log out of Nullify", Long: "Clear stored credentials for the current or specified host.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) - logoutHost, err := resolveHostForAuth() if err != nil { return err @@ -134,8 +127,7 @@ var tokenCmd = &cobra.Command{ Short: "Print access token to stdout", Long: "Print the current access token. Useful for piping to other tools.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() hostForToken, err := resolveHostForAuth() if err != nil { diff --git a/cmd/cli/cmd/ci.go b/cmd/cli/cmd/ci.go index 24d21d8..dd986cf 100644 --- a/cmd/cli/cmd/ci.go +++ b/cmd/cli/cmd/ci.go @@ -8,7 +8,6 @@ import ( "sync/atomic" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" @@ -39,18 +38,11 @@ Exit codes: # Check a specific repo nullify ci gate --repo my-org/my-repo`, - // SilenceErrors: this command writes its own gate-failure summary to - // stdout and must not have cobra echo the sentinel error to stderr. - // Auth/network errors are printed explicitly below to preserve the - // original stderr output. - SilenceErrors: true, RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) return err } nullifyClient := authCtx.Client() @@ -70,7 +62,6 @@ Exit codes: } if !validThreshold { err := fmt.Errorf("invalid --severity-threshold %q. Valid values: critical, high, medium, low", severityThreshold) - fmt.Fprintf(os.Stderr, "Error: %v\n", err) return withExitCode(1, err) } @@ -132,12 +123,12 @@ Exit codes: if apiErrors > 0 { err := fmt.Errorf("%d scanner request(s) failed; failing the gate (cannot confirm a clean result)", apiErrors) - fmt.Fprintf(os.Stderr, "Error: %v\n", err) return withExitCode(ExitNetworkError, err) } if totalFindings > 0 { fmt.Printf("\nGate failed: %d findings at or above %s severity\n", totalFindings, severityThreshold) + cmd.SilenceErrors = true return withExitCode(ExitFindings, fmt.Errorf("gate failed: %d findings at or above %s severity", totalFindings, severityThreshold)) } @@ -151,13 +142,12 @@ var ciReportCmd = &cobra.Command{ Short: "Generate a findings report (markdown or SARIF)", Long: `Output a report of security findings. The default markdown format produces a summary table suitable for PR comments (counts by type and severity). The sarif - format emits a SARIF v2.1.0 document for upload to code-scanning tools.`, +format emits a SARIF v2.1.0 document for upload to code-scanning tools.`, Example: ` nullify ci report nullify ci report --repo my-org/my-repo nullify ci report --format sarif > nullify.sarif`, RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -242,7 +232,7 @@ summary table suitable for PR comments (counts by type and severity). The sarif wrapped, _ := json.Marshal(map[string]any{"findings": all, "total": len(all)}) sarifBytes, err := output.SARIFBytes(wrapped) if err != nil { - return networkError("failed to build SARIF report: %v", err) + return networkError("failed to build SARIF report: %w", err) } fmt.Println(string(sarifBytes)) return nil diff --git a/cmd/cli/cmd/errors.go b/cmd/cli/cmd/errors.go new file mode 100644 index 0000000..89ee6bd --- /dev/null +++ b/cmd/cli/cmd/errors.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +func reportError( + cmd *cobra.Command, + err error, + format string, + args ...any, +) error { + fmt.Fprintf(cmd.ErrOrStderr(), format, args...) + cmd.SilenceErrors = true + return err +} diff --git a/cmd/cli/cmd/exitcodes.go b/cmd/cli/cmd/exitcodes.go index 9c0b84e..f4a4615 100644 --- a/cmd/cli/cmd/exitcodes.go +++ b/cmd/cli/cmd/exitcodes.go @@ -13,10 +13,6 @@ const ( ExitNetworkError = 3 ) -// exitCodeError wraps an error with a specific process exit code. RunE handlers -// return these so that exit-code mapping happens in exactly one place -// (main.go), instead of scattered os.Exit calls that would skip deferred -// cleanup such as logger.Close. type exitCodeError struct { code int err error @@ -38,8 +34,10 @@ func (e *exitCodeError) ExitCode() int { return e.code } -// withExitCode wraps err so that the CLI exits with the given code. The -// underlying error is preserved (and printed once by cobra). +type exitCoder interface { + ExitCode() int +} + func withExitCode(code int, err error) error { if err == nil { return nil @@ -47,30 +45,23 @@ func withExitCode(code int, err error) error { return &exitCodeError{code: code, err: err} } -// authError builds an exit-code error for authentication failures. func authError(format string, args ...any) error { return withExitCode(ExitAuthError, fmt.Errorf(format, args...)) } -// networkError builds an exit-code error for network/API failures. func networkError(format string, args ...any) error { return withExitCode(ExitNetworkError, fmt.Errorf(format, args...)) } -// findingsError builds an exit-code error indicating findings exceeded the gate. -func findingsError(format string, args ...any) error { - return withExitCode(ExitFindings, fmt.Errorf(format, args...)) -} - // ExitCodeForError resolves the process exit code for a top-level error. // Plain errors map to exit code 1; coded errors use their embedded code. func ExitCodeForError(err error) int { if err == nil { return ExitSuccess } - var coded *exitCodeError + var coded exitCoder if errors.As(err, &coded) { - return coded.code + return coded.ExitCode() } return 1 } diff --git a/cmd/cli/cmd/exitcodes_test.go b/cmd/cli/cmd/exitcodes_test.go index e603289..9f42f92 100644 --- a/cmd/cli/cmd/exitcodes_test.go +++ b/cmd/cli/cmd/exitcodes_test.go @@ -8,6 +8,11 @@ import ( "github.com/stretchr/testify/require" ) +type externalExitError struct{} + +func (externalExitError) Error() string { return "external" } +func (externalExitError) ExitCode() int { return 30 } + func TestExitCodeForError(t *testing.T) { tests := []struct { name string @@ -18,9 +23,10 @@ func TestExitCodeForError(t *testing.T) { {"plain error", errors.New("boom"), 1}, {"auth error", authError("nope"), ExitAuthError}, {"network error", networkError("nope"), ExitNetworkError}, - {"findings error", findingsError("nope"), ExitFindings}, + {"findings error", withExitCode(ExitFindings, errors.New("nope")), ExitFindings}, {"explicit code 1", withExitCode(1, errors.New("x")), 1}, {"wrapped coded error", fmt.Errorf("ctx: %w", authError("nope")), ExitAuthError}, + {"external coded error", externalExitError{}, 30}, } for _, tt := range tests { diff --git a/cmd/cli/cmd/findings.go b/cmd/cli/cmd/findings.go index dd27f8c..86e9d0d 100644 --- a/cmd/cli/cmd/findings.go +++ b/cmd/cli/cmd/findings.go @@ -8,7 +8,6 @@ import ( "strings" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -32,8 +31,7 @@ Results are paginated automatically up to --limit total findings.`, # Fetch up to 500 findings nullify findings --limit 500`, RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -147,7 +145,12 @@ Results are paginated automatically up to --limit total findings.`, var resp unifiedResponse if err := json.Unmarshal([]byte(respBody), &resp); err != nil { - return networkError("parsing response: %w", err) + return reportError( + cmd, + networkError("parsing response: %w", err), + "Error parsing response: %v\n", + err, + ) } allFindings = append(allFindings, resp.Findings...) diff --git a/cmd/cli/cmd/fix.go b/cmd/cli/cmd/fix.go index 427ebb3..68ec1aa 100644 --- a/cmd/cli/cmd/fix.go +++ b/cmd/cli/cmd/fix.go @@ -7,7 +7,6 @@ import ( "os" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -28,8 +27,7 @@ Supports SAST and SCA dependency findings.`, nullify fix def456 --type sca`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() findingID := args[0] @@ -62,14 +60,24 @@ Supports SAST and SCA dependency findings.`, _, err = lib.DoPost(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/fix%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - return fmt.Errorf("generating fix: %w", err) + return reportError( + cmd, + fmt.Errorf("generating fix: %w", err), + "Error generating fix: %v\n", + err, + ) } // Step 2: Get diff diffBody, err := lib.DoGet(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/cache/diff%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - return fmt.Errorf("getting diff: %w", err) + return reportError( + cmd, + fmt.Errorf("getting diff: %w", err), + "Error getting diff: %v\n", + err, + ) } result := map[string]any{ @@ -86,7 +94,12 @@ Supports SAST and SCA dependency findings.`, prBody, err := lib.DoPost(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, fmt.Sprintf("%s/%s/autofix/cache/create_pr%s", basePath, url.PathEscape(findingID), qs)) if err != nil { - return fmt.Errorf("creating PR: %w", err) + return reportError( + cmd, + fmt.Errorf("creating PR: %w", err), + "Error creating PR: %v\n", + err, + ) } result["pr"] = json.RawMessage(prBody) } diff --git a/cmd/cli/cmd/init.go b/cmd/cli/cmd/init.go index 2eab8c5..d6b00d7 100644 --- a/cmd/cli/cmd/init.go +++ b/cmd/cli/cmd/init.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/wizard" "github.com/spf13/cobra" ) @@ -13,8 +12,7 @@ var initCmd = &cobra.Command{ Short: "Set up Nullify CLI for the first time", Long: "Interactive setup wizard that configures your Nullify domain, authentication, repository detection, and MCP integration.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() fmt.Println("Welcome to Nullify CLI setup!") fmt.Println("This wizard will help you get started.") diff --git a/cmd/cli/cmd/mcp.go b/cmd/cli/cmd/mcp.go index 1508a0a..f29233e 100644 --- a/cmd/cli/cmd/mcp.go +++ b/cmd/cli/cmd/mcp.go @@ -7,7 +7,6 @@ import ( "github.com/nullify-platform/cli/internal/api" "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/mcp" "github.com/spf13/cobra" ) @@ -23,8 +22,7 @@ var mcpServeCmd = &cobra.Command{ Short: "Start the MCP server", Long: "Start the Nullify MCP server over stdio. Configure your AI tool to run 'nullify mcp serve'.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { diff --git a/cmd/cli/cmd/open.go b/cmd/cli/cmd/open.go index 07f3f02..1a67d73 100644 --- a/cmd/cli/cmd/open.go +++ b/cmd/cli/cmd/open.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/logger" "github.com/spf13/cobra" ) @@ -14,8 +13,7 @@ var openCmd = &cobra.Command{ Use: "open", Short: "Open the Nullify dashboard in your browser", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() openHost, err := resolveHostE(ctx) if err != nil { @@ -30,7 +28,13 @@ var openCmd = &cobra.Command{ } if err := auth.OpenBrowser(url); err != nil { - fmt.Fprintf(os.Stderr, "Visit %s manually.\n", url) + fmt.Fprintf( + cmd.ErrOrStderr(), + "Error: could not open browser: %v\nVisit %s manually.\n", + err, + url, + ) + cmd.SilenceErrors = true return fmt.Errorf("could not open browser: %w", err) } return nil diff --git a/cmd/cli/cmd/pentest.go b/cmd/cli/cmd/pentest.go index 3ce2d97..f8c8ff9 100644 --- a/cmd/cli/cmd/pentest.go +++ b/cmd/cli/cmd/pentest.go @@ -3,7 +3,6 @@ package cmd import ( "fmt" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/pentest" "github.com/spf13/cobra" ) @@ -13,8 +12,7 @@ var pentestCmd = &cobra.Command{ Short: "Run a pentest scan against your API endpoints", Long: "Run pentest scans against your API endpoints. Supports local Docker-based scanning and cloud-based scanning.", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() pentestArgs := getPentestArgs(cmd) nullifyClient, err := getNullifyClientE(ctx) diff --git a/cmd/cli/cmd/repos.go b/cmd/cli/cmd/repos.go index 88305c0..a73cdb1 100644 --- a/cmd/cli/cmd/repos.go +++ b/cmd/cli/cmd/repos.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/nullify-platform/cli/internal/api" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -15,8 +14,7 @@ var reposCmd = &cobra.Command{ Short: "List monitored repositories", Example: " nullify repos\n nullify repos -o table", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { diff --git a/cmd/cli/cmd/root.go b/cmd/cli/cmd/root.go index 42a83f9..b931447 100644 --- a/cmd/cli/cmd/root.go +++ b/cmd/cli/cmd/root.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "sync" "github.com/nullify-platform/cli/internal/api" "github.com/nullify-platform/cli/internal/auth" @@ -14,6 +15,14 @@ import ( "github.com/spf13/cobra" ) +var wrapRuntimeCommands sync.Once +var commandOutputDefaults map[*cobra.Command]commandOutput + +type commandOutput struct { + silenceErrors bool + silenceUsage bool +} + var ( host string verbose bool @@ -25,34 +34,91 @@ var ( nullifyToken string githubToken string - getAPIClient func() *api.Client + getAPIClient commands.ClientFactory ) var rootCmd = &cobra.Command{ - Use: "nullify", - Short: "Nullify CLI - autonomous AI workforce for product security", - Long: "Nullify CLI provides access to the Nullify API for security scanning, findings management, and automation.", - Version: logger.Version, - PersistentPreRun: func(cmd *cobra.Command, args []string) { - // Skip config loading for auth login and completion commands - if cmd.Name() == "login" || cmd.Name() == "completion" { - return - } + Use: "nullify", + Short: "Nullify CLI - autonomous AI workforce for product security", + Long: "Nullify CLI provides access to the Nullify API for security scanning, findings management, and automation.", + Version: logger.Version, + PersistentPreRunE: prepareCommand, +} - if noColor || os.Getenv("NO_COLOR") != "" { - _ = os.Setenv("NO_COLOR", "1") - } - }, +func prepareCommand(cmd *cobra.Command, _ []string) error { + if noColor || os.Getenv("NO_COLOR") != "" { + _ = os.Setenv("NO_COLOR", "1") + } + + ctx, err := setupLogger(cmd.Context()) + if err != nil { + return fmt.Errorf("configure logger: %w", err) + } + cmd.Root().SetContext(ctx) + cmd.SetContext(ctx) + return nil } func Execute() error { - // Silence cobra's automatic usage dump on errors (it's noisy for runtime - // failures), but let cobra print the error message itself exactly once. - rootCmd.SilenceUsage = true + wrapRuntimeCommands.Do(func() { + commandOutputDefaults = captureCommandOutput(rootCmd) + setRuntimeErrorBehavior(rootCmd) + }) + resetCommandOutput(rootCmd, commandOutputDefaults) + rootCmd.SetContext(context.Background()) + defer func() { + logger.Close(rootCmd.Context()) + }() + + rootCmd.SilenceUsage = false rootCmd.SilenceErrors = false return rootCmd.Execute() } +func setRuntimeErrorBehavior(cmd *cobra.Command) { + if cmd.RunE != nil && !commands.PreservesRuntimeUsage(cmd) { + run := cmd.RunE + cmd.RunE = func(cmd *cobra.Command, args []string) error { + err := run(cmd, args) + if err != nil { + cmd.SilenceUsage = true + } + return err + } + } + for _, child := range cmd.Commands() { + setRuntimeErrorBehavior(child) + } +} + +func captureCommandOutput(cmd *cobra.Command) map[*cobra.Command]commandOutput { + defaults := map[*cobra.Command]commandOutput{ + cmd: { + silenceErrors: cmd.SilenceErrors, + silenceUsage: cmd.SilenceUsage, + }, + } + for _, child := range cmd.Commands() { + for command, output := range captureCommandOutput(child) { + defaults[command] = output + } + } + return defaults +} + +func resetCommandOutput( + cmd *cobra.Command, + defaults map[*cobra.Command]commandOutput, +) { + if output, ok := defaults[cmd]; ok { + cmd.SilenceErrors = output.silenceErrors + cmd.SilenceUsage = output.silenceUsage + } + for _, child := range cmd.Commands() { + resetCommandOutput(child, defaults) + } +} + func init() { rootCmd.PersistentFlags().StringVar(&host, "host", "", "The base URL of your Nullify API instance (e.g., acme.nullify.ai)") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") @@ -68,28 +134,12 @@ func init() { noColor = true } - // Package-level getAPIClient for use by other command files - getAPIClient = func() *api.Client { - ctx := setupLogger(context.Background()) - nullifyHost := resolveHost(ctx) - token, err := lib.GetNullifyToken(ctx, nullifyHost, nullifyToken, githubToken) + getAPIClient = func(ctx context.Context) (*api.Client, error) { + authCtx, err := resolveCommandAuth(ctx) if err != nil { - logger.L(ctx).Error("failed to get token", logger.Err(err)) - os.Exit(ExitAuthError) - } - - // Load default query parameters from stored credentials - defaultParams := map[string]string{} - creds, err := auth.LoadCredentials() - if err == nil { - if hostCreds, ok := creds[auth.CredentialKey(nullifyHost)]; ok { - defaultParams = hostCreds.QueryParameters - } + return nil, err } - - // api.NewClient defaults to a retrying HTTP client, so no - // WithHTTPClient override is needed here. - return api.NewClient(nullifyHost, token, defaultParams) + return authCtx.APIClient(), nil } // Register generated API commands under 'api' parent for cleaner top-level help @@ -116,7 +166,7 @@ func init() { commands.RegisterDepsAnalyzeCommand(rootCmd, getAPIClient) } -func setupLogger(ctx context.Context) context.Context { +func setupLogger(ctx context.Context) (context.Context, error) { logLevel := "warn" if verbose { logLevel = "info" @@ -125,12 +175,7 @@ func setupLogger(ctx context.Context) context.Context { logLevel = "debug" } - ctx, err := logger.ConfigureDevelopmentLogger(ctx, logLevel) - if err != nil { - panic(err) - } - - return ctx + return logger.ConfigureDevelopmentLogger(ctx, logLevel) } func getLogLevel() string { @@ -143,12 +188,7 @@ func getLogLevel() string { return "warn" } -// resolveHostE resolves the Nullify host from flag, env var, or config file. -// It returns a coded error (exit code 1 for a malformed host, ExitAuthError -// when no host is configured) instead of calling os.Exit, so callers in RunE -// handlers can return it up the stack and let deferred cleanup run. func resolveHostE(ctx context.Context) (string, error) { - // 1. Flag takes priority if host != "" { sanitized, err := lib.SanitizeNullifyHost(host) if err != nil { @@ -157,7 +197,6 @@ func resolveHostE(ctx context.Context) (string, error) { return sanitized, nil } - // 2. Env var (takes precedence over config file) if envHost := os.Getenv("NULLIFY_HOST"); envHost != "" { sanitized, err := lib.SanitizeNullifyHost(envHost) if err == nil { @@ -166,7 +205,6 @@ func resolveHostE(ctx context.Context) (string, error) { logger.L(ctx).Warn("NULLIFY_HOST env var is invalid, falling through to config", logger.String("host", envHost), logger.Err(err)) } - // 3. Read from config file cfg, err := auth.LoadConfig() if err == nil && cfg.Host != "" { sanitized, err := lib.SanitizeNullifyHost(cfg.Host) @@ -179,19 +217,6 @@ func resolveHostE(ctx context.Context) (string, error) { return "", authError("no host configured. Run 'nullify init' to set up, or 'nullify auth login --host .nullify.ai' to configure.") } -// resolveHost is the os.Exit-on-error variant retained for the generated API -// commands' getAPIClient factory, which cannot easily thread errors back up. -func resolveHost(ctx context.Context) string { - nullifyHost, err := resolveHostE(ctx) - if err != nil { - logger.L(ctx).Error("failed to resolve host", logger.Err(err)) - os.Exit(ExitCodeForError(err)) - } - return nullifyHost -} - -// getNullifyClientE builds a NullifyClient, returning a coded error on auth -// failure instead of calling os.Exit. func getNullifyClientE(ctx context.Context) (*client.NullifyClient, error) { nullifyHost, err := resolveHostE(ctx) if err != nil { diff --git a/cmd/cli/cmd/root_behavior_test.go b/cmd/cli/cmd/root_behavior_test.go new file mode 100644 index 0000000..d9f3112 --- /dev/null +++ b/cmd/cli/cmd/root_behavior_test.go @@ -0,0 +1,182 @@ +package cmd + +import ( + "bytes" + "context" + "errors" + "net/http" + "testing" + + "github.com/nullify-platform/cli/internal/api" + "github.com/nullify-platform/cli/internal/commands" + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" +) + +func TestRuntimeErrorsSuppressUsage(t *testing.T) { + root := &cobra.Command{Use: "test"} + root.AddCommand(&cobra.Command{ + Use: "run", + RunE: func(cmd *cobra.Command, args []string) error { + return errors.New("runtime failure") + }, + }) + setRuntimeErrorBehavior(root) + + output := executeCommand(t, root, "run") + + require.Contains(t, output, "Error: runtime failure") + require.NotContains(t, output, "Usage:") +} + +func TestFrameworkErrorsIncludeUsage(t *testing.T) { + root := &cobra.Command{Use: "test"} + root.AddCommand(&cobra.Command{ + Use: "run", + RunE: func(cmd *cobra.Command, args []string) error { return nil }, + }) + setRuntimeErrorBehavior(root) + + output := executeCommand(t, root, "run", "--unknown") + + require.Contains(t, output, "unknown flag") + require.Contains(t, output, "Usage:") +} + +func TestStaticSilenceUsageSurvivesReset(t *testing.T) { + root := &cobra.Command{Use: "test"} + child := &cobra.Command{ + Use: "run", + SilenceUsage: true, + RunE: func(cmd *cobra.Command, args []string) error { + return nil + }, + } + root.AddCommand(child) + defaults := captureCommandOutput(root) + setRuntimeErrorBehavior(root) + child.SilenceUsage = false + resetCommandOutput(root, defaults) + + output := executeCommand(t, root, "run", "--unknown") + + require.Contains(t, output, "unknown flag") + require.NotContains(t, output, "Usage:") +} + +func TestGeneratedInputErrorsIncludeUsage(t *testing.T) { + root := &cobra.Command{Use: "test"} + commands.RegisterAdminCommands( + root, + func(context.Context) (*api.Client, error) { + return &api.Client{}, nil + }, + ) + setRuntimeErrorBehavior(root) + + output := executeCommand( + t, + root, + "admin", + "list-scan-coverage", + "--limit", + "invalid", + ) + + require.Contains(t, output, "invalid syntax") + require.Contains(t, output, "Usage:") +} + +func TestGeneratedClientFactoryErrorsReturnThroughCobra(t *testing.T) { + want := errors.New("authentication failed") + root := &cobra.Command{Use: "test"} + commands.RegisterAdminCommands( + root, + func(context.Context) (*api.Client, error) { + return nil, want + }, + ) + setRuntimeErrorBehavior(root) + var output bytes.Buffer + root.SetOut(&output) + root.SetErr(&output) + root.SetArgs([]string{"admin", "list-scan-coverage"}) + + err := root.Execute() + + require.ErrorIs(t, err, want) + require.NotContains(t, output.String(), "Usage:") +} + +func TestGeneratedRuntimeErrorsIncludeUsage(t *testing.T) { + root := &cobra.Command{Use: "test"} + commands.RegisterAdminCommands( + root, + func(context.Context) (*api.Client, error) { + return &api.Client{ + BaseURL: "https://example.com", + HTTPClient: &http.Client{ + Transport: roundTripperFunc(func(*http.Request) (*http.Response, error) { + return nil, errors.New("connection refused") + }), + }, + }, nil + }, + ) + setRuntimeErrorBehavior(root) + + output := executeCommand(t, root, "admin", "list-scan-coverage") + + require.Contains(t, output, "connection refused") + require.Contains(t, output, "Usage:") +} + +func TestContextDefaultFactoryErrorsSuppressUsage(t *testing.T) { + want := errors.New("authentication failed") + root := &cobra.Command{Use: "test"} + commands.RegisterContextCommands( + root, + func(context.Context) (*api.Client, error) { + return nil, want + }, + ) + commands.ApplyContextCommandDefaults( + root, + func(context.Context) (*api.Client, error) { + return nil, want + }, + ) + setRuntimeErrorBehavior(root) + var output bytes.Buffer + root.SetOut(&output) + root.SetErr(&output) + root.SetArgs([]string{"context", "get-project", "repo", "project"}) + + err := root.Execute() + + require.ErrorIs(t, err, want) + require.NotContains(t, output.String(), "Usage:") +} + +type roundTripperFunc func(*http.Request) (*http.Response, error) + +func (fn roundTripperFunc) RoundTrip( + req *http.Request, +) (*http.Response, error) { + return fn(req) +} + +func executeCommand( + t *testing.T, + root *cobra.Command, + args ...string, +) string { + t.Helper() + + var output bytes.Buffer + root.SetOut(&output) + root.SetErr(&output) + root.SetArgs(args) + require.Error(t, root.Execute()) + return output.String() +} diff --git a/cmd/cli/cmd/runtime_auth.go b/cmd/cli/cmd/runtime_auth.go index c2d9380..33d2d0b 100644 --- a/cmd/cli/cmd/runtime_auth.go +++ b/cmd/cli/cmd/runtime_auth.go @@ -9,17 +9,11 @@ import ( "github.com/nullify-platform/cli/internal/auth" "github.com/nullify-platform/cli/internal/client" "github.com/nullify-platform/cli/internal/lib" + "github.com/nullify-platform/cli/internal/terminal" ) -// stdinIsTTY reports whether stdin is connected to an interactive terminal. -// Commands that prompt for input use this to fail fast in non-interactive -// environments (CI, pipes) instead of blocking forever on a read. func stdinIsTTY() bool { - info, err := os.Stdin.Stat() - if err != nil { - return false - } - return info.Mode()&os.ModeCharDevice != 0 + return terminal.IsInteractive(os.Stdin) } type commandAuthContext struct { diff --git a/cmd/cli/cmd/runtime_auth_test.go b/cmd/cli/cmd/runtime_auth_test.go index 42181d9..3ff0ab2 100644 --- a/cmd/cli/cmd/runtime_auth_test.go +++ b/cmd/cli/cmd/runtime_auth_test.go @@ -26,7 +26,7 @@ func TestResolveCommandAuthUsesEnvTokenWithoutStoredCredentials(t *testing.T) { githubToken = originalGithubToken }) - authCtx, err := resolveCommandAuth(setupLogger(context.Background())) + authCtx, err := resolveCommandAuth(context.Background()) require.NoError(t, err) require.Equal(t, "acme.nullify.ai", authCtx.Host) require.Equal(t, "env-token", authCtx.Token) @@ -60,7 +60,7 @@ func TestResolveCommandAuthClonesStoredQueryParams(t *testing.T) { githubToken = originalGithubToken }) - authCtx, err := resolveCommandAuth(setupLogger(context.Background())) + authCtx, err := resolveCommandAuth(context.Background()) require.NoError(t, err) require.Equal(t, map[string]string{"githubOwnerId": "123"}, authCtx.QueryParams) diff --git a/cmd/cli/cmd/sbom.go b/cmd/cli/cmd/sbom.go index 8d88924..24299cf 100644 --- a/cmd/cli/cmd/sbom.go +++ b/cmd/cli/cmd/sbom.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/nullify-platform/cli/internal/api" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -22,8 +21,7 @@ var sbomGetCmd = &cobra.Command{ Example: " nullify sbom get --repository-id repo-123\n" + " nullify sbom get --repository-id repo-123 --project-id proj-456", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() repositoryID, _ := cmd.Flags().GetString("repository-id") projectID, _ := cmd.Flags().GetString("project-id") diff --git a/cmd/cli/cmd/scan.go b/cmd/cli/cmd/scan.go index 4dc7b20..6e4f320 100644 --- a/cmd/cli/cmd/scan.go +++ b/cmd/cli/cmd/scan.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/nullify-platform/cli/internal/api" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -21,8 +20,7 @@ var scanStartCmd = &cobra.Command{ Short: "Start a cloud scan", Example: " nullify scan start", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -52,8 +50,7 @@ var scanStatusCmd = &cobra.Command{ Args: cobra.ExactArgs(1), Example: " nullify scan status abc123", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -86,8 +83,7 @@ var scanRunsCmd = &cobra.Command{ Example: " nullify scan runs --type sast --repository-id repo-123\n" + " nullify scan runs --type sca --repository-id repo-123 --limit 10", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() scanType, _ := cmd.Flags().GetString("type") repositoryID, _ := cmd.Flags().GetString("repository-id") diff --git a/cmd/cli/cmd/status.go b/cmd/cli/cmd/status.go index 743ac67..7b7aab7 100644 --- a/cmd/cli/cmd/status.go +++ b/cmd/cli/cmd/status.go @@ -9,7 +9,6 @@ import ( "text/tabwriter" "github.com/nullify-platform/cli/internal/lib" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" @@ -22,8 +21,7 @@ var securityStatusCmd = &cobra.Command{ Example: ` nullify status nullify status -o table`, RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -37,7 +35,12 @@ var securityStatusCmd = &cobra.Command{ overviewBody, err := lib.DoPostJSON(ctx, nullifyClient.HttpClient, nullifyClient.BaseURL, "/admin/metrics/overview"+qs, strings.NewReader(`{"query":{}}`)) if err != nil { - return networkError("fetching metrics: %w", err) + return reportError( + cmd, + networkError("fetching metrics: %w", err), + "Error fetching metrics: %v\n", + err, + ) } var overview any diff --git a/cmd/cli/cmd/threat.go b/cmd/cli/cmd/threat.go index dce8013..92f50c9 100644 --- a/cmd/cli/cmd/threat.go +++ b/cmd/cli/cmd/threat.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/nullify-platform/cli/internal/api" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -23,8 +22,7 @@ var threatListCmd = &cobra.Command{ Short: "List threat investigations", Example: " nullify threat list", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -54,8 +52,7 @@ var threatGetCmd = &cobra.Command{ Args: cobra.ExactArgs(1), Example: " nullify threat get ti-123", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() authCtx, err := resolveCommandAuth(ctx) if err != nil { @@ -87,8 +84,7 @@ var threatCreateCmd = &cobra.Command{ Example: " nullify threat create --title \"Log4Shell\" --severity critical\n" + " nullify threat create --title \"CVE sweep\" --cve-ids CVE-2021-44228,CVE-2021-45046", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() title, _ := cmd.Flags().GetString("title") description, _ := cmd.Flags().GetString("description") diff --git a/cmd/cli/cmd/whoami.go b/cmd/cli/cmd/whoami.go index 180892a..fc49cd3 100644 --- a/cmd/cli/cmd/whoami.go +++ b/cmd/cli/cmd/whoami.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/nullify-platform/cli/internal/auth" - "github.com/nullify-platform/cli/internal/logger" "github.com/nullify-platform/cli/internal/output" "github.com/spf13/cobra" ) @@ -14,8 +13,7 @@ var whoamiCmd = &cobra.Command{ Use: "whoami", Short: "Show current authentication status", RunE: func(cmd *cobra.Command, args []string) error { - ctx := setupLogger(cmd.Context()) - defer logger.Close(ctx) + ctx := cmd.Context() whoamiHost, err := resolveHostE(ctx) if err != nil { diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 85834ae..014e504 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -4,18 +4,10 @@ import ( "os" "github.com/nullify-platform/cli/cmd/cli/cmd" - "github.com/nullify-platform/cli/internal/commands" ) func main() { - // commands.ExitCodeFromError maps the deps-analyze workflow's - // exit-coded errors (severity gate: 10/20/30, invalid: 2, transient: - // 1) onto the process exit code; any other error falls back to 1. if err := cmd.Execute(); err != nil { - exitCode := cmd.ExitCodeForError(err) - if exitCode == 1 { - exitCode = commands.ExitCodeFromError(err) - } - os.Exit(exitCode) + os.Exit(cmd.ExitCodeForError(err)) } } diff --git a/go.mod b/go.mod index 0003c1e..4cf5dbb 100644 --- a/go.mod +++ b/go.mod @@ -93,5 +93,6 @@ require ( github.com/nullify-platform/logger v1.32.2 github.com/stretchr/testify v1.11.1 go.uber.org/zap v1.28.0 + golang.org/x/term v0.39.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 7737cb4..e44e02c 100644 --- a/go.sum +++ b/go.sum @@ -181,6 +181,8 @@ golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= +golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= diff --git a/internal/commands/admin.go b/internal/commands/admin.go index 275e8d4..6c48919 100644 --- a/internal/commands/admin.go +++ b/internal/commands/admin.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterAdminCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "admin", Short: "Administration and Metrics", @@ -33,7 +33,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-scan-coverage", Short: "Get Scan Coverage", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminAssessmentsScanCoverageInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -70,6 +74,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Max repos per page (default 50)") cmd.Flags().String("offset", "", "Pagination offset (default 0)") cmd.Flags().String("search", "", "Case-insensitive substring filter on repository name or owner") @@ -82,7 +87,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-assessments-scan-coverage-findings", Short: "Get Scan Coverage Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminAssessmentsScanCoverageFindingsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -119,6 +128,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Max findings per page (default 50, max 500)") cmd.Flags().String("offset", "", "Pagination offset (default 0)") cmd.Flags().String("repository-id", "", "Repository ID to drill into") @@ -131,7 +141,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-checklist", Short: "Get Checklist", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminChecklistInput{} out, err := client.ListAdminChecklist(cmd.Context(), in) if err != nil { @@ -144,6 +158,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -153,7 +168,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Context Upload Credentials", Long: "Request body (JSON) fields: branch (string), commitSha (string), contextType (string, required), environment (object), fromPR (integer), name (string, required), prNumber (integer), repository (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminContextIngestInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -195,6 +214,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -206,7 +226,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "List Unified Events", Long: "Request body (JSON) fields: afterId (string), afterTimeUnix (integer), autofixId (string), beforeTimeUnix (integer), campaignId (string), eventTypes (array), findingIds (array), limit (integer), prCanonicalId (string), runId (string), services (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminEventsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -248,6 +272,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -259,7 +284,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetAdminFindingFindingIdInput{} in.FindingID = args[0] out, err := client.GetAdminFindingFindingId(cmd.Context(), in) @@ -273,6 +302,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -282,7 +312,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Query Findings", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminFindingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -324,6 +358,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -335,7 +370,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Download Findings", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminFindingsDownloadInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -377,6 +416,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -387,7 +427,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-fix-effort", Short: "Get Fix Effort Mapping", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminFixEffortInput{} out, err := client.ListAdminFixEffort(cmd.Context(), in) if err != nil { @@ -400,6 +444,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -409,7 +454,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Put Fix Effort Mapping", Long: "Request body (JSON) fields: fixEffort (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateAdminFixEffortInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -451,6 +500,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -461,7 +511,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-getFileContents", Short: "Get File Contents", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminGetFileContentsInput{} if v, _ := cmd.Flags().GetString("end-line"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -506,6 +560,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("end-line", "", "") cmd.Flags().String("file-path", "", "") cmd.Flags().String("project-id", "", "") @@ -521,7 +576,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get File Owners", Long: "Request body (JSON) fields: files (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminGetFileOwnersInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -563,6 +622,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -573,7 +633,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-getPullRequest", Short: "Get PR State", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminGetPullRequestInput{} if v, _ := cmd.Flags().GetString("pr-id"); v != "" { x := string(v) @@ -594,6 +658,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("pr-id", "", "") cmd.Flags().String("repository-id", "", "") serviceCmd.AddCommand(cmd) @@ -604,7 +669,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-installations", Short: "Get App Installations", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminInstallationsInput{} out, err := client.ListAdminInstallations(cmd.Context(), in) if err != nil { @@ -617,6 +686,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -625,7 +695,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-azure", Short: "Get Azure Configuration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsAzureInput{} out, err := client.ListAdminIntegrationsAzure(cmd.Context(), in) if err != nil { @@ -638,6 +712,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -646,7 +721,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "create-azure", Short: "Install Azure DevOps Integration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsAzureInput{} out, err := client.CreateAdminIntegrationsAzure(cmd.Context(), in) if err != nil { @@ -659,6 +738,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -668,7 +748,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Set Azure Credentials", Long: "Request body (JSON) fields: clientId (string, required), clientSecret (string), tenantId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsAzureCredentialsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -710,6 +794,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -720,7 +805,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-buildkite", Short: "Delete Buildkite Integration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsBuildkiteInput{} out, err := client.DeleteAdminIntegrationsBuildkite(cmd.Context(), in) if err != nil { @@ -733,6 +822,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -741,7 +831,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-buildkite", Short: "Get Buildkite Integration Status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsBuildkiteInput{} out, err := client.ListAdminIntegrationsBuildkite(cmd.Context(), in) if err != nil { @@ -754,6 +848,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -763,7 +858,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Set Buildkite API Token", Long: "Request body (JSON) fields: apiToken (string, required), orgSlug (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsBuildkiteTokenInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -805,6 +904,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -815,7 +915,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-circleci", Short: "Delete CircleCI Integration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsCircleciInput{} out, err := client.DeleteAdminIntegrationsCircleci(cmd.Context(), in) if err != nil { @@ -828,6 +932,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -836,7 +941,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-circleci", Short: "Get CircleCI Integration Status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsCircleciInput{} out, err := client.ListAdminIntegrationsCircleci(cmd.Context(), in) if err != nil { @@ -849,6 +958,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -858,7 +968,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Set CircleCI API Token", Long: "Request body (JSON) fields: apiToken (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCircleciTokenInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -900,6 +1014,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -910,7 +1025,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-integrations-cloud-aws-settings", Short: "Delete Cloud AWS Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsCloudAwsSettingsInput{} out, err := client.DeleteAdminIntegrationsCloudAwsSettings(cmd.Context(), in) if err != nil { @@ -923,6 +1042,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -931,7 +1051,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-cloud-aws-settings", Short: "Get Cloud AWS Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsCloudAwsSettingsInput{} out, err := client.ListAdminIntegrationsCloudAwsSettings(cmd.Context(), in) if err != nil { @@ -944,6 +1068,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -953,7 +1078,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Upsert Cloud AWS Settings", Long: "Request body (JSON) fields: awsAccounts (array, required), externalId (string), iamRoleName (string, required), preferredDeployment (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudAwsSettingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -995,6 +1124,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1006,7 +1136,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Validate AWS Role", Long: "Request body (JSON) fields: accountIds (array, required), onboarding (boolean), roleNameToAssume (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudAwsValidateRoleInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1048,6 +1182,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1058,7 +1193,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-integrations-cloud-azure-settings", Short: "Delete Cloud Azure Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsCloudAzureSettingsInput{} out, err := client.DeleteAdminIntegrationsCloudAzureSettings(cmd.Context(), in) if err != nil { @@ -1071,6 +1210,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1079,7 +1219,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-cloud-azure-settings", Short: "Get Cloud Azure Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsCloudAzureSettingsInput{} out, err := client.ListAdminIntegrationsCloudAzureSettings(cmd.Context(), in) if err != nil { @@ -1092,6 +1236,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1101,7 +1246,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Upsert Cloud Azure Settings", Long: "Request body (JSON) fields: clientId (string), clientSecret (string), displayName (string), subscriptions (array), tenantId (string, required), useManagedIdentity (boolean).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudAzureSettingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1143,6 +1292,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1153,7 +1303,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-integrations-cloud-gcp-settings", Short: "Delete Cloud GCP Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsCloudGcpSettingsInput{} out, err := client.DeleteAdminIntegrationsCloudGcpSettings(cmd.Context(), in) if err != nil { @@ -1166,6 +1320,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1174,7 +1329,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-cloud-gcp-settings", Short: "Get Cloud GCP Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsCloudGcpSettingsInput{} out, err := client.ListAdminIntegrationsCloudGcpSettings(cmd.Context(), in) if err != nil { @@ -1187,6 +1346,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1196,7 +1356,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Upsert Cloud GCP Settings", Long: "Request body (JSON) fields: displayName (string), gkeClusterOidcIssuerUrls (array), gkeServiceAccountUniqueId (string), projects (array), workloadIdentityProvider (string, required), workloadIdentityServiceAccountEmail (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudGcpSettingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1238,6 +1402,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1249,7 +1414,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Validate GCP Credentials", Long: "Request body (JSON) fields: projectIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudGcpValidateInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1291,6 +1460,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1302,7 +1472,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Whitelist K8s Connector Accounts", Long: "Request body (JSON) fields: accountIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsCloudK8sWhitelistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1344,6 +1518,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1354,7 +1529,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-app-settings", Short: "Get GitHub App Settings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsGithubAppSettingsInput{} out, err := client.ListAdminIntegrationsGithubAppSettings(cmd.Context(), in) if err != nil { @@ -1367,6 +1546,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1375,7 +1555,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-jenkins", Short: "Delete Jenkins Integration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminIntegrationsJenkinsInput{} out, err := client.DeleteAdminIntegrationsJenkins(cmd.Context(), in) if err != nil { @@ -1388,6 +1572,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1396,7 +1581,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-jenkins", Short: "Get Jenkins Integration Status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsJenkinsInput{} out, err := client.ListAdminIntegrationsJenkins(cmd.Context(), in) if err != nil { @@ -1409,6 +1598,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1418,7 +1608,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Set Jenkins API Token", Long: "Request body (JSON) fields: apiToken (string, required), url (string, required), username (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsJenkinsTokenInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1460,6 +1654,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1470,7 +1665,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-jira", Short: "Get Jira Configuration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsJiraInput{} out, err := client.ListAdminIntegrationsJira(cmd.Context(), in) if err != nil { @@ -1483,6 +1682,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1492,7 +1692,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Update Jira Configuration", Long: "Request body (JSON) fields: autoCreate (boolean, required), issueType (string, required), projectKey (string, required), severityThreshold (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsJiraInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1534,6 +1738,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1544,7 +1749,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-linear-install", Short: "Start Linear OAuth install", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsLinearInstallInput{} out, err := client.ListAdminIntegrationsLinearInstall(cmd.Context(), in) if err != nil { @@ -1557,6 +1766,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1565,7 +1775,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-oauth", Short: "Get Linear OAuth install status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsLinearOauthInput{} out, err := client.ListAdminIntegrationsLinearOauth(cmd.Context(), in) if err != nil { @@ -1578,6 +1792,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1586,7 +1801,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-notifications", Short: "Get Notification Config", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsNotificationsInput{} out, err := client.ListAdminIntegrationsNotifications(cmd.Context(), in) if err != nil { @@ -1599,6 +1818,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1608,7 +1828,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Put Notification Config", Long: "Request body (JSON) fields: notifications (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateAdminIntegrationsNotificationsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1650,6 +1874,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1660,7 +1885,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-slack", Short: "Get Slack Configuration", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsSlackInput{} out, err := client.ListAdminIntegrationsSlack(cmd.Context(), in) if err != nil { @@ -1673,6 +1902,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1681,7 +1911,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-slack-install", Short: "Start Slack distributed install", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsSlackInstallInput{} out, err := client.ListAdminIntegrationsSlackInstall(cmd.Context(), in) if err != nil { @@ -1694,6 +1928,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1703,7 +1938,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Set Slack API Key", Long: "Request body (JSON) fields: apiKey (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminIntegrationsSlackKeyInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1745,6 +1984,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1755,7 +1995,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-teams", Short: "Get Integration Teams", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsTeamsInput{} if v, _ := cmd.Flags().GetString("provider"); v != "" { x := string(v) @@ -1772,6 +2016,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("provider", "", "The integration provider to query teams from") serviceCmd.AddCommand(cmd) } @@ -1781,7 +2026,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-integrations-users", Short: "Get Integration Users", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminIntegrationsUsersInput{} if v, _ := cmd.Flags().GetString("provider"); v != "" { x := string(v) @@ -1798,6 +2047,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("provider", "", "The integration provider to query users from") serviceCmd.AddCommand(cmd) } @@ -1808,7 +2058,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Findings Metrics", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminMetricsFindingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1850,6 +2104,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1860,7 +2115,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-interactions", Short: "Get Interactions", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminMetricsInteractionsInput{} out, err := client.ListAdminMetricsInteractions(cmd.Context(), in) if err != nil { @@ -1873,6 +2132,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1882,7 +2142,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Metrics Over Time", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminMetricsOverTimeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1928,6 +2192,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("resolution", "", "Time granularity for metrics aggregation (hour, day, week)") cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") @@ -1940,7 +2205,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Query Overview", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminMetricsOverviewInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1982,6 +2251,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1993,7 +2263,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Query Raw Metrics", Long: "Request body (JSON) fields: query (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminMetricsRawInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2035,6 +2309,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2045,7 +2320,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-aggregate", Short: "Usage Aggregate", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminMetricsUsageAggregateInput{} if v, _ := cmd.Flags().GetString("agent"); v != "" { x := string(v) @@ -2082,6 +2361,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("agent", "", "") cmd.Flags().String("branch-type", "", "") cmd.Flags().String("class", "", "") @@ -2096,7 +2376,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-ledger", Short: "Usage Ledger", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminMetricsUsageLedgerInput{} if v, _ := cmd.Flags().GetString("agent"); v != "" { x := string(v) @@ -2150,6 +2434,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("agent", "", "") cmd.Flags().String("branch-type", "", "") cmd.Flags().String("class", "", "") @@ -2167,7 +2452,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-timeseries", Short: "Usage Timeseries", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminMetricsUsageTimeseriesInput{} if v, _ := cmd.Flags().GetString("agent"); v != "" { x := string(v) @@ -2200,6 +2489,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("agent", "", "") cmd.Flags().String("class", "", "") cmd.Flags().String("from", "", "") @@ -2213,7 +2503,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-organization", Short: "Get Organization", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminOrganizationInput{} out, err := client.ListAdminOrganization(cmd.Context(), in) if err != nil { @@ -2226,6 +2520,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2234,7 +2529,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-acknowledgment", Short: "Get Privacy Acknowledgment", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminPrivacyAcknowledgmentInput{} if v, _ := cmd.Flags().GetString("policy-version"); v != "" { x := string(v) @@ -2251,6 +2550,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("policy-version", "", "The version of the privacy policy to check") serviceCmd.AddCommand(cmd) } @@ -2261,7 +2561,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Privacy Acknowledgment", Long: "Request body (JSON) fields: policyVersion (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminPrivacyAcknowledgmentInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2303,6 +2607,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2313,7 +2618,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-repositories", Short: "Get Repositories", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminRepositoriesInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -2347,6 +2656,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Maximum number of repositories to return per page") cmd.Flags().String("next-token", "", "Pagination token for the next page of results") cmd.Flags().String("search", "", "Case-insensitive search filter for repository names") @@ -2360,7 +2670,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Initialize Repositories", Long: "Request body (JSON) fields: repositories (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminRepositoriesInitializeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2402,6 +2716,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2413,7 +2728,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Uninitialize Repositories", Long: "Request body (JSON) fields: repositories (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminRepositoriesUninitializeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2455,6 +2774,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2465,7 +2785,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-repository-property-team-keys", Short: "Delete Repository Property Team Key", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminRepositoryPropertyTeamKeysInput{} if v, _ := cmd.Flags().GetString("key-id"); v != "" { x := string(v) @@ -2482,6 +2806,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("key-id", "", "The repository property team key ID") serviceCmd.AddCommand(cmd) } @@ -2491,7 +2816,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-repository-property-team-keys", Short: "List Repository Property Team Keys", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminRepositoryPropertyTeamKeysInput{} out, err := client.ListAdminRepositoryPropertyTeamKeys(cmd.Context(), in) if err != nil { @@ -2504,6 +2833,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2513,7 +2843,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Create Repository Property Team Key", Long: "Request body (JSON) fields: propertyKey (string, required), providerId (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminRepositoryPropertyTeamKeysInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2555,6 +2889,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2565,7 +2900,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "delete-service_accounts", Short: "Delete Service Account", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminServiceAccountsInput{} if v, _ := cmd.Flags().GetString("service-account-id"); v != "" { x := string(v) @@ -2582,6 +2921,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("service-account-id", "", "The service account ID") serviceCmd.AddCommand(cmd) } @@ -2591,7 +2931,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-service_accounts", Short: "Get Service Accounts", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminServiceAccountsInput{} out, err := client.ListAdminServiceAccounts(cmd.Context(), in) if err != nil { @@ -2604,6 +2948,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2613,7 +2958,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Create Service Account", Long: "Request body (JSON) fields: name (string, required), platform (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminServiceAccountsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2655,6 +3004,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2665,7 +3015,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-sla", Short: "Get SLAs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminSlaInput{} out, err := client.ListAdminSla(cmd.Context(), in) if err != nil { @@ -2678,6 +3032,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2687,7 +3042,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post SLA", Long: "Request body (JSON) fields: allowExtensions (boolean, required), maxDaysToFix (integer, required), priority (object, required), severity (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminSlaInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2729,6 +3088,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2740,7 +3100,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Put Bulk SLA", Long: "Request body (JSON) fields: slas (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateAdminSlaBulkInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2782,6 +3146,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2794,7 +3159,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Long: "Request body (JSON) fields: allowExtensions (boolean), maxDaysToFix (integer), priority (object), severity (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchAdminSlaSlaIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2837,6 +3206,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2847,7 +3217,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-team-source-preferences", Short: "Get Team Source Preferences", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamSourcePreferencesInput{} out, err := client.ListAdminTeamSourcePreferences(cmd.Context(), in) if err != nil { @@ -2860,6 +3234,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2869,7 +3244,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Update Team Source Preferences", Long: "Request body (JSON) fields: githubTeamsEnabled (boolean, required), repositoryPropertyEnabled (boolean, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateAdminTeamSourcePreferencesInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2911,6 +3290,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2921,7 +3301,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-team-sync-runs", Short: "List Team Sync Runs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamSyncRunsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -2946,6 +3330,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("source", "", "") serviceCmd.AddCommand(cmd) @@ -2957,7 +3342,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Trigger Team Sync", Long: "Request body (JSON) fields: source (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamSyncRunsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2999,6 +3388,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3010,7 +3400,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Team", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetAdminTeamTeamIDInput{} in.TeamID = args[0] out, err := client.GetAdminTeamTeamID(cmd.Context(), in) @@ -3024,6 +3418,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3032,7 +3427,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-teams", Short: "Get All Teams", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -3061,6 +3460,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Maximum number of teams to return per page") cmd.Flags().String("next-token", "", "Pagination token for the next page of results") cmd.Flags().String("search", "", "Case-insensitive search filter for team names") @@ -3073,7 +3473,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Team", Long: "Request body (JSON) fields: codeOwnerships (array), github (object), gitlab (object), groundRules (array), jira (object), leadId (string), memberIds (array), messageChannelProvider (object, required), name (string, required), privacy (object, required), slug (string, required), ticketProjectProvider (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3115,6 +3519,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3125,7 +3530,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-appzip", Short: "Get Teams App Zip", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamsAppzipInput{} out, err := client.ListAdminTeamsAppzip(cmd.Context(), in) if err != nil { @@ -3138,6 +3547,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3147,7 +3557,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Compass/Atlassian Team", Long: "Request body (JSON) fields: displayName (string, required), lead (string, required), members (array, required), providerId (object), repositories (array, required), teamKey (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsCompassInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3189,6 +3603,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3199,7 +3614,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-teams-findings", Short: "Get All Team Findings mapping", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamsFindingsInput{} out, err := client.ListAdminTeamsFindings(cmd.Context(), in) if err != nil { @@ -3212,6 +3631,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3221,7 +3641,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Manual Team Findings Assignment", Long: "Request body (JSON) fields: mappings (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsFindingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3263,6 +3687,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3274,7 +3699,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Sync Team Findings", Long: "Request body (JSON) fields: async (boolean), findingIds (array), findingTypes (array), repositoryIds (array), repositoryNames (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsFindingsSyncInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3316,6 +3745,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3327,7 +3757,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Merge Teams", Long: "Request body (JSON) fields: sources (array, required), targetTeamId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsMergeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3369,6 +3803,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3380,7 +3815,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Delete Manual Team", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminTeamsTeamIDInput{} in.TeamID = args[0] out, err := client.DeleteAdminTeamsTeamID(cmd.Context(), in) @@ -3394,6 +3833,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3404,7 +3844,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Long: "Request body (JSON) fields: codeOwnerships (array), github (object), gitlab (object), groundRules (array), jira (object), leadId (string), memberIds (array), messageChannelProvider (object), name (string), privacy (object), slug (string), ticketProjectProvider (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchAdminTeamsTeamIDInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3447,6 +3891,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3459,7 +3904,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Long: "Request body (JSON) fields: afterId (string), afterTimeUnix (integer), autofixId (string), beforeTimeUnix (integer), campaignId (string), eventTypes (array), findingIds (array), limit (integer), prCanonicalId (string), runId (string), services (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminTeamsTeamIDEventsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3502,6 +3951,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3513,7 +3963,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Team Findings mapping", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminTeamsTeamIDFindingsInput{} in.TeamID = args[0] out, err := client.ListAdminTeamsTeamIDFindings(cmd.Context(), in) @@ -3527,6 +3981,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3535,7 +3990,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-savedViews", Short: "Get UI Saved Views", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUiSavedViewsInput{} out, err := client.ListAdminUiSavedViews(cmd.Context(), in) if err != nil { @@ -3548,6 +4007,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3557,7 +4017,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post UI Saved View", Long: "Request body (JSON) fields: savedView (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminUiSavedViewsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3599,6 +4063,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3610,7 +4075,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Delete UI Saved View", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminUiSavedViewsSavedViewIdInput{} in.SavedViewID = args[0] out, err := client.DeleteAdminUiSavedViewsSavedViewId(cmd.Context(), in) @@ -3624,6 +4093,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3634,7 +4104,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Long: "Request body (JSON) fields: savedView (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchAdminUiSavedViewsSavedViewIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3677,6 +4151,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3687,7 +4162,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-current", Short: "Get Current User", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUserCurrentInput{} out, err := client.ListAdminUserCurrent(cmd.Context(), in) if err != nil { @@ -3700,6 +4179,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3708,7 +4188,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-mapping", Short: "Get User Mapping", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUserMappingInput{} if v, _ := cmd.Flags().GetString("provider-id"); v != "" { x := string(v) @@ -3729,6 +4213,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("provider-id", "", "") cmd.Flags().String("user-id", "", "") serviceCmd.AddCommand(cmd) @@ -3740,7 +4225,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Add User Mappings", Long: "Request body (JSON) fields: useSuggestions (boolean, required), userMappings (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminUserMappingInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3782,6 +4271,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3792,7 +4282,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-suggestions", Short: "Get User Mapping Suggestions", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUserMappingSuggestionsInput{} out, err := client.ListAdminUserMappingSuggestions(cmd.Context(), in) if err != nil { @@ -3805,6 +4299,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3814,7 +4309,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Delete User Mapping", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminUserMappingUserIdInput{} in.UserID = args[0] data, err := client.DeleteAdminUserMappingUserId(cmd.Context(), in) @@ -3824,6 +4323,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3834,7 +4334,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Long: "Request body (JSON) fields: azure (object), bitbucket (object), github (object), gitlab (object), jira (object), linear (object), slack (object), teams (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateAdminUserMappingUserIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3873,6 +4377,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3883,7 +4388,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-mappings", Short: "Get User Mappings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUserMappingsInput{} out, err := client.ListAdminUserMappings(cmd.Context(), in) if err != nil { @@ -3896,6 +4405,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3905,7 +4415,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get User", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetAdminUserUserIDInput{} in.UserID = args[0] out, err := client.GetAdminUserUserID(cmd.Context(), in) @@ -3919,6 +4433,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3927,7 +4442,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Use: "list-users", Short: "Get All Users", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUsersInput{} out, err := client.ListAdminUsers(cmd.Context(), in) if err != nil { @@ -3940,6 +4459,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3949,7 +4469,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post User", Long: "Request body (JSON) fields: user (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminUsersInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3991,6 +4515,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -4002,7 +4527,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Post Bulk Get User Mappings", Long: "Request body (JSON) fields: gitCanonicalUserIds (array), githubCanonicalUserIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateAdminUsersBulkSearchMappingsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -4044,6 +4573,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -4055,7 +4585,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get Provider Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetAdminUsersProviderIDInput{} in.ProviderID = args[0] out, err := client.GetAdminUsersProviderID(cmd.Context(), in) @@ -4069,6 +4603,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -4078,7 +4613,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get User By Provider", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetAdminUsersProviderIDUserIDInput{} in.ProviderID = args[0] in.UserID = args[1] @@ -4093,6 +4632,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -4102,7 +4642,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Delete User Erasure (GDPR Art. 17)", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteAdminUsersUserIdErasureInput{} in.UserID = args[0] out, err := client.DeleteAdminUsersUserIdErasure(cmd.Context(), in) @@ -4116,6 +4660,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -4125,7 +4670,11 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) Short: "Get User Data Export (GDPR Art. 15, 20)", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAdminUsersUserIdExportInput{} in.UserID = args[0] if v, _ := cmd.Flags().GetString("format"); v != "" { @@ -4143,6 +4692,7 @@ func RegisterAdminCommands(parent *cobra.Command, getClient func() *api.Client) return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("format", "", "Export format (json)") serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/asset-graph.go b/internal/commands/asset-graph.go index a741d24..a5e9de1 100644 --- a/internal/commands/asset-graph.go +++ b/internal/commands/asset-graph.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterAssetGraphCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "asset-graph", Short: "Asset Graph (reachability, search, subgraph, summary)", @@ -33,7 +33,11 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli Use: "list-reachability", Short: "Get Asset Graph Reachability", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAssetGraphReachabilityInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -54,6 +58,7 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "") cmd.Flags().String("node-id", "", "") serviceCmd.AddCommand(cmd) @@ -64,7 +69,11 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli Use: "list-search", Short: "Search Asset Graph", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAssetGraphSearchInput{} if v, _ := cmd.Flags().GetString("max-results"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -94,6 +103,7 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("max-results", "", "") cmd.Flags().String("object-types", "", "") cmd.Flags().String("q", "", "") @@ -105,7 +115,11 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli Use: "list-subgraph", Short: "Get Asset Graph Subgraph", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAssetGraphSubgraphInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -147,6 +161,7 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "") cmd.Flags().String("depth", "", "") cmd.Flags().String("max-nodes", "", "") @@ -160,7 +175,11 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli Use: "list-summary", Short: "Get Asset Graph Summary", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListAssetGraphSummaryInput{} out, err := client.ListAssetGraphSummary(cmd.Context(), in) if err != nil { @@ -173,6 +192,7 @@ func RegisterAssetGraphCommands(parent *cobra.Command, getClient func() *api.Cli return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/behavior.go b/internal/commands/behavior.go new file mode 100644 index 0000000..1966066 --- /dev/null +++ b/internal/commands/behavior.go @@ -0,0 +1,17 @@ +package commands + +import "github.com/spf13/cobra" + +const preserveRuntimeUsageAnnotation = "nullify.preserve-runtime-usage" + +func preserveRuntimeUsage(cmd *cobra.Command) { + if cmd.Annotations == nil { + cmd.Annotations = make(map[string]string) + } + cmd.Annotations[preserveRuntimeUsageAnnotation] = "true" +} + +// PreservesRuntimeUsage reports whether runtime errors should include usage. +func PreservesRuntimeUsage(cmd *cobra.Command) bool { + return cmd.Annotations[preserveRuntimeUsageAnnotation] == "true" +} diff --git a/internal/commands/bughunt_bridge.go b/internal/commands/bughunt_bridge.go index 669750f..de6d181 100644 --- a/internal/commands/bughunt_bridge.go +++ b/internal/commands/bughunt_bridge.go @@ -3,13 +3,12 @@ package commands import ( "strings" - "github.com/nullify-platform/cli/internal/api" "github.com/spf13/cobra" ) // RegisterBughuntSubcommands adds generated DAST API subcommands that relate to // bughunt functionality to the handwritten bughunt command. -func RegisterBughuntSubcommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterBughuntSubcommands(parent *cobra.Command, getClient ClientFactory) { tmp := &cobra.Command{Use: "tmp"} RegisterDastCommands(tmp, getClient) diff --git a/internal/commands/client_factory.go b/internal/commands/client_factory.go new file mode 100644 index 0000000..f414a6e --- /dev/null +++ b/internal/commands/client_factory.go @@ -0,0 +1,10 @@ +package commands + +import ( + "context" + + "github.com/nullify-platform/cli/internal/api" +) + +// ClientFactory creates an authenticated API client for a command context. +type ClientFactory func(context.Context) (*api.Client, error) diff --git a/internal/commands/context.go b/internal/commands/context.go index df3143e..d1d3ce6 100644 --- a/internal/commands/context.go +++ b/internal/commands/context.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterContextCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "context", Short: "Repository and Code Classification", @@ -33,7 +33,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-applications", Short: "Get Applications", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextApplicationsInput{} out, err := client.ListContextApplications(cmd.Context(), in) if err != nil { @@ -46,6 +50,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -55,7 +60,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Create Application", Long: "Request body (JSON) fields: application (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextApplicationsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -97,6 +106,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -108,7 +118,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Rebuild Applications", Long: "Request body (JSON) fields: force (boolean, required), providerOwnerId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextApplicationsRebuildInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -150,6 +164,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -161,7 +176,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Application", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextApplicationsApplicationIdInput{} in.ApplicationID = args[0] out, err := client.DeleteContextApplicationsApplicationId(cmd.Context(), in) @@ -175,6 +194,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -184,7 +204,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Application", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextApplicationsApplicationIdInput{} in.ApplicationID = args[0] out, err := client.GetContextApplicationsApplicationId(cmd.Context(), in) @@ -198,6 +222,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -208,7 +233,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: application (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextApplicationsApplicationIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -251,6 +280,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -262,7 +292,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Application Schema", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextApplicationsApplicationIdSchemaInput{} in.ApplicationID = args[0] out, err := client.ListContextApplicationsApplicationIdSchema(cmd.Context(), in) @@ -276,6 +310,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -284,7 +319,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-artifact-deployments", Short: "List Artifact Deployments", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextArtifactDeploymentsInput{} if v, _ := cmd.Flags().GetString("artifact-id"); v != "" { x := string(v) @@ -329,6 +368,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("artifact-id", "", "") cmd.Flags().String("cloud-resource-id", "", "") cmd.Flags().String("compute-type", "", "") @@ -345,7 +385,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Artifact Deployment", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextArtifactDeploymentsDeploymentIdInput{} in.DeploymentID = args[0] out, err := client.GetContextArtifactDeploymentsDeploymentId(cmd.Context(), in) @@ -359,6 +403,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -367,7 +412,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-artifacts", Short: "List Artifacts", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextArtifactsInput{} if v, _ := cmd.Flags().GetString("include-deleted"); v != "" { b := v == "true" @@ -408,6 +457,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("include-deleted", "", "") cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") @@ -423,7 +473,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Artifact", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextArtifactsArtifactIdInput{} in.ArtifactID = args[0] out, err := client.DeleteContextArtifactsArtifactId(cmd.Context(), in) @@ -437,6 +491,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -446,7 +501,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Artifact", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextArtifactsArtifactIdInput{} in.ArtifactID = args[0] out, err := client.GetContextArtifactsArtifactId(cmd.Context(), in) @@ -460,6 +519,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -468,7 +528,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-cloud-accounts", Short: "Get Asset Inventory Cloud Accounts", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextAssetInventoryCloudAccountsInput{} if v, _ := cmd.Flags().GetString("active"); v != "" { b := v == "true" @@ -501,6 +565,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("active", "", "") cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") @@ -513,7 +578,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-cloud-resources", Short: "Get Asset Inventory Cloud Resources", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextAssetInventoryCloudResourcesInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -558,6 +627,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "") cmd.Flags().String("active", "", "") cmd.Flags().String("category", "", "") @@ -573,7 +643,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-public-facing", Short: "Get Public Facing Assets", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextAssetInventoryPublicFacingInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -606,6 +680,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "") cmd.Flags().String("cloud-provider", "", "") cmd.Flags().String("limit", "", "") @@ -618,7 +693,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-resources", Short: "Get Asset Inventory Resources", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextAssetInventoryResourcesInput{} if v, _ := cmd.Flags().GetString("active"); v != "" { b := v == "true" @@ -655,6 +734,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("active", "", "") cmd.Flags().String("category", "", "") cmd.Flags().String("limit", "", "") @@ -668,7 +748,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-cicd-pipelines", Short: "List CI/CD Pipelines", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCicdPipelinesInput{} if v, _ := cmd.Flags().GetString("include-deleted"); v != "" { b := v == "true" @@ -709,6 +793,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("include-deleted", "", "") cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") @@ -724,7 +809,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete CI/CD Pipeline", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextCicdPipelinesPipelineIdInput{} in.PipelineID = args[0] out, err := client.DeleteContextCicdPipelinesPipelineId(cmd.Context(), in) @@ -738,6 +827,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -747,7 +837,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get CI/CD Pipeline", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextCicdPipelinesPipelineIdInput{} in.PipelineID = args[0] out, err := client.GetContextCicdPipelinesPipelineId(cmd.Context(), in) @@ -761,6 +855,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -770,7 +865,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Cloud Recon Discovered Nodes", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCloudReconAccountsAccountIdDiscoveredNodesInput{} in.AccountID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -808,6 +907,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("object-type", "", "") cmd.Flags().String("offset", "", "") @@ -821,7 +921,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Cloud Recon Hotspots", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCloudReconAccountsAccountIdHotspotsInput{} in.AccountID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -855,6 +959,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("offset", "", "") cmd.Flags().String("severity", "", "") @@ -867,7 +972,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Latest Cloud Recon Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCloudReconAccountsAccountIdScansLatestInput{} in.AccountID = args[0] out, err := client.ListContextCloudReconAccountsAccountIdScansLatest(cmd.Context(), in) @@ -881,6 +990,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -890,7 +1000,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Persist Cloud Recon Scan", Long: "Request body (JSON) fields: accountId (string, required), completedAt (string), modelName (string), payload (string, required), provider (string, required), scanId (string), schemaVersion (string, required), startedAt (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextCloudReconScansInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -932,6 +1046,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -942,7 +1057,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-cross-account-trusts", Short: "Get Tenant Cloud Recon Cross-Account Trusts", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCloudReconTenantsCrossAccountTrustsInput{} out, err := client.ListContextCloudReconTenantsCrossAccountTrusts(cmd.Context(), in) if err != nil { @@ -955,6 +1074,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -963,7 +1083,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "create-start", Short: "Start Cloud Scan", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextCloudScanStartInput{} out, err := client.CreateContextCloudScanStart(cmd.Context(), in) if err != nil { @@ -976,6 +1100,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -985,7 +1110,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Cloud Scan Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextCloudScanScanIdStatusInput{} in.ScanID = args[0] out, err := client.ListContextCloudScanScanIdStatus(cmd.Context(), in) @@ -999,6 +1128,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1007,7 +1137,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "delete-deps", Short: "Delete dependency data", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextDepsInput{} if v, _ := cmd.Flags().GetString("ecosystem"); v != "" { x := string(v) @@ -1048,6 +1182,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("global", "", "") cmd.Flags().String("introduced-at", "", "") @@ -1063,7 +1198,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-deps", Short: "List Tenant Wide Dependencies (Historical)", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsInput{} if v, _ := cmd.Flags().GetString("cursor"); v != "" { x := string(v) @@ -1088,6 +1227,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("cursor", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1098,7 +1238,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-active", Short: "List Tenant Wide Active Dependencies", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsActiveInput{} if v, _ := cmd.Flags().GetString("cursor"); v != "" { x := string(v) @@ -1151,6 +1295,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("cursor", "", "") cmd.Flags().String("direct", "", "") cmd.Flags().String("ecosystem", "", "") @@ -1168,7 +1313,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-summary", Short: "Tenant Wide Active Dependency Summary", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsActiveSummaryInput{} if v, _ := cmd.Flags().GetString("direct"); v != "" { b := v == "true" @@ -1209,6 +1358,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("direct", "", "") cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("name", "", "") @@ -1225,7 +1375,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Dependencies by Bom Ref", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsByRefBomRefInput{} in.BomRef = args[0] if v, _ := cmd.Flags().GetString("cursor"); v != "" { @@ -1251,6 +1405,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("cursor", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1262,7 +1417,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "List Dependents of a Bom Ref", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsDependentsBomRefInput{} in.BomRef = args[0] if v, _ := cmd.Flags().GetString("cursor"); v != "" { @@ -1288,6 +1447,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("cursor", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1298,7 +1458,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-exposure", Short: "Global package exposure by version filter (semver or hash)", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsExposureInput{} if v, _ := cmd.Flags().GetString("ecosystem"); v != "" { x := string(v) @@ -1323,6 +1487,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("name", "", "") cmd.Flags().String("range", "", "") @@ -1335,7 +1500,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "List Active Dependencies", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsRepositoryRepositoryIdProjectProjectIdActiveInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -1362,6 +1531,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("direct", "", "") cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("search", "", "") @@ -1374,7 +1544,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Dependencies at commit", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsRepositoryRepositoryIdProjectProjectIdAtCommitInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -1390,6 +1564,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1399,7 +1574,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Dependency diff between two commits", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsRepositoryRepositoryIdProjectProjectIdDiffInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -1422,6 +1601,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("from-commit", "", "") cmd.Flags().String("to-commit", "", "") serviceCmd.AddCommand(cmd) @@ -1433,7 +1613,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Project package exposure by version filter (semver or hash)", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsRepositoryRepositoryIdProjectProjectIdExposureInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -1460,6 +1644,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("name", "", "") cmd.Flags().String("range", "", "") @@ -1472,7 +1657,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Package exposure history (windows)", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsRepositoryRepositoryIdProjectProjectIdHistoryInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -1495,6 +1684,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ecosystem", "", "") cmd.Flags().String("name", "", "") serviceCmd.AddCommand(cmd) @@ -1505,7 +1695,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-without-lockfile", Short: "List projects/repos without lockfiles", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextDepsWithoutLockfileInput{} if v, _ := cmd.Flags().GetString("level"); v != "" { x := string(v) @@ -1522,6 +1716,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("level", "", "") serviceCmd.AddCommand(cmd) } @@ -1531,7 +1726,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-entrypoints", Short: "List Entrypoints", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextEntrypointsInput{} if v, _ := cmd.Flags().GetString("include-deleted"); v != "" { b := v == "true" @@ -1572,6 +1771,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("include-deleted", "", "") cmd.Flags().String("kind", "", "") cmd.Flags().String("limit", "", "") @@ -1587,7 +1787,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Entrypoint", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextEntrypointsEntrypointIdInput{} in.EntrypointID = args[0] out, err := client.DeleteContextEntrypointsEntrypointId(cmd.Context(), in) @@ -1601,6 +1805,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1610,7 +1815,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Entrypoint", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextEntrypointsEntrypointIdInput{} in.EntrypointID = args[0] out, err := client.GetContextEntrypointsEntrypointId(cmd.Context(), in) @@ -1624,6 +1833,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1632,7 +1842,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-memories", Short: "Get Memories", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextMemoriesInput{} if v, _ := cmd.Flags().GetString("is-latest"); v != "" { b := v == "true" @@ -1677,6 +1891,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("is-latest", "", "Filter for latest memories only") cmd.Flags().String("limit", "", "Maximum number of results (default: 50, max: 1000)") cmd.Flags().String("memory-type", "", "Filter by memory type") @@ -1693,7 +1908,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Create Memory", Long: "Request body (JSON) fields: citations (array), confidence (number), content (string, required), createdBy (string), crossReferences (array), isUserCreated (boolean), memoryType (object, required), metadata (object), parentNoteId (string), priority (object), resourceId (string), resourceType (object), tags (array), title (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextMemoriesInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1735,6 +1954,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1745,7 +1965,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-type", Short: "Get Memories By Type", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextMemoriesTypeInput{} if v, _ := cmd.Flags().GetString("is-latest"); v != "" { b := v == "true" @@ -1778,6 +2002,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("is-latest", "", "") cmd.Flags().String("limit", "", "") cmd.Flags().String("memory-type", "", "") @@ -1791,7 +2016,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Memory", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextMemoriesMemoryIdInput{} in.MemoryID = args[0] out, err := client.DeleteContextMemoriesMemoryId(cmd.Context(), in) @@ -1805,6 +2034,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1814,7 +2044,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Memory", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextMemoriesMemoryIdInput{} in.MemoryID = args[0] if v, _ := cmd.Flags().GetString("version"); v != "" { @@ -1832,6 +2066,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("version", "", "") serviceCmd.AddCommand(cmd) } @@ -1843,7 +2078,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: citations (array), confidence (number), content (string), createNewVersion (boolean), crossReferences (array), metadata (object), parentNoteId (string), priority (object), tags (array), title (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextMemoriesMemoryIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1886,6 +2125,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1897,7 +2137,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Memory Versions", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextMemoriesMemoryIdVersionsInput{} in.MemoryID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -1919,6 +2163,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Maximum number of versions to return (default: 50)") serviceCmd.AddCommand(cmd) } @@ -1928,7 +2173,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-organization", Short: "Get Organization Context", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextOrganizationInput{} out, err := client.ListContextOrganization(cmd.Context(), in) if err != nil { @@ -1941,6 +2190,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1950,7 +2200,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Update Classification of the Organization", Long: "Request body (JSON) fields: name (string), notes (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextOrganizationInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1988,6 +2242,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1999,7 +2254,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Upsert Classification of the Organization", Long: "Request body (JSON) fields: organization (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateContextOrganizationInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2041,6 +2300,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2051,7 +2311,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "create-resync", Short: "Resync RAG Vector Store", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextRagResyncInput{} out, err := client.CreateContextRagResync(cmd.Context(), in) if err != nil { @@ -2064,6 +2328,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2072,7 +2337,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-repo-scans", Short: "List Repo Context Scans", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepoScansInput{} if v, _ := cmd.Flags().GetString("commit-sha"); v != "" { x := string(v) @@ -2113,6 +2382,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("commit-sha", "", "") cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") @@ -2127,7 +2397,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Create Repo Context Scan", Long: "Request body (JSON) fields: branch (string), commitSha (string, required), projectsTouched (array), repositoryId (string, required), sbomsGenerated (array), status (string), subagentsRun (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextRepoScansInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2169,6 +2443,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2180,7 +2455,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Repo Context Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextRepoScansScanIdInput{} in.ScanID = args[0] out, err := client.GetContextRepoScansScanId(cmd.Context(), in) @@ -2194,6 +2473,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2204,7 +2484,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: completedAt (string), errorMessage (string), projectsTouched (array), sbomsGenerated (array), status (string), subagentsRun (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextRepoScansScanIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2247,6 +2531,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2258,7 +2543,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Create Report Generation Job", Long: "Request body (JSON) fields: packages (array, required), repositories (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextReportsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2300,6 +2589,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2311,7 +2601,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Report Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextReportsJobIdInput{} in.JobID = args[0] out, err := client.GetContextReportsJobId(cmd.Context(), in) @@ -2325,6 +2619,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2333,7 +2628,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-repositories", Short: "Get Contexts of Repositories", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepositoriesInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -2366,6 +2665,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") cmd.Flags().String("sort", "", "") @@ -2379,7 +2679,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Repository", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextRepositoriesRepositoryIdInput{} in.RepositoryID = args[0] out, err := client.DeleteContextRepositoriesRepositoryId(cmd.Context(), in) @@ -2393,6 +2697,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2402,7 +2707,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Repository", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextRepositoriesRepositoryIdInput{} in.RepositoryID = args[0] out, err := client.GetContextRepositoriesRepositoryId(cmd.Context(), in) @@ -2416,6 +2725,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2426,7 +2736,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: name (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextRepositoriesRepositoryIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2465,6 +2779,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2476,7 +2791,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "List Projects", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepositoriesRepositoryIdProjectsInput{} in.RepositoryID = args[0] if v, _ := cmd.Flags().GetString("include-deleted"); v != "" { @@ -2506,6 +2825,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("include-deleted", "", "") cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") @@ -2518,7 +2838,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Project", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextRepositoriesRepositoryIdProjectsProjectIdInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2533,6 +2857,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2542,7 +2867,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Project", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextRepositoriesRepositoryIdProjectsProjectIdInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2557,6 +2886,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2567,7 +2897,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: deletedAt (string), description (string), isDeleted (boolean), metadata (object), tags (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextRepositoriesRepositoryIdProjectsProjectIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2611,6 +2945,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2622,7 +2957,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Project Schema", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepositoriesRepositoryIdProjectsProjectIdSchemaInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2637,6 +2976,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2647,7 +2987,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: content (string, required), format (object, required), type (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextRepositoriesRepositoryIdProjectsProjectIdSchemaInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2691,6 +3035,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2702,7 +3047,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Project Schema Metadata", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepositoriesRepositoryIdProjectsProjectIdSchemaMetadataInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2717,6 +3066,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2726,7 +3076,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Project Schema Raw File", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextRepositoriesRepositoryIdProjectsProjectIdSchemaRawInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2741,6 +3095,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2750,7 +3105,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Compute Dependencies Repository/Project SBOM Ingest Replay", Long: "Request body (JSON) fields: globalReplay (boolean), projectID (string), repositoryID (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextSbomingestorReplayInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2792,6 +3151,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2802,7 +3162,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "delete-sboms", Short: "Delete SBOMs for tenant", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextSbomsInput{} if v, _ := cmd.Flags().GetString("dry-run"); v != "" { b := v == "true" @@ -2831,6 +3195,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("dry-run", "", "") cmd.Flags().String("invalid-only", "", "") cmd.Flags().String("project-id", "", "") @@ -2844,7 +3209,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Generate SBOM", Long: "Request body (JSON) fields: cloneUrl (string), commitSha (string), defaultBranch (string), repositoryId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextSbomsGenerateInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2886,6 +3255,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -2897,7 +3267,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Latest SBOMs for Repository", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextSbomsRepositoryRepositoryIdLatestInput{} in.RepositoryID = args[0] out, err := client.ListContextSbomsRepositoryRepositoryIdLatest(cmd.Context(), in) @@ -2911,6 +3285,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -2920,7 +3295,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Repository/Project SBOMs", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextSbomsRepositoryRepositoryIdProjectProjectIdInput{} in.RepositoryID = args[0] in.ProjectID = args[1] @@ -2967,6 +3346,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("from-commit", "", "") cmd.Flags().String("from-time", "", "") cmd.Flags().String("page", "", "") @@ -2982,7 +3362,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get or generate SBOM", Long: "Request body (JSON) fields: branch (string), cdxgenMajor (integer), cloneURL (string), commitSHA (string), isDefaultBranchPush (boolean), lockfileSetHash (string), ownerProvider (object), repositoryID (string), repositoryProvider (object), scannerVersion (string), tenantID (string), timestamp (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextSbomsResolveInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3024,6 +3408,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3035,7 +3420,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Scan SBOM (get-or-generate)", Long: "Request body (JSON) fields: commitSha (string, required), forceRegenerate (boolean), projectId (string, required), repositoryId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextSbomsScanInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3077,6 +3466,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3087,7 +3477,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-tree", Short: "Get SBOM key tree for tenant", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextSbomsTreeInput{} if v, _ := cmd.Flags().GetString("verbose"); v != "" { b := v == "true" @@ -3104,6 +3498,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("verbose", "", "") serviceCmd.AddCommand(cmd) } @@ -3113,7 +3508,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-schemas", Short: "List Schemas", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextSchemasInput{} out, err := client.ListContextSchemas(cmd.Context(), in) if err != nil { @@ -3126,6 +3525,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3135,7 +3535,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Post Vault File", Long: "Request body (JSON) fields: description (string), fileName (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextVaultFileInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3177,6 +3581,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3188,7 +3593,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Vault File", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteContextVaultFileFileIdInput{} in.FileID = args[0] data, err := client.DeleteContextVaultFileFileId(cmd.Context(), in) @@ -3198,6 +3607,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3207,7 +3617,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Vault File", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetContextVaultFileFileIdInput{} in.FileID = args[0] out, err := client.GetContextVaultFileFileId(cmd.Context(), in) @@ -3221,6 +3635,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3231,7 +3646,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: documentId (string), metadata (object), processedAt (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchContextVaultFileFileNameInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3274,6 +3693,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -3284,7 +3704,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-files", Short: "Get Vault Files", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextVaultFilesInput{} out, err := client.ListContextVaultFiles(cmd.Context(), in) if err != nil { @@ -3297,6 +3721,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3305,7 +3730,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-list", Short: "Get Vault Files List", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListContextVaultFilesListInput{} out, err := client.ListContextVaultFilesList(cmd.Context(), in) if err != nil { @@ -3318,6 +3747,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -3327,7 +3757,11 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client Short: "Trigger Vault Onboarding", Long: "Request body (JSON) fields: fileIDs (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateContextVaultOnboardInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -3369,6 +3803,7 @@ func RegisterContextCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) diff --git a/internal/commands/context_defaults.go b/internal/commands/context_defaults.go index 13d2571..a18a5d1 100644 --- a/internal/commands/context_defaults.go +++ b/internal/commands/context_defaults.go @@ -10,7 +10,7 @@ import ( // ApplyContextCommandDefaults installs CLI-side opinionated defaults on top of // the generated 'context' subcommand tree. Must be called after // RegisterContextCommands. -func ApplyContextCommandDefaults(parent *cobra.Command, getClient func() *api.Client) { +func ApplyContextCommandDefaults(parent *cobra.Command, getClient ClientFactory) { contextCmd := findChild(parent, "context") if contextCmd == nil { return @@ -34,7 +34,17 @@ func ApplyContextCommandDefaults(parent *cobra.Command, getClient func() *api.Cl if contextGetProjectHasSelector(c) || len(args) < 2 { return orig(c, args) } - latest, err := latestCommitForProject(c, getClient(), args[0], args[1]) + client, err := getClient(c.Context()) + if err != nil { + c.SilenceUsage = true + return err + } + latest, err := latestCommitForProject( + c, + client, + args[0], + args[1], + ) if err != nil { return err } diff --git a/internal/commands/context_push.go b/internal/commands/context_push.go index 089d5a4..89e9afa 100644 --- a/internal/commands/context_push.go +++ b/internal/commands/context_push.go @@ -16,7 +16,7 @@ const maxUploadSize = 50 << 20 // 50 MB // RegisterContextPushCommand adds the 'push' subcommand to the existing 'context' command. // Must be called after RegisterContextCommands. -func RegisterContextPushCommand(parent *cobra.Command, getClient func() *api.Client) { +func RegisterContextPushCommand(parent *cobra.Command, getClient ClientFactory) { // Find the existing 'context' command registered by the generated code var contextCmd *cobra.Command for _, cmd := range parent.Commands() { @@ -120,7 +120,11 @@ func RegisterContextPushCommand(parent *cobra.Command, getClient func() *api.Cli return nil } - client := getClient() + client, err := getClient(ctx) + if err != nil { + cmd.SilenceUsage = true + return err + } logger.L(ctx).Info("requesting upload credentials", logger.String("repository", repo), @@ -164,6 +168,7 @@ func RegisterContextPushCommand(parent *cobra.Command, getClient func() *api.Cli return nil }, } + preserveRuntimeUsage(pushCmd) pushCmd.Flags().StringVar(&contextType, "type", "", "Context type (terraform, ci_logs, config, deploy, api_spec)") pushCmd.Flags().StringVar(&repository, "repository", "", "Repository in org/repo format (auto-detected if omitted)") diff --git a/internal/commands/cspm.go b/internal/commands/cspm.go index d983c7a..477039e 100644 --- a/internal/commands/cspm.go +++ b/internal/commands/cspm.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterCspmCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "cspm", Short: "Cloud Security Posture Management (CSPM)", @@ -33,7 +33,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-findings", Short: "Get CSPM Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmFindingsInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -90,6 +94,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "Filter by account ID") cmd.Flags().String("limit", "", "Maximum number of findings to return") cmd.Flags().String("next-token", "", "Token for pagination") @@ -109,7 +114,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetCspmFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetCspmFindingsFindingId(cmd.Context(), in) @@ -123,6 +132,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -132,7 +142,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -158,6 +172,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -169,7 +184,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Finding Autofix Diff", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmFindingsFindingIdAutofixCacheDiffInput{} in.FindingID = args[0] out, err := client.ListCspmFindingsFindingIdAutofixCacheDiff(cmd.Context(), in) @@ -183,6 +202,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -193,7 +213,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateCspmFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -236,6 +260,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -247,7 +272,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListCspmFindingsFindingIdAutofixState(cmd.Context(), in) @@ -261,6 +290,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -270,7 +300,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListCspmFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -284,6 +318,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -294,7 +329,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string), userCanonicalId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateCspmFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -337,6 +376,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -347,7 +387,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-scans", Short: "Get CSPM Scans", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListCspmScansInput{} if v, _ := cmd.Flags().GetString("account-id"); v != "" { x := string(v) @@ -388,6 +432,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("account-id", "", "Filter by account ID") cmd.Flags().String("limit", "", "Maximum number of scans to return") cmd.Flags().String("next-token", "", "Token for pagination") @@ -403,7 +448,11 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get CSPM Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetCspmScansScanIdInput{} in.ScanID = args[0] out, err := client.GetCspmScansScanId(cmd.Context(), in) @@ -417,6 +466,7 @@ func RegisterCspmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/dast.go b/internal/commands/dast.go index e2147e8..9d7fac5 100644 --- a/internal/commands/dast.go +++ b/internal/commands/dast.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterDastCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "dast", Short: "Dynamic Application Security Testing (DAST)", @@ -33,7 +33,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-config", Short: "Get BugHunt Config", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntConfigInput{} out, err := client.ListDastBughuntConfig(cmd.Context(), in) if err != nil { @@ -46,6 +50,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -55,7 +60,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Put BugHunt Config", Long: "Request body (JSON) fields: config (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateDastBughuntConfigInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -97,6 +106,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -108,7 +118,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Validate BugHunt Config", Long: "Request body (JSON) fields: config (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastBughuntConfigValidateInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -150,6 +164,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -160,7 +175,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-bughunt-findings", Short: "Get BugHunt Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntFindingsInput{} out, err := client.ListDastBughuntFindings(cmd.Context(), in) if err != nil { @@ -173,6 +192,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -182,7 +202,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastBughuntFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetDastBughuntFindingsFindingId(cmd.Context(), in) @@ -196,6 +220,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -206,7 +231,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allow (boolean, required), reason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchDastBughuntFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -249,6 +278,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -260,7 +290,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListDastBughuntFindingsFindingIdEvents(cmd.Context(), in) @@ -274,6 +308,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -283,7 +318,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Create Interactor []", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListDastBughuntFindingsFindingIdTriage(cmd.Context(), in) @@ -297,6 +336,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -305,7 +345,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-bughunt-scans", Short: "Get BugHunt Scans", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntScansInput{} out, err := client.ListDastBughuntScans(cmd.Context(), in) if err != nil { @@ -318,6 +362,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -327,7 +372,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Start BugHunt Scan", Long: "Request body (JSON) fields: intensity (object, required), scope (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastBughuntScansInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -369,6 +418,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -380,7 +430,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastBughuntScansScanIdInput{} in.ScanID = args[0] out, err := client.GetDastBughuntScansScanId(cmd.Context(), in) @@ -394,6 +448,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -403,7 +458,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Scan Diff", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntScansScanIdDiffInput{} in.ScanID = args[0] if v, _ := cmd.Flags().GetString("against"); v != "" { @@ -421,6 +480,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("against", "", "") serviceCmd.AddCommand(cmd) } @@ -431,7 +491,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Scan Findings", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntScansScanIdFindingsInput{} in.ScanID = args[0] out, err := client.ListDastBughuntScansScanIdFindings(cmd.Context(), in) @@ -445,6 +509,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -454,7 +519,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get BugHunt Sub-Agent Network Log", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntScansScanIdLogsInput{} in.ScanID = args[0] out, err := client.ListDastBughuntScansScanIdLogs(cmd.Context(), in) @@ -468,6 +537,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -477,7 +547,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Stop BugHunt Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastBughuntScansScanIdStopInput{} in.ScanID = args[0] out, err := client.CreateDastBughuntScansScanIdStop(cmd.Context(), in) @@ -491,6 +565,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -499,7 +574,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-suite-runs", Short: "Get BugHunt Suite Runs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastBughuntSuiteRunsInput{} out, err := client.ListDastBughuntSuiteRuns(cmd.Context(), in) if err != nil { @@ -512,6 +591,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -522,7 +602,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: intensity (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastBughuntSuitesSuiteRunNowInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -565,6 +649,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -575,7 +660,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-credentials", Short: "Get All Credentials", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastCredentialsInput{} out, err := client.ListDastCredentials(cmd.Context(), in) if err != nil { @@ -588,6 +677,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -597,7 +687,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Create Credential", Long: "Request body (JSON) fields: config (object, required), description (string, required), name (string, required), type (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastCredentialsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -639,6 +733,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -650,7 +745,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Delete Credential", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteDastCredentialsCredentialIdInput{} in.CredentialID = args[0] out, err := client.DeleteDastCredentialsCredentialId(cmd.Context(), in) @@ -664,6 +763,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -673,7 +773,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Credential", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastCredentialsCredentialIdInput{} in.CredentialID = args[0] out, err := client.GetDastCredentialsCredentialId(cmd.Context(), in) @@ -687,6 +791,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -697,7 +802,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: config (object, required), description (string, required), name (string, required), type (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateDastCredentialsCredentialIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -740,6 +849,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -751,7 +861,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Validate Credential", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastCredentialsCredentialIdValidateInput{} in.CredentialID = args[0] out, err := client.CreateDastCredentialsCredentialIdValidate(cmd.Context(), in) @@ -765,6 +879,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -773,7 +888,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-applications", Short: "Get Pentest App Configs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestApplicationsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -798,6 +917,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -809,7 +929,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Create Application", Long: "Request body (JSON) fields: credentialIds (array, required), id (string), targets (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestApplicationsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -851,6 +975,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -862,7 +987,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Delete Pentest App Config", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteDastPentestApplicationsApplicationIdInput{} in.ApplicationID = args[0] out, err := client.DeleteDastPentestApplicationsApplicationId(cmd.Context(), in) @@ -876,6 +1005,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -885,7 +1015,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest App Config", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastPentestApplicationsApplicationIdInput{} in.ApplicationID = args[0] out, err := client.GetDastPentestApplicationsApplicationId(cmd.Context(), in) @@ -899,6 +1033,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -909,7 +1044,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: credentialIds (array), targets (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.UpdateDastPentestApplicationsApplicationIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -952,6 +1091,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -964,7 +1104,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: triggeredByScan (boolean).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestApplicationsApplicationIdPreflightInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1007,6 +1151,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1018,7 +1163,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Latest Pentest Preflight for Application", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestApplicationsApplicationIdPreflightLatestInput{} in.ApplicationID = args[0] out, err := client.ListDastPentestApplicationsApplicationIdPreflightLatest(cmd.Context(), in) @@ -1032,6 +1181,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1041,7 +1191,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Preflight Quota", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestApplicationsApplicationIdPreflightQuotaInput{} in.ApplicationID = args[0] out, err := client.ListDastPentestApplicationsApplicationIdPreflightQuota(cmd.Context(), in) @@ -1055,6 +1209,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1063,7 +1218,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-pentest-findings", Short: "Get Pentest Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsInput{} if v, _ := cmd.Flags().GetString("is-allowlisted"); v != "" { b := v == "true" @@ -1120,6 +1279,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("is-allowlisted", "", "") cmd.Flags().String("is-false-positive", "", "") cmd.Flags().String("is-latest", "", "") @@ -1139,7 +1299,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastPentestFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetDastPentestFindingsFindingId(cmd.Context(), in) @@ -1153,6 +1317,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1163,7 +1328,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1202,6 +1371,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1213,7 +1383,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get DAST Pentest Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -1239,6 +1413,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -1250,7 +1425,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Finding Autofix Diff", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdAutofixCacheDiffInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdAutofixCacheDiff(cmd.Context(), in) @@ -1264,6 +1443,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1274,7 +1454,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1317,6 +1501,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1328,7 +1513,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get DAST Pentest Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdAutofixState(cmd.Context(), in) @@ -1342,6 +1531,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1351,7 +1541,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get DAST Pentest Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -1365,6 +1559,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1374,7 +1569,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdEvents(cmd.Context(), in) @@ -1388,6 +1587,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1397,7 +1597,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Finding Full", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdFullInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdFull(cmd.Context(), in) @@ -1411,6 +1615,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1421,7 +1626,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1464,6 +1673,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1475,7 +1685,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Finding Full", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListDastPentestFindingsFindingIdTriage(cmd.Context(), in) @@ -1489,6 +1703,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1499,7 +1714,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: unallowlistReason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1538,6 +1757,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1549,7 +1769,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Preflight", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastPentestPreflightsPreflightIdInput{} in.PreflightID = args[0] out, err := client.GetDastPentestPreflightsPreflightId(cmd.Context(), in) @@ -1563,6 +1787,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1572,7 +1797,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Preflight Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestPreflightsPreflightIdEventsInput{} in.PreflightID = args[0] if v, _ := cmd.Flags().GetString("after-seq"); v != "" { @@ -1602,6 +1831,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("after-seq", "", "") cmd.Flags().String("limit", "", "") serviceCmd.AddCommand(cmd) @@ -1612,7 +1842,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-pentest-scans", Short: "Get Pentest Scans", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1637,6 +1871,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -1648,7 +1883,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetDastPentestScansScanIdInput{} in.ScanID = args[0] out, err := client.GetDastPentestScansScanId(cmd.Context(), in) @@ -1662,6 +1901,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1671,7 +1911,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan Findings", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdFindingsInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdFindings(cmd.Context(), in) @@ -1685,6 +1929,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1694,7 +1939,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Auth Matrix Hypotheses", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdHypothesesInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdHypotheses(cmd.Context(), in) @@ -1708,6 +1957,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1717,7 +1967,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Sub-Agent Network Log", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdLogsInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdLogs(cmd.Context(), in) @@ -1731,6 +1985,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1740,7 +1995,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan Report", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdReportInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdReport(cmd.Context(), in) @@ -1754,6 +2013,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1763,7 +2023,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan Report Download URL", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdReportDownloadInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdReportDownload(cmd.Context(), in) @@ -1777,6 +2041,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1786,7 +2051,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan External Report PDF", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdReportExternalPdfInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdReportExternalPdf(cmd.Context(), in) @@ -1800,6 +2069,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1809,7 +2079,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Pentest Scan Report PDF", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastPentestScansScanIdReportPdfInput{} in.ScanID = args[0] out, err := client.ListDastPentestScansScanIdReportPdf(cmd.Context(), in) @@ -1823,6 +2097,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1832,7 +2107,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Stop Pentest Scan", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestScansScanIdStopInput{} in.ScanID = args[0] out, err := client.CreateDastPentestScansScanIdStop(cmd.Context(), in) @@ -1846,6 +2125,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1855,7 +2135,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Start Pentest Scan from Application", Long: "Request body (JSON) fields: applicationId (string, required), configOverrides (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateDastPentestStartInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1897,6 +2181,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1907,7 +2192,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-last", Short: "Get Pentest Last Scan Status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastScansStatusLastInput{} out, err := client.ListDastScansStatusLast(cmd.Context(), in) if err != nil { @@ -1920,6 +2209,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1928,7 +2218,11 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-sourceips", Short: "Get Source IPs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListDastSourceipsInput{} out, err := client.ListDastSourceips(cmd.Context(), in) if err != nil { @@ -1941,6 +2235,7 @@ func RegisterDastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/deps_analyze.go b/internal/commands/deps_analyze.go index 7a630af..488f7e3 100644 --- a/internal/commands/deps_analyze.go +++ b/internal/commands/deps_analyze.go @@ -15,7 +15,6 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "io" "net/http" @@ -36,7 +35,7 @@ import ( // transient/retry, 2 = invalid invocation) and add the deps-specific // severity codes 10/20/30. They live here rather than in the cmd package // because cmd imports commands — referencing the cmd constants would be -// an import cycle. main.go maps these onto os.Exit via ExitCodeFromError. +// an import cycle. const ( exitVulnerableFound = 10 exitSuspiciousFound = 20 @@ -82,7 +81,7 @@ var terminalStatuses = map[string]bool{ // even though the scpm calls aren't in the generated surface yet, // credentials and host come from the same source as every other // nullify command. -func RegisterDepsAnalyzeCommand(parent *cobra.Command, getClient func() *api.Client) { +func RegisterDepsAnalyzeCommand(parent *cobra.Command, getClient ClientFactory) { var depsCmd *cobra.Command for _, c := range parent.Commands() { if c.Name() == "deps" { @@ -137,7 +136,11 @@ Exit codes: SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() - return runDepsAnalyze(ctx, getClient(), depsAnalyzeOpts{ + client, err := getClient(ctx) + if err != nil { + return err + } + return runDepsAnalyze(ctx, client, depsAnalyzeOpts{ BaseRef: baseRef, HeadRef: headRef, RepoPath: repoPath, @@ -540,9 +543,6 @@ func short(sha string) string { return sha } -// exitErr wraps an error with an exit code so the top-level handler in -// main.go can translate it to os.Exit(N). Declared locally so this -// command doesn't drag in the cli's main-pkg exit-code wiring. type exitErr struct { Code int Msg string @@ -550,20 +550,8 @@ type exitErr struct { func (e exitErr) Error() string { return e.Msg } +func (e exitErr) ExitCode() int { return e.Code } + func exitError(code int, format string, args ...any) error { return exitErr{Code: code, Msg: fmt.Sprintf(format, args...)} } - -// ExitCodeFromError returns the exit code an exitErr wants, or -// exitTransientFailure (1) for any other non-nil error. main.go calls -// this to translate the workflow's result into a process exit code. -func ExitCodeFromError(err error) int { - if err == nil { - return 0 - } - var ee exitErr - if errors.As(err, &ee) { - return ee.Code - } - return exitTransientFailure -} diff --git a/internal/commands/deps_analyze_test.go b/internal/commands/deps_analyze_test.go index 3d0059e..9ae1f2e 100644 --- a/internal/commands/deps_analyze_test.go +++ b/internal/commands/deps_analyze_test.go @@ -46,8 +46,8 @@ func TestCheckFailOn(t *testing.T) { if (err != nil) != c.wantErr { t.Fatalf("checkFailOn(%q, %q) err = %v, wantErr %v", c.failOn, c.verdict, err, c.wantErr) } - if c.wantErr && ExitCodeFromError(err) != c.wantExit { - t.Errorf("exit code = %d, want %d", ExitCodeFromError(err), c.wantExit) + if c.wantErr { + assertExitCode(t, err, c.wantExit) } }) } @@ -68,20 +68,22 @@ func TestClassifyVerdict_UnknownFailsClosed(t *testing.T) { if err := checkFailOn("none", worst); err != nil { t.Errorf("unknown verdict should NOT fail --fail-on=none, got %v", err) } - if ExitCodeFromError(checkFailOn("malicious", worst)) != exitMaliciousFound { - t.Error("unknown verdict should exit with malicious code") - } + assertExitCode( + t, + checkFailOn("malicious", worst), + exitMaliciousFound, + ) } -func TestExitCodeFromError(t *testing.T) { - if got := ExitCodeFromError(nil); got != 0 { - t.Errorf("nil → %d, want 0", got) - } - if got := ExitCodeFromError(exitError(exitMaliciousFound, "boom")); got != exitMaliciousFound { - t.Errorf("exitErr → %d, want %d", got, exitMaliciousFound) +func assertExitCode(t *testing.T, err error, want int) { + t.Helper() + + coded, ok := err.(interface{ ExitCode() int }) + if !ok { + t.Fatalf("error %T does not provide an exit code", err) } - if got := ExitCodeFromError(context.Canceled); got != exitTransientFailure { - t.Errorf("plain error → %d, want %d", got, exitTransientFailure) + if got := coded.ExitCode(); got != want { + t.Errorf("exit code = %d, want %d", got, want) } } diff --git a/internal/commands/infrastructure.go b/internal/commands/infrastructure.go index 75f2d12..e94b59e 100644 --- a/internal/commands/infrastructure.go +++ b/internal/commands/infrastructure.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterInfrastructureCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "infrastructure", Short: "Infrastructure Graphs", @@ -33,7 +33,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Use: "list-graphs", Short: "List Infrastructure Graphs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsInput{} out, err := client.ListInfrastructureGraphs(cmd.Context(), in) if err != nil { @@ -46,6 +50,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -54,7 +59,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Use: "list-info", Short: "Get Infrastructure Graph Info", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsInfoInput{} out, err := client.ListInfrastructureGraphsInfo(cmd.Context(), in) if err != nil { @@ -67,6 +76,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -75,7 +85,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Use: "list-summary", Short: "Get Infrastructure Graph Summary", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsSummaryInput{} out, err := client.ListInfrastructureGraphsSummary(cmd.Context(), in) if err != nil { @@ -88,6 +102,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -97,7 +112,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Short: "Get Infrastructure Graph", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetInfrastructureGraphsAccountIdInput{} in.AccountID = args[0] out, err := client.GetInfrastructureGraphsAccountId(cmd.Context(), in) @@ -111,6 +130,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -120,7 +140,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Short: "Get Infrastructure Graph Download URL", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsAccountIdDownloadInput{} in.AccountID = args[0] out, err := client.ListInfrastructureGraphsAccountIdDownload(cmd.Context(), in) @@ -134,6 +158,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -143,7 +168,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Short: "List Infrastructure Graph Versions", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsAccountIdVersionsInput{} in.AccountID = args[0] out, err := client.ListInfrastructureGraphsAccountIdVersions(cmd.Context(), in) @@ -157,6 +186,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -166,7 +196,11 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api Short: "Get Infrastructure Graph Version", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListInfrastructureGraphsAccountIdVersionsVersionInput{} in.AccountID = args[0] in.Version = args[1] @@ -181,6 +215,7 @@ func RegisterInfrastructureCommands(parent *cobra.Command, getClient func() *api return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/manager.go b/internal/commands/manager.go index a472189..ea75ab4 100644 --- a/internal/commands/manager.go +++ b/internal/commands/manager.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterManagerCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "manager", Short: "Finding Lifecycle Management", @@ -33,7 +33,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-campaigns", Short: "List Campaigns", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -62,6 +66,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -73,7 +78,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Post Campaign", Long: "Request body (JSON) fields: createdAfter (string), createdBefore (string), description (string), endDate (string), findingIds (array), generatedReasoning (string), isActive (boolean), limitPerType (integer), maxStoryPoints (integer), minPriority (number), noEndDate (boolean), owner (string), priorityLabels (array), repositoryNames (array), sortByColumns (string), sortByDirection (string), startDate (string), summary (string), teamIDs (array), teamNames (array), title (string), types (array), userNames (array), vulnerabilityCVEIds (array), vulnerabilityCWEIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerCampaignsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -115,6 +124,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -125,7 +135,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-default", Short: "Get Default Campaigns", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsDefaultInput{} out, err := client.ListManagerCampaignsDefault(cmd.Context(), in) if err != nil { @@ -138,6 +152,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -146,7 +161,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "create-generate", Short: "Generate Default Campaigns", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerCampaignsDefaultGenerateInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -175,6 +194,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -185,7 +205,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-findings", Short: "Get All Campaigns Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsFindingsInput{} out, err := client.ListManagerCampaignsFindings(cmd.Context(), in) if err != nil { @@ -198,6 +222,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -206,7 +231,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-refresh", Short: "Refresh Campaign Metrics", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsMetricsRefreshInput{} if v, _ := cmd.Flags().GetString("include-expired"); v != "" { b := v == "true" @@ -223,6 +252,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("include-expired", "", "Whether to include expired campaigns in the metrics refresh (default: false)") serviceCmd.AddCommand(cmd) } @@ -232,7 +262,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-previews", Short: "Get Campaign Previews", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsPreviewsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -261,6 +295,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -271,7 +306,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-summaries", Short: "Get Campaign Summaries", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsSummariesInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -300,6 +339,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -311,7 +351,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Campaign", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerCampaignsCampaignIdInput{} in.CampaignID = args[0] data, err := client.DeleteManagerCampaignsCampaignId(cmd.Context(), in) @@ -321,6 +365,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -330,7 +375,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Campaign by ID", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetManagerCampaignsCampaignIdInput{} in.CampaignID = args[0] out, err := client.GetManagerCampaignsCampaignId(cmd.Context(), in) @@ -344,6 +393,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -354,7 +404,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: createdAfter (string), createdBefore (string), description (string), endDate (string), findingIds (array), generatedReasoning (string), isActive (boolean), limitPerType (integer), maxStoryPoints (integer), minPriority (number), noEndDate (boolean), owner (string), priorityLabels (array), repositoryNames (array), sortByColumns (string), sortByDirection (string), startDate (string), summary (string), teamIDs (array), teamNames (array), title (string), types (array), userNames (array), vulnerabilityCVEIds (array), vulnerabilityCWEIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerCampaignsCampaignIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -397,6 +451,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -408,7 +463,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Campaign Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsCampaignIdEventsInput{} in.CampaignID = args[0] if v, _ := cmd.Flags().GetString("action-types"); v != "" { @@ -448,6 +507,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("action-types", "", "Filter by action types (e.g., PR_CREATE, TICKET_CREATE)") cmd.Flags().String("page", "", "Page number, 1-indexed (default: 1)") cmd.Flags().String("page-size", "", "Number of events per page (default: 1000)") @@ -461,7 +521,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get (Triaged) Findings Associated with a campaign", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsCampaignIdFindingsInput{} in.CampaignID = args[0] out, err := client.ListManagerCampaignsCampaignIdFindings(cmd.Context(), in) @@ -475,6 +539,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -484,7 +549,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Campaign Preview Details", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsCampaignIdPreviewInput{} in.CampaignID = args[0] out, err := client.ListManagerCampaignsCampaignIdPreview(cmd.Context(), in) @@ -498,6 +567,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -507,7 +577,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "List Campaign Runs", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCampaignsCampaignIdRunsInput{} in.CampaignID = args[0] if v, _ := cmd.Flags().GetString("cursor"); v != "" { @@ -533,6 +607,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("cursor", "", "") cmd.Flags().String("limit", "", "") serviceCmd.AddCommand(cmd) @@ -544,7 +619,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Campaign Run", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetManagerCampaignsCampaignIdRunsRunIdInput{} in.CampaignID = args[0] in.RunID = args[1] @@ -559,6 +638,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -567,7 +647,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-sessions", Short: "List Chat Sessions", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerChatSessionsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -592,6 +676,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -603,7 +688,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Chat Session", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerChatSessionsChatIDInput{} in.ChatID = args[0] out, err := client.DeleteManagerChatSessionsChatID(cmd.Context(), in) @@ -617,6 +706,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -626,7 +716,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Chat Session", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetManagerChatSessionsChatIDInput{} in.ChatID = args[0] out, err := client.GetManagerChatSessionsChatID(cmd.Context(), in) @@ -640,6 +734,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -650,7 +745,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: title (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerChatSessionsChatIDInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -693,6 +792,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -704,7 +804,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Chat Session Actions", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerChatSessionsChatIDActionsInput{} in.ChatID = args[0] out, err := client.ListManagerChatSessionsChatIDActions(cmd.Context(), in) @@ -718,6 +822,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -727,7 +832,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get chat session audit trail", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerChatSessionsChatIDAuditInput{} in.ChatID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -753,6 +862,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -764,7 +874,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Chat Session History", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerChatSessionsChatIDHistoryInput{} in.ChatID = args[0] if v, _ := cmd.Flags().GetString("page"); v != "" { @@ -794,6 +908,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -804,7 +919,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-config", Short: "Get Manager config", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerConfigInput{} out, err := client.ListManagerConfig(cmd.Context(), in) if err != nil { @@ -817,6 +936,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -826,7 +946,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Update Manager config", Long: "Request body (JSON) fields: config (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerConfigInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -868,6 +992,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -878,7 +1003,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-credits", Short: "Get Manager credit balance", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCreditsInput{} out, err := client.ListManagerCredits(cmd.Context(), in) if err != nil { @@ -891,6 +1020,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -900,7 +1030,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Update Manager credit balance", Long: "Request body (JSON) fields: credits (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerCreditsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -942,6 +1076,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -952,7 +1087,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "delete-customer-questions", Short: "Delete All Customer Question Sets", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerCustomerQuestionsInput{} out, err := client.DeleteManagerCustomerQuestions(cmd.Context(), in) if err != nil { @@ -965,6 +1104,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -973,7 +1113,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-customer-questions", Short: "List Customer Question Sets", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerCustomerQuestionsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1002,6 +1146,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1013,7 +1158,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Customer Question Set", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerCustomerQuestionsQuestionSetIdInput{} in.QuestionSetID = args[0] out, err := client.DeleteManagerCustomerQuestionsQuestionSetId(cmd.Context(), in) @@ -1027,6 +1176,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1036,7 +1186,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Customer Question Set", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetManagerCustomerQuestionsQuestionSetIdInput{} in.QuestionSetID = args[0] out, err := client.GetManagerCustomerQuestionsQuestionSetId(cmd.Context(), in) @@ -1050,6 +1204,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1060,7 +1215,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: answer (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerCustomerQuestionsQuestionSetIdAnswersQuestionIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1104,6 +1263,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1115,7 +1275,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Customer Question", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerCustomerQuestionsQuestionSetIdQuestionsQuestionIdInput{} in.QuestionSetID = args[0] in.QuestionID = args[1] @@ -1130,6 +1294,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1138,7 +1303,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-escalations", Short: "Get Escalations", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerEscalationsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1167,6 +1336,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1179,7 +1349,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: reasoning (string), status (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerEscalationsEscalationIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1218,6 +1392,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1228,7 +1403,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-events", Short: "Get Events", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerEventsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1257,6 +1436,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1268,7 +1448,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Deduplicate Events", Long: "Request body (JSON) fields: dryRun (boolean), from (string), keep (string), statuses (array), timeoutSeconds (integer), to (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerEventsDeduplicateInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1310,6 +1494,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1321,7 +1506,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Delete Event", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.DeleteManagerEventsEventIdInput{} in.EventID = args[0] out, err := client.DeleteManagerEventsEventId(cmd.Context(), in) @@ -1335,6 +1524,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1344,7 +1534,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerFindingsFindingIdEventsInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("action-types"); v != "" { @@ -1380,6 +1574,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("action-types", "", "Filter by action types (e.g., PR_CREATE, TICKET_CREATE)") cmd.Flags().String("cursor", "", "Pagination cursor from previous request") cmd.Flags().String("limit", "", "Maximum number of events to return (default 100, max 1000)") @@ -1392,7 +1587,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-groundrules", Short: "Get Manager ground rules", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerGroundrulesInput{} out, err := client.ListManagerGroundrules(cmd.Context(), in) if err != nil { @@ -1405,6 +1604,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1414,7 +1614,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Patch a GroundRules object to S3", Long: "Request body (JSON) fields: groundRules (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerGroundrulesInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1456,6 +1660,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1467,7 +1672,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Post a GroundRules object to S3", Long: "Request body (JSON) fields: groundRules (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerGroundrulesInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1509,6 +1718,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1519,7 +1729,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-metrics", Short: "Get Metrics", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerMetricsInput{} out, err := client.ListManagerMetrics(cmd.Context(), in) if err != nil { @@ -1532,6 +1746,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1540,7 +1755,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-plans", Short: "Get Plans", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerPlansInput{} if v, _ := cmd.Flags().GetString("campaign-id"); v != "" { x := string(v) @@ -1573,6 +1792,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("campaign-id", "", "") cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") @@ -1584,7 +1804,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-state", Short: "Get Manager State", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerStateInput{} out, err := client.ListManagerState(cmd.Context(), in) if err != nil { @@ -1597,6 +1821,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1605,7 +1830,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-latest", Short: "Get Manager State (Legacy)", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerStateLatestInput{} out, err := client.ListManagerStateLatest(cmd.Context(), in) if err != nil { @@ -1618,6 +1847,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1626,7 +1856,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-states", Short: "Get Manager States", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerStatesInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1655,6 +1889,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1665,7 +1900,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-strategy", Short: "Get Active Strategy", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerStrategyInput{} out, err := client.ListManagerStrategy(cmd.Context(), in) if err != nil { @@ -1678,6 +1917,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1687,7 +1927,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Patch Active Strategy", Long: "Request body (JSON) fields: quarters (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerStrategyInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1729,6 +1973,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1739,7 +1984,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "create-strategy-trigger", Short: "Trigger Strategy Generation", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerStrategyTriggerInput{} out, err := client.CreateManagerStrategyTrigger(cmd.Context(), in) if err != nil { @@ -1752,6 +2001,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1760,7 +2010,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-versions", Short: "List Strategy Versions", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerStrategyVersionsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1789,6 +2043,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1799,7 +2054,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "create-tacit-knowledge-trigger", Short: "Trigger TacitKnowledge", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerTacitKnowledgeTriggerInput{} out, err := client.CreateManagerTacitKnowledgeTrigger(cmd.Context(), in) if err != nil { @@ -1812,6 +2071,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1820,7 +2080,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-threat-investigations", Short: "Get Threat Investigations", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListManagerThreatInvestigationsInput{} if v, _ := cmd.Flags().GetString("page"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1849,6 +2113,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("page", "", "") cmd.Flags().String("page-size", "", "") serviceCmd.AddCommand(cmd) @@ -1860,7 +2125,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Post Threat Investigation", Long: "Request body (JSON) fields: advice (string), affectedPackages (array), articleLinks (array), cveIds (array), cvss (number), description (string), ecosystem (string), keywords (string), severity (string), title (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerThreatInvestigationsInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1902,6 +2171,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1913,7 +2183,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Threat Investigation", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetManagerThreatInvestigationsThreatInvestigationIdInput{} in.ThreatInvestigationID = args[0] out, err := client.GetManagerThreatInvestigationsThreatInvestigationId(cmd.Context(), in) @@ -1927,6 +2201,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1937,7 +2212,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: action (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchManagerThreatInvestigationsThreatInvestigationIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1980,6 +2259,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1991,7 +2271,11 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client Short: "Start a Manager run", Long: "Request body (JSON) fields: campaignId (string), mode (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateManagerTriggerInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -2033,6 +2317,7 @@ func RegisterManagerCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) diff --git a/internal/commands/orchestrator.go b/internal/commands/orchestrator.go index 21509b5..8d9615b 100644 --- a/internal/commands/orchestrator.go +++ b/internal/commands/orchestrator.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterOrchestratorCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "orchestrator", Short: "Scan Orchestration (autofix batches, code reviews, retriage, onboarding)", @@ -34,7 +34,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Start Batch Autofix", Long: "Request body (JSON) fields: dastBugHuntFindingIDs (array), dastPentestFindingIDs (array), ownerProvider (object, required), sastFindingIDs (array), scaContainerFindingIDs (array), scaDependencyFindingIDs (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateOrchestratorAutofixBatchInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -76,6 +80,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -87,7 +92,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Get Batch Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetOrchestratorAutofixBatchExecutionIdInput{} in.ExecutionID = args[0] out, err := client.GetOrchestratorAutofixBatchExecutionId(cmd.Context(), in) @@ -101,6 +110,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -109,7 +119,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Use: "list-codereviews", Short: "Get Code Reviews", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListOrchestratorCodereviewsInput{} out, err := client.ListOrchestratorCodereviews(cmd.Context(), in) if err != nil { @@ -122,6 +136,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -131,7 +146,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Get Code Review", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetOrchestratorCodereviewsIdInput{} in.ID = args[0] out, err := client.GetOrchestratorCodereviewsId(cmd.Context(), in) @@ -145,6 +164,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -154,7 +174,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Retriage Findings", Long: "Request body (JSON) fields: continueOnError (boolean), debounceBypass (boolean), filters (object), findingType (string, required), message (object), platformProvider (string), triggerSource (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateOrchestratorFindingsRetriageInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -196,6 +220,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -207,7 +232,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Get Finding Autofix Iterations", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListOrchestratorFindingsFindingIDAutofixIterationsInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("finding-type"); v != "" { @@ -225,6 +254,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("finding-type", "", "") serviceCmd.AddCommand(cmd) } @@ -235,7 +265,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Complete Onboarding (Test Only)", Long: "Request body (JSON) fields: tenantId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateOrchestratorOnboardingCompleteInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -277,6 +311,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -288,7 +323,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Short: "Start Onboarding", Long: "Request body (JSON) fields: gitOwnerProvider (object, required), repositoryIds (array).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateOrchestratorOnboardingStartInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -330,6 +369,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -340,7 +380,11 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C Use: "list-status", Short: "Get Onboarding Status", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListOrchestratorOnboardingStatusInput{} out, err := client.ListOrchestratorOnboardingStatus(cmd.Context(), in) if err != nil { @@ -353,6 +397,7 @@ func RegisterOrchestratorCommands(parent *cobra.Command, getClient func() *api.C return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/commands/pentest_bridge.go b/internal/commands/pentest_bridge.go index afcd4e4..e3d5967 100644 --- a/internal/commands/pentest_bridge.go +++ b/internal/commands/pentest_bridge.go @@ -3,13 +3,12 @@ package commands import ( "strings" - "github.com/nullify-platform/cli/internal/api" "github.com/spf13/cobra" ) // RegisterPentestSubcommands adds generated DAST API subcommands that relate to // pentest functionality to the handwritten pentest command. -func RegisterPentestSubcommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterPentestSubcommands(parent *cobra.Command, getClient ClientFactory) { tmp := &cobra.Command{Use: "tmp"} RegisterDastCommands(tmp, getClient) diff --git a/internal/commands/sast.go b/internal/commands/sast.go index 1630ce8..e94f69f 100644 --- a/internal/commands/sast.go +++ b/internal/commands/sast.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterSastCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "sast", Short: "Static Application Security Testing (SAST)", @@ -33,7 +33,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-events", Short: "Get SAST Events", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastEventsInput{} if v, _ := cmd.Flags().GetString("event-type"); v != "" { for _, s := range strings.Split(v, ",") { @@ -80,6 +84,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("event-type", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("finding-id", "", "") @@ -95,7 +100,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-findings", Short: "Get SAST Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsInput{} if v, _ := cmd.Flags().GetString("ai-generated"); v != "" { b := v == "true" @@ -190,6 +199,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ai-generated", "", "true = AI code-review only, false = rule-only, omitted = both") cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") @@ -218,7 +228,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Allowlist Batch of SAST Findings", Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required), findingIds (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSastFindingsAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -256,6 +270,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -266,7 +281,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-detailed", Short: "Get Findings Detailed", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("ai-generated"); v != "" { b := v == "true" @@ -352,6 +371,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ai-generated", "", "true = AI code-review only, false = rule-only, omitted = both") cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -377,7 +397,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-preview", Short: "Get SAST Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsPreviewInput{} if v, _ := cmd.Flags().GetString("ai-generated"); v != "" { b := v == "true" @@ -472,6 +496,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("ai-generated", "", "true = AI code-review only, false = rule-only, omitted = both") cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") @@ -500,7 +525,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetSastFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetSastFindingsFindingId(cmd.Context(), in) @@ -514,6 +543,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -524,7 +554,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchSastFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -567,6 +601,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -579,7 +614,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSastFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -622,6 +661,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -633,7 +673,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SAST Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -659,6 +703,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -670,7 +715,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Autofix Diff", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdAutofixCacheDiffInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdAutofixCacheDiff(cmd.Context(), in) @@ -684,6 +733,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -694,7 +744,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSastFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -737,6 +791,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -748,7 +803,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SAST Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdAutofixState(cmd.Context(), in) @@ -762,6 +821,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -771,7 +831,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SAST Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -785,6 +849,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -794,7 +859,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdEvents(cmd.Context(), in) @@ -808,6 +877,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -818,7 +888,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSastFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -861,6 +935,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -872,7 +947,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Triaged Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdTriage(cmd.Context(), in) @@ -886,6 +965,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -896,7 +976,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: unallowlistReason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSastFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -935,6 +1019,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -946,7 +1031,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListSastFindingsFindingIdUsers(cmd.Context(), in) @@ -960,6 +1049,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -968,7 +1058,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-repositories", Short: "Get Repositories", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastRepositoriesInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -993,6 +1087,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -1004,7 +1099,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Repository Stats", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetSastRepositoriesRepositoryIdInput{} in.RepositoryID = args[0] out, err := client.GetSastRepositoriesRepositoryId(cmd.Context(), in) @@ -1018,6 +1117,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1026,7 +1126,11 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-scan-runs", Short: "List Scan Runs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSastScanRunsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1063,6 +1167,7 @@ func RegisterSastCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Max scan runs per page (default 10, max 50)") cmd.Flags().String("offset", "", "Pagination offset (default 0)") cmd.Flags().String("repository-id", "", "Repository ID to list scan runs for") diff --git a/internal/commands/sca.go b/internal/commands/sca.go index 812fcb4..5d68b92 100644 --- a/internal/commands/sca.go +++ b/internal/commands/sca.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterScaCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "sca", Short: "Software Composition Analysis (SCA)", @@ -33,7 +33,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-containers-findings", Short: "Get SCA Container Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsInput{} if v, _ := cmd.Flags().GetString("auto-fix-state"); v != "" { x := string(v) @@ -103,6 +107,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -124,7 +129,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-containers-findings-detailed", Short: "Get SCA Container Findings [DEPRECATED - TO BE REMOVED BY 2025]", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -190,6 +199,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -210,7 +220,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-containers-findings-preview", Short: "Get SCA Container Findings Preview", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsPreviewInput{} if v, _ := cmd.Flags().GetString("auto-fix-state"); v != "" { x := string(v) @@ -280,6 +294,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -302,7 +317,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Container Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetScaContainersFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetScaContainersFindingsFindingId(cmd.Context(), in) @@ -316,6 +335,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -326,7 +346,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchScaContainersFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -369,6 +393,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -381,7 +406,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaContainersFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -420,6 +449,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -431,7 +461,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCA Container Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -457,6 +491,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -469,7 +504,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaContainersFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -512,6 +551,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -523,7 +563,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Container Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListScaContainersFindingsFindingIdAutofixState(cmd.Context(), in) @@ -537,6 +581,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -546,7 +591,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Container Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListScaContainersFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -560,6 +609,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -569,7 +619,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCA Container Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListScaContainersFindingsFindingIdEvents(cmd.Context(), in) @@ -583,6 +637,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -593,7 +648,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaContainersFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -636,6 +695,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -647,7 +707,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Triaged Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListScaContainersFindingsFindingIdTriage(cmd.Context(), in) @@ -661,6 +725,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -671,7 +736,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: unallowlistReason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaContainersFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -710,6 +779,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -721,7 +791,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Related Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaContainersFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListScaContainersFindingsFindingIdUsers(cmd.Context(), in) @@ -735,6 +809,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -743,7 +818,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-dependencies-findings", Short: "Get SCA Dependency Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsInput{} if v, _ := cmd.Flags().GetString("auto-fix-state"); v != "" { x := string(v) @@ -813,6 +892,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -834,7 +914,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-dependencies-findings-detailed", Short: "Get SCA Dependency Findings Detailed [DEPRECATED - TO BE REMOVED BY 2025]", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -900,6 +984,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -920,7 +1005,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-dependencies-findings-preview", Short: "Get SCA Dependency Findings Preview", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsPreviewInput{} if v, _ := cmd.Flags().GetString("auto-fix-state"); v != "" { x := string(v) @@ -990,6 +1079,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("auto-fix-state", "", "filter by AutoFixState (e.g. 'none' for findings with no cached fix)") cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -1012,7 +1102,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetScaDependenciesFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetScaDependenciesFindingsFindingId(cmd.Context(), in) @@ -1026,6 +1120,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1036,7 +1131,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchScaDependenciesFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1079,6 +1178,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1091,7 +1191,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaDependenciesFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1130,6 +1234,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1141,7 +1246,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCA Dependency Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -1167,6 +1276,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -1178,7 +1288,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCA Dependency Finding Fix", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdAutofixCacheDiffInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdAutofixCacheDiff(cmd.Context(), in) @@ -1192,6 +1306,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1202,7 +1317,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaDependenciesFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1245,6 +1364,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1256,7 +1376,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Dependency Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdAutofixState(cmd.Context(), in) @@ -1270,6 +1394,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1279,7 +1404,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Dependency Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -1293,6 +1422,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1302,7 +1432,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCA Dependency Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdEvents(cmd.Context(), in) @@ -1316,6 +1450,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1326,7 +1461,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaDependenciesFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1369,6 +1508,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1380,7 +1520,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Triaged Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdTriage(cmd.Context(), in) @@ -1394,6 +1538,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1404,7 +1549,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: unallowlistReason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScaDependenciesFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1443,6 +1592,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1454,7 +1604,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Related Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaDependenciesFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListScaDependenciesFindingsFindingIdUsers(cmd.Context(), in) @@ -1468,6 +1622,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1476,7 +1631,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-events", Short: "Get SCA Events", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaEventsInput{} if v, _ := cmd.Flags().GetString("event-type"); v != "" { for _, s := range strings.Split(v, ",") { @@ -1523,6 +1682,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("event-type", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("finding-id", "", "") @@ -1538,7 +1698,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-repositories", Short: "Get Repository Stats", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaRepositoriesInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1563,6 +1727,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("next-token", "", "") serviceCmd.AddCommand(cmd) @@ -1574,7 +1739,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Repository Stats", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetScaRepositoriesRepositoryIdInput{} in.RepositoryID = args[0] out, err := client.GetScaRepositoriesRepositoryId(cmd.Context(), in) @@ -1588,6 +1757,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1597,7 +1767,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Repository SBOM", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaRepositoriesRepositoryIdSbomInput{} in.RepositoryID = args[0] out, err := client.ListScaRepositoriesRepositoryIdSbom(cmd.Context(), in) @@ -1611,6 +1785,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1619,7 +1794,11 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-scan-runs", Short: "List Scan Runs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScaScanRunsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1660,6 +1839,7 @@ func RegisterScaCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Max scan runs per page (default 10, max 50)") cmd.Flags().String("offset", "", "Pagination offset (default 0)") cmd.Flags().String("repository-id", "", "Repository ID to list scan runs for") diff --git a/internal/commands/scpm.go b/internal/commands/scpm.go index a52bf11..47b882b 100644 --- a/internal/commands/scpm.go +++ b/internal/commands/scpm.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterScpmCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "scpm", Short: "SaaS Security Posture Management (SCPM)", @@ -34,7 +34,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Request malware analysis for an OCI container image", Long: "Request body (JSON) fields: idempotencyKey (string), previousReference (string), reference (string, required), registry (string, required), repository (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmContainersAnalyzeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -76,6 +80,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -86,7 +91,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-dependencies", Short: "Get CI/CD Dependencies", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmDependenciesInput{} if v, _ := cmd.Flags().GetString("name"); v != "" { x := string(v) @@ -115,6 +124,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("name", "", "Filter by dependency name (e.g., actions/checkout, tj-actions/changed-files)") cmd.Flags().String("pinned", "", "Filter by pinned status") cmd.Flags().String("platform", "", "Filter by CI/CD platform (github-actions, gitlab-ci, azure-pipelines)") @@ -128,7 +138,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Request malware analysis for a dependency", Long: "Request body (JSON) fields: ecosystem (string, required), idempotencyKey (string), name (string, required), previousVersion (string), version (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmDependenciesAnalyzeInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -170,6 +184,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -181,7 +196,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Batch query vulnerabilities + malware verdict for dependencies", Long: "Request body (JSON) fields: packages (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmDependenciesQueryBatchInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -223,6 +242,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -233,7 +253,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-events", Short: "Get SCPM Events", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmEventsInput{} out, err := client.ListScpmEvents(cmd.Context(), in) if err != nil { @@ -246,6 +270,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -254,7 +279,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-findings", Short: "Get SCPM Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -337,6 +366,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("has-pull-request", "", "") @@ -362,7 +392,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Allowlist Batch of SCPM Findings", Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required), findingIds (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -400,6 +434,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -410,7 +445,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-detailed", Short: "Get Findings Detailed", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -488,6 +527,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("has-pull-request", "", "") @@ -511,7 +551,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Use: "list-preview", Short: "Get SCPM Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsPreviewInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -594,6 +638,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("has-pull-request", "", "") @@ -619,7 +664,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Retriage Findings", Long: "Request body (JSON) fields: branch (string), continueOnError (boolean), findingIds (array, required), forceRetriage (boolean), priorityMinimum (string), repositoryIds (array, required), reprocessFailedTriages (boolean), reprocessFalsePositives (boolean).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsRetriageInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -661,6 +710,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -672,7 +722,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Presigned URL to Upload SCPM Findings", Long: "Request body (JSON) fields: scanId (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsUploadInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -714,6 +768,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -725,7 +780,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetScpmFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetScpmFindingsFindingId(cmd.Context(), in) @@ -739,6 +798,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -749,7 +809,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchScpmFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -792,6 +856,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -804,7 +869,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -847,6 +916,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -858,7 +928,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCPM Finding Autofix Activity", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdAutofixActivityInput{} in.FindingID = args[0] if v, _ := cmd.Flags().GetString("limit"); v != "" { @@ -884,6 +958,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "") cmd.Flags().String("since-id", "", "") serviceCmd.AddCommand(cmd) @@ -896,7 +971,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: force (boolean).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsFindingIdAutofixCacheInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -935,6 +1014,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -947,7 +1027,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: message (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsFindingIdAutofixCacheCreatePrInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -990,6 +1074,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1001,7 +1086,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCPM Finding Autofix Diff", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdAutofixCacheDiffInput{} in.FindingID = args[0] out, err := client.ListScpmFindingsFindingIdAutofixCacheDiff(cmd.Context(), in) @@ -1015,6 +1104,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1025,7 +1115,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: assignees (array), force (boolean), message (string), originCampaignId (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsFindingIdAutofixFixInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1068,6 +1162,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1079,7 +1174,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCPM Finding Autofix State", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdAutofixStateInput{} in.FindingID = args[0] out, err := client.ListScpmFindingsFindingIdAutofixState(cmd.Context(), in) @@ -1093,6 +1192,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1102,7 +1202,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get SCPM Finding Autofix Status", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdAutofixStatusInput{} in.FindingID = args[0] out, err := client.ListScpmFindingsFindingIdAutofixStatus(cmd.Context(), in) @@ -1116,6 +1220,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1125,7 +1230,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListScpmFindingsFindingIdEvents(cmd.Context(), in) @@ -1139,6 +1248,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1148,7 +1258,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Short: "Get Triaged Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListScpmFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListScpmFindingsFindingIdTriage(cmd.Context(), in) @@ -1162,6 +1276,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1172,7 +1287,11 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { Long: "Request body (JSON) fields: unallowlistReason (string, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateScpmFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1211,6 +1330,7 @@ func RegisterScpmCommands(parent *cobra.Command, getClient func() *api.Client) { return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) diff --git a/internal/commands/secrets.go b/internal/commands/secrets.go index 3bfd678..4d24418 100644 --- a/internal/commands/secrets.go +++ b/internal/commands/secrets.go @@ -21,7 +21,7 @@ var _ = strconv.Atoi var _ = strings.Split var _ = models.RequestScope{} -func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client) { +func RegisterSecretsCommands(parent *cobra.Command, getClient ClientFactory) { serviceCmd := &cobra.Command{ Use: "secrets", Short: "Secrets Detection", @@ -33,7 +33,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-credentials-findings", Short: "Get Secrets Credential Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsCredentialsFindingsInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -91,6 +95,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -110,7 +115,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Allowlist Batch of Credential Findings", Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required), findingIds (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsCredentialsFindingsAllowlistBatchInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -148,6 +157,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -158,7 +168,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-credentials-findings-detailed", Short: "Get Secrets Credential Findings Detailed", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsCredentialsFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -216,6 +230,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -235,7 +250,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Credential Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetSecretsCredentialsFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetSecretsCredentialsFindingsFindingId(cmd.Context(), in) @@ -249,6 +268,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -259,7 +279,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object), userNotes (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchSecretsCredentialsFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -302,6 +326,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -314,7 +339,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsCredentialsFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -353,6 +382,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -364,7 +394,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsCredentialsFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListSecretsCredentialsFindingsFindingIdEvents(cmd.Context(), in) @@ -378,6 +412,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -388,7 +423,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsCredentialsFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -431,6 +470,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -442,7 +482,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Triaged Credential Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsCredentialsFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListSecretsCredentialsFindingsFindingIdTriage(cmd.Context(), in) @@ -456,6 +500,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -466,7 +511,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: unallowlistReason (string, required), unallowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsCredentialsFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -505,6 +554,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -516,7 +566,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Credential Finding Related Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsCredentialsFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListSecretsCredentialsFindingsFindingIdUsers(cmd.Context(), in) @@ -530,6 +584,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -538,7 +593,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-events", Short: "Get Secret Events", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsEventsInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -597,6 +656,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("event-type", "", "") cmd.Flags().String("file-owner-name", "", "") @@ -614,7 +674,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-findings", Short: "Get Secrets Credential Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -672,6 +736,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -691,7 +756,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Allowlist Batch of Credential Findings", Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required), findingIds (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsFindingsAllowlistBatchInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -729,6 +798,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -739,7 +809,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-findings-detailed", Short: "Get Secrets Credential Findings Detailed - [DEPRECATED - TO BE REMOVED BY 2025]", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsDetailedInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -797,6 +871,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -815,7 +890,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-preview", Short: "Get Secrets Credential Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsPreviewInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -873,6 +952,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -892,7 +972,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Credential Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetSecretsFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetSecretsFindingsFindingId(cmd.Context(), in) @@ -906,6 +990,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -916,7 +1001,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: priorityOverride (object), severityOverride (object), userNotes (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchSecretsFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -959,6 +1048,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -971,7 +1061,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1010,6 +1104,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1021,7 +1116,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Finding Events", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsFindingIdEventsInput{} in.FindingID = args[0] out, err := client.ListSecretsFindingsFindingIdEvents(cmd.Context(), in) @@ -1035,6 +1134,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1045,7 +1145,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1088,6 +1192,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1099,7 +1204,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Triaged Credential Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListSecretsFindingsFindingIdTriage(cmd.Context(), in) @@ -1113,6 +1222,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1123,7 +1233,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: unallowlistReason (string, required), unallowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1162,6 +1276,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1173,7 +1288,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Credential Finding Related Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListSecretsFindingsFindingIdUsers(cmd.Context(), in) @@ -1187,6 +1306,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1195,7 +1315,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-scan-runs", Short: "List Scan Runs", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsScanRunsInput{} if v, _ := cmd.Flags().GetString("limit"); v != "" { if n, err := strconv.Atoi(v); err != nil { @@ -1232,6 +1356,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("limit", "", "Max scan runs per page (default 10, max 50)") cmd.Flags().String("offset", "", "Pagination offset (default 0)") cmd.Flags().String("repository-id", "", "Repository ID to list scan runs for") @@ -1244,7 +1369,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Use: "list-sensitivedata-findings", Short: "Get Sensitive Data Findings", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsSensitivedataFindingsInput{} if v, _ := cmd.Flags().GetString("branch"); v != "" { x := string(v) @@ -1302,6 +1431,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("branch", "", "") cmd.Flags().String("file-owner-name", "", "") cmd.Flags().String("is-allowlisted", "", "") @@ -1321,7 +1451,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Allowlist Batch of Sensitive Data Findings", Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required), findingIds (array, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsSensitivedataFindingsAllowlistBatchInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1359,6 +1493,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1370,7 +1505,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Sensitive Data Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.GetSecretsSensitivedataFindingsFindingIdInput{} in.FindingID = args[0] out, err := client.GetSecretsSensitivedataFindingsFindingId(cmd.Context(), in) @@ -1384,6 +1523,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1394,7 +1534,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: priorityOverride (object), userNotes (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.PatchSecretsSensitivedataFindingsFindingIdInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1437,6 +1581,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1449,7 +1594,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: allowlistReason (string, required), allowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsSensitivedataFindingsFindingIdAllowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1488,6 +1637,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1500,7 +1650,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: assignees (array), campaignId (string), campaignTitle (string), message (string), project (string).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsSensitivedataFindingsFindingIdTicketInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1543,6 +1697,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1554,7 +1709,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Triaged Sensitive Data Finding", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsSensitivedataFindingsFindingIdTriageInput{} in.FindingID = args[0] out, err := client.ListSecretsSensitivedataFindingsFindingIdTriage(cmd.Context(), in) @@ -1568,6 +1727,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } @@ -1578,7 +1738,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Long: "Request body (JSON) fields: unallowlistReason (string, required), unallowlistType (object, required).\n\nProvide the body with --data '', --data-file (- for stdin), or piped stdin.", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.CreateSecretsSensitivedataFindingsFindingIdUnallowlistInput{} dataFlag, _ := cmd.Flags().GetString("data") dataFile, _ := cmd.Flags().GetString("data-file") @@ -1617,6 +1781,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) cmd.Flags().String("data", "", "Request body as a raw JSON string") cmd.Flags().String("data-file", "", "Read request body JSON from a file (- for stdin)") serviceCmd.AddCommand(cmd) @@ -1628,7 +1793,11 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client Short: "Get Sensitive Data Finding Related Users", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { - client := getClient() + client, err := getClient(cmd.Context()) + if err != nil { + cmd.SilenceUsage = true + return err + } in := api.ListSecretsSensitivedataFindingsFindingIdUsersInput{} in.FindingID = args[0] out, err := client.ListSecretsSensitivedataFindingsFindingIdUsers(cmd.Context(), in) @@ -1642,6 +1811,7 @@ func RegisterSecretsCommands(parent *cobra.Command, getClient func() *api.Client return output.Print(cmd, data) }, } + preserveRuntimeUsage(cmd) serviceCmd.AddCommand(cmd) } diff --git a/internal/output/spinner.go b/internal/output/spinner.go index 13e5c8b..8c7cd69 100644 --- a/internal/output/spinner.go +++ b/internal/output/spinner.go @@ -2,42 +2,51 @@ package output import ( "fmt" + "io" "os" "sync" "time" + + "github.com/nullify-platform/cli/internal/terminal" ) // Spinner displays a simple progress spinner on stderr. type Spinner struct { msg string done chan struct{} + stop chan struct{} once sync.Once } -// stderrIsTTY reports whether stderr is connected to a terminal. When it is -// not (e.g. CI logs, redirected output), the spinner stays silent to avoid -// polluting logs with ANSI escape sequences and braille frames. func stderrIsTTY() bool { - info, err := os.Stderr.Stat() - if err != nil { - return false - } - return info.Mode()&os.ModeCharDevice != 0 + return terminal.IsInteractive(os.Stderr) } // NewSpinner starts a spinner with the given message. Call Stop() when done. // If quiet is true, no spinner is displayed but Stop() is still safe to call. // The spinner is also suppressed when stderr is not a terminal. func NewSpinner(msg string, quiet bool) *Spinner { + return newSpinner(msg, quiet, stderrIsTTY(), os.Stderr) +} + +func newSpinner( + msg string, + quiet bool, + interactive bool, + writer io.Writer, +) *Spinner { s := &Spinner{ msg: msg, done: make(chan struct{}), + stop: make(chan struct{}), } - if quiet || !stderrIsTTY() { + if quiet || !interactive { + close(s.stop) return s } go func() { + defer close(s.stop) frames := []rune{'⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'} i := 0 ticker := time.NewTicker(80 * time.Millisecond) @@ -45,10 +54,10 @@ func NewSpinner(msg string, quiet bool) *Spinner { for { select { case <-s.done: - fmt.Fprintf(os.Stderr, "\r\033[K") + fmt.Fprint(writer, "\r\033[K") return case <-ticker.C: - fmt.Fprintf(os.Stderr, "\r%c %s", frames[i%len(frames)], s.msg) + fmt.Fprintf(writer, "\r%c %s", frames[i%len(frames)], s.msg) i++ } } @@ -62,4 +71,5 @@ func (s *Spinner) Stop() { s.once.Do(func() { close(s.done) }) + <-s.stop } diff --git a/internal/output/spinner_test.go b/internal/output/spinner_test.go new file mode 100644 index 0000000..aae9388 --- /dev/null +++ b/internal/output/spinner_test.go @@ -0,0 +1,29 @@ +package output + +import ( + "bytes" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestSpinnerStopWaitsForWriter(t *testing.T) { + var output bytes.Buffer + spinner := newSpinner("working", false, true, &output) + + time.Sleep(100 * time.Millisecond) + spinner.Stop() + written := output.String() + time.Sleep(100 * time.Millisecond) + + require.NotEmpty(t, written) + require.Equal(t, written, output.String()) +} + +func TestSilentSpinnerCanStopMoreThanOnce(t *testing.T) { + spinner := newSpinner("working", false, false, &bytes.Buffer{}) + + spinner.Stop() + spinner.Stop() +} diff --git a/internal/terminal/terminal.go b/internal/terminal/terminal.go new file mode 100644 index 0000000..a4a3690 --- /dev/null +++ b/internal/terminal/terminal.go @@ -0,0 +1,12 @@ +package terminal + +import ( + "os" + + "golang.org/x/term" +) + +// IsInteractive reports whether a file is attached to a terminal. +func IsInteractive(file *os.File) bool { + return term.IsTerminal(int(file.Fd())) +} diff --git a/internal/terminal/terminal_test.go b/internal/terminal/terminal_test.go new file mode 100644 index 0000000..f7c9b15 --- /dev/null +++ b/internal/terminal/terminal_test.go @@ -0,0 +1,18 @@ +package terminal + +import ( + "os" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIsInteractiveRejectsDevNull(t *testing.T) { + file, err := os.Open(os.DevNull) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, file.Close()) + }) + + require.False(t, IsInteractive(file)) +} diff --git a/internal/wizard/steps.go b/internal/wizard/steps.go index d903386..a161c96 100644 --- a/internal/wizard/steps.go +++ b/internal/wizard/steps.go @@ -12,17 +12,11 @@ import ( "github.com/nullify-platform/cli/internal/auth" "github.com/nullify-platform/cli/internal/lib" "github.com/nullify-platform/cli/internal/logger" + "github.com/nullify-platform/cli/internal/terminal" ) -// stdinIsTTY reports whether stdin is connected to an interactive terminal. -// Steps that prompt for input use this to fail fast in non-interactive -// environments (CI, pipes) instead of blocking forever on a read. func stdinIsTTY() bool { - info, err := os.Stdin.Stat() - if err != nil { - return false - } - return info.Mode()&os.ModeCharDevice != 0 + return terminal.IsInteractive(os.Stdin) } // DomainStep checks if a valid host is configured and prompts the user if not. diff --git a/scripts/generate/main.go b/scripts/generate/main.go index 9d1efc5..bf618cd 100644 --- a/scripts/generate/main.go +++ b/scripts/generate/main.go @@ -564,7 +564,11 @@ func generateCommandFile(outputDir string, service string, endpoints []Endpoint, if svcDesc == "" { svcDesc = svcPascal + " commands" } - fmt.Fprintf(&sb, "func Register%sCommands(parent *cobra.Command, getClient func() *api.Client) {\n", svcPascal) + fmt.Fprintf( + &sb, + "func Register%sCommands(parent *cobra.Command, getClient ClientFactory) {\n", + svcPascal, + ) fmt.Fprintf(&sb, "\tserviceCmd := &cobra.Command{\n\t\tUse: %q,\n\t\tShort: %q,\n\t}\n\tparent.AddCommand(serviceCmd)\n\n", service, svcDesc) for _, ep := range endpoints { @@ -617,7 +621,8 @@ func emitCobraCommand(sb *strings.Builder, ep Endpoint, r *modelRegistry) { fmt.Fprintf(sb, "\t\t\tArgs: cobra.ExactArgs(%d),\n", len(pathNames)) } sb.WriteString("\t\t\tRunE: func(cmd *cobra.Command, args []string) error {\n") - sb.WriteString("\t\t\t\tclient := getClient()\n") + sb.WriteString("\t\t\t\tclient, err := getClient(cmd.Context())\n") + sb.WriteString("\t\t\t\tif err != nil {\n\t\t\t\t\tcmd.SilenceUsage = true\n\t\t\t\t\treturn err\n\t\t\t\t}\n") fmt.Fprintf(sb, "\t\t\t\tin := api.%s{}\n", inputStructName(ep)) // Body resolution (before path/query overrides so the latter win): @@ -674,6 +679,7 @@ func emitCobraCommand(sb *strings.Builder, ep Endpoint, r *modelRegistry) { sb.WriteString("\t\t\t\treturn output.Print(cmd, data)\n") } sb.WriteString("\t\t\t},\n\t\t}\n") + sb.WriteString("\t\tpreserveRuntimeUsage(cmd)\n") // Flag declarations. for _, p := range queryParams {