Skip to content

Commit 56e1b0f

Browse files
authored
feat: add json output to func run (knative#2893)
1 parent 69bdcbb commit 56e1b0f

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

cmd/run.go

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cmd
22

33
import (
44
"context"
5+
"encoding/json"
56
"errors"
67
"fmt"
78
"os"
@@ -28,7 +29,7 @@ NAME
2829
SYNOPSIS
2930
{{rootCmdUse}} run [-t|--container] [-r|--registry] [-i|--image] [-e|--env]
3031
[--build] [-b|--builder] [--builder-image] [-c|--confirm]
31-
[--address] [-v|--verbose]
32+
[--address] [--json] [-v|--verbose]
3233
3334
DESCRIPTION
3435
Run the function locally.
@@ -71,9 +72,12 @@ EXAMPLES
7172
7273
o Run the function locally on a specific address.
7374
$ {{rootCmdUse}} run --address=0.0.0.0:8081
75+
76+
o Run the function locally and output JSON with the service address.
77+
$ {{rootCmdUse}} run --json
7478
`,
7579
SuggestFor: []string{"rnu"},
76-
PreRunE: bindEnv("address", "build", "builder", "builder-image", "confirm", "container", "env", "image", "path", "registry", "start-timeout", "verbose"),
80+
PreRunE: bindEnv("build", "builder", "builder-image", "confirm", "container", "env", "image", "path", "registry", "start-timeout", "verbose", "address", "json"),
7781
RunE: func(cmd *cobra.Command, _ []string) error {
7882
return runRun(cmd, newClient)
7983
},
@@ -129,6 +133,7 @@ EXAMPLES
129133
cmd.Flags().Lookup("build").NoOptDefVal = "true" // register `--build` as equivalient to `--build=true`
130134
cmd.Flags().String("address", "",
131135
"Interface and port on which to bind and listen. Default is 127.0.0.1:8080, or an available port if 8080 is not available. ($FUNC_ADDRESS)")
136+
cmd.Flags().Bool("json", false, "Output as JSON. ($FUNC_JSON)")
132137

133138
// Oft-shared flags:
134139
addConfirmFlag(cmd, cfg.Confirm)
@@ -171,6 +176,11 @@ func runRun(cmd *cobra.Command, newClient ClientFactory) (err error) {
171176
return
172177
}
173178

179+
// Ignore the verbose flag if JSON output
180+
if cfg.JSON {
181+
cfg.Verbose = false
182+
}
183+
174184
// Client
175185
clientOptions, err := cfg.clientOptions()
176186
if err != nil {
@@ -249,7 +259,27 @@ func runRun(cmd *cobra.Command, newClient ClientFactory) (err error) {
249259
}
250260
}()
251261

252-
fmt.Fprintf(cmd.OutOrStderr(), "Running on host port %v\n", job.Port)
262+
// Output based on format
263+
if cfg.JSON {
264+
// Create JSON output structure
265+
output := struct {
266+
Address string `json:"address"`
267+
Host string `json:"host"`
268+
Port string `json:"port"`
269+
}{
270+
Address: fmt.Sprintf("http://%s:%s", job.Host, job.Port),
271+
Host: job.Host,
272+
Port: job.Port,
273+
}
274+
275+
jsonData, err := json.Marshal(output)
276+
if err != nil {
277+
return fmt.Errorf("failed to marshal JSON output: %w", err)
278+
}
279+
fmt.Fprintln(cmd.OutOrStdout(), string(jsonData))
280+
} else {
281+
fmt.Fprintf(cmd.OutOrStderr(), "Running on host port %v\n", job.Port)
282+
}
253283

254284
select {
255285
case <-cmd.Context().Done():
@@ -293,6 +323,9 @@ type runConfig struct {
293323

294324
// Address is the interface and port to bind (e.g. "0.0.0.0:8081")
295325
Address string
326+
327+
// JSON output format
328+
JSON bool
296329
}
297330

298331
func newRunConfig(cmd *cobra.Command) (c runConfig) {
@@ -303,6 +336,7 @@ func newRunConfig(cmd *cobra.Command) (c runConfig) {
303336
Container: viper.GetBool("container"),
304337
StartTimeout: viper.GetDuration("start-timeout"),
305338
Address: viper.GetString("address"),
339+
JSON: viper.GetBool("json"),
306340
}
307341
// NOTE: .Env should be viper.GetStringSlice, but this returns unparsed
308342
// results and appears to be an open issue since 2017:

cmd/run_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func TestRun_Run(t *testing.T) {
2121
runError error // Set the runner to yield this error
2222
buildInvoked bool // should Builder.Build be invoked?
2323
runInvoked bool // should Runner.Run be invoked?
24+
jsonOutput bool // expect JSON output format
2425
}{
2526
{
2627
name: "run and build by default",
@@ -100,6 +101,14 @@ func TestRun_Run(t *testing.T) {
100101
buildInvoked: true,
101102
runInvoked: false,
102103
},
104+
{
105+
name: "run with json output",
106+
desc: "Should output JSON format when --json flag is used",
107+
args: []string{"--json"},
108+
buildInvoked: true,
109+
runInvoked: true,
110+
jsonOutput: true,
111+
},
103112
}
104113
for _, tt := range tests {
105114
t.Run(tt.name, func(t *testing.T) {

docs/reference/func_run.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ NAME
1111
SYNOPSIS
1212
func run [-t|--container] [-r|--registry] [-i|--image] [-e|--env]
1313
[--build] [-b|--builder] [--builder-image] [-c|--confirm]
14-
[--address] [-v|--verbose]
14+
[--address] [--json] [-v|--verbose]
1515

1616
DESCRIPTION
1717
Run the function locally.
@@ -55,6 +55,9 @@ EXAMPLES
5555
o Run the function locally on a specific address.
5656
$ func run --address=0.0.0.0:8081
5757

58+
o Run the function locally and output JSON with the service address.
59+
$ func run --json
60+
5861

5962
```
6063
func run
@@ -72,6 +75,7 @@ func run
7275
-e, --env stringArray Environment variable to set in the form NAME=VALUE. You may provide this flag multiple times for setting multiple environment variables. To unset, specify the environment variable name followed by a "-" (e.g., NAME-).
7376
-h, --help help for run
7477
-i, --image string Full image name in the form [registry]/[namespace]/[name]:[tag]. This option takes precedence over --registry. Specifying tag is optional. ($FUNC_IMAGE)
78+
--json Output as JSON. ($FUNC_JSON)
7579
-p, --path string Path to the function. Default is current directory ($FUNC_PATH)
7680
-r, --registry string Container registry + registry namespace. (ex 'ghcr.io/myuser'). The full image name is automatically determined using this along with function name. ($FUNC_REGISTRY)
7781
-v, --verbose Print verbose logs ($FUNC_VERBOSE)

0 commit comments

Comments
 (0)