feat: add --json output mode to all func subcommands#3822
feat: add --json output mode to all func subcommands#3822Ankitsinghsisodya wants to merge 3 commits into
Conversation
- Added JSON output functionality to multiple commands including build, create, delete, deploy, describe, environment, invoke, languages, list, logs, repository, run, subscribe, templates, and version. - Introduced a standardized JSON response structure for success and error messages, enhancing the user experience and consistency across the CLI. - Updated existing commands to check for the --json flag and return structured JSON responses when enabled. - Added tests to ensure the correctness of JSON output and error handling in various scenarios. This enhancement improves the usability of the CLI by allowing users to easily parse command outputs programmatically.
- Added JSON output support for various commands, ensuring structured responses when the --json flag is enabled. - Updated error handling in commands like 'completion', 'mcp start', and 'tkn-tasks' to return appropriate error messages when JSON output is requested. - Redirected non-error messages to stderr in commands such as 'deploy' and 'invoke' to prevent contamination of JSON output on stdout. - Improved test cases to validate the new output behavior and error handling across commands. These changes enhance the user experience by providing clearer error messages and maintaining output consistency across the CLI.
- Updated the `invoke` command to return the response body directly as JSON when the `--json` flag is enabled, improving output consistency. - Removed the internal alias for `writeJSONError` in the `json.go` file to streamline the codebase. - Added documentation to multiple command reference files to include the `--json` option, ensuring users are aware of the new output format. These changes enhance the user experience by providing structured JSON responses across various commands, facilitating easier parsing and integration.
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: Ankitsinghsisodya The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Hi @Ankitsinghsisodya. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Tip We noticed you've done this a few times! Consider joining the org to skip this step and gain Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a global --json mode with a standard response envelope for machine-readable CLI output, including structured error reporting, and updates command docs/tests accordingly.
Changes:
- Introduces JSON envelope helpers (
WriteJSONSuccess,WriteJSONError) and applies them across multiple commands. - Adds a global
--jsonpersistent flag and updates the top-level error sink to emit JSON errors. - Updates generated reference docs and adjusts tests to validate the new JSON envelope shape.
Reviewed changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/app/app.go | Emits structured JSON errors from the top-level error sink when JSON mode is enabled |
| cmd/json.go | Adds JSON envelope types/helpers and error classification mapping |
| cmd/json_test.go | Adds tests for JSON envelope shape and error classification mapping |
| cmd/root.go | Adds global persistent --json flag and binds it to viper |
| cmd/version.go | Emits version output as a JSON envelope when JSON mode is enabled |
| cmd/tkn_tasks.go | Rejects --json for raw YAML output command |
| cmd/templates.go | Switches templates output to JSON envelope when JSON mode is enabled |
| cmd/templates_test.go | Updates templates tests to expect JSON envelope |
| cmd/subscribe.go | Emits subscribe success payload in JSON envelope |
| cmd/run.go | Emits run success payload in JSON envelope |
| cmd/repository.go | Emits repository subcommand success payloads in JSON envelope |
| cmd/mcp.go | Rejects --json for long-running stdio-protocol server |
| cmd/logs.go | Rejects --json for streaming logs |
| cmd/list.go | Wraps list JSON output inside the standard envelope |
| cmd/languages.go | Switches languages output to JSON envelope when JSON mode is enabled |
| cmd/languages_test.go | Updates languages tests to expect JSON envelope |
| cmd/invoke.go | Emits invoke response in JSON envelope and moves verbose text to stderr |
| cmd/environment.go | Emits environment output in JSON envelope when JSON mode is enabled |
| cmd/describe.go | Wraps describe JSON output inside the standard envelope |
| cmd/deploy.go | Moves deploy status text to stderr and emits deploy result JSON envelope |
| cmd/deploy_test.go | Adjusts deploy tests for messages now written to stderr |
| cmd/delete.go | Emits delete success payload in JSON envelope |
| cmd/create.go | Emits create success payload in JSON envelope |
| cmd/config_git.go | Adds JSON envelope behavior for unimplemented config git command |
| cmd/completion.go | Rejects --json for raw shell completion script output |
| cmd/build.go | Emits build success payload in JSON envelope |
| docs/reference/func.md | Documents global --json flag |
| docs/reference/func_version.md | Documents inherited --json flag |
| docs/reference/func_subscribe.md | Documents inherited --json flag |
| docs/reference/func_repository_rename.md | Documents inherited --json flag |
| docs/reference/func_repository_remove.md | Documents inherited --json flag |
| docs/reference/func_repository_list.md | Documents inherited --json flag |
| docs/reference/func_repository_add.md | Documents inherited --json flag |
| docs/reference/func_repository.md | Documents inherited --json flag |
| docs/reference/func_mcp_start.md | Documents inherited --json flag |
| docs/reference/func_mcp.md | Documents inherited --json flag |
| docs/reference/func_logs.md | Documents inherited --json flag |
| docs/reference/func_list.md | Documents inherited --json flag |
| docs/reference/func_invoke.md | Documents inherited --json flag |
| docs/reference/func_environment.md | Documents inherited --json flag |
| docs/reference/func_describe.md | Documents inherited --json flag |
| docs/reference/func_deploy.md | Documents inherited --json flag |
| docs/reference/func_delete.md | Documents inherited --json flag |
| docs/reference/func_create.md | Documents inherited --json flag |
| docs/reference/func_config_volumes_remove.md | Documents inherited --json flag |
| docs/reference/func_config_volumes_add.md | Documents inherited --json flag |
| docs/reference/func_config_volumes.md | Documents inherited --json flag |
| docs/reference/func_config_labels_remove.md | Documents inherited --json flag |
| docs/reference/func_config_labels_add.md | Documents inherited --json flag |
| docs/reference/func_config_labels.md | Documents inherited --json flag |
| docs/reference/func_config_git_set.md | Documents inherited --json flag |
| docs/reference/func_config_git_remove.md | Documents inherited --json flag |
| docs/reference/func_config_git.md | Documents inherited --json flag |
| docs/reference/func_config_envs_remove.md | Documents inherited --json flag |
| docs/reference/func_config_envs_add.md | Documents inherited --json flag |
| docs/reference/func_config_envs.md | Documents inherited --json flag |
| docs/reference/func_config.md | Documents inherited --json flag |
| docs/reference/func_completion.md | Documents inherited --json flag |
| docs/reference/func_build.md | Documents inherited --json flag |
Comments suppressed due to low confidence (1)
pkg/app/app.go:1
- The error from
cmd.WriteJSONErroris ignored. Since this is the top-level error sink, failing to write JSON should fall back to a plain-text error on stderr (or at least print an additional message) so failures don't become silent/no-output in JSON mode.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // isJSONEnabled reports whether --json was explicitly set for this execution. | ||
| // Using cmd.Flag("json").Changed (rather than viper.GetBool("json")) avoids | ||
| // stale viper state polluting test runs. | ||
| func isJSONEnabled(cmd *cobra.Command) bool { | ||
| f := cmd.Flag("json") | ||
| return f != nil && f.Changed | ||
| } |
| var resp JSONResponse | ||
| if err := json.Unmarshal([]byte(buf()), &resp); err != nil { | ||
| t.Fatalf("output is not valid JSON: %v", err) | ||
| } | ||
| if resp.APIVersion != "v1" { | ||
| t.Errorf("expected apiVersion 'v1', got %q", resp.APIVersion) | ||
| } | ||
| if resp.Status != "ok" { | ||
| t.Errorf("expected status 'ok', got %q", resp.Status) | ||
| } | ||
| if resp.Data == nil { | ||
| t.Error("expected non-nil data in templates JSON response") | ||
| } | ||
| _ = cmp.Diff // keep import used |
| var resp JSONResponse | ||
| if err := json.Unmarshal([]byte(buf()), &resp); err != nil { | ||
| t.Fatalf("output is not valid JSON: %v", err) | ||
| } | ||
| if resp.APIVersion != "v1" { | ||
| t.Errorf("expected apiVersion 'v1', got %q", resp.APIVersion) | ||
| } | ||
| if resp.Status != "ok" { | ||
| t.Errorf("expected status 'ok', got %q", resp.Status) | ||
| } | ||
| if resp.Data == nil { | ||
| t.Error("expected non-nil data") | ||
| } |
Summary
Implements structured JSON output for every
funcsubcommand, as described in #3769.All JSON is written to stdout using a versioned envelope:
{"apiVersion":"v1","status":"ok","data":{...}} {"apiVersion":"v1","status":"error","error":{"category":"...","code":"...","retryable":false,"message":"...","hint":"..."}}The flag is opt-in — all existing human-readable output is unchanged.
Changes
New files
cmd/json.go— sharedJSONResponse/JSONErrorstructs,WriteJSONSuccess,WriteJSONError,errorToJSONError(maps 14+ typed errors to category/code/retryable), andisJSONEnabledhelpercmd/json_test.go— 20 unit tests covering every error-type mapping, envelope shape,apiVersionpresence, and round-trip validityGlobal plumbing
cmd/root.go—--jsonregistered as a persistent flag on the root command (inheritable by all subcommands), bound to Viperpkg/app/app.go— top-level error sink writesWriteJSONErrorto stdout when--jsonis set, instead of plain text to stderrPer-command success payloads
Test plan
go test knative.dev/func/cmd -run "TestWriteJSON|TestAPIVersion|TestErrorToJSONError|TestRound|TestLanguages_JSON|TestTemplates_JSON|TestTemplates_ByLanguage|TestRepository_List"— all 26 passfunc create -l go myfunc --json→ envelope withstatus: okfunc logs --json→ returns error:--json is not supported for streaming commands