mirror of https://github.com/knative/func.git
Cleanup commands (#807)
* src: refactor commands Commands are constructed from root, not by using init() blocks. Signed-off-by: Matej Vasek <mvasek@redhat.com> * fixup the prefix issue Signed-off-by: Matej Vasek <mvasek@redhat.com> * fixup style Signed-off-by: Matej Vasek <mvasek@redhat.com> * fixup nolint:misspell Signed-off-by: Matej Vasek <mvasek@redhat.com>
This commit is contained in:
parent
e1095e0509
commit
abd4eea0c7
|
|
@ -19,12 +19,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/progress"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add to the root a new "Build" command which obtains an appropriate
|
||||
// instance of fn.Client from the given client creator function.
|
||||
root.AddCommand(NewBuildCmd(newBuildClient))
|
||||
}
|
||||
|
||||
func newBuildClient(cfg buildConfig) (*fn.Client, error) {
|
||||
builder := buildpacks.NewBuilder()
|
||||
listener := progress.New()
|
||||
|
|
|
|||
|
|
@ -7,15 +7,11 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(completionCmd)
|
||||
}
|
||||
|
||||
// completionCmd represents the completion command
|
||||
var completionCmd = &cobra.Command{
|
||||
Use: "completion <bash|zsh|fish>",
|
||||
Short: "Generate completion scripts for bash, fish and zsh",
|
||||
Long: `To load completion run
|
||||
func NewCompletionCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "completion <bash|zsh|fish>",
|
||||
Short: "Generate completion scripts for bash, fish and zsh",
|
||||
Long: `To load completion run
|
||||
|
||||
For zsh:
|
||||
source <(func completion zsh)
|
||||
|
|
@ -28,23 +24,25 @@ For bash:
|
|||
source <(func completion bash)
|
||||
|
||||
`,
|
||||
ValidArgs: []string{"bash", "zsh", "fish"},
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
if len(args) < 1 {
|
||||
return errors.New("missing argument")
|
||||
}
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
err = root.GenBashCompletion(os.Stdout)
|
||||
case "zsh":
|
||||
err = root.GenZshCompletion(os.Stdout)
|
||||
case "fish":
|
||||
err = root.GenFishCompletion(os.Stdout, true)
|
||||
default:
|
||||
err = errors.New("unknown shell, only bash, zsh and fish are supported")
|
||||
}
|
||||
ValidArgs: []string{"bash", "zsh", "fish"},
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
if len(args) < 1 {
|
||||
return errors.New("missing argument")
|
||||
}
|
||||
switch args[0] {
|
||||
case "bash":
|
||||
err = cmd.Root().GenBashCompletion(os.Stdout)
|
||||
case "zsh":
|
||||
err = cmd.Root().GenZshCompletion(os.Stdout)
|
||||
case "fish":
|
||||
err = cmd.Root().GenFishCompletion(os.Stdout, true)
|
||||
default:
|
||||
err = errors.New("unknown shell, only bash, zsh and fish are supported")
|
||||
}
|
||||
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,24 +43,28 @@ func (s standardLoaderSaver) Save(f fn.Function) error {
|
|||
|
||||
var defaultLoaderSaver standardLoaderSaver
|
||||
|
||||
func init() {
|
||||
root.AddCommand(configCmd)
|
||||
setPathFlag(configCmd)
|
||||
configCmd.AddCommand(NewConfigLabelsCmd(defaultLoaderSaver))
|
||||
}
|
||||
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Configure a function",
|
||||
Long: `Configure a function
|
||||
func NewConfigCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Configure a function",
|
||||
Long: `Configure a function
|
||||
|
||||
Interactive propmt that allows configuration of Volume mounts, Environment
|
||||
variables, and Labels for a function project present in the current directory
|
||||
or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"cfg", "cofnig"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: runConfigCmd,
|
||||
SuggestFor: []string{"cfg", "cofnig"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: runConfigCmd,
|
||||
}
|
||||
|
||||
setPathFlag(cmd)
|
||||
|
||||
cmd.AddCommand(NewConfigLabelsCmd(defaultLoaderSaver))
|
||||
cmd.AddCommand(NewConfigEnvsCmd())
|
||||
cmd.AddCommand(NewConfigVolumesCmd())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runConfigCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
|
|
|
|||
|
|
@ -14,41 +14,47 @@ import (
|
|||
"knative.dev/kn-plugin-func/utils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setPathFlag(configEnvsCmd)
|
||||
setPathFlag(configEnvsAddCmd)
|
||||
setPathFlag(configEnvsRemoveCmd)
|
||||
configCmd.AddCommand(configEnvsCmd)
|
||||
configEnvsCmd.AddCommand(configEnvsAddCmd)
|
||||
configEnvsCmd.AddCommand(configEnvsRemoveCmd)
|
||||
}
|
||||
|
||||
var configEnvsCmd = &cobra.Command{
|
||||
Use: "envs",
|
||||
Short: "List and manage configured environment variable for a function",
|
||||
Long: `List and manage configured environment variable for a function
|
||||
func NewConfigEnvsCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "envs",
|
||||
Short: "List and manage configured environment variable for a function",
|
||||
Long: `List and manage configured environment variable for a function
|
||||
|
||||
Prints configured Environment variable for a function project present in
|
||||
the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"ensv", "env"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
SuggestFor: []string{"ensv", "env"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
listEnvs(function)
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
listEnvs(function)
|
||||
configEnvsAddCmd := NewConfigEnvsAddCmd()
|
||||
configEnvsRemoveCmd := NewConfigEnvsRemoveCmd()
|
||||
|
||||
return
|
||||
},
|
||||
setPathFlag(cmd)
|
||||
setPathFlag(configEnvsAddCmd)
|
||||
setPathFlag(configEnvsRemoveCmd)
|
||||
|
||||
cmd.AddCommand(configEnvsAddCmd)
|
||||
cmd.AddCommand(configEnvsRemoveCmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
var configEnvsAddCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add environment variable to the function configuration",
|
||||
Long: `Add environment variable to the function configuration
|
||||
func NewConfigEnvsAddCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add environment variable to the function configuration",
|
||||
Long: `Add environment variable to the function configuration
|
||||
|
||||
Interactive prompt to add Environment variables to the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
|
|
@ -56,36 +62,41 @@ in the current directory or from the directory specified with --path.
|
|||
The environment variable can be set directly from a value,
|
||||
from an environment variable on the local machine or from Secrets and ConfigMaps.
|
||||
`,
|
||||
SuggestFor: []string{"ad", "create", "insert", "append"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
SuggestFor: []string{"ad", "create", "insert", "append"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runAddEnvsPrompt(cmd.Context(), function)
|
||||
},
|
||||
}
|
||||
|
||||
return runAddEnvsPrompt(cmd.Context(), function)
|
||||
},
|
||||
}
|
||||
|
||||
var configEnvsRemoveCmd = &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove environment variable from the function configuration",
|
||||
Long: `Remove environment variable from the function configuration
|
||||
func NewConfigEnvsRemoveCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove environment variable from the function configuration",
|
||||
Long: `Remove environment variable from the function configuration
|
||||
|
||||
Interactive prompt to remove Environment variables from the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"rm", "del", "delete", "rmeove"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
SuggestFor: []string{"rm", "del", "delete", "rmeove"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runRemoveEnvsPrompt(function)
|
||||
},
|
||||
}
|
||||
|
||||
return runRemoveEnvsPrompt(function)
|
||||
},
|
||||
}
|
||||
|
||||
func listEnvs(f fn.Function) {
|
||||
|
|
|
|||
|
|
@ -13,75 +13,86 @@ import (
|
|||
"knative.dev/kn-plugin-func/k8s"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setPathFlag(configVolumesCmd)
|
||||
setPathFlag(configVolumesAddCmd)
|
||||
setPathFlag(configVolumesRemoveCmd)
|
||||
configCmd.AddCommand(configVolumesCmd)
|
||||
configVolumesCmd.AddCommand(configVolumesAddCmd)
|
||||
configVolumesCmd.AddCommand(configVolumesRemoveCmd)
|
||||
}
|
||||
|
||||
var configVolumesCmd = &cobra.Command{
|
||||
Use: "volumes",
|
||||
Short: "List and manage configured volumes for a function",
|
||||
Long: `List and manage configured volumes for a function
|
||||
func NewConfigVolumesCmd() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "volumes",
|
||||
Short: "List and manage configured volumes for a function",
|
||||
Long: `List and manage configured volumes for a function
|
||||
|
||||
Prints configured Volume mounts for a function project present in
|
||||
the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"volums", "volume", "vols"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
SuggestFor: []string{"volums", "volume", "vols"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
listVolumes(function)
|
||||
|
||||
return
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
listVolumes(function)
|
||||
configVolumesAddCmd := NewConfigVolumesAddCmd()
|
||||
configVolumesRemoveCmd := NewConfigVolumesRemoveCmd()
|
||||
|
||||
return
|
||||
},
|
||||
setPathFlag(cmd)
|
||||
setPathFlag(configVolumesAddCmd)
|
||||
setPathFlag(configVolumesRemoveCmd)
|
||||
|
||||
cmd.AddCommand(configVolumesAddCmd)
|
||||
cmd.AddCommand(configVolumesRemoveCmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
var configVolumesAddCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add volume to the function configuration",
|
||||
Long: `Add volume to the function configuration
|
||||
func NewConfigVolumesAddCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add volume to the function configuration",
|
||||
Long: `Add volume to the function configuration
|
||||
|
||||
Interactive prompt to add Secrets and ConfigMaps as Volume mounts to the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"ad", "create", "insert", "append"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
SuggestFor: []string{"ad", "create", "insert", "append"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runAddVolumesPrompt(cmd.Context(), function)
|
||||
},
|
||||
}
|
||||
|
||||
return runAddVolumesPrompt(cmd.Context(), function)
|
||||
},
|
||||
}
|
||||
|
||||
var configVolumesRemoveCmd = &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove volume from the function configuration",
|
||||
Long: `Remove volume from the function configuration
|
||||
func NewConfigVolumesRemoveCmd() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove volume from the function configuration",
|
||||
Long: `Remove volume from the function configuration
|
||||
|
||||
Interactive prompt to remove Volume mounts from the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"del", "delete", "rmeove"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
SuggestFor: []string{"del", "delete", "rmeove"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args, defaultLoaderSaver)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runRemoveVolumesPrompt(function)
|
||||
},
|
||||
}
|
||||
|
||||
return runRemoveVolumesPrompt(function)
|
||||
},
|
||||
}
|
||||
|
||||
func listVolumes(f fn.Function) {
|
||||
|
|
|
|||
|
|
@ -25,12 +25,6 @@ type ErrInvalidRuntime error
|
|||
// ErrInvalidTemplate indicates that the passed template was invalid.
|
||||
type ErrInvalidTemplate error
|
||||
|
||||
func init() {
|
||||
// Add to the root a new "Create" command which obtains an appropriate
|
||||
// instance of fn.Client from the given client creator function.
|
||||
root.AddCommand(NewCreateCmd(newCreateClient))
|
||||
}
|
||||
|
||||
// createClientFn is a factory function which returns a Client suitable for
|
||||
// use with the Create command.
|
||||
type createClientFn func(createConfig) *fn.Client
|
||||
|
|
@ -53,16 +47,16 @@ func NewCreateCmd(clientFn createClientFn) *cobra.Command {
|
|||
Short: "Create a Function Project",
|
||||
Long: `
|
||||
NAME
|
||||
{{.Prefix}}func create - Create a Function project.
|
||||
{{.Name}} create - Create a Function project.
|
||||
|
||||
SYNOPSIS
|
||||
{{.Prefix}}func create [-l|--language] [-t|--template] [-r|--repository]
|
||||
{{.Name}} create [-l|--language] [-t|--template] [-r|--repository]
|
||||
[-c|--confirm] [-v|--verbose] [path]
|
||||
|
||||
DESCRIPTION
|
||||
Creates a new Function project.
|
||||
|
||||
$ {{.Prefix}}func create -l node -t http
|
||||
$ {{.Name}} create -l node -t http
|
||||
|
||||
Creates a Function in the current directory '.' which is written in the
|
||||
language/runtime 'node' and handles HTTP events.
|
||||
|
|
@ -71,24 +65,24 @@ DESCRIPTION
|
|||
the path if necessary.
|
||||
|
||||
To complete this command interactivly, use --confirm (-c):
|
||||
$ {{.Prefix}}func create -c
|
||||
$ {{.Name}} create -c
|
||||
|
||||
Available Language Runtimes and Templates:
|
||||
{{ .Options | indent 2 " " | indent 1 "\t" }}
|
||||
|
||||
To install more language runtimes and their templates see '{{.Prefix}}func repository'.
|
||||
To install more language runtimes and their templates see '{{.Name}} repository'.
|
||||
|
||||
EXAMPLES
|
||||
o Create a Node.js Function (the default language runtime) in the current
|
||||
directory (the default path) which handles http events (the default
|
||||
template).
|
||||
$ {{.Prefix}}func create
|
||||
$ {{.Name}} create
|
||||
|
||||
o Create a Node.js Function in the directory 'myfunc'.
|
||||
$ {{.Prefix}}func create myfunc
|
||||
$ {{.Name}} create myfunc
|
||||
|
||||
o Create a Go Function which handles CloudEvents in ./myfunc.
|
||||
$ {{.Prefix}}func create -l go -t cloudevents myfunc
|
||||
$ {{.Name}} create -l go -t cloudevents myfunc
|
||||
`,
|
||||
SuggestFor: []string{"vreate", "creaet", "craete", "new"},
|
||||
PreRunE: bindEnv("language", "template", "repository", "confirm"),
|
||||
|
|
@ -182,10 +176,10 @@ func runCreateHelp(cmd *cobra.Command, args []string, clientFn createClientFn) {
|
|||
|
||||
var data = struct {
|
||||
Options string
|
||||
Prefix string
|
||||
Name string
|
||||
}{
|
||||
Options: options,
|
||||
Prefix: pluginPrefix(),
|
||||
Name: cmd.Root().Name(),
|
||||
}
|
||||
if err := tpl.Execute(cmd.OutOrStdout(), data); err != nil {
|
||||
fmt.Fprintf(cmd.ErrOrStderr(), "unable to display help text: %v", err)
|
||||
|
|
|
|||
|
|
@ -14,12 +14,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/progress"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Create a new delete command with a reference to
|
||||
// a function which yields an appropriate concrete client instance.
|
||||
root.AddCommand(NewDeleteCmd(newDeleteClient))
|
||||
}
|
||||
|
||||
// newDeleteClient returns an instance of a Client using the
|
||||
// final config state.
|
||||
// Testing note: This method is swapped out during testing to allow
|
||||
|
|
|
|||
|
|
@ -24,10 +24,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/progress"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(NewDeployCmd(newDeployClient))
|
||||
}
|
||||
|
||||
func newDeployClient(cfg deployConfig) (*fn.Client, error) {
|
||||
listener := progress.New()
|
||||
builder := buildpacks.NewBuilder()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
|
@ -28,6 +29,25 @@ func main() {
|
|||
os.Exit(137)
|
||||
}()
|
||||
|
||||
cmd.SetMeta(date, vers, hash)
|
||||
cmd.Execute(ctx)
|
||||
root, err := cmd.NewRootCmd(cmd.RootCommandConfig{
|
||||
Name: "func",
|
||||
Date: date,
|
||||
Version: vers,
|
||||
Hash: hash,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := root.ExecuteContext(ctx); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
os.Exit(130)
|
||||
return
|
||||
}
|
||||
// Errors are printed to STDERR output and the process exits with code of 1.
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/knative"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(NewInfoCmd(newInfoClient))
|
||||
}
|
||||
|
||||
func newInfoClient(cfg infoConfig) (*fn.Client, error) {
|
||||
describer, err := knative.NewDescriber(cfg.Namespace)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -18,10 +18,6 @@ import (
|
|||
knative "knative.dev/kn-plugin-func/knative"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(NewInvokeCmd(newInvokeClient))
|
||||
}
|
||||
|
||||
type invokeClientFn func(invokeConfig) (*fn.Client, error)
|
||||
|
||||
func newInvokeClient(cfg invokeConfig) (*fn.Client, error) {
|
||||
|
|
@ -44,10 +40,10 @@ func NewInvokeCmd(clientFn invokeClientFn) *cobra.Command {
|
|||
Short: "Invoke a Function",
|
||||
Long: `
|
||||
NAME
|
||||
{{.Prefix}}func invoke - Invoke a Function.
|
||||
{{.Name}} invoke - Invoke a Function.
|
||||
|
||||
SYNOPSIS
|
||||
{{.Prefix}}func invoke [-t|--target] [-f|--format]
|
||||
{{.Name}} invoke [-t|--target] [-f|--format]
|
||||
[--id] [--source] [--type] [--data] [--file] [--content-type]
|
||||
[-s|--save] [-p|--path] [-c|--confirm] [-v|--verbose]
|
||||
|
||||
|
|
@ -71,54 +67,54 @@ DESCRIPTION
|
|||
Invocation Target
|
||||
The Function instance to invoke can be specified using the --target flag
|
||||
which accepts the values "local", "remote", or <URL>. By default the
|
||||
local Function instance is chosen if running (see {{.Prefix}}func run).
|
||||
local Function instance is chosen if running (see {{.Name}} run).
|
||||
To explicitly target the remote (deployed) Function:
|
||||
{{.Prefix}}func invoke --target=remote
|
||||
{{.Name}} invoke --target=remote
|
||||
To target an arbitrary endpoint, provide a URL:
|
||||
{{.Prefix}}func invoke --target=https://myfunction.example.com
|
||||
{{.Name}} invoke --target=https://myfunction.example.com
|
||||
|
||||
Invocation Data
|
||||
Providing a filename in the --file flag will base64 encode its contents
|
||||
as the "data" parameter sent to the Function. The value of --content-type
|
||||
should be set to the type from the source file. For example, the following
|
||||
would send a JPEG base64 encoded in the "data" POST parameter:
|
||||
{{.Prefix}}func invoke --file=example.jpeg --content-type=image/jpeg
|
||||
{{.Name}} invoke --file=example.jpeg --content-type=image/jpeg
|
||||
|
||||
Message Format
|
||||
By default Functions are sent messages which match the invocation format
|
||||
of the template they were created using; for example "http" or "cloudevent".
|
||||
To override this behavior, use the --format (-f) flag.
|
||||
{{.Prefix}}func invoke -f=cloudevent -t=http://my-sink.my-cluster
|
||||
{{.Name}} invoke -f=cloudevent -t=http://my-sink.my-cluster
|
||||
|
||||
EXAMPLES
|
||||
|
||||
o Invoke the default (local or remote) running Function with default values
|
||||
$ {{.Prefix}}func invoke
|
||||
$ {{.Name}} invoke
|
||||
|
||||
o Run the Function locally and then invoke it with a test request:
|
||||
(run in two terminals or by running the first in the background)
|
||||
$ {{.Prefix}}func run
|
||||
$ {{.Prefix}}func invoke
|
||||
$ {{.Name}} run
|
||||
$ {{.Name}} invoke
|
||||
|
||||
o Deploy and then invoke the remote Function:
|
||||
$ {{.Prefix}}func deploy
|
||||
$ {{.Prefix}}func invoke
|
||||
$ {{.Name}} deploy
|
||||
$ {{.Name}} invoke
|
||||
|
||||
o Invoke a remote (deployed) Function when it is already running locally:
|
||||
(overrides the default behavior of preferring locally running instances)
|
||||
$ {{.Prefix}}func invoke --target=remote
|
||||
$ {{.Name}} invoke --target=remote
|
||||
|
||||
o Specify the data to send to the Function as a flag
|
||||
$ {{.Prefix}}func invoke --data="Hello World!"
|
||||
$ {{.Name}} invoke --data="Hello World!"
|
||||
|
||||
o Send a JPEG to the Function
|
||||
$ {{.Prefix}}func invoke --file=example.jpeg --content-type=image/jpeg
|
||||
$ {{.Name}} invoke --file=example.jpeg --content-type=image/jpeg
|
||||
|
||||
o Invoke an arbitrary endpoint (HTTP POST)
|
||||
$ {{.Prefix}}func invoke --target="https://my-http-handler.example.com"
|
||||
$ {{.Name}} invoke --target="https://my-http-handler.example.com"
|
||||
|
||||
o Invoke an arbitrary endpoint (CloudEvent)
|
||||
$ {{.Prefix}}func invoke -f=cloudevent -t="https://my-event-broker.example.com"
|
||||
$ {{.Name}} invoke -f=cloudevent -t="https://my-event-broker.example.com"
|
||||
|
||||
`,
|
||||
SuggestFor: []string{"emit", "emti", "send", "emit", "exec", "nivoke", "onvoke", "unvoke", "knvoke", "imvoke", "ihvoke", "ibvoke"},
|
||||
|
|
@ -203,9 +199,9 @@ func runInvokeHelp(cmd *cobra.Command, args []string, clientFn invokeClientFn) {
|
|||
)
|
||||
|
||||
var data = struct {
|
||||
Prefix string
|
||||
Name string
|
||||
}{
|
||||
Prefix: pluginPrefix(),
|
||||
Name: cmd.Root().Name(),
|
||||
}
|
||||
|
||||
if err := tpl.Execute(cmd.OutOrStdout(), data); err != nil {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/knative"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(NewListCmd(newListClient))
|
||||
}
|
||||
|
||||
func newListClient(cfg listConfig) (*fn.Client, error) {
|
||||
// TODO(lkingland): does an empty namespace mean all namespaces
|
||||
// or the default namespace as defined in user's config?
|
||||
|
|
|
|||
|
|
@ -12,15 +12,6 @@ import (
|
|||
fn "knative.dev/kn-plugin-func"
|
||||
)
|
||||
|
||||
func init() {
|
||||
repositoryCmd := NewRepositoryCmd(newRepositoryClient)
|
||||
repositoryCmd.AddCommand(NewRepositoryListCmd(newRepositoryClient))
|
||||
repositoryCmd.AddCommand(NewRepositoryAddCmd(newRepositoryClient))
|
||||
repositoryCmd.AddCommand(NewRepositoryRenameCmd(newRepositoryClient))
|
||||
repositoryCmd.AddCommand(NewRepositoryRemoveCmd(newRepositoryClient))
|
||||
root.AddCommand(repositoryCmd)
|
||||
}
|
||||
|
||||
// repositoryClientFn is a function which yields both a client and the final
|
||||
// config used to instantiate.
|
||||
type repositoryClientFn func([]string) (repositoryConfig, RepositoryClient, error)
|
||||
|
|
@ -174,6 +165,12 @@ EXAMPLES
|
|||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return runRepository(cmd, args, clientFn)
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewRepositoryListCmd(newRepositoryClient))
|
||||
cmd.AddCommand(NewRepositoryAddCmd(newRepositoryClient))
|
||||
cmd.AddCommand(NewRepositoryRenameCmd(newRepositoryClient))
|
||||
cmd.AddCommand(NewRepositoryRemoveCmd(newRepositoryClient))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
|
|||
164
cmd/root.go
164
cmd/root.go
|
|
@ -2,7 +2,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
|
@ -29,69 +28,34 @@ var exampleTemplate = template.Must(template.New("example").Parse(`
|
|||
curl $(kn service describe myfunc -o url)
|
||||
`))
|
||||
|
||||
// The root of the command tree defines the command name, description, globally
|
||||
type RootCommandConfig struct {
|
||||
Name string // usually `func` or `kn func`
|
||||
Date string
|
||||
Version string
|
||||
Hash string
|
||||
}
|
||||
|
||||
// NewRootCmd creates the root of the command tree defines the command name, description, globally
|
||||
// available flags, etc. It has no action of its own, such that running the
|
||||
// resultant binary with no arguments prints the help/usage text.
|
||||
var root = &cobra.Command{
|
||||
Use: "func",
|
||||
Short: "Serverless Functions",
|
||||
SilenceErrors: true, // we explicitly handle errors in Execute()
|
||||
SilenceUsage: true, // no usage dump on error
|
||||
Long: `Serverless Functions
|
||||
func NewRootCmd(config RootCommandConfig) (*cobra.Command, error) {
|
||||
var err error
|
||||
|
||||
root := &cobra.Command{
|
||||
Use: config.Name,
|
||||
Short: "Serverless Functions",
|
||||
SilenceErrors: true, // we explicitly handle errors in Execute()
|
||||
SilenceUsage: true, // no usage dump on error
|
||||
Long: `Serverless Functions
|
||||
|
||||
Create, build and deploy Functions in serverless containers for multiple runtimes on Knative`,
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
root.Example, err = replaceNameInTemplate("func", "example")
|
||||
root.Example, err = replaceNameInTemplate(config.Name, "example")
|
||||
if err != nil {
|
||||
root.Example = "Usage could not be loaded"
|
||||
}
|
||||
}
|
||||
|
||||
func replaceNameInTemplate(name, template string) (string, error) {
|
||||
var buffer bytes.Buffer
|
||||
err := exampleTemplate.ExecuteTemplate(&buffer, template, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
// pluginPrefix returns an optional prefix for help commands based on the
|
||||
// value of the FUNC_PARENT_COMMAND environment variable.
|
||||
func pluginPrefix() string {
|
||||
parent := os.Getenv("FUNC_PARENT_COMMAND")
|
||||
if parent != "" {
|
||||
return parent + " "
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// NewRootCmd can be used to embed the func commands as a library, such as
|
||||
// a plugin in 'kn'.
|
||||
func NewRootCmd() (*cobra.Command, error) {
|
||||
// TODO: have 'kn' provide this environment variable, such that this works
|
||||
// generically, and works whether it is compiled in as a library or used via
|
||||
// the `kn-func` binary naming convention.
|
||||
os.Setenv("FUNC_PARENT_COMMAND", "kn")
|
||||
|
||||
// TODO: update the below to use the environment variable, and the general
|
||||
// structure seen in the create command's help text.
|
||||
root.Use = "kn func"
|
||||
var err error
|
||||
root.Example, err = replaceNameInTemplate("kn func", "example")
|
||||
if err != nil {
|
||||
root.Example = "Usage could not be loaded"
|
||||
}
|
||||
return root, err
|
||||
}
|
||||
|
||||
// When the code is loaded into memory upon invocation, the cobra/viper packages
|
||||
// are invoked to gather system context. This includes reading the configuration
|
||||
// file, environment variables, and parsing the command flags.
|
||||
func init() {
|
||||
// read in environment variables that match
|
||||
viper.AutomaticEnv()
|
||||
|
||||
|
|
@ -101,9 +65,9 @@ func init() {
|
|||
// which thus overrides both the default and the value read in from the
|
||||
// config file (i.e. flags always take highest precidence).
|
||||
root.PersistentFlags().BoolVarP(&verbose, "verbose", "v", verbose, "print verbose logs")
|
||||
err := viper.BindPFlag("verbose", root.PersistentFlags().Lookup("verbose"))
|
||||
err = viper.BindPFlag("verbose", root.PersistentFlags().Lookup("verbose"))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Override the --version template to match the output format from the
|
||||
|
|
@ -112,24 +76,38 @@ func init() {
|
|||
|
||||
// Prefix all environment variables with "FUNC_" to avoid collisions with other apps.
|
||||
viper.SetEnvPrefix("func")
|
||||
|
||||
version := Version{
|
||||
Date: config.Date,
|
||||
Vers: config.Version,
|
||||
Hash: config.Hash,
|
||||
}
|
||||
|
||||
root.Version = version.String()
|
||||
|
||||
root.AddCommand(NewVersionCmd(version))
|
||||
root.AddCommand(NewCreateCmd(newCreateClient))
|
||||
root.AddCommand(NewConfigCmd())
|
||||
root.AddCommand(NewBuildCmd(newBuildClient))
|
||||
root.AddCommand(NewDeployCmd(newDeployClient))
|
||||
root.AddCommand(NewDeleteCmd(newDeleteClient))
|
||||
root.AddCommand(NewInfoCmd(newInfoClient))
|
||||
root.AddCommand(NewListCmd(newListClient))
|
||||
root.AddCommand(NewInvokeCmd(newInvokeClient))
|
||||
root.AddCommand(NewRepositoryCmd(newRepositoryClient))
|
||||
root.AddCommand(NewRunCmd(newRunClient))
|
||||
root.AddCommand(NewCompletionCmd())
|
||||
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// Execute the command tree by executing the root command, which runs
|
||||
// according to the context defined by: the optional config file,
|
||||
// Environment Variables, command arguments and flags.
|
||||
func Execute(ctx context.Context) {
|
||||
// Sets version to a string partially populated by compile-time flags.
|
||||
root.Version = version.String()
|
||||
// Execute the root of the command tree.
|
||||
if err := root.ExecuteContext(ctx); err != nil {
|
||||
if ctx.Err() != nil {
|
||||
os.Exit(130)
|
||||
return
|
||||
}
|
||||
// Errors are printed to STDERR output and the process exits with code of 1.
|
||||
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
func replaceNameInTemplate(name, template string) (string, error) {
|
||||
var buffer bytes.Buffer
|
||||
err := exampleTemplate.ExecuteTemplate(&buffer, template, name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
|
@ -338,3 +316,45 @@ func setPathFlag(cmd *cobra.Command) {
|
|||
func setNamespaceFlag(cmd *cobra.Command) {
|
||||
cmd.Flags().StringP("namespace", "n", "", "The namespace on the cluster. By default, the namespace in func.yaml is used or the currently active namespace if not set in the configuration. (Env: $FUNC_NAMESPACE)")
|
||||
}
|
||||
|
||||
type Version struct {
|
||||
// Date of compilation
|
||||
Date string
|
||||
// Version tag of the git commit, or 'tip' if no tag.
|
||||
Vers string
|
||||
// Hash of the currently active git commit on build.
|
||||
Hash string
|
||||
// Verbose printing enabled for the string representation.
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
// If 'vers' is not a semver already, then the binary was built either
|
||||
// from an untagged git commit (set semver to v0.0.0), or was built
|
||||
// directly from source (set semver to v0.0.0-source).
|
||||
if strings.HasPrefix(v.Vers, "v") {
|
||||
// Was built via make with a tagged commit
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s-%s", v.Vers, v.Hash, v.Date)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
} else if v.Vers == "tip" {
|
||||
// Was built via make from an untagged commit
|
||||
v.Vers = "v0.0.0"
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s-%s", v.Vers, v.Hash, v.Date)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
} else {
|
||||
// Was likely built from source
|
||||
v.Vers = "v0.0.0"
|
||||
v.Hash = "source"
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s", v.Vers, v.Hash)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,11 @@ func TestRoot_mergeEnvMaps(t *testing.T) {
|
|||
|
||||
func TestRoot_CMDParameterized(t *testing.T) {
|
||||
|
||||
rootConfig := RootCommandConfig{
|
||||
Name: "func",
|
||||
}
|
||||
|
||||
root, _ := NewRootCmd(rootConfig)
|
||||
if root.Use != "func" {
|
||||
t.Fatalf("default command use should be \"func\".")
|
||||
}
|
||||
|
|
@ -129,13 +134,17 @@ func TestRoot_CMDParameterized(t *testing.T) {
|
|||
t.Fatalf("default command example should assume \"func\" as executable name. error: %v", err)
|
||||
}
|
||||
|
||||
cmd, err := NewRootCmd()
|
||||
rootConfig = RootCommandConfig{
|
||||
Name: "kn func",
|
||||
}
|
||||
|
||||
cmd, err := NewRootCmd(rootConfig)
|
||||
if cmd.Use != "kn func" && err != nil {
|
||||
t.Fatalf("plugin command use should be \"kn func\".")
|
||||
}
|
||||
|
||||
usageExample, _ = replaceNameInTemplate("kn func", "example")
|
||||
cmd, err = NewRootCmd()
|
||||
cmd, err = NewRootCmd(rootConfig)
|
||||
if cmd.Example != usageExample || err != nil {
|
||||
t.Fatalf("plugin command example should assume \"kn func\" as executable name. error: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ import (
|
|||
"knative.dev/kn-plugin-func/progress"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(NewRunCmd(newRunClient))
|
||||
}
|
||||
|
||||
func newRunClient(cfg runConfig) *fn.Client {
|
||||
bc := newBuildConfig()
|
||||
runner := docker.NewRunner()
|
||||
|
|
|
|||
|
|
@ -2,88 +2,25 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/ory/viper"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// metadata about the build process/binary etc.
|
||||
// Not populated if building from source with go build.
|
||||
// Set by the `make` targets.
|
||||
var version = Version{}
|
||||
func NewVersionCmd(version Version) *cobra.Command {
|
||||
runVersion := func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println(version)
|
||||
}
|
||||
|
||||
// SetMeta is called by `main` with any provided build metadata
|
||||
func SetMeta(date, vers, hash string) {
|
||||
version.Date = date // build timestamp
|
||||
version.Vers = vers // version tag
|
||||
version.Hash = hash // git commit hash
|
||||
}
|
||||
|
||||
func init() {
|
||||
root.AddCommand(versionCmd)
|
||||
}
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show the version",
|
||||
Long: `Show the version
|
||||
cmd := &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Show the version",
|
||||
Long: `Show the version
|
||||
|
||||
Use the --verbose option to include the build date stamp and commit hash"
|
||||
`,
|
||||
SuggestFor: []string{"vers", "verison"},
|
||||
Run: runVersion,
|
||||
}
|
||||
|
||||
func runVersion(cmd *cobra.Command, args []string) {
|
||||
// update version with the value of the (global) flag 'verbose'
|
||||
version.Verbose = viper.GetBool("verbose")
|
||||
|
||||
// version is the metadata, serialized.
|
||||
fmt.Println(version)
|
||||
}
|
||||
|
||||
// versionMetadata is set by the main package.
|
||||
// When compiled from source, they remain the zero value.
|
||||
// When compiled via `make`, they are initialized to the noted values.
|
||||
type Version struct {
|
||||
// Date of compilation
|
||||
Date string
|
||||
// Version tag of the git commit, or 'tip' if no tag.
|
||||
Vers string
|
||||
// Hash of the currently active git commit on build.
|
||||
Hash string
|
||||
// Verbose printing enabled for the string representation.
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
func (v Version) String() string {
|
||||
// If 'vers' is not a semver already, then the binary was built either
|
||||
// from an untagged git commit (set semver to v0.0.0), or was built
|
||||
// directly from source (set semver to v0.0.0-source).
|
||||
if strings.HasPrefix(v.Vers, "v") {
|
||||
// Was built via make with a tagged commit
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s-%s", v.Vers, v.Hash, v.Date)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
} else if v.Vers == "tip" {
|
||||
// Was built via make from an untagged commit
|
||||
v.Vers = "v0.0.0"
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s-%s", v.Vers, v.Hash, v.Date)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
} else {
|
||||
// Was likely built from source
|
||||
v.Vers = "v0.0.0"
|
||||
v.Hash = "source"
|
||||
if v.Verbose {
|
||||
return fmt.Sprintf("%s-%s", v.Vers, v.Hash)
|
||||
} else {
|
||||
return v.Vers
|
||||
}
|
||||
SuggestFor: []string{"vers", "verison"}, //nolint:misspell
|
||||
Run: runVersion,
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,13 +35,19 @@ func (f *funcPlugin) Execute(args []string) error {
|
|||
cancel()
|
||||
}()
|
||||
|
||||
rootCmd, _ := cmd.NewRootCmd()
|
||||
rootConfig := cmd.RootCommandConfig{
|
||||
Name: "kn func",
|
||||
}
|
||||
|
||||
info, _ := debug.ReadBuildInfo()
|
||||
for _, dep := range info.Deps {
|
||||
if strings.Contains(dep.Path, "knative.dev/kn-plugin-func") {
|
||||
cmd.SetMeta("", dep.Version, dep.Sum)
|
||||
rootConfig.Version, rootConfig.Hash = dep.Version, dep.Sum
|
||||
}
|
||||
}
|
||||
|
||||
rootCmd, _ := cmd.NewRootCmd(rootConfig)
|
||||
|
||||
oldArgs := os.Args
|
||||
defer (func() {
|
||||
os.Args = oldArgs
|
||||
|
|
|
|||
Loading…
Reference in New Issue