chore: refactor commands help to use templates (#1485)

* chore: extend help template engine and docs generator to get root use

* chore: refactor deploy cmd

* chore: refactor build cmd

* chore: refactor all relevant commands and remove defaultTemplatedHelp func

* chore: update docs

* chore: remove unused functions

* chore: add template func for rendering sub-templates

* chore: fix for typos
This commit is contained in:
Adam Boczek 2023-01-16 21:40:53 +01:00 committed by GitHub
parent ccfa475bf8
commit 2f021f118b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 147 additions and 232 deletions

View File

@ -23,11 +23,11 @@ func NewBuildCmd(newClient ClientFactory) *cobra.Command {
Short: "Build a Function",
Long: `
NAME
{{.Name}} build - Build a Function
{{rootCmdUse}} build - Build a Function
SYNOPSIS
{{.Name}} build [-r|--registry] [--builder] [--builder-image] [--push]
[--palatform] [-p|--path] [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} build [-r|--registry] [--builder] [--builder-image] [--push]
[--platform] [-p|--path] [-c|--confirm] [-v|--verbose]
DESCRIPTION
@ -37,7 +37,7 @@ DESCRIPTION
By default building is handled automatically when deploying (see the deploy
subcommand). However, sometimes it is useful to build a function container
outside of this normal deployment process, for example for testing or during
composition when integrationg with other systems. Additionally, the container
composition when integrating with other systems. Additionally, the container
can be pushed to the configured registry using the --push option.
When building a function for the first time, either a registry or explicit
@ -47,21 +47,21 @@ EXAMPLES
o Build a function container using the given registry.
The full image name will be calculated using the registry and function name.
$ {{.Name}} build --registry registry.example.com/alice
$ {{rootCmdUse}} build --registry registry.example.com/alice
o Build a function container using an explicit image name, ignoring registry
and function name.
$ {{.Name}} build --image registry.example.com/alice/f:latest
$ {{rootCmdUse}} build --image registry.example.com/alice/f:latest
o Rebuild a function using prior values to determine container name.
$ {{.Name}} build
$ {{rootCmdUse}} build
o Build a function specifying the Source-to-Image (S2I) builder
$ {{.Name}} build --builder=s2i
$ {{rootCmdUse}} build --builder=s2i
o Build a function specifying the Pack builder with a custom Buildpack
builder image.
$ {{.Name}} build --builder=pack --builder-image=cnbs/sample-builder:bionic
$ {{rootCmdUse}} build --builder=pack --builder-image=cnbs/sample-builder:bionic
`,
SuggestFor: []string{"biuld", "buidl", "built"},
@ -80,12 +80,12 @@ EXAMPLES
// Function Context
f, _ := fn.NewFunction(effectivePath())
if f.Initialized() {
cfg = cfg.Apply(f) // defined values on f take precidence over cfg defaults
cfg = cfg.Apply(f) // defined values on f take precedence over cfg defaults
}
// Flags
//
// NOTE on falag defaults:
// NOTE on flag defaults:
// Use the config value when available, as this will include global static
// defaults, user settings and the value from the function with context.
// Use the function struct for flag flags which are not globally configurable
@ -126,9 +126,6 @@ EXAMPLES
fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err)
}
// Help Text
cmd.SetHelpFunc(defaultTemplatedHelp)
return cmd
}
@ -150,7 +147,7 @@ func runBuild(cmd *cobra.Command, _ []string, newClient ClientFactory) (err erro
if err != nil {
return
}
f = cfg.Configure(f) // Updates f at path to include buil request values
f = cfg.Configure(f) // Updates f at path to include build request values
// Checks if there is a difference between defined registry and its value used as a prefix in the image tag
// In case of a mismatch a new image tag is created and used for build
@ -188,7 +185,7 @@ func runBuild(cmd *cobra.Command, _ []string, newClient ClientFactory) (err erro
defer done()
// TODO(lkingland): this write will be unnecessary when the client API is
// udated to accept function structs rather than a path as argument.
// updated to accept function structs rather than a path as argument.
if err = f.Write(); err != nil {
return
}
@ -203,7 +200,7 @@ func runBuild(cmd *cobra.Command, _ []string, newClient ClientFactory) (err erro
// TODO(lkingland): when the above Build and Push calls are refactored to not
// write the function but instead take and return a function struct, use
// `reuturn f.Write()` below and remove from above such that function on disk
// `return f.Write()` below and remove from above such that function on disk
// is only written on success and thus is always in a known valid state unless
// manually edited.
// return f.Write()
@ -264,7 +261,7 @@ func (c buildConfig) Configure(f fn.Function) fn.Function {
return f
}
// Prompt the user with value of config members, allowing for interaractive changes.
// Prompt the user with value of config members, allowing for interactive changes.
// Skipped if not in an interactive terminal (non-TTY), or if --confirm false (agree to
// all prompts) was set (default).
func (c buildConfig) Prompt() (buildConfig, error) {
@ -301,8 +298,8 @@ func (c buildConfig) Prompt() (buildConfig, error) {
}
// Image Name Override
// Calculate a better image name mesage which shows the value of the final
// image name as it will be calclated if an explicit image name is not used.
// Calculate a better image name message which shows the value of the final
// image name as it will be calculated if an explicit image name is not used.
var imagePromptMessageSuffix string
if name := deriveImage(c.Image, c.Registry, c.Path); name != "" {
imagePromptMessageSuffix = fmt.Sprintf(". if not specified, the default '%v' will be used')", name)
@ -337,7 +334,7 @@ func (c buildConfig) Validate() (err error) {
return
}
// Platform is only supportd with the S2I builder at this time
// Platform is only supported with the S2I builder at this time
if c.Platform != "" && c.Builder != builders.S2I {
err = errors.New("Only S2I builds currently support specifying platform")
return

View File

@ -56,7 +56,6 @@ or from the directory specified with --path.
PreRunE: bindEnv("path"),
RunE: runConfigCmd,
}
cmd.SetHelpFunc(defaultTemplatedHelp)
setPathFlag(cmd)

View File

@ -66,22 +66,22 @@ The environment variable can be set directly from a value,
from an environment variable on the local machine or from Secrets and ConfigMaps.
It is also possible to import all keys as environment variables from a Secret or ConfigMap.`,
Example: `# set environment variable directly
{{.Name}} config envs add --name=VARNAME --value=myValue
{{rootCmdUse}} config envs add --name=VARNAME --value=myValue
# set environment variable from local env $LOC_ENV
{{.Name}} config envs add --name=VARNAME --value='{{"{{"}} env:LOC_ENV {{"}}"}}'
{{rootCmdUse}} config envs add --name=VARNAME --value='{{"{{"}} env:LOC_ENV {{"}}"}}'
set environment variable from a secret
{{.Name}} config envs add --name=VARNAME --value='{{"{{"}} secret:secretName:key {{"}}"}}'
{{rootCmdUse}} config envs add --name=VARNAME --value='{{"{{"}} secret:secretName:key {{"}}"}}'
# set all key as environment variables from a secret
{{.Name}} config envs add --value='{{"{{"}} secret:secretName {{"}}"}}'
{{rootCmdUse}} config envs add --value='{{"{{"}} secret:secretName {{"}}"}}'
# set environment variable from a configMap
{{.Name}} config envs add --name=VARNAME --value='{{"{{"}} configMap:confMapName:key {{"}}"}}'
{{rootCmdUse}} config envs add --name=VARNAME --value='{{"{{"}} configMap:confMapName:key {{"}}"}}'
# set all key as environment variables from a configMap
{{.Name}} config envs add --value='{{"{{"}} configMap:confMapName {{"}}"}}'`,
{{rootCmdUse}} config envs add --value='{{"{{"}} configMap:confMapName {{"}}"}}'`,
SuggestFor: []string{"ad", "create", "insert", "append"},
PreRunE: bindEnv("path", "name", "value"),
RunE: func(cmd *cobra.Command, args []string) (err error) {
@ -126,7 +126,6 @@ set environment variable from a secret
cmd.Flags().StringP("name", "", "", "Name of the environment variable.")
cmd.Flags().StringP("value", "", "", "Value of the environment variable.")
cmd.SetHelpFunc(defaultTemplatedHelp)
return cmd
}

View File

@ -34,7 +34,6 @@ the current directory or from the directory specified with --path.
return
},
}
configLabelsCmd.SetHelpFunc(defaultTemplatedHelp)
var configLabelsAddCmd = &cobra.Command{
Use: "add",
@ -58,7 +57,6 @@ the local machine.
return runAddLabelsPrompt(cmd.Context(), function, loaderSaver)
},
}
configLabelsAddCmd.SetHelpFunc(defaultTemplatedHelp)
var configLabelsRemoveCmd = &cobra.Command{
Use: "remove",
@ -79,7 +77,6 @@ directory or from the directory specified with --path.
return runRemoveLabelsPrompt(function, loaderSaver)
},
}
configLabelsRemoveCmd.SetHelpFunc(defaultTemplatedHelp)
setPathFlag(configLabelsCmd)
setPathFlag(configLabelsAddCmd)

View File

@ -34,7 +34,6 @@ the current directory or from the directory specified with --path.
return
},
}
cmd.SetHelpFunc(defaultTemplatedHelp)
configVolumesAddCmd := NewConfigVolumesAddCmd()
configVolumesRemoveCmd := NewConfigVolumesRemoveCmd()
@ -69,7 +68,7 @@ in the current directory or from the directory specified with --path.
return runAddVolumesPrompt(cmd.Context(), function)
},
}
cmd.SetHelpFunc(defaultTemplatedHelp)
return cmd
}
@ -93,7 +92,7 @@ in the current directory or from the directory specified with --path.
return runRemoveVolumesPrompt(function)
},
}
cmd.SetHelpFunc(defaultTemplatedHelp)
return cmd
}

View File

@ -6,7 +6,6 @@ import (
"os"
"strings"
"text/tabwriter"
"text/template"
"github.com/AlecAivazis/survey/v2"
"github.com/ory/viper"
@ -33,16 +32,16 @@ func NewCreateCmd(newClient ClientFactory) *cobra.Command {
Short: "Create a function project",
Long: `
NAME
{{.Name}} create - Create a function project.
{{rootCmdUse}} create - Create a function project.
SYNOPSIS
{{.Name}} create [-l|--language] [-t|--template] [-r|--repository]
{{rootCmdUse}} create [-l|--language] [-t|--template] [-r|--repository]
[-c|--confirm] [-v|--verbose] [path]
DESCRIPTION
Creates a new function project.
$ {{.Name}} create -l node -t http
$ {{rootCmdUse}} create -l node -t http
Creates a function in the current directory '.' which is written in the
language/runtime 'node' and handles HTTP events.
@ -51,25 +50,25 @@ DESCRIPTION
the path if necessary.
To complete this command interactively, use --confirm (-c):
$ {{.Name}} create -c
$ {{rootCmdUse}} create -c
Available Language Runtimes and Templates:
{{ .Options | indent 2 " " | indent 1 "\t" }}
To install more language runtimes and their templates see '{{.Name}} repository'.
To install more language runtimes and their templates see '{{rootCmdUse}} 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).
$ {{.Name}} create
$ {{rootCmdUse}} create
o Create a Node.js function in the directory 'myfunc'.
$ {{.Name}} create myfunc
$ {{rootCmdUse}} create myfunc
o Create a Go function which handles CloudEvents in ./myfunc.
$ {{.Name}} create -l go -t cloudevents myfunc
$ {{rootCmdUse}} create -l go -t cloudevents myfunc
`,
SuggestFor: []string{"vreate", "creaet", "craete", "new"},
PreRunE: bindEnv("language", "template", "repository", "confirm"),
@ -87,9 +86,6 @@ EXAMPLES
cmd.Flags().StringP("repository", "r", "", "URI to a Git repository containing the specified template (Env: $FUNC_REPOSITORY)")
cmd.Flags().BoolP("confirm", "c", cfg.Confirm, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)")
// Help Action
cmd.SetHelpFunc(func(cmd *cobra.Command, args []string) { runCreateHelp(cmd, args, newClient) })
// Run Action
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runCreate(cmd, args, newClient)
@ -146,43 +142,6 @@ func runCreate(cmd *cobra.Command, args []string, newClient ClientFactory) (err
return nil
}
// Run Help
func runCreateHelp(cmd *cobra.Command, args []string, newClient ClientFactory) {
// Error-tolerant implementation:
// Help can not fail when creating the client config (such as on invalid
// flag values) because help text is needed in that situation. Therefore,
// this implementation must be resilient to cfg zero value.
failSoft := func(err error) {
if err != nil {
fmt.Fprintf(cmd.OutOrStderr(), "error: help text may be partial: %v", err)
}
}
tpl := createHelpTemplate(cmd)
cfg, err := newCreateConfig(cmd, args, newClient)
failSoft(err)
client, done := newClient(
ClientConfig{Verbose: cfg.Verbose},
fn.WithRepository(cfg.Repository))
defer done()
options, err := RuntimeTemplateOptions(client) // human-friendly
failSoft(err)
var data = struct {
Options string
Name string
}{
Options: options,
Name: cmd.Root().Use,
}
if err := tpl.Execute(cmd.OutOrStdout(), data); err != nil {
fmt.Fprintf(cmd.ErrOrStderr(), "unable to display help text: %v", err)
}
}
type createConfig struct {
Path string // Absolute path to function source
Runtime string // Language Runtime
@ -529,23 +488,6 @@ func templatesWithPrefix(prefix, runtime string, client *fn.Client) ([]string, e
return suggestions, nil
}
// Template Helpers
// ---------------
// createHelpTemplate is the template for the create command help
func createHelpTemplate(cmd *cobra.Command) *template.Template {
body := cmd.Long + "\n\n" + cmd.UsageString()
t := template.New("help")
fm := template.FuncMap{
"indent": func(i int, c string, v string) string {
indentation := strings.Repeat(c, i)
return indentation + strings.Replace(v, "\n", "\n"+indentation, -1)
},
}
t.Funcs(fm)
return template.Must(t.Parse(body))
}
// RuntimeTemplateOptions is a human-friendly table of valid Language Runtime
// to Template combinations.
func RuntimeTemplateOptions(client *fn.Client) (string, error) {

View File

@ -13,7 +13,7 @@ import (
func NewDeleteCmd(newClient ClientFactory) *cobra.Command {
cmd := &cobra.Command{
Use: "delete [NAME]",
Use: "delete <name>",
Short: "Undeploy a function",
Long: `Undeploy a function
@ -25,10 +25,10 @@ No local files are deleted.
`,
Example: `
# Undeploy the function defined in the local directory
{{.Name}} delete
{{rootCmdUse}} delete
# Undeploy the function 'myfunc' in namespace 'apps'
{{.Name}} delete -n apps myfunc
{{rootCmdUse}} delete -n apps myfunc
`,
SuggestFor: []string{"remove", "rm", "del"},
ValidArgsFunction: CompleteFunctionList,
@ -48,8 +48,6 @@ No local files are deleted.
cmd.Flags().StringP("all", "a", "true", "Delete all resources created for a function, eg. Pipelines, Secrets, etc. (Env: $FUNC_ALL) (allowed values: \"true\", \"false\")")
setPathFlag(cmd)
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runDelete(cmd, args, newClient)
}

View File

@ -33,10 +33,10 @@ func NewDeployCmd(newClient ClientFactory) *cobra.Command {
Short: "Deploy a Function",
Long: `
NAME
{{.Name}} deploy - Deploy a Function
{{rootCmdUse}} deploy - Deploy a Function
SYNOPSIS
{{.Name}} deploy [-R|--remote] [-r|--registry] [-i|--image] [-n|--namespace]
{{rootCmdUse}} deploy [-R|--remote] [-r|--registry] [-i|--image] [-n|--namespace]
[-e|env] [-g|--git-url] [-t|git-branch] [-d|--git-dir]
[-b|--build] [--builder] [--builder-image] [-p|--push]
[--platform] [-c|--confirm] [-v|--verbose]
@ -71,52 +71,52 @@ DESCRIPTION
registry after being successfully built. The --push flag can be used
to disable pushing. This could be used, for example, to trigger a redeploy
of a service without needing to build, or even have the container available
locally with '{{.Name}} deploy --build=false --push==false'.
locally with '{{rootCmdUse}} deploy --build=false --push==false'.
Remote
Building and pushing (deploying) is by default run on localhost. This
process can also be triggered to run remotely in a Tekton-enabled cluster.
The --remote flag indicates that a build and deploy pipeline should be
invoked in the remote. Deploying with '{{.Name}} deploy --remote' will
invoked in the remote. Deploying with '{{rootCmdUse}} deploy --remote' will
send the function's source code to be built and deployed by the cluster,
eliminating the need for a local container engine. To trigger deployment
of a git repository instead of local source, combine with '--git-url':
'{{.Name}} deploy --remote --git-url=git.example.com/alice/f.git'
'{{rootCmdUse}} deploy --remote --git-url=git.example.com/alice/f.git'
EXAMPLES
o Deploy the function using interactive prompts. This is useful for the first
deployment, since most settings will be remembered for future deployments.
$ {{.Name}} deploy -c
$ {{rootCmdUse}} deploy -c
o Deploy the function in the current working directory.
The function image will be pushed to "ghcr.io/alice/<Function Name>"
$ {{.Name}} deploy --registry ghcr.io/alice
$ {{rootCmdUse}} deploy --registry ghcr.io/alice
o Deploy the function in the current working directory, manually specifying
the final image name and target cluster namespace.
$ {{.Name}} deploy --image ghcr.io/alice/myfunc --namespace myns
$ {{rootCmdUse}} deploy --image ghcr.io/alice/myfunc --namespace myns
o Deploy the current function's source code by sending it to the cluster to
be built and deployed:
$ {{.Name}} deploy --remote
$ {{rootCmdUse}} deploy --remote
o Trigger a remote deploy, which instructs the cluster to build and deploy
the function in the specified git repository.
$ {{.Name}} deploy --remote --git-url=https://example.com/alice/myfunc.git
$ {{rootCmdUse}} deploy --remote --git-url=https://example.com/alice/myfunc.git
o Deploy the function, rebuilding the image even if no changes have been
detected in the local filesystem (source).
$ {{.Name}} deploy --build
$ {{rootCmdUse}} deploy --build
o Deploy without rebuilding, even if changes have been detected in the
local filesystem.
$ {{.Name}} deploy --build=false
$ {{rootCmdUse}} deploy --build=false
o Redeploy a function which has already been built and pushed. Works without
the use of a local container engine. For example, if the function was
manually deleted from the cluster, it can be quickly redeployed with:
$ {{.Name}} deploy --build=false --push=false
$ {{rootCmdUse}} deploy --build=false --push=false
`,
SuggestFor: []string{"delpoy", "deplyo"},
@ -159,8 +159,6 @@ EXAMPLES
fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err)
}
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runDeploy(cmd, args, newClient)
}

View File

@ -26,10 +26,10 @@ the current directory or from the directory specified with --path.
`,
Example: `
# Show the details of a function as declared in the local func.yaml
{{.Name}} info
{{rootCmdUse}} describe
# Show the details of the function in the directory with yaml output
{{.Name}} info --output yaml --path myotherfunc
{{rootCmdUse}} describe --output yaml --path myotherfunc
`,
SuggestFor: []string{"ifno", "fino", "get"},
@ -53,8 +53,6 @@ the current directory or from the directory specified with --path.
fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err)
}
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runDescribe(cmd, args, newClient)
}

View File

@ -21,10 +21,10 @@ func NewInvokeCmd(newClient ClientFactory) *cobra.Command {
Short: "Invoke a function",
Long: `
NAME
{{.Name}} invoke - test a function by invoking it with test data
{{rootCmdUse}} invoke - test a function by invoking it with test data
SYNOPSIS
{{.Name}} invoke [-t|--target] [-f|--format]
{{rootCmdUse}} invoke [-t|--target] [-f|--format]
[--id] [--source] [--type] [--data] [--file] [--content-type]
[-s|--save] [-p|--path] [-i|--insecure] [-c|--confirm] [-v|--verbose]
@ -48,57 +48,57 @@ 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 {{.Name}} run).
local function instance is chosen if running (see {{rootCmdUse}} run).
To explicitly target the remote (deployed) function:
{{.Name}} invoke --target=remote
{{rootCmdUse}} invoke --target=remote
To target an arbitrary endpoint, provide a URL:
{{.Name}} invoke --target=https://myfunction.example.com
{{rootCmdUse}} 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:
{{.Name}} invoke --file=example.jpeg --content-type=image/jpeg
{{rootCmdUse}} 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.
{{.Name}} invoke -f=cloudevent -t=http://my-sink.my-cluster
{{rootCmdUse}} invoke -f=cloudevent -t=http://my-sink.my-cluster
EXAMPLES
o Invoke the default (local or remote) running function with default values
$ {{.Name}} invoke
$ {{rootCmdUse}} 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)
$ {{.Name}} run
$ {{.Name}} invoke
$ {{rootCmdUse}} run
$ {{rootCmdUse}} invoke
o Deploy and then invoke the remote function:
$ {{.Name}} deploy
$ {{.Name}} invoke
$ {{rootCmdUse}} deploy
$ {{rootCmdUse}} invoke
o Invoke a remote (deployed) function when it is already running locally:
(overrides the default behavior of preferring locally running instances)
$ {{.Name}} invoke --target=remote
$ {{rootCmdUse}} invoke --target=remote
o Specify the data to send to the function as a flag
$ {{.Name}} invoke --data="Hello World!"
$ {{rootCmdUse}} invoke --data="Hello World!"
o Send a JPEG to the function
$ {{.Name}} invoke --file=example.jpeg --content-type=image/jpeg
$ {{rootCmdUse}} invoke --file=example.jpeg --content-type=image/jpeg
o Invoke an arbitrary endpoint (HTTP POST)
$ {{.Name}} invoke --target="https://my-http-handler.example.com"
$ {{rootCmdUse}} invoke --target="https://my-http-handler.example.com"
o Invoke an arbitrary endpoint (CloudEvent)
$ {{.Name}} invoke -f=cloudevent -t="https://my-event-broker.example.com"
$ {{rootCmdUse}} invoke -f=cloudevent -t="https://my-event-broker.example.com"
o Allow insecure server connections when using SSL
$ {{.Name}} invoke --insecure
$ {{rootCmdUse}} invoke --insecure
`,
SuggestFor: []string{"emit", "emti", "send", "emit", "exec", "nivoke", "onvoke", "unvoke", "knvoke", "imvoke", "ihvoke", "ibvoke"},
@ -124,8 +124,6 @@ EXAMPLES
cmd.Flags().BoolP("insecure", "i", false, "Allow insecure server connections when using SSL. (Env: $FUNC_INSECURE)")
cmd.Flags().BoolP("confirm", "c", cfg.Confirm, "Prompt to confirm all options interactively. (Env: $FUNC_CONFIRM)")
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runInvoke(cmd, args, newClient)
}

View File

@ -16,10 +16,10 @@ func NewLanguagesCmd(newClient ClientFactory) *cobra.Command {
Short: "List available function language runtimes",
Long: `
NAME
{{.Name}} languages - list available language runtimes.
{{rootCmdUse}} languages - list available language runtimes.
SYNOPSIS
{{.Name}} languages [--json] [-r|--repository]
{{rootCmdUse}} languages [--json] [-r|--repository]
DESCRIPTION
List the language runtimes that are currently available.
@ -39,13 +39,13 @@ DESCRIPTION
EXAMPLES
o Show a list of all available language runtimes
$ {{.Name}} languages
$ {{rootCmdUse}} languages
o Return a list of all language runtimes in JSON
$ {{.Name}} languages --json
$ {{rootCmdUse}} languages --json
o Return language runtimes in a specific repository
$ {{.Name}} languages --repository=https://github.com/boson-project/templates
$ {{rootCmdUse}} languages --repository=https://github.com/boson-project/templates
`,
SuggestFor: []string{"language", "runtime", "runtimes", "lnaguages", "languagse",
"panguages", "manguages", "kanguages", "lsnguages", "lznguages"},
@ -55,8 +55,6 @@ EXAMPLES
cmd.Flags().BoolP("json", "", false, "Set output to JSON format. (Env: $FUNC_JSON)")
cmd.Flags().StringP("repository", "r", "", "URI to a specific repository to consider (Env: $FUNC_REPOSITORY)")
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runLanguages(cmd, args, newClient)
}

View File

@ -27,13 +27,13 @@ Lists all deployed functions in a given namespace.
`,
Example: `
# List all functions in the current namespace with human readable output
{{.Name}} list
{{rootCmdUse}} list
# List all functions in the 'test' namespace with yaml output
{{.Name}} list --namespace test --output yaml
{{rootCmdUse}} list --namespace test --output yaml
# List all functions in all namespaces with JSON output
{{.Name}} list --all-namespaces --output json
{{rootCmdUse}} list --all-namespaces --output json
`,
SuggestFor: []string{"ls", "lsit"},
PreRunE: bindEnv("all-namespaces", "output", "namespace"),
@ -54,8 +54,6 @@ Lists all deployed functions in a given namespace.
fmt.Println("internal: error while calling RegisterFlagCompletionFunc: ", err)
}
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runList(cmd, args, newClient)
}

View File

@ -23,14 +23,14 @@ func NewRepositoryCmd(newClient ClientFactory) *cobra.Command {
Aliases: []string{"repo", "repositories"},
Long: `
NAME
{{.Name}} - Manage set of installed repositories.
{{rootCmdUse}} - Manage set of installed repositories.
SYNOPSIS
{{.Name}} repo [-c|--confirm] [-v|--verbose]
{{.Name}} repo list [-r|--repositories] [-c|--confirm] [-v|--verbose]
{{.Name}} repo add <name> <url>[-r|--repositories] [-c|--confirm] [-v|--verbose]
{{.Name}} repo rename <old> <new> [-r|--repositories] [-c|--confirm] [-v|--verbose]
{{.Name}} repo remove <name> [-r|--repositories] [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} repo [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} repo list [-r|--repositories] [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} repo add <name> <url>[-r|--repositories] [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} repo rename <old> <new> [-r|--repositories] [-c|--confirm] [-v|--verbose]
{{rootCmdUse}} repo remove <name> [-r|--repositories] [-c|--confirm] [-v|--verbose]
DESCRIPTION
Manage template repositories installed on disk at either the default location
@ -49,7 +49,7 @@ DESCRIPTION
specifying a repository name prefix.
For example, to create a new Go function using the 'http' template from the
default repository.
$ {{.Name}} create -l go -t http
$ {{rootCmdUse}} create -l go -t http
The Repository Flag:
Installing repositories locally is optional. To use a template from a remote
@ -57,7 +57,7 @@ DESCRIPTION
This leaves the local disk untouched. For example, To create a function using
the Boson Project Hello-World template without installing the template
repository locally, use the --repository (-r) flag on create:
$ {{.Name}} create -l go \
$ {{rootCmdUse}} create -l go \
--template hello-world \
--repository https://github.com/boson-project/templates
@ -71,19 +71,19 @@ COMMANDS
With no arguments, this help text is shown. To manage repositories with
an interactive prompt, use the use the --confirm (-c) flag.
$ {{.Name}} repository -c
$ {{rootCmdUse}} repository -c
add
Add a new repository to the installed set.
$ {{.Name}} repository add <name> <URL>
$ {{rootCmdUse}} repository add <name> <URL>
For Example, to add the Boson Project repository:
$ {{.Name}} repository add boson https://github.com/boson-project/templates
$ {{rootCmdUse}} repository add boson https://github.com/boson-project/templates
Once added, a function can be created with templates from the new repository
by prefixing the template name with the repository. For example, to create
a new function using the Go Hello World template:
$ {{.Name}} create -l go -t boson/hello-world
$ {{rootCmdUse}} create -l go -t boson/hello-world
list
List all available repositories, including the installed default
@ -93,7 +93,7 @@ COMMANDS
rename
Rename a previously installed repository from <old> to <new>. Only installed
repositories can be renamed.
$ {{.Name}} repository rename <name> <new name>
$ {{rootCmdUse}} repository rename <name> <new name>
remove
Remove a repository by name. Removes the repository from local storage
@ -101,40 +101,40 @@ COMMANDS
deletion, but in regular mode this is done immediately, so please use
caution, especially when using an altered repositories location
(via the FUNC_REPOSITORIES_PATH environment variable).
$ {{.Name}} repository remove <name>
$ {{rootCmdUse}} repository remove <name>
EXAMPLES
o Run in confirmation mode (interactive prompts) using the --confirm flag
$ {{.Name}} repository -c
$ {{rootCmdUse}} repository -c
o Add a repository and create a new function using a template from it:
$ {{.Name}} repository add boson https://github.com/boson-project/templates
$ {{.Name}} repository list
$ {{rootCmdUse}} repository add boson https://github.com/boson-project/templates
$ {{rootCmdUse}} repository list
default
boson
$ {{.Name}} create -l go -t boson/hello-world
$ {{rootCmdUse}} create -l go -t boson/hello-world
...
o List all repositories including the URL from which remotes were installed
$ {{.Name}} repository list -v
$ {{rootCmdUse}} repository list -v
default
boson https://github.com/boson-project/templates
o Rename an installed repository
$ {{.Name}} repository list
$ {{rootCmdUse}} repository list
default
boson
$ {{.Name}} repository rename boson boson-examples
$ {{.Name}} repository list
$ {{rootCmdUse}} repository rename boson boson-examples
$ {{rootCmdUse}} repository list
default
boson-examples
o Remove an installed repository
$ {{.Name}} repository list
$ {{rootCmdUse}} repository list
default
boson-examples
$ {{.Name}} repository remove boson-examples
$ {{.Name}} repository list
$ {{rootCmdUse}} repository remove boson-examples
$ {{rootCmdUse}} repository list
default
`,
SuggestFor: []string{"repositories", "repos", "template", "templates", "pack", "packs"},
@ -150,8 +150,6 @@ EXAMPLES
// Flags
cmd.Flags().BoolP("confirm", "c", cfg.Confirm, "Prompt to confirm all options interactively (Env: $FUNC_CONFIRM)")
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runRepository(cmd, args, newClient)
}

View File

@ -8,7 +8,6 @@ import (
"path/filepath"
"strings"
"testing"
"text/template"
"time"
"knative.dev/func/cmd/templates"
@ -454,22 +453,6 @@ func surveySelectDefault(value string, options []string) string {
return ""
}
// defaultTemplatedHelp evaluates the given command's help text as a template
// some commands define their own help command when additional values are
// required beyond these basics.
func defaultTemplatedHelp(cmd *cobra.Command, args []string) {
var (
body = cmd.Long + "\n\n" + cmd.UsageString()
t = template.New("help")
tpl = template.Must(t.Parse(body))
)
var data = struct{ Name string }{Name: cmd.Root().Use}
if err := tpl.Execute(cmd.OutOrStdout(), data); err != nil {
fmt.Fprintf(cmd.ErrOrStderr(), "unable to display help text: %v", err)
}
}
// clearEnvs sets all environment variables with the prefix of FUNC_ to
// empty (unsets) for the duration of the test t.
func clearEnvs(t *testing.T) {

View File

@ -29,17 +29,17 @@ to the function's source. Use --build to override this behavior.
`,
Example: `
# Run the function locally, building if necessary
{{.Name}} run
{{rootCmdUse}} run
# Run the function, forcing a rebuild of the image.
# This is useful when the function's image was manually deleted, necessitating
# A rebuild even when no changes have been made the function's source.
{{.Name}} run --build
{{rootCmdUse}} run --build
# Run the function's existing image, disabling auto-build.
# This is useful when filesystem changes have been made, but one wishes to
# run the previously built image without rebuilding.
{{.Name}} run --build=false
{{rootCmdUse}} run --build=false
`,
SuggestFor: []string{"rnu"},
@ -55,8 +55,6 @@ to the function's source. Use --build to override this behavior.
cmd.Flags().StringP("registry", "r", "", "Registry + namespace part of the image if building, ex 'quay.io/myuser' (Env: $FUNC_REGISTRY)")
setPathFlag(cmd)
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runRun(cmd, args, newClient)
}

View File

@ -23,10 +23,10 @@ func NewTemplatesCmd(newClient ClientFactory) *cobra.Command {
Short: "Templates",
Long: `
NAME
{{.Name}} templates - list available templates
{{rootCmdUse}} templates - list available templates
SYNOPSIS
{{.Name}} templates [language] [--json] [-r|--repository]
{{rootCmdUse}} templates [language] [--json] [-r|--repository]
DESCRIPTION
List all templates available, optionally for a specific language runtime.
@ -44,16 +44,16 @@ DESCRIPTION
EXAMPLES
o Show a list of all available templates grouped by language runtime
$ {{.Name}} templates
$ {{rootCmdUse}} templates
o Show a list of all templates for the Go runtime
$ {{.Name}} templates go
$ {{rootCmdUse}} templates go
o Return a list of all template runtimes in JSON output format
$ {{.Name}} templates --json
$ {{rootCmdUse}} templates --json
o Return Go templates in a specific repository
$ {{.Name}} templates go --repository=https://github.com/boson-project/templates
$ {{rootCmdUse}} templates go --repository=https://github.com/boson-project/templates
`,
SuggestFor: []string{"template", "templtaes", "templatse", "remplates",
"gemplates", "yemplates", "tenplates", "tekplates", "tejplates",
@ -66,8 +66,6 @@ EXAMPLES
cmd.Flags().Bool("json", false, "Set output to JSON format. (Env: $FUNC_JSON)")
cmd.Flags().StringP("repository", "r", "", "URI to a specific repository to consider (Env: $FUNC_REPOSITORY)")
cmd.SetHelpFunc(defaultTemplatedHelp)
cmd.RunE = func(cmd *cobra.Command, args []string) error {
return runTemplates(cmd, args, newClient)
}

View File

@ -85,14 +85,26 @@ func (e templateEngine) templateFunctions() template.FuncMap {
"visibleFlags": visibleFlags,
"rpad": rpad,
"rootCmdName": e.rootCmdName,
"rootCmdUse": e.rootCmdUse,
"isRootCmd": e.isRootCmd,
"flagsUsages": flagsUsagesCobra, // or use flagsUsagesKubectl for kubectl like flag styles
"trim": strings.TrimSpace,
"trimRight": func(s string) string { return strings.TrimRightFunc(s, unicode.IsSpace) },
"trimLeft": func(s string) string { return strings.TrimLeftFunc(s, unicode.IsSpace) },
"execTemplate": e.executeTemplate,
}
}
func (e templateEngine) executeTemplate(tbody string, data any) (string, error) {
t, err := template.New("").Funcs(e.templateFunctions()).Parse(tbody)
if err != nil {
return "", err
}
buf := &strings.Builder{}
err = t.Execute(buf, data)
return buf.String(), err
}
func (e templateEngine) cmdGroupsString() string {
groups := make([]string, 0, len(e.CommandGroups))
for _, cmdGroup := range e.CommandGroups {
@ -112,6 +124,10 @@ func (e templateEngine) rootCmdName() string {
return e.RootCmd.CommandPath()
}
func (e templateEngine) rootCmdUse() string {
return e.RootCmd.Use
}
func (e templateEngine) isRootCmd(c *cobra.Command) bool {
return e.RootCmd == c
}

View File

@ -38,7 +38,7 @@ const (
// sectionExamples is the help template section that displays command examples.
sectionExamples = `{{if .HasExample}}Examples:
{{trimRight .Example}}
{{trimRight (execTemplate .Example .)}}
{{end}}`

View File

@ -13,29 +13,26 @@ func NewVersionCmd(version Version) *cobra.Command {
Short: "Show the version",
Long: `
NAME
{{.Name}} version - function version information.
{{rootCmdUse}} version - function version information.
SYNOPSIS
{{.Name}} version [-v|--verbose]
{{rootCmdUse}} version [-v|--verbose]
DESCRIPTION
Print version information. Use the --verbose option to see date stamp and
associated git source control hash if available.
o Print the functions version
$ {{.Name}} version
$ {{rootCmdUse}} version
o Print the functions version along with date and associated git commit hash.
$ {{.Name}} version -v
$ {{rootCmdUse}} version -v
`,
SuggestFor: []string{"vers", "verison"}, //nolint:misspell
PreRunE: bindEnv("verbose"),
}
// Help Action
cmd.SetHelpFunc(defaultTemplatedHelp)
// Run Action
cmd.Run = func(cmd *cobra.Command, args []string) {
runVersion(cmd, args, version)

View File

@ -23,6 +23,9 @@ var (
indentation := strings.Repeat(c, i)
return indentation + strings.Replace(v, "\n", "\n"+indentation, -1)
},
"rootCmdUse": func() string {
return rootName
},
}
rootName = "func"
@ -90,7 +93,7 @@ func ignoreConfigEnv() (done func()) {
// processSubCommands is a recursive function which writes the markdown text
// for all subcommands of the provided cobra command, prepending the parent
// string to the fiile name, and recursively calls itself for each subcommand.
// string to the file name, and recursively calls itself for each subcommand.
func processSubCommands(c *cobra.Command, parent string, opts TemplateOptions) error {
for _, cc := range c.Commands() {
name := cc.Name()
@ -100,6 +103,7 @@ func processSubCommands(c *cobra.Command, parent string, opts TemplateOptions) e
if parent != "" {
name = parent + "_" + name
}
opts.Use = cc.Use
if err := writeMarkdown(cc, name, opts); err != nil {
return err
}

View File

@ -10,7 +10,7 @@ NAME
SYNOPSIS
func build [-r|--registry] [--builder] [--builder-image] [--push]
[--palatform] [-p|--path] [-c|--confirm] [-v|--verbose]
[--platform] [-p|--path] [-c|--confirm] [-v|--verbose]
DESCRIPTION
@ -20,7 +20,7 @@ DESCRIPTION
By default building is handled automatically when deploying (see the deploy
subcommand). However, sometimes it is useful to build a function container
outside of this normal deployment process, for example for testing or during
composition when integrationg with other systems. Additionally, the container
composition when integrating with other systems. Additionally, the container
can be pushed to the configured registry using the --push option.
When building a function for the first time, either a registry or explicit
@ -34,7 +34,7 @@ EXAMPLES
o Build a function container using an explicit image name, ignoring registry
and function name.
$ func build --image registry.example.com/alice/f:latest
$ func build --image registry.example.com/alice/f:latest
o Rebuild a function using prior values to determine container name.
$ func build
@ -44,7 +44,7 @@ EXAMPLES
o Build a function specifying the Pack builder with a custom Buildpack
builder image.
$ func build --builder=pack --builder-image=cnbs/sample-builder:bionic
$ func build --builder=pack --builder-image=cnbs/sample-builder:bionic

View File

@ -15,7 +15,7 @@ SYNOPSIS
DESCRIPTION
Creates a new function project.
$ func create -l node -t http
$ func create -l node -t http
Creates a function in the current directory '.' which is written in the
language/runtime 'node' and handles HTTP events.
@ -24,7 +24,7 @@ DESCRIPTION
the path if necessary.
To complete this command interactively, use --confirm (-c):
$ func create -c
$ func create -c
Available Language Runtimes and Templates:
Language Template

View File

@ -14,7 +14,7 @@ No local files are deleted.
```
func delete [NAME]
func delete <name>
```
### Examples

View File

@ -19,10 +19,10 @@ func describe <name>
```
# Show the details of a function as declared in the local func.yaml
func info
func describe
# Show the details of the function in the directory with yaml output
func info --output yaml --path myotherfunc
func describe --output yaml --path myotherfunc
```