mirror of https://github.com/knative/func.git
feat: add json output to func run (#2893)
This commit is contained in:
parent
69bdcbbecd
commit
56e1b0f7f5
38
cmd/run.go
38
cmd/run.go
|
@ -2,6 +2,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -28,7 +29,7 @@ NAME
|
|||
SYNOPSIS
|
||||
{{rootCmdUse}} run [-t|--container] [-r|--registry] [-i|--image] [-e|--env]
|
||||
[--build] [-b|--builder] [--builder-image] [-c|--confirm]
|
||||
[--address] [-v|--verbose]
|
||||
[--address] [--json] [-v|--verbose]
|
||||
|
||||
DESCRIPTION
|
||||
Run the function locally.
|
||||
|
@ -71,9 +72,12 @@ EXAMPLES
|
|||
|
||||
o Run the function locally on a specific address.
|
||||
$ {{rootCmdUse}} run --address=0.0.0.0:8081
|
||||
|
||||
o Run the function locally and output JSON with the service address.
|
||||
$ {{rootCmdUse}} run --json
|
||||
`,
|
||||
SuggestFor: []string{"rnu"},
|
||||
PreRunE: bindEnv("address", "build", "builder", "builder-image", "confirm", "container", "env", "image", "path", "registry", "start-timeout", "verbose"),
|
||||
PreRunE: bindEnv("build", "builder", "builder-image", "confirm", "container", "env", "image", "path", "registry", "start-timeout", "verbose", "address", "json"),
|
||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||
return runRun(cmd, newClient)
|
||||
},
|
||||
|
@ -129,6 +133,7 @@ EXAMPLES
|
|||
cmd.Flags().Lookup("build").NoOptDefVal = "true" // register `--build` as equivalient to `--build=true`
|
||||
cmd.Flags().String("address", "",
|
||||
"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)")
|
||||
cmd.Flags().Bool("json", false, "Output as JSON. ($FUNC_JSON)")
|
||||
|
||||
// Oft-shared flags:
|
||||
addConfirmFlag(cmd, cfg.Confirm)
|
||||
|
@ -171,6 +176,11 @@ func runRun(cmd *cobra.Command, newClient ClientFactory) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Ignore the verbose flag if JSON output
|
||||
if cfg.JSON {
|
||||
cfg.Verbose = false
|
||||
}
|
||||
|
||||
// Client
|
||||
clientOptions, err := cfg.clientOptions()
|
||||
if err != nil {
|
||||
|
@ -249,7 +259,27 @@ func runRun(cmd *cobra.Command, newClient ClientFactory) (err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
// Output based on format
|
||||
if cfg.JSON {
|
||||
// Create JSON output structure
|
||||
output := struct {
|
||||
Address string `json:"address"`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
}{
|
||||
Address: fmt.Sprintf("http://%s:%s", job.Host, job.Port),
|
||||
Host: job.Host,
|
||||
Port: job.Port,
|
||||
}
|
||||
|
||||
jsonData, err := json.Marshal(output)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal JSON output: %w", err)
|
||||
}
|
||||
fmt.Fprintln(cmd.OutOrStdout(), string(jsonData))
|
||||
} else {
|
||||
fmt.Fprintf(cmd.OutOrStderr(), "Running on host port %v\n", job.Port)
|
||||
}
|
||||
|
||||
select {
|
||||
case <-cmd.Context().Done():
|
||||
|
@ -293,6 +323,9 @@ type runConfig struct {
|
|||
|
||||
// Address is the interface and port to bind (e.g. "0.0.0.0:8081")
|
||||
Address string
|
||||
|
||||
// JSON output format
|
||||
JSON bool
|
||||
}
|
||||
|
||||
func newRunConfig(cmd *cobra.Command) (c runConfig) {
|
||||
|
@ -303,6 +336,7 @@ func newRunConfig(cmd *cobra.Command) (c runConfig) {
|
|||
Container: viper.GetBool("container"),
|
||||
StartTimeout: viper.GetDuration("start-timeout"),
|
||||
Address: viper.GetString("address"),
|
||||
JSON: viper.GetBool("json"),
|
||||
}
|
||||
// NOTE: .Env should be viper.GetStringSlice, but this returns unparsed
|
||||
// results and appears to be an open issue since 2017:
|
||||
|
|
|
@ -21,6 +21,7 @@ func TestRun_Run(t *testing.T) {
|
|||
runError error // Set the runner to yield this error
|
||||
buildInvoked bool // should Builder.Build be invoked?
|
||||
runInvoked bool // should Runner.Run be invoked?
|
||||
jsonOutput bool // expect JSON output format
|
||||
}{
|
||||
{
|
||||
name: "run and build by default",
|
||||
|
@ -100,6 +101,14 @@ func TestRun_Run(t *testing.T) {
|
|||
buildInvoked: true,
|
||||
runInvoked: false,
|
||||
},
|
||||
{
|
||||
name: "run with json output",
|
||||
desc: "Should output JSON format when --json flag is used",
|
||||
args: []string{"--json"},
|
||||
buildInvoked: true,
|
||||
runInvoked: true,
|
||||
jsonOutput: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -11,7 +11,7 @@ NAME
|
|||
SYNOPSIS
|
||||
func run [-t|--container] [-r|--registry] [-i|--image] [-e|--env]
|
||||
[--build] [-b|--builder] [--builder-image] [-c|--confirm]
|
||||
[--address] [-v|--verbose]
|
||||
[--address] [--json] [-v|--verbose]
|
||||
|
||||
DESCRIPTION
|
||||
Run the function locally.
|
||||
|
@ -55,6 +55,9 @@ EXAMPLES
|
|||
o Run the function locally on a specific address.
|
||||
$ func run --address=0.0.0.0:8081
|
||||
|
||||
o Run the function locally and output JSON with the service address.
|
||||
$ func run --json
|
||||
|
||||
|
||||
```
|
||||
func run
|
||||
|
@ -72,6 +75,7 @@ func run
|
|||
-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-).
|
||||
-h, --help help for run
|
||||
-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)
|
||||
--json Output as JSON. ($FUNC_JSON)
|
||||
-p, --path string Path to the function. Default is current directory ($FUNC_PATH)
|
||||
-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)
|
||||
-v, --verbose Print verbose logs ($FUNC_VERBOSE)
|
||||
|
|
Loading…
Reference in New Issue