Add grouping for help message + streamlined help messages (#887)

* Add grouping for help message + streamlined help messages

The top-level looks like

kn is the command line interface for managing Knative Serving and Eventing objects

 Find more information about Knative at: https://knative.dev

Serving Commands:
  service     Manage Knative services
  revision    Manage service revisions
  route       List and show service routes

Eventing Commands:
  source      Manage event sources
  trigger     Manage event triggers

Other Commands:
  plugin      Manage kn plugins
  completion  Output shell completion code
  version     Show the version of this client

Use "kn <command> --help" for more information about a given command.
Use "kn options" for a list of global command-line options (applies to all commands).

The following changes have been applied:

* Add CommandGroups for grouping commands together
* Add flexible templating for the help messages
* Moved global options to an own command ('kn options', much like 'kubectl options')
* Aligned wording and typography of help messages

These features has been highly inspired by kubectl grouping & help templating but has been considerably been stripped down to the needs of kn.

Signed-off-by: Roland Huß <roland@ro14nd.de>

* chore: Add missing file

* Update pkg/templates/command_groups.go

Co-authored-by: Matt Moore <mattmoor@vmware.com>

* chore: Add some test for error messages

* fix formatting

* chore: Add test

* moar tests

* Update pkg/kn/commands/completion/completion.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/source/apiserver/delete.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/service/list.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/route/route.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/revision/delete.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/plugin/plugin.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/service/delete.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/revision/delete.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* Update pkg/kn/commands/service/delete.go

Co-authored-by: Navid Shaikh <nshaikh@redhat.com>

* regen docs

* chore: Update conventions doc

* Move some direct configuration of rootcmd to NewRootCommand()

* Moved CaptureOutput to "test" package for reuse

Co-authored-by: Matt Moore <mattmoor@vmware.com>
Co-authored-by: Navid Shaikh <nshaikh@redhat.com>
This commit is contained in:
Roland Huß 2020-06-18 09:06:25 +02:00 committed by GitHub
parent c7426459be
commit b916a5b3ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
103 changed files with 1162 additions and 358 deletions

View File

@ -18,6 +18,7 @@ import (
"fmt"
"math/rand"
"os"
"regexp"
"strings"
"time"
@ -35,8 +36,8 @@ func init() {
func main() {
err := run(os.Args[1:])
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
if err != nil && len(os.Args) > 1 {
printError(err)
// This is the only point from where to exit when an error occurs
os.Exit(1)
}
@ -106,8 +107,14 @@ func stripFlags(args []string) ([]string, error) {
*commandsFound = append(*commandsFound, arg)
}
},
SilenceErrors: true,
SilenceUsage: true,
}
// No help and usage functions to prin
extractCommand.SetHelpFunc(func(*cobra.Command, []string) {})
extractCommand.SetUsageFunc(func(*cobra.Command) error { return nil })
// Filter out --help and -h options to avoid special treatment which we don't
// need here
extractCommand.SetArgs(filterHelpOptions(args))
@ -172,10 +179,34 @@ func validateRootCommand(cmd *cobra.Command) error {
if err == nil && foundCmd.HasSubCommands() && len(innerArgs) > 0 {
argsWithoutFlags, err := stripFlags(innerArgs)
if len(argsWithoutFlags) > 0 || err != nil {
return errors.Errorf("unknown sub-command '%s' for '%s'. Available sub-commands: %s", innerArgs[0], foundCmd.Name(), strings.Join(root.ExtractSubCommandNames(foundCmd.Commands()), ", "))
return errors.Errorf("unknown sub-command '%s' for '%s'. Available sub-commands: %s", innerArgs[0], foundCmd.CommandPath(), strings.Join(root.ExtractSubCommandNames(foundCmd.Commands()), ", "))
}
// If no args where given (only flags), then fall through to execute the command itself, which leads to
// a more appropriate error message
}
return nil
}
// printError prints out any given error
func printError(err error) {
fmt.Fprintf(os.Stderr, "Error: %s\n", cleanupErrorMessage(err.Error()))
fmt.Fprintf(os.Stderr, "Run '%s --help' for usage\n", extractCommandPathFromErrorMessage(err.Error(), os.Args[0]))
}
// extractCommandPathFromErrorMessage tries to extract the command name from an error message
// by checking a pattern like 'kn service' in the error message. If not found, return the
// base command name.
func extractCommandPathFromErrorMessage(errorMsg string, arg0 string) string {
extractPattern := regexp.MustCompile(fmt.Sprintf("'(%s\\s.+?)'", arg0))
command := extractPattern.FindSubmatch([]byte(errorMsg))
if command != nil {
return string(command[1])
}
return arg0
}
// cleanupErrorMessage remove any redundance content of an error message
func cleanupErrorMessage(msg string) string {
regexp := regexp.MustCompile("(?i)^error:\\s*")
return string(regexp.ReplaceAll([]byte(msg), []byte("")))
}

View File

@ -15,14 +15,16 @@
package main
import (
"errors"
"fmt"
"os"
"strings"
"testing"
"github.com/spf13/cobra"
"gotest.tools/assert"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/kn/root"
"knative.dev/client/pkg/util"
)
@ -226,6 +228,31 @@ func TestStripFlags(t *testing.T) {
}
}
func TestRunWithError(t *testing.T) {
data := []struct {
given string
expected string
}{
{
"unknown sub-command blub",
"Error: unknown sub-command blub",
},
{
"error: unknown type blub",
"Error: unknown type blub",
},
}
for _, d := range data {
capture := test.CaptureOutput(t)
printError(errors.New(d.given))
stdOut, errOut := capture.Close()
assert.Equal(t, stdOut, "")
assert.Assert(t, strings.Contains(errOut, d.expected))
assert.Assert(t, util.ContainsAll(errOut, "Run", "--help", "usage"))
}
}
// Smoke test
func TestRun(t *testing.T) {
oldArgs := os.Args
@ -234,9 +261,9 @@ func TestRun(t *testing.T) {
os.Args = oldArgs
})()
capture := commands.CaptureStdout(t)
capture := test.CaptureOutput(t)
err := run(os.Args[1:])
out := capture.Close()
out, _ := capture.Close()
assert.NilError(t, err)
assert.Assert(t, util.ContainsAllIgnoreCase(out, "version", "build", "git"))

View File

@ -51,6 +51,7 @@ be used:
- `create` creates a resource.
- `update` updates a resource.
- `delete` deletes a resource.
- `apply` for an idempotent "create-or-update", much like `kubetl apply`
For a given resource, create and update should use the same arguments as much as
possible and where it makes sense.
@ -84,6 +85,7 @@ Flags are used for specifying the input for `kn` commands and can have different
characteristics:
- They can be _mandatory_ or _optional_
- Mandatory flags are mentioned in the `Use` attribute of a command like in `service NAME --image IMAGE` for `ServiceCommand`
- Optional flags can have _default values_
- Flag values can be _scalars_, _binary_, _lists_ or _maps_ (see below for
details)

View File

@ -1,13 +1,12 @@
## kn
Knative client
kn manages Knative Serving and Eventing resources
### Synopsis
Manage your Knative building blocks:
kn is the command line interface for managing Knative Serving and Eventing resources
* Serving: Manage your services and release new software to them.
* Eventing: Manage event subscriptions and channels. Connect up event sources.
Find more information about Knative at: https://knative.dev
### Options
@ -21,11 +20,12 @@ Manage your Knative building blocks:
### SEE ALSO
* [kn completion](kn_completion.md) - Output shell completion code
* [kn plugin](kn_plugin.md) - Plugin command group
* [kn revision](kn_revision.md) - Revision command group
* [kn route](kn_route.md) - Route command group
* [kn service](kn_service.md) - Service command group
* [kn source](kn_source.md) - Event source command group
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn version](kn_version.md) - Prints the client version
* [kn options](kn_options.md) - Print the list of flags inherited by all commands
* [kn plugin](kn_plugin.md) - Manage kn plugins
* [kn revision](kn_revision.md) - Manage service revisions
* [kn route](kn_route.md) - List and describe service routes
* [kn service](kn_service.md) - Manage Knative services
* [kn source](kn_source.md) - Manage event sources
* [kn trigger](kn_trigger.md) - Manage event triggers
* [kn version](kn_version.md) - Show the version of this client

View File

@ -13,7 +13,7 @@ Supported Shells:
- zsh
```
kn completion [SHELL] [flags]
kn completion SHELL
```
### Examples
@ -44,5 +44,5 @@ kn completion [SHELL] [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn](kn.md) - kn manages Knative Serving and Eventing resources

37
docs/cmd/kn_options.md Normal file
View File

@ -0,0 +1,37 @@
## kn options
Print the list of flags inherited by all commands
### Synopsis
Print the list of flags inherited by all commands
```
kn options [flags]
```
### Examples
```
# Print flags inherited by all commands
kn options
```
### Options
```
-h, --help help for options
```
### Options inherited from parent commands
```
--config string kn configuration file (default: ~/.config/kn/config.yaml)
--kubeconfig string kubectl configuration file (default: ~/.kube/config)
--log-http log http traffic
```
### SEE ALSO
* [kn](kn.md) - kn manages Knative Serving and Eventing resources

View File

@ -1,16 +1,16 @@
## kn plugin
Plugin command group
Manage kn plugins
### Synopsis
Provides utilities for interacting and managing with kn plugins.
Manage kn plugins
Plugins provide extended functionality that is not part of the core kn command-line distribution.
Please refer to the documentation and examples for more information about how write your own plugins.
Please refer to the documentation and examples for more information about how to write your own plugins.
```
kn plugin [flags]
kn plugin
```
### Options
@ -29,6 +29,6 @@ kn plugin [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn plugin list](kn_plugin_list.md) - List plugins

View File

@ -10,10 +10,10 @@ Available plugins are those that are:
- executable
- begin with "kn-"
- Kn's plugin directory
- Anywhere in the execution $PATH (if plugins.path-lookup config variable is enabled)
- Anywhere in the execution $PATH (if plugins.path-lookup configuration variable is enabled)
```
kn plugin list [flags]
kn plugin list
```
### Options
@ -33,5 +33,5 @@ kn plugin list [flags]
### SEE ALSO
* [kn plugin](kn_plugin.md) - Plugin command group
* [kn plugin](kn_plugin.md) - Manage kn plugins

View File

@ -1,13 +1,13 @@
## kn revision
Revision command group
Manage service revisions
### Synopsis
Revision command group
Manage service revisions
```
kn revision [flags]
kn revision
```
### Options
@ -26,8 +26,8 @@ kn revision [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn revision delete](kn_revision_delete.md) - Delete a revision.
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn revision delete](kn_revision_delete.md) - Delete revisions
* [kn revision describe](kn_revision_describe.md) - Show details of a revision
* [kn revision list](kn_revision_list.md) - List available revisions.
* [kn revision list](kn_revision_list.md) - List revisions

View File

@ -1,13 +1,13 @@
## kn revision delete
Delete a revision.
Delete revisions
### Synopsis
Delete a revision.
Delete revisions
```
kn revision delete NAME [flags]
kn revision delete NAME [NAME ...]
```
### Examples
@ -39,5 +39,5 @@ kn revision delete NAME [flags]
### SEE ALSO
* [kn revision](kn_revision.md) - Revision command group
* [kn revision](kn_revision.md) - Manage service revisions

View File

@ -7,7 +7,7 @@ Show details of a revision
Show details of a revision
```
kn revision describe NAME [flags]
kn revision describe NAME
```
### Options
@ -31,5 +31,5 @@ kn revision describe NAME [flags]
### SEE ALSO
* [kn revision](kn_revision.md) - Revision command group
* [kn revision](kn_revision.md) - Manage service revisions

View File

@ -1,13 +1,13 @@
## kn revision list
List available revisions.
List revisions
### Synopsis
List revisions for a given service.
```
kn revision list [name] [flags]
kn revision list
```
### Examples
@ -50,5 +50,5 @@ kn revision list [name] [flags]
### SEE ALSO
* [kn revision](kn_revision.md) - Revision command group
* [kn revision](kn_revision.md) - Manage service revisions

View File

@ -1,13 +1,13 @@
## kn route
Route command group
List and describe service routes
### Synopsis
Route command group
List and describe service routes
```
kn route [flags]
kn route
```
### Options
@ -26,7 +26,7 @@ kn route [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn route describe](kn_route_describe.md) - Show details of a route
* [kn route list](kn_route_list.md) - List available routes.
* [kn route list](kn_route_list.md) - List routes

View File

@ -7,7 +7,7 @@ Show details of a route
Show details of a route
```
kn route describe NAME [flags]
kn route describe NAME
```
### Options
@ -31,5 +31,5 @@ kn route describe NAME [flags]
### SEE ALSO
* [kn route](kn_route.md) - Route command group
* [kn route](kn_route.md) - List and describe service routes

View File

@ -1,13 +1,13 @@
## kn route list
List available routes.
List routes
### Synopsis
List available routes.
List routes
```
kn route list NAME [flags]
kn route list NAME
```
### Examples
@ -46,5 +46,5 @@ kn route list NAME [flags]
### SEE ALSO
* [kn route](kn_route.md) - Route command group
* [kn route](kn_route.md) - List and describe service routes

View File

@ -1,13 +1,13 @@
## kn service
Service command group
Manage Knative services
### Synopsis
Service command group
Manage Knative services
```
kn service [flags]
kn service
```
### Options
@ -26,11 +26,11 @@ kn service [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn service create](kn_service_create.md) - Create a service.
* [kn service delete](kn_service_delete.md) - Delete a service.
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn service create](kn_service_create.md) - Create a service
* [kn service delete](kn_service_delete.md) - Delete services
* [kn service describe](kn_service_describe.md) - Show details of a service
* [kn service export](kn_service_export.md) - Export a service.
* [kn service list](kn_service_list.md) - List available services.
* [kn service update](kn_service_update.md) - Update a service.
* [kn service export](kn_service_export.md) - Export a service and its revisions
* [kn service list](kn_service_list.md) - List services
* [kn service update](kn_service_update.md) - Update a service

View File

@ -1,13 +1,13 @@
## kn service create
Create a service.
Create a service
### Synopsis
Create a service.
Create a service
```
kn service create NAME --image IMAGE [flags]
kn service create NAME --image IMAGE
```
### Examples
@ -101,5 +101,5 @@ kn service create NAME --image IMAGE [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -1,13 +1,13 @@
## kn service delete
Delete a service.
Delete services
### Synopsis
Delete a service.
Delete services
```
kn service delete NAME [flags]
kn service delete NAME [NAME ...]
```
### Examples
@ -46,5 +46,5 @@ kn service delete NAME [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -7,7 +7,7 @@ Show details of a service
Show details of a service
```
kn service describe NAME [flags]
kn service describe NAME
```
### Options
@ -31,5 +31,5 @@ kn service describe NAME [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -1,13 +1,13 @@
## kn service export
Export a service.
Export a service and its revisions
### Synopsis
Export a service.
Export a service and its revisions
```
kn service export NAME [flags]
kn service export NAME
```
### Examples
@ -46,5 +46,5 @@ kn service export NAME [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -1,13 +1,13 @@
## kn service list
List available services.
List services
### Synopsis
List available services.
List services
```
kn service list [name] [flags]
kn service list
```
### Examples
@ -46,5 +46,5 @@ kn service list [name] [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -1,13 +1,13 @@
## kn service update
Update a service.
Update a service
### Synopsis
Update a service.
Update a service
```
kn service update NAME [flags]
kn service update NAME
```
### Examples
@ -91,5 +91,5 @@ kn service update NAME [flags]
### SEE ALSO
* [kn service](kn_service.md) - Service command group
* [kn service](kn_service.md) - Manage Knative services

View File

@ -1,13 +1,13 @@
## kn source
Event source command group
Manage event sources
### Synopsis
Event source command group
Manage event sources
```
kn source [flags]
kn source SOURCE|COMMAND
```
### Options
@ -26,10 +26,10 @@ kn source [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source list](kn_source_list.md) - List available sources
* [kn source list-types](kn_source_list-types.md) - List available source types
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources
* [kn source binding](kn_source_binding.md) - Manage sink bindings
* [kn source list](kn_source_list.md) - List event sources
* [kn source list-types](kn_source_list-types.md) - List event source types
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn source apiserver
Kubernetes API Server Event Source command group
Manage Kubernetes api-server sources
### Synopsis
Kubernetes API Server Event Source command group
Manage Kubernetes api-server sources
```
kn source apiserver [flags]
kn source apiserver COMMAND
```
### Options
@ -26,10 +26,10 @@ kn source apiserver [flags]
### SEE ALSO
* [kn source](kn_source.md) - Event source command group
* [kn source apiserver create](kn_source_apiserver_create.md) - Create an ApiServer source.
* [kn source apiserver delete](kn_source_apiserver_delete.md) - Delete an ApiServer source.
* [kn source apiserver describe](kn_source_apiserver_describe.md) - Show details of an ApiServer source
* [kn source apiserver list](kn_source_apiserver_list.md) - List ApiServer sources.
* [kn source apiserver update](kn_source_apiserver_update.md) - Update an ApiServer source.
* [kn source](kn_source.md) - Manage event sources
* [kn source apiserver create](kn_source_apiserver_create.md) - Create an api-server source
* [kn source apiserver delete](kn_source_apiserver_delete.md) - Delete an api-server source
* [kn source apiserver describe](kn_source_apiserver_describe.md) - Show details of an api-server source
* [kn source apiserver list](kn_source_apiserver_list.md) - List api-server sources
* [kn source apiserver update](kn_source_apiserver_update.md) - Update an api-server source

View File

@ -1,13 +1,13 @@
## kn source apiserver create
Create an ApiServer source.
Create an api-server source
### Synopsis
Create an ApiServer source.
Create an api-server source
```
kn source apiserver create NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE [flags]
kn source apiserver create NAME --resource RESOURCE --sink SINK
```
### Examples
@ -43,5 +43,5 @@ kn source apiserver create NAME --resource RESOURCE --service-account ACCOUNTNAM
### SEE ALSO
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources

View File

@ -1,13 +1,13 @@
## kn source apiserver delete
Delete an ApiServer source.
Delete an api-server source
### Synopsis
Delete an ApiServer source.
Delete an api-server source
```
kn source apiserver delete NAME [flags]
kn source apiserver delete NAME
```
### Examples
@ -35,5 +35,5 @@ kn source apiserver delete NAME [flags]
### SEE ALSO
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources

View File

@ -1,13 +1,13 @@
## kn source apiserver describe
Show details of an ApiServer source
Show details of an api-server source
### Synopsis
Show details of an ApiServer source
Show details of an api-server source
```
kn source apiserver describe NAME [flags]
kn source apiserver describe NAME
```
### Examples
@ -36,5 +36,5 @@ kn source apiserver describe NAME [flags]
### SEE ALSO
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources

View File

@ -1,13 +1,13 @@
## kn source apiserver list
List ApiServer sources.
List api-server sources
### Synopsis
List ApiServer sources.
List api-server sources
```
kn source apiserver list [flags]
kn source apiserver list
```
### Examples
@ -43,5 +43,5 @@ kn source apiserver list [flags]
### SEE ALSO
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources

View File

@ -1,13 +1,13 @@
## kn source apiserver update
Update an ApiServer source.
Update an api-server source
### Synopsis
Update an ApiServer source.
Update an api-server source
```
kn source apiserver update NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE [flags]
kn source apiserver update NAME
```
### Examples
@ -43,5 +43,5 @@ kn source apiserver update NAME --resource RESOURCE --service-account ACCOUNTNAM
### SEE ALSO
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
* [kn source apiserver](kn_source_apiserver.md) - Manage Kubernetes api-server sources

View File

@ -1,13 +1,13 @@
## kn source binding
Sink binding command group
Manage sink bindings
### Synopsis
Sink binding command group
Manage sink bindings
```
kn source binding [flags]
kn source binding COMMAND
```
### Options
@ -26,10 +26,10 @@ kn source binding [flags]
### SEE ALSO
* [kn source](kn_source.md) - Event source command group
* [kn source binding create](kn_source_binding_create.md) - Create a sink binding.
* [kn source binding delete](kn_source_binding_delete.md) - Delete a sink binding.
* [kn source](kn_source.md) - Manage event sources
* [kn source binding create](kn_source_binding_create.md) - Create a sink binding
* [kn source binding delete](kn_source_binding_delete.md) - Delete a sink binding
* [kn source binding describe](kn_source_binding_describe.md) - Show details of a sink binding
* [kn source binding list](kn_source_binding_list.md) - List sink bindings.
* [kn source binding update](kn_source_binding_update.md) - Update a sink binding.
* [kn source binding list](kn_source_binding_list.md) - List sink bindings
* [kn source binding update](kn_source_binding_update.md) - Update a sink binding

View File

@ -1,13 +1,13 @@
## kn source binding create
Create a sink binding.
Create a sink binding
### Synopsis
Create a sink binding.
Create a sink binding
```
kn source binding create NAME --subject SUBJECT --sink SINK --ce-override KEY=VALUE [flags]
kn source binding create NAME --subject SUBJECT --sink SINK
```
### Examples
@ -38,5 +38,5 @@ kn source binding create NAME --subject SUBJECT --sink SINK --ce-override KEY=VA
### SEE ALSO
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source binding](kn_source_binding.md) - Manage sink bindings

View File

@ -1,13 +1,13 @@
## kn source binding delete
Delete a sink binding.
Delete a sink binding
### Synopsis
Delete a sink binding.
Delete a sink binding
```
kn source binding delete NAME [flags]
kn source binding delete NAME
```
### Examples
@ -35,5 +35,5 @@ kn source binding delete NAME [flags]
### SEE ALSO
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source binding](kn_source_binding.md) - Manage sink bindings

View File

@ -7,7 +7,7 @@ Show details of a sink binding
Show details of a sink binding
```
kn source binding describe NAME [flags]
kn source binding describe NAME
```
### Examples
@ -36,5 +36,5 @@ kn source binding describe NAME [flags]
### SEE ALSO
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source binding](kn_source_binding.md) - Manage sink bindings

View File

@ -1,13 +1,13 @@
## kn source binding list
List sink bindings.
List sink bindings
### Synopsis
List sink bindings.
List sink bindings
```
kn source binding list [flags]
kn source binding list
```
### Examples
@ -43,5 +43,5 @@ kn source binding list [flags]
### SEE ALSO
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source binding](kn_source_binding.md) - Manage sink bindings

View File

@ -1,13 +1,13 @@
## kn source binding update
Update a sink binding.
Update a sink binding
### Synopsis
Update a sink binding.
Update a sink binding
```
kn source binding update NAME --subject SCHEDULE --sink SINK --ce-override OVERRIDE [flags]
kn source binding update NAME
```
### Examples
@ -38,5 +38,5 @@ kn source binding update NAME --subject SCHEDULE --sink SINK --ce-override OVERR
### SEE ALSO
* [kn source binding](kn_source_binding.md) - Sink binding command group
* [kn source binding](kn_source_binding.md) - Manage sink bindings

View File

@ -1,23 +1,23 @@
## kn source list-types
List available source types
List event source types
### Synopsis
List available source types
List event source types
```
kn source list-types [flags]
kn source list-types
```
### Examples
```
# List available eventing source types
# List available event source types
kn source list-types
# List available eventing source types in YAML format
# List available event source types in YAML format
kn source list-types -o yaml
```
@ -42,5 +42,5 @@ kn source list-types [flags]
### SEE ALSO
* [kn source](kn_source.md) - Event source command group
* [kn source](kn_source.md) - Manage event sources

View File

@ -1,13 +1,13 @@
## kn source list
List available sources
List event sources
### Synopsis
List available sources
List event sources
```
kn source list [flags]
kn source list
```
### Examples
@ -47,5 +47,5 @@ kn source list [flags]
### SEE ALSO
* [kn source](kn_source.md) - Event source command group
* [kn source](kn_source.md) - Manage event sources

View File

@ -1,13 +1,13 @@
## kn source ping
Ping source command group
Manage ping sources
### Synopsis
Ping source command group
Manage ping sources
```
kn source ping [flags]
kn source ping COMMAND
```
### Options
@ -26,10 +26,10 @@ kn source ping [flags]
### SEE ALSO
* [kn source](kn_source.md) - Event source command group
* [kn source ping create](kn_source_ping_create.md) - Create a Ping source.
* [kn source ping delete](kn_source_ping_delete.md) - Delete a Ping source.
* [kn source ping describe](kn_source_ping_describe.md) - Show details of a Ping source
* [kn source ping list](kn_source_ping_list.md) - List Ping sources.
* [kn source ping update](kn_source_ping_update.md) - Update a Ping source.
* [kn source](kn_source.md) - Manage event sources
* [kn source ping create](kn_source_ping_create.md) - Create a ping source
* [kn source ping delete](kn_source_ping_delete.md) - Delete a ping source
* [kn source ping describe](kn_source_ping_describe.md) - Show details of a ping source
* [kn source ping list](kn_source_ping_list.md) - List ping sources
* [kn source ping update](kn_source_ping_update.md) - Update a ping source

View File

@ -1,13 +1,13 @@
## kn source ping create
Create a Ping source.
Create a ping source
### Synopsis
Create a Ping source.
Create a ping source
```
kn source ping create NAME --schedule SCHEDULE --sink SINK --data DATA [flags]
kn source ping create NAME
```
### Examples
@ -39,5 +39,5 @@ kn source ping create NAME --schedule SCHEDULE --sink SINK --data DATA [flags]
### SEE ALSO
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn source ping delete
Delete a Ping source.
Delete a ping source
### Synopsis
Delete a Ping source.
Delete a ping source
```
kn source ping delete NAME [flags]
kn source ping delete NAME
```
### Examples
@ -35,5 +35,5 @@ kn source ping delete NAME [flags]
### SEE ALSO
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn source ping describe
Show details of a Ping source
Show details of a ping source
### Synopsis
Show details of a Ping source
Show details of a ping source
```
kn source ping describe NAME [flags]
kn source ping describe NAME
```
### Examples
@ -36,5 +36,5 @@ kn source ping describe NAME [flags]
### SEE ALSO
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn source ping list
List Ping sources.
List ping sources
### Synopsis
List Ping sources.
List ping sources
```
kn source ping list [flags]
kn source ping list
```
### Examples
@ -43,5 +43,5 @@ kn source ping list [flags]
### SEE ALSO
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn source ping update
Update a Ping source.
Update a ping source
### Synopsis
Update a Ping source.
Update a ping source
```
kn source ping update NAME --schedule SCHEDULE --sink SERVICE --data DATA [flags]
kn source ping update NAME
```
### Examples
@ -39,5 +39,5 @@ kn source ping update NAME --schedule SCHEDULE --sink SERVICE --data DATA [flags
### SEE ALSO
* [kn source ping](kn_source_ping.md) - Ping source command group
* [kn source ping](kn_source_ping.md) - Manage ping sources

View File

@ -1,13 +1,13 @@
## kn trigger
Trigger command group
Manage event triggers
### Synopsis
Trigger command group
Manage event triggers
```
kn trigger [flags]
kn trigger
```
### Options
@ -26,10 +26,10 @@ kn trigger [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn trigger create](kn_trigger_create.md) - Create a trigger
* [kn trigger delete](kn_trigger_delete.md) - Delete a trigger.
* [kn trigger delete](kn_trigger_delete.md) - Delete a trigger
* [kn trigger describe](kn_trigger_describe.md) - Show details of a trigger
* [kn trigger list](kn_trigger_list.md) - List available triggers.
* [kn trigger list](kn_trigger_list.md) - List triggers
* [kn trigger update](kn_trigger_update.md) - Update a trigger

View File

@ -7,7 +7,7 @@ Create a trigger
Create a trigger
```
kn trigger create NAME --broker BROKER --sink SINK [flags]
kn trigger create NAME --sink SINK
```
### Examples
@ -42,5 +42,5 @@ kn trigger create NAME --broker BROKER --sink SINK [flags]
### SEE ALSO
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn trigger](kn_trigger.md) - Manage event triggers

View File

@ -1,13 +1,13 @@
## kn trigger delete
Delete a trigger.
Delete a trigger
### Synopsis
Delete a trigger.
Delete a trigger
```
kn trigger delete NAME [flags]
kn trigger delete NAME
```
### Examples
@ -35,5 +35,5 @@ kn trigger delete NAME [flags]
### SEE ALSO
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn trigger](kn_trigger.md) - Manage event triggers

View File

@ -7,7 +7,7 @@ Show details of a trigger
Show details of a trigger
```
kn trigger describe NAME [flags]
kn trigger describe NAME
```
### Examples
@ -36,5 +36,5 @@ kn trigger describe NAME [flags]
### SEE ALSO
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn trigger](kn_trigger.md) - Manage event triggers

View File

@ -1,13 +1,13 @@
## kn trigger list
List available triggers.
List triggers
### Synopsis
List available triggers.
List triggers
```
kn trigger list [name] [flags]
kn trigger list
```
### Examples
@ -43,5 +43,5 @@ kn trigger list [name] [flags]
### SEE ALSO
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn trigger](kn_trigger.md) - Manage event triggers

View File

@ -7,7 +7,7 @@ Update a trigger
Update a trigger
```
kn trigger update NAME --filter KEY=VALUE --sink SINK [flags]
kn trigger update NAME
```
### Examples
@ -46,5 +46,5 @@ kn trigger update NAME --filter KEY=VALUE --sink SINK [flags]
### SEE ALSO
* [kn trigger](kn_trigger.md) - Trigger command group
* [kn trigger](kn_trigger.md) - Manage event triggers

View File

@ -1,13 +1,13 @@
## kn version
Prints the client version
Show the version of this client
### Synopsis
Prints the client version
Show the version of this client
```
kn version [flags]
kn version
```
### Options
@ -27,5 +27,5 @@ kn version [flags]
### SEE ALSO
* [kn](kn.md) - Knative client
* [kn](kn.md) - kn manages Knative Serving and Eventing resources

View File

@ -0,0 +1,77 @@
// Copyright 2020 The Knative Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// OutputCapture allows to capture any text written to standard out or standard error
// which is especially useful during testing.
//
// Call it like:
//
// capture := CaptureOutput(t)
// doSomeActionThatWritesToStdOutAndStdErr()
// stdOut, stdErr := capture.Close()
//
// CaptureOutpu() and capture.Close() should always come in pairs as Close() also
// restores the old streams
package test
import (
"io/ioutil"
"os"
"testing"
"gotest.tools/assert"
)
type OutputCapture struct {
outRead, outWrite *os.File
errorRead, errorWrite *os.File
t *testing.T
oldStdout *os.File
oldStderr *os.File
}
// CaptureOutput sets up standard our and standard error to capture any
// output which
func CaptureOutput(t *testing.T) OutputCapture {
ret := OutputCapture{
oldStdout: os.Stdout,
oldStderr: os.Stderr,
t: t,
}
var err error
ret.outRead, ret.outWrite, err = os.Pipe()
assert.NilError(t, err)
os.Stdout = ret.outWrite
ret.errorRead, ret.errorWrite, err = os.Pipe()
assert.NilError(t, err)
os.Stderr = ret.errorWrite
return ret
}
// Close return the output collected and restores the original standard out and error streams
// (i.e. those that were present before the call to CaptureOutput).
func (c OutputCapture) Close() (string, string) {
err := c.outWrite.Close()
assert.NilError(c.t, err)
err = c.errorWrite.Close()
assert.NilError(c.t, err)
outOutput, err := ioutil.ReadAll(c.outRead)
assert.NilError(c.t, err)
errOutput, err := ioutil.ReadAll(c.errorRead)
assert.NilError(c.t, err)
os.Stdout = c.oldStdout
os.Stderr = c.oldStderr
return string(outOutput), string(errOutput)
}

View File

@ -15,9 +15,10 @@
package completion
import (
"fmt"
"os"
"github.com/pkg/errors"
"knative.dev/client/pkg/kn/commands"
"github.com/spf13/cobra"
@ -43,23 +44,23 @@ Supported Shells:
// NewCompletionCommand implements shell auto-completion feature for Bash and Zsh
func NewCompletionCommand(p *commands.KnParams) *cobra.Command {
return &cobra.Command{
Use: "completion [SHELL]",
Use: "completion SHELL",
Short: "Output shell completion code",
Long: desc,
ValidArgs: []string{"bash", "zsh"},
Example: eg,
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 {
switch args[0] {
case "bash":
cmd.Root().GenBashCompletion(os.Stdout)
return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh":
cmd.Root().GenZshCompletion(os.Stdout)
return cmd.Root().GenZshCompletion(os.Stdout)
default:
fmt.Println("only supports 'bash' or 'zsh' shell completion")
return errors.New("'bash' or 'zsh' shell completion is supported")
}
} else {
fmt.Println("accepts one argument either 'bash' or 'zsh'")
return errors.New("Only one argument can be provided, either 'bash' or 'zsh'")
}
},
}

View File

@ -17,6 +17,7 @@ package completion
import (
"testing"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/util"
@ -28,31 +29,30 @@ func TestCompletionUsage(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{})
assert.Assert(t, util.ContainsAllIgnoreCase(completionCmd.Use, "completion"))
assert.Assert(t, util.ContainsAllIgnoreCase(completionCmd.Short, "completion", "shell"))
assert.Assert(t, completionCmd.RunE == nil)
assert.Assert(t, completionCmd.Run == nil)
assert.Assert(t, completionCmd.RunE != nil)
}
func TestCompletionGeneration(t *testing.T) {
for _, shell := range []string{"bash", "zsh"} {
completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t)
completionCmd.Run(&cobra.Command{}, []string{shell})
out := c.Close()
assert.Assert(t, out != "")
c := test.CaptureOutput(t)
err := completionCmd.RunE(&cobra.Command{}, []string{shell})
assert.NilError(t, err)
stdOut, stdErr := c.Close()
assert.Assert(t, stdErr == "")
assert.Assert(t, stdOut != "")
}
}
func TestCompletionNoArg(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t)
completionCmd.Run(&cobra.Command{}, []string{})
out := c.Close()
assert.Assert(t, util.ContainsAll(out, "bash", "zsh", "one", "argument"))
err := completionCmd.RunE(&cobra.Command{}, []string{})
assert.Assert(t, util.ContainsAll(err.Error(), "bash", "zsh", "one", "argument"))
}
func TestCompletionWrongArg(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t)
completionCmd.Run(&cobra.Command{}, []string{"sh"})
out := c.Close()
assert.Assert(t, util.ContainsAll(out, "bash", "zsh", "only", "supports"))
err := completionCmd.RunE(&cobra.Command{}, []string{"sh"})
assert.Assert(t, util.ContainsAll(err.Error(), "bash", "zsh", "support"))
}

View File

@ -0,0 +1,50 @@
// Copyright © 2020 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package options
import (
"github.com/pkg/errors"
"github.com/spf13/cobra"
"knative.dev/client/pkg/templates"
)
// NewCmdOptions implements the options command
func NewOptionsCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "options",
Short: "Print the list of flags inherited by all commands",
Long: "Print the list of flags inherited by all commands",
Example: `# Print flags inherited by all commands
kn options`,
Run: func(cmd *cobra.Command, args []string) {
cmd.SetOut(cmd.OutOrStdout())
cmd.Usage()
},
// Be quiet
SilenceErrors: true,
SilenceUsage: true,
// Allow all options
FParseErrWhitelist: cobra.FParseErrWhitelist{UnknownFlags: true},
}
cmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return errors.Errorf("%s for '%s'", err.Error(), c.CommandPath())
})
cmd.SetUsageFunc(templates.NewGlobalOptionsFunc())
cmd.SetHelpFunc(func(command *cobra.Command, args []string) {
templates.NewGlobalOptionsFunc()(command)
})
return cmd
}

View File

@ -48,7 +48,7 @@ Available plugins are those that are:
- executable
- begin with "kn-"
- Kn's plugin directory
- Anywhere in the execution $PATH (if plugins.path-lookup config variable is enabled)`,
- Anywhere in the execution $PATH (if plugins.path-lookup configuration variable is enabled)`,
RunE: func(cmd *cobra.Command, args []string) error {
return listPlugins(cmd, plFlags)
},

View File

@ -23,11 +23,11 @@ import (
func NewPluginCommand(p *commands.KnParams) *cobra.Command {
pluginCmd := &cobra.Command{
Use: "plugin",
Short: "Plugin command group",
Long: `Provides utilities for interacting and managing with kn plugins.
Short: "Manage kn plugins",
Long: `Manage kn plugins
Plugins provide extended functionality that is not part of the core kn command-line distribution.
Please refer to the documentation and examples for more information about how write your own plugins.`,
Please refer to the documentation and examples for more information about how to write your own plugins.`,
}
pluginCmd.AddCommand(NewPluginListCommand(p))

View File

@ -29,8 +29,8 @@ func NewRevisionDeleteCommand(p *commands.KnParams) *cobra.Command {
var waitFlags commands.WaitFlags
RevisionDeleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete a revision.",
Use: "delete NAME [NAME ...]",
Short: "Delete revisions",
Example: `
# Delete a revision 'svc1-abcde' in default namespace
kn revision delete svc1-abcde`,

View File

@ -38,8 +38,8 @@ func NewRevisionListCommand(p *commands.KnParams) *cobra.Command {
revisionListFlags := flags.NewListPrintFlags(RevisionListHandlers)
revisionListCommand := &cobra.Command{
Use: "list [name]",
Short: "List available revisions.",
Use: "list",
Short: "List revisions",
Long: "List revisions for a given service.",
Example: `
# List all revisions

View File

@ -24,7 +24,7 @@ import (
func NewRevisionCommand(p *commands.KnParams) *cobra.Command {
revisionCmd := &cobra.Command{
Use: "revision",
Short: "Revision command group",
Short: "Manage service revisions",
}
revisionCmd.AddCommand(NewRevisionListCommand(p))
revisionCmd.AddCommand(NewRevisionDescribeCommand(p))

View File

@ -32,7 +32,7 @@ func NewRouteListCommand(p *commands.KnParams) *cobra.Command {
routeListFlags := flags.NewListPrintFlags(RouteListHandlers)
routeListCommand := &cobra.Command{
Use: "list NAME",
Short: "List available routes.",
Short: "List routes",
Example: `
# List all routes
kn route list

View File

@ -23,7 +23,7 @@ import (
func NewRouteCommand(p *commands.KnParams) *cobra.Command {
routeCmd := &cobra.Command{
Use: "route",
Short: "Route command group",
Short: "List and describe service routes",
}
routeCmd.AddCommand(NewRouteListCommand(p))
routeCmd.AddCommand(NewRouteDescribeCommand(p))

View File

@ -72,7 +72,7 @@ func NewServiceCreateCommand(p *commands.KnParams) *cobra.Command {
serviceCreateCommand := &cobra.Command{
Use: "create NAME --image IMAGE",
Short: "Create a service.",
Short: "Create a service",
Example: create_example,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {

View File

@ -30,8 +30,8 @@ func NewServiceDeleteCommand(p *commands.KnParams) *cobra.Command {
var waitFlags commands.WaitFlags
serviceDeleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete a service.",
Use: "delete NAME [NAME ...]",
Short: "Delete services",
Example: `
# Delete a service 'svc1' in default namespace
kn service delete svc1

View File

@ -50,7 +50,7 @@ func NewServiceExportCommand(p *commands.KnParams) *cobra.Command {
command := &cobra.Command{
Use: "export NAME",
Short: "Export a service.",
Short: "Export a service and its revisions",
Example: `
# Export a service in YAML format
kn service export foo -n bar -o yaml

View File

@ -31,8 +31,8 @@ func NewServiceListCommand(p *commands.KnParams) *cobra.Command {
serviceListFlags := flags.NewListPrintFlags(ServiceListHandlers)
serviceListCommand := &cobra.Command{
Use: "list [name]",
Short: "List available services.",
Use: "list",
Short: "List services",
Example: `
# List all services
kn service list

View File

@ -34,7 +34,7 @@ const (
func NewServiceCommand(p *commands.KnParams) *cobra.Command {
serviceCmd := &cobra.Command{
Use: "service",
Short: "Service command group",
Short: "Manage Knative services",
}
serviceCmd.AddCommand(NewServiceListCommand(p))
serviceCmd.AddCommand(NewServiceDescribeCommand(p))

View File

@ -55,8 +55,8 @@ func NewServiceUpdateCommand(p *commands.KnParams) *cobra.Command {
var waitFlags commands.WaitFlags
var trafficFlags flags.Traffic
serviceUpdateCommand := &cobra.Command{
Use: "update NAME [flags]",
Short: "Update a service.",
Use: "update NAME",
Short: "Update a service",
Example: updateExample,
RunE: func(cmd *cobra.Command, args []string) (err error) {
if len(args) != 1 {

View File

@ -26,8 +26,8 @@ import (
// NewAPIServerCommand for managing ApiServer source
func NewAPIServerCommand(p *commands.KnParams) *cobra.Command {
apiServerSourceCmd := &cobra.Command{
Use: "apiserver",
Short: "Kubernetes API Server Event Source command group",
Use: "apiserver COMMAND",
Short: "Manage Kubernetes api-server sources",
}
apiServerSourceCmd.AddCommand(NewAPIServerCreateCommand(p))
apiServerSourceCmd.AddCommand(NewAPIServerUpdateCommand(p))

View File

@ -32,8 +32,8 @@ func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "create NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE",
Short: "Create an ApiServer source.",
Use: "create NAME --resource RESOURCE --sink SINK",
Short: "Create an api-server source",
Example: `
# Create an ApiServerSource 'k8sevents' which consumes Kubernetes events and sends message to service 'mysvc' as a cloudevent
kn source apiserver create k8sevents --resource Event:v1 --service-account myaccountname --sink svc:mysvc`,

View File

@ -27,7 +27,7 @@ import (
func NewAPIServerDeleteCommand(p *commands.KnParams) *cobra.Command {
deleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete an ApiServer source.",
Short: "Delete an api-server source",
Example: `
# Delete an ApiServerSource 'k8sevents' in default namespace
kn source apiserver delete k8sevents`,

View File

@ -32,7 +32,7 @@ func NewAPIServerDescribeCommand(p *commands.KnParams) *cobra.Command {
apiServerDescribe := &cobra.Command{
Use: "describe NAME",
Short: "Show details of an ApiServer source",
Short: "Show details of an api-server source",
Example: `
# Describe an ApiServer source with name 'k8sevents'
kn source apiserver describe k8sevents`,

View File

@ -29,7 +29,7 @@ func NewAPIServerListCommand(p *commands.KnParams) *cobra.Command {
listCommand := &cobra.Command{
Use: "list",
Short: "List ApiServer sources.",
Short: "List api-server sources",
Example: `
# List all ApiServer sources
kn source apiserver list

View File

@ -32,8 +32,8 @@ func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "update NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE",
Short: "Update an ApiServer source.",
Use: "update NAME",
Short: "Update an api-server source",
Example: `
# Update an ApiServerSource 'k8sevents' with different service account and sink service
kn source apiserver update k8sevents --service-account newsa --sink svc:newsvc`,

View File

@ -32,8 +32,8 @@ import (
// NewBindingCommand is the root command for all binding related commands
func NewBindingCommand(p *commands.KnParams) *cobra.Command {
bindingCmd := &cobra.Command{
Use: "binding",
Short: "Sink binding command group",
Use: "binding COMMAND",
Short: "Manage sink bindings",
}
bindingCmd.AddCommand(NewBindingCreateCommand(p))
bindingCmd.AddCommand(NewBindingUpdateCommand(p))

View File

@ -32,8 +32,8 @@ func NewBindingCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "create NAME --subject SUBJECT --sink SINK --ce-override KEY=VALUE",
Short: "Create a sink binding.",
Use: "create NAME --subject SUBJECT --sink SINK",
Short: "Create a sink binding",
Example: `
# Create a sink binding which connects a deployment 'myapp' with a Knative service 'mysvc'
kn source binding create my-binding --subject Deployment:apps/v1:myapp --sink svc:mysvc`,

View File

@ -26,7 +26,7 @@ import (
func NewBindingDeleteCommand(p *commands.KnParams) *cobra.Command {
cmd := &cobra.Command{
Use: "delete NAME",
Short: "Delete a sink binding.",
Short: "Delete a sink binding",
Example: `
# Delete a sink binding with name 'my-binding'
kn source binding delete my-binding`,

View File

@ -28,7 +28,7 @@ func NewBindingListCommand(p *commands.KnParams) *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List sink bindings.",
Short: "List sink bindings",
Example: `
# List all sink binidngs
kn source binding list

View File

@ -32,8 +32,8 @@ func NewBindingUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "update NAME --subject SCHEDULE --sink SINK --ce-override OVERRIDE",
Short: "Update a sink binding.",
Use: "update NAME",
Short: "Update a sink binding",
Example: `
# Update the subject of a sink binding 'my-binding' to a new cronjob with label selector 'app=ping'
kn source binding update my-binding --subject cronjob:batch/v1beta1:app=ping"`,

View File

@ -41,7 +41,7 @@ func NewListCommand(p *commands.KnParams) *cobra.Command {
listFlags := flags.NewListPrintFlags(ListHandlers)
listCommand := &cobra.Command{
Use: "list",
Short: "List available sources",
Short: "List event sources",
Example: listExample,
RunE: func(cmd *cobra.Command, args []string) error {
namespace, err := p.GetNamespace(cmd)

View File

@ -28,12 +28,12 @@ func NewListTypesCommand(p *commands.KnParams) *cobra.Command {
listTypesFlags := flags.NewListPrintFlags(ListTypesHandlers)
listTypesCommand := &cobra.Command{
Use: "list-types",
Short: "List available source types",
Short: "List event source types",
Example: `
# List available eventing source types
# List available event source types
kn source list-types
# List available eventing source types in YAML format
# List available event source types in YAML format
kn source list-types -o yaml`,
RunE: func(cmd *cobra.Command, args []string) error {
namespace, err := p.GetNamespace(cmd)

View File

@ -32,8 +32,8 @@ func NewPingCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "create NAME --schedule SCHEDULE --sink SINK --data DATA",
Short: "Create a Ping source.",
Use: "create NAME",
Short: "Create a ping source",
Example: `
# Create a Ping source 'my-ping' which fires every two minutes and sends '{ value: "hello" }' to service 'mysvc' as a cloudevent
kn source ping create my-ping --schedule "*/2 * * * *" --data '{ value: "hello" }' --sink svc:mysvc`,

View File

@ -26,7 +26,7 @@ import (
func NewPingDeleteCommand(p *commands.KnParams) *cobra.Command {
pingDeleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete a Ping source.",
Short: "Delete a ping source",
Example: `
# Delete a Ping source 'my-ping'
kn source ping delete my-ping`,

View File

@ -32,7 +32,7 @@ func NewPingDescribeCommand(p *commands.KnParams) *cobra.Command {
pingDescribe := &cobra.Command{
Use: "describe NAME",
Short: "Show details of a Ping source",
Short: "Show details of a ping source",
Example: `
# Describe a Ping source with name 'myping'
kn source ping describe myping`,

View File

@ -29,7 +29,7 @@ func NewPingListCommand(p *commands.KnParams) *cobra.Command {
listCommand := &cobra.Command{
Use: "list",
Short: "List Ping sources.",
Short: "List ping sources",
Example: `
# List all Ping sources
kn source ping list

View File

@ -26,8 +26,8 @@ import (
// NewPingCommand is the root command for all Ping source related commands
func NewPingCommand(p *commands.KnParams) *cobra.Command {
pingImporterCmd := &cobra.Command{
Use: "ping",
Short: "Ping source command group",
Use: "ping COMMAND",
Short: "Manage ping sources",
}
pingImporterCmd.AddCommand(NewPingCreateCommand(p))
pingImporterCmd.AddCommand(NewPingDeleteCommand(p))

View File

@ -32,8 +32,8 @@ func NewPingUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "update NAME --schedule SCHEDULE --sink SERVICE --data DATA",
Short: "Update a Ping source.",
Use: "update NAME",
Short: "Update a ping source",
Example: `
# Update the schedule of a Ping source 'my-ping' to fire every minute
kn source ping update my-ping --schedule "* * * * *"`,

View File

@ -25,8 +25,8 @@ import (
func NewSourceCommand(p *commands.KnParams) *cobra.Command {
sourceCmd := &cobra.Command{
Use: "source",
Short: "Event source command group",
Use: "source SOURCE|COMMAND",
Short: "Manage event sources",
}
sourceCmd.AddCommand(NewListTypesCommand(p))
sourceCmd.AddCommand(NewListCommand(p))

View File

@ -16,12 +16,9 @@ package commands
import (
"bytes"
"io/ioutil"
"os"
"testing"
"github.com/spf13/cobra"
"gotest.tools/assert"
"k8s.io/apimachinery/pkg/runtime"
clienttesting "k8s.io/client-go/testing"
servingv1fake "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake"
@ -93,35 +90,6 @@ func CreateDynamicTestKnCommand(cmd *cobra.Command, knParams *KnParams, objects
}
type StdoutCapture struct {
r, w *os.File
t *testing.T
oldStdout *os.File
}
func CaptureStdout(t *testing.T) StdoutCapture {
ret := StdoutCapture{
oldStdout: os.Stdout,
t: t,
}
var err error
ret.r, ret.w, err = os.Pipe()
assert.NilError(t, err)
os.Stdout = ret.w
return ret
}
// CaptureStdout collects the current content of os.Stdout
func (c StdoutCapture) Close() string {
err := c.w.Close()
assert.NilError(c.t, err)
ret, err := ioutil.ReadAll(c.r)
assert.NilError(c.t, err)
os.Stdout = c.oldStdout
return string(ret)
}
// NewTestCommand can be used by tes
func NewTestCommand(subCommand *cobra.Command, params *KnParams) *cobra.Command {
rootCmd := &cobra.Command{

View File

@ -20,6 +20,8 @@ import (
"github.com/spf13/cobra"
"gotest.tools/assert"
"knative.dev/client/lib/test"
)
func TestCreateTestKnCommand(t *testing.T) {
@ -56,8 +58,9 @@ func TestCreateDynamicTestKnCommand(t *testing.T) {
}
func TestCaptureStdout(t *testing.T) {
c := CaptureStdout(t)
c := test.CaptureOutput(t)
fmt.Print("Hello World !")
out := c.Close()
assert.Equal(t, out, "Hello World !")
stdOut, stdErr := c.Close()
assert.Equal(t, stdErr, "")
assert.Equal(t, stdOut, "Hello World !")
}

View File

@ -33,7 +33,7 @@ func NewTriggerCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "create NAME --broker BROKER --sink SINK",
Use: "create NAME --sink SINK",
Short: "Create a trigger",
Example: `
# Create a trigger 'mytrigger' to declare a subscription to events from default broker. The subscriber is service 'mysvc'

View File

@ -26,7 +26,7 @@ import (
func NewTriggerDeleteCommand(p *commands.KnParams) *cobra.Command {
TriggerDeleteCommand := &cobra.Command{
Use: "delete NAME",
Short: "Delete a trigger.",
Short: "Delete a trigger",
Example: `
# Delete a trigger 'mytrigger' in default namespace
kn trigger delete mytrigger`,

View File

@ -28,8 +28,8 @@ func NewTriggerListCommand(p *commands.KnParams) *cobra.Command {
triggerListFlags := flags.NewListPrintFlags(TriggerListHandlers)
triggerListCommand := &cobra.Command{
Use: "list [name]",
Short: "List available triggers.",
Use: "list",
Short: "List triggers",
Example: `
# List all triggers
kn trigger list

View File

@ -29,7 +29,7 @@ const (
func NewTriggerCommand(p *commands.KnParams) *cobra.Command {
triggerCmd := &cobra.Command{
Use: "trigger",
Short: "Trigger command group",
Short: "Manage event triggers",
}
triggerCmd.AddCommand(NewTriggerCreateCommand(p))
triggerCmd.AddCommand(NewTriggerUpdateCommand(p))

View File

@ -36,7 +36,7 @@ func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags
cmd := &cobra.Command{
Use: "update NAME --filter KEY=VALUE --sink SINK",
Use: "update NAME",
Short: "Update a trigger",
Example: `
# Update the filter which key is 'type' to value 'knative.dev.bar' in a trigger 'mytrigger'

View File

@ -50,7 +50,7 @@ type knVersion struct {
func NewVersionCommand(p *commands.KnParams) *cobra.Command {
versionCmd := &cobra.Command{
Use: "version",
Short: "Prints the client version",
Short: "Show the version of this client",
RunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("output") {
return printVersionMachineReadable(cmd)

View File

@ -25,6 +25,7 @@ import (
"sigs.k8s.io/yaml"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/util"
)
var versionOutputTemplate = `Version: {{.Version}}
@ -73,7 +74,7 @@ func TestVersion(t *testing.T) {
t.Run("creates a VersionCommand", func(t *testing.T) {
setup()
assert.Equal(t, versionCmd.Use, "version")
assert.Equal(t, versionCmd.Short, "Prints the client version")
assert.Assert(t, util.ContainsAll(versionCmd.Short, "version"))
assert.Assert(t, versionCmd.RunE != nil)
})

View File

@ -17,17 +17,16 @@ package root
import (
"flag"
"fmt"
"os"
"strings"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"golang.org/x/crypto/ssh/terminal"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
_ "k8s.io/client-go/plugin/pkg/client/auth/oidc"
"knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/kn/commands/completion"
"knative.dev/client/pkg/kn/commands/options"
"knative.dev/client/pkg/kn/commands/plugin"
"knative.dev/client/pkg/kn/commands/revision"
"knative.dev/client/pkg/kn/commands/route"
@ -37,6 +36,7 @@ import (
"knative.dev/client/pkg/kn/commands/version"
"knative.dev/client/pkg/kn/config"
"knative.dev/client/pkg/kn/flags"
"knative.dev/client/pkg/templates"
)
// NewRootCommand creates the default `kn` command with a default plugin handler
@ -46,19 +46,17 @@ func NewRootCommand() (*cobra.Command, error) {
rootCmd := &cobra.Command{
Use: "kn",
Short: "Knative client",
Long: `Manage your Knative building blocks:
Short: "kn manages Knative Serving and Eventing resources",
Long: `kn is the command line interface for managing Knative Serving and Eventing resources
* Serving: Manage your services and release new software to them.
* Eventing: Manage event subscriptions and channels. Connect up event sources.`,
Find more information about Knative at: https://knative.dev`,
// Disable docs header
DisableAutoGenTag: true,
// Affects children as well
SilenceUsage: true,
// Prevents Cobra from dealing with errors as we deal with them in main.go
// Disable usage & error printing from cobra as we
// are handling all error output on our own
SilenceUsage: true,
SilenceErrors: true,
// Validate our boolean configs
@ -77,18 +75,40 @@ func NewRootCommand() (*cobra.Command, error) {
rootCmd.PersistentFlags().StringVar(&p.KubeCfgPath, "kubeconfig", "", "kubectl configuration file (default: ~/.kube/config)")
flags.AddBothBoolFlags(rootCmd.PersistentFlags(), &p.LogHTTP, "log-http", "", false, "log http traffic")
// root child commands
rootCmd.AddCommand(service.NewServiceCommand(p))
rootCmd.AddCommand(revision.NewRevisionCommand(p))
rootCmd.AddCommand(plugin.NewPluginCommand(p))
rootCmd.AddCommand(route.NewRouteCommand(p))
rootCmd.AddCommand(completion.NewCompletionCommand(p))
rootCmd.AddCommand(version.NewVersionCommand(p))
rootCmd.AddCommand(source.NewSourceCommand(p))
rootCmd.AddCommand(trigger.NewTriggerCommand(p))
// Grouped commands
groups := templates.CommandGroups{
{
Header: "Serving Commands:",
Commands: []*cobra.Command{
service.NewServiceCommand(p),
revision.NewRevisionCommand(p),
route.NewRouteCommand(p),
},
},
{
Header: "Eventing Commands:",
Commands: []*cobra.Command{
source.NewSourceCommand(p),
trigger.NewTriggerCommand(p),
},
},
{
Header: "Other Commands:",
Commands: []*cobra.Command{
plugin.NewPluginCommand(p),
completion.NewCompletionCommand(p),
version.NewVersionCommand(p),
},
},
}
// Add all commands to the root command, flat
groups.AddTo(rootCmd)
// Initialize default `help` cmd early to prevent unknown command errors
rootCmd.InitDefaultHelpCmd()
groups.SetRootUsage(rootCmd)
// Add the "options" commands for showing all global options
rootCmd.AddCommand(options.NewOptionsCommand())
// Check that command groups can't execute and that leaf commands don't h
err := validateCommandStructure(rootCmd)
@ -96,8 +116,10 @@ func NewRootCommand() (*cobra.Command, error) {
return nil, err
}
// Wrap usage.
fitUsageMessageToTerminalWidth(rootCmd)
// Add some command context when flags can not be parsed
rootCmd.SetFlagErrorFunc(func(c *cobra.Command, err error) error {
return errors.Errorf("%s for '%s'", err.Error(), c.CommandPath())
})
// For glog parse error. TOO: Check why this is needed
flag.CommandLine.Parse([]string{})
@ -132,15 +154,6 @@ func validateCommandStructure(cmd *cobra.Command) error {
return nil
}
func fitUsageMessageToTerminalWidth(rootCmd *cobra.Command) {
width, _, err := terminal.GetSize(int(os.Stdout.Fd()))
if err == nil {
newUsage := strings.ReplaceAll(rootCmd.UsageTemplate(), "FlagUsages ",
fmt.Sprintf("FlagUsagesWrapped %d ", width))
rootCmd.SetUsageTemplate(newUsage)
}
}
// ExtractSubCommandNames extracts the names of all sub commands of a given command
func ExtractSubCommandNames(cmds []*cobra.Command) []string {
var ret []string

View File

@ -15,6 +15,7 @@
package root
import (
"errors"
"strings"
"testing"
@ -30,7 +31,7 @@ func TestNewRootCommand(t *testing.T) {
assert.Assert(t, rootCmd != nil)
assert.Equal(t, rootCmd.Name(), "kn")
assert.Equal(t, rootCmd.Short, "Knative client")
assert.Assert(t, util.ContainsAll(rootCmd.Short, "Knative", "Serving", "Eventing"))
assert.Assert(t, util.ContainsAll(rootCmd.Long, "Knative", "Serving", "Eventing"))
assert.Assert(t, rootCmd.DisableAutoGenTag)
@ -43,6 +44,10 @@ func TestNewRootCommand(t *testing.T) {
assert.Assert(t, rootCmd.PersistentFlags().Lookup("kubeconfig") != nil)
assert.Assert(t, rootCmd.RunE == nil)
fErrorFunc := rootCmd.FlagErrorFunc()
err = fErrorFunc(rootCmd, errors.New("test"))
assert.Equal(t, err.Error(), "test for 'kn'")
}
func TestSubCommands(t *testing.T) {

View File

@ -0,0 +1,60 @@
// Copyright © 2020 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package templates
import (
"github.com/spf13/cobra"
)
// A command group is for grouping together commands
type CommandGroup struct {
// Title for command group shown in help/usage messages
Header string
// List of commands for this group
Commands []*cobra.Command
}
type CommandGroups []CommandGroup
// Add all commands from this group slice to the given command
func (g CommandGroups) AddTo(cmd *cobra.Command) {
for _, group := range g {
for _, sub := range group.Commands {
cmd.AddCommand(sub)
}
}
}
// SetRootUsage sets our own help and usage function messages to the root command
func (g CommandGroups) SetRootUsage(rootCmd *cobra.Command) {
engine := &templateEngine{
RootCmd: rootCmd,
CommandGroups: g,
}
setHelpFlagsToSubCommands(rootCmd)
rootCmd.SetUsageFunc(engine.usageFunc())
rootCmd.SetHelpFunc(engine.helpFunc())
}
func setHelpFlagsToSubCommands(parent *cobra.Command) {
for _, cmd := range parent.Commands() {
if cmd.HasSubCommands() {
setHelpFlagsToSubCommands(cmd)
}
cmd.DisableFlagsInUseLine = true
}
}

View File

@ -0,0 +1,69 @@
// Copyright © 2020 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package templates
import (
"fmt"
"testing"
"github.com/spf13/cobra"
"gotest.tools/assert"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/util"
)
var groups = CommandGroups{
{
"header-1",
[]*cobra.Command{{Use: "c0"}, {Use: "c1"}},
},
{
"header-2",
[]*cobra.Command{{Use: "c2"}},
},
}
func TestAddTo(t *testing.T) {
rootCmd := &cobra.Command{Use: "root"}
groups.AddTo(rootCmd)
for idx, cmd := range rootCmd.Commands() {
assert.Equal(t, cmd.Name(), fmt.Sprintf("c%d", idx))
}
}
func TestSetUsage(t *testing.T) {
rootCmd := &cobra.Command{Use: "root", Short: "root", Run: func(cmd *cobra.Command, args []string) {}}
groups.AddTo(rootCmd)
groups.SetRootUsage(rootCmd)
for _, cmd := range rootCmd.Commands() {
assert.Assert(t, cmd.DisableFlagsInUseLine)
}
capture := test.CaptureOutput(t)
err := (rootCmd.UsageFunc())(rootCmd)
assert.NilError(t, err)
stdOut, stdErr := capture.Close()
assert.Equal(t, stdErr, "")
assert.Assert(t, util.ContainsAll(stdOut, "header-1", "header-2"))
capture = test.CaptureOutput(t)
(rootCmd.HelpFunc())(rootCmd, nil)
stdOut, stdErr = capture.Close()
assert.Equal(t, stdErr, "")
assert.Assert(t, util.ContainsAll(stdOut, "root", "header-1", "header-2"))
}

Some files were not shown because too many files have changed in this diff Show More