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" "fmt"
"math/rand" "math/rand"
"os" "os"
"regexp"
"strings" "strings"
"time" "time"
@ -35,8 +36,8 @@ func init() {
func main() { func main() {
err := run(os.Args[1:]) err := run(os.Args[1:])
if err != nil { if err != nil && len(os.Args) > 1 {
fmt.Fprintf(os.Stderr, "Error: %v\n", err) printError(err)
// This is the only point from where to exit when an error occurs // This is the only point from where to exit when an error occurs
os.Exit(1) os.Exit(1)
} }
@ -106,8 +107,14 @@ func stripFlags(args []string) ([]string, error) {
*commandsFound = append(*commandsFound, arg) *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 // Filter out --help and -h options to avoid special treatment which we don't
// need here // need here
extractCommand.SetArgs(filterHelpOptions(args)) extractCommand.SetArgs(filterHelpOptions(args))
@ -172,10 +179,34 @@ func validateRootCommand(cmd *cobra.Command) error {
if err == nil && foundCmd.HasSubCommands() && len(innerArgs) > 0 { if err == nil && foundCmd.HasSubCommands() && len(innerArgs) > 0 {
argsWithoutFlags, err := stripFlags(innerArgs) argsWithoutFlags, err := stripFlags(innerArgs)
if len(argsWithoutFlags) > 0 || err != nil { 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 // If no args where given (only flags), then fall through to execute the command itself, which leads to
// a more appropriate error message // a more appropriate error message
} }
return nil 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 package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"strings"
"testing" "testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/pkg/kn/commands" "knative.dev/client/lib/test"
"knative.dev/client/pkg/kn/root" "knative.dev/client/pkg/kn/root"
"knative.dev/client/pkg/util" "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 // Smoke test
func TestRun(t *testing.T) { func TestRun(t *testing.T) {
oldArgs := os.Args oldArgs := os.Args
@ -234,9 +261,9 @@ func TestRun(t *testing.T) {
os.Args = oldArgs os.Args = oldArgs
})() })()
capture := commands.CaptureStdout(t) capture := test.CaptureOutput(t)
err := run(os.Args[1:]) err := run(os.Args[1:])
out := capture.Close() out, _ := capture.Close()
assert.NilError(t, err) assert.NilError(t, err)
assert.Assert(t, util.ContainsAllIgnoreCase(out, "version", "build", "git")) assert.Assert(t, util.ContainsAllIgnoreCase(out, "version", "build", "git"))

View File

@ -51,6 +51,7 @@ be used:
- `create` creates a resource. - `create` creates a resource.
- `update` updates a resource. - `update` updates a resource.
- `delete` deletes 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 For a given resource, create and update should use the same arguments as much as
possible and where it makes sense. 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: characteristics:
- They can be _mandatory_ or _optional_ - 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_ - Optional flags can have _default values_
- Flag values can be _scalars_, _binary_, _lists_ or _maps_ (see below for - Flag values can be _scalars_, _binary_, _lists_ or _maps_ (see below for
details) details)

View File

@ -1,13 +1,12 @@
## kn ## kn
Knative client kn manages Knative Serving and Eventing resources
### Synopsis ### 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. Find more information about Knative at: https://knative.dev
* Eventing: Manage event subscriptions and channels. Connect up event sources.
### Options ### Options
@ -21,11 +20,12 @@ Manage your Knative building blocks:
### SEE ALSO ### SEE ALSO
* [kn completion](kn_completion.md) - Output shell completion code * [kn completion](kn_completion.md) - Output shell completion code
* [kn plugin](kn_plugin.md) - Plugin command group * [kn options](kn_options.md) - Print the list of flags inherited by all commands
* [kn revision](kn_revision.md) - Revision command group * [kn plugin](kn_plugin.md) - Manage kn plugins
* [kn route](kn_route.md) - Route command group * [kn revision](kn_revision.md) - Manage service revisions
* [kn service](kn_service.md) - Service command group * [kn route](kn_route.md) - List and describe service routes
* [kn source](kn_source.md) - Event source command group * [kn service](kn_service.md) - Manage Knative services
* [kn trigger](kn_trigger.md) - Trigger command group * [kn source](kn_source.md) - Manage event sources
* [kn version](kn_version.md) - Prints the client version * [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 - zsh
``` ```
kn completion [SHELL] [flags] kn completion SHELL
``` ```
### Examples ### Examples
@ -44,5 +44,5 @@ kn completion [SHELL] [flags]
### SEE ALSO ### 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 ## kn plugin
Plugin command group Manage kn plugins
### Synopsis ### 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. 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 ### Options
@ -29,6 +29,6 @@ kn plugin [flags]
### SEE ALSO ### 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 * [kn plugin list](kn_plugin_list.md) - List plugins

View File

@ -10,10 +10,10 @@ Available plugins are those that are:
- executable - executable
- begin with "kn-" - begin with "kn-"
- Kn's plugin directory - 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 ### Options
@ -33,5 +33,5 @@ kn plugin list [flags]
### SEE ALSO ### 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 ## kn revision
Revision command group Manage service revisions
### Synopsis ### Synopsis
Revision command group Manage service revisions
``` ```
kn revision [flags] kn revision
``` ```
### Options ### Options
@ -26,8 +26,8 @@ kn revision [flags]
### SEE ALSO ### SEE ALSO
* [kn](kn.md) - Knative client * [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn revision delete](kn_revision_delete.md) - Delete a revision. * [kn revision delete](kn_revision_delete.md) - Delete revisions
* [kn revision describe](kn_revision_describe.md) - Show details of a revision * [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 ## kn revision delete
Delete a revision. Delete revisions
### Synopsis ### Synopsis
Delete a revision. Delete revisions
``` ```
kn revision delete NAME [flags] kn revision delete NAME [NAME ...]
``` ```
### Examples ### Examples
@ -39,5 +39,5 @@ kn revision delete NAME [flags]
### SEE ALSO ### 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 Show details of a revision
``` ```
kn revision describe NAME [flags] kn revision describe NAME
``` ```
### Options ### Options
@ -31,5 +31,5 @@ kn revision describe NAME [flags]
### SEE ALSO ### 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 ## kn revision list
List available revisions. List revisions
### Synopsis ### Synopsis
List revisions for a given service. List revisions for a given service.
``` ```
kn revision list [name] [flags] kn revision list
``` ```
### Examples ### Examples
@ -50,5 +50,5 @@ kn revision list [name] [flags]
### SEE ALSO ### 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 ## kn route
Route command group List and describe service routes
### Synopsis ### Synopsis
Route command group List and describe service routes
``` ```
kn route [flags] kn route
``` ```
### Options ### Options
@ -26,7 +26,7 @@ kn route [flags]
### SEE ALSO ### 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 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 Show details of a route
``` ```
kn route describe NAME [flags] kn route describe NAME
``` ```
### Options ### Options
@ -31,5 +31,5 @@ kn route describe NAME [flags]
### SEE ALSO ### 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 ## kn route list
List available routes. List routes
### Synopsis ### Synopsis
List available routes. List routes
``` ```
kn route list NAME [flags] kn route list NAME
``` ```
### Examples ### Examples
@ -46,5 +46,5 @@ kn route list NAME [flags]
### SEE ALSO ### 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 ## kn service
Service command group Manage Knative services
### Synopsis ### Synopsis
Service command group Manage Knative services
``` ```
kn service [flags] kn service
``` ```
### Options ### Options
@ -26,11 +26,11 @@ kn service [flags]
### SEE ALSO ### SEE ALSO
* [kn](kn.md) - Knative client * [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [kn service create](kn_service_create.md) - Create a service. * [kn service create](kn_service_create.md) - Create a service
* [kn service delete](kn_service_delete.md) - Delete 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 describe](kn_service_describe.md) - Show details of a service
* [kn service export](kn_service_export.md) - Export a service. * [kn service export](kn_service_export.md) - Export a service and its revisions
* [kn service list](kn_service_list.md) - List available services. * [kn service list](kn_service_list.md) - List services
* [kn service update](kn_service_update.md) - Update a service. * [kn service update](kn_service_update.md) - Update a service

View File

@ -1,13 +1,13 @@
## kn service create ## kn service create
Create a service. Create a service
### Synopsis ### Synopsis
Create a service. Create a service
``` ```
kn service create NAME --image IMAGE [flags] kn service create NAME --image IMAGE
``` ```
### Examples ### Examples
@ -101,5 +101,5 @@ kn service create NAME --image IMAGE [flags]
### SEE ALSO ### 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 ## kn service delete
Delete a service. Delete services
### Synopsis ### Synopsis
Delete a service. Delete services
``` ```
kn service delete NAME [flags] kn service delete NAME [NAME ...]
``` ```
### Examples ### Examples
@ -46,5 +46,5 @@ kn service delete NAME [flags]
### SEE ALSO ### 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 Show details of a service
``` ```
kn service describe NAME [flags] kn service describe NAME
``` ```
### Options ### Options
@ -31,5 +31,5 @@ kn service describe NAME [flags]
### SEE ALSO ### 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 ## kn service export
Export a service. Export a service and its revisions
### Synopsis ### Synopsis
Export a service. Export a service and its revisions
``` ```
kn service export NAME [flags] kn service export NAME
``` ```
### Examples ### Examples
@ -46,5 +46,5 @@ kn service export NAME [flags]
### SEE ALSO ### 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 ## kn service list
List available services. List services
### Synopsis ### Synopsis
List available services. List services
``` ```
kn service list [name] [flags] kn service list
``` ```
### Examples ### Examples
@ -46,5 +46,5 @@ kn service list [name] [flags]
### SEE ALSO ### 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 ## kn service update
Update a service. Update a service
### Synopsis ### Synopsis
Update a service. Update a service
``` ```
kn service update NAME [flags] kn service update NAME
``` ```
### Examples ### Examples
@ -91,5 +91,5 @@ kn service update NAME [flags]
### SEE ALSO ### 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 ## kn source
Event source command group Manage event sources
### Synopsis ### Synopsis
Event source command group Manage event sources
``` ```
kn source [flags] kn source SOURCE|COMMAND
``` ```
### Options ### Options
@ -26,10 +26,10 @@ kn source [flags]
### SEE ALSO ### SEE ALSO
* [kn](kn.md) - Knative client * [kn](kn.md) - kn manages Knative Serving and Eventing resources
* [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
* [kn source binding](kn_source_binding.md) - Sink binding command group * [kn source binding](kn_source_binding.md) - Manage sink bindings
* [kn source list](kn_source_list.md) - List available sources * [kn source list](kn_source_list.md) - List event sources
* [kn source list-types](kn_source_list-types.md) - List available source types * [kn source list-types](kn_source_list-types.md) - List event source types
* [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 apiserver ## kn source apiserver
Kubernetes API Server Event Source command group Manage Kubernetes api-server sources
### Synopsis ### Synopsis
Kubernetes API Server Event Source command group Manage Kubernetes api-server sources
``` ```
kn source apiserver [flags] kn source apiserver COMMAND
``` ```
### Options ### Options
@ -26,10 +26,10 @@ kn source apiserver [flags]
### SEE ALSO ### SEE ALSO
* [kn source](kn_source.md) - Event source command group * [kn source](kn_source.md) - Manage event sources
* [kn source apiserver create](kn_source_apiserver_create.md) - Create an ApiServer source. * [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 ApiServer 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 ApiServer 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 ApiServer sources. * [kn source apiserver list](kn_source_apiserver_list.md) - List api-server sources
* [kn source apiserver update](kn_source_apiserver_update.md) - Update an ApiServer source. * [kn source apiserver update](kn_source_apiserver_update.md) - Update an api-server source

View File

@ -1,13 +1,13 @@
## kn source apiserver create ## kn source apiserver create
Create an ApiServer source. Create an api-server source
### Synopsis ### 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 ### Examples
@ -43,5 +43,5 @@ kn source apiserver create NAME --resource RESOURCE --service-account ACCOUNTNAM
### SEE ALSO ### 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 ## kn source apiserver delete
Delete an ApiServer source. Delete an api-server source
### Synopsis ### Synopsis
Delete an ApiServer source. Delete an api-server source
``` ```
kn source apiserver delete NAME [flags] kn source apiserver delete NAME
``` ```
### Examples ### Examples
@ -35,5 +35,5 @@ kn source apiserver delete NAME [flags]
### SEE ALSO ### 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 ## kn source apiserver describe
Show details of an ApiServer source Show details of an api-server source
### Synopsis ### 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 ### Examples
@ -36,5 +36,5 @@ kn source apiserver describe NAME [flags]
### SEE ALSO ### 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 ## kn source apiserver list
List ApiServer sources. List api-server sources
### Synopsis ### Synopsis
List ApiServer sources. List api-server sources
``` ```
kn source apiserver list [flags] kn source apiserver list
``` ```
### Examples ### Examples
@ -43,5 +43,5 @@ kn source apiserver list [flags]
### SEE ALSO ### 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 ## kn source apiserver update
Update an ApiServer source. Update an api-server source
### Synopsis ### 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 ### Examples
@ -43,5 +43,5 @@ kn source apiserver update NAME --resource RESOURCE --service-account ACCOUNTNAM
### SEE ALSO ### 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 ## kn source binding
Sink binding command group Manage sink bindings
### Synopsis ### Synopsis
Sink binding command group Manage sink bindings
``` ```
kn source binding [flags] kn source binding COMMAND
``` ```
### Options ### Options
@ -26,10 +26,10 @@ kn source binding [flags]
### SEE ALSO ### SEE ALSO
* [kn source](kn_source.md) - Event source command group * [kn source](kn_source.md) - Manage event sources
* [kn source binding create](kn_source_binding_create.md) - Create a sink binding. * [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 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 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 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 update](kn_source_binding_update.md) - Update a sink binding

View File

@ -1,13 +1,13 @@
## kn source binding create ## kn source binding create
Create a sink binding. Create a sink binding
### Synopsis ### 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 ### Examples
@ -38,5 +38,5 @@ kn source binding create NAME --subject SUBJECT --sink SINK --ce-override KEY=VA
### SEE ALSO ### 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 ## kn source binding delete
Delete a sink binding. Delete a sink binding
### Synopsis ### Synopsis
Delete a sink binding. Delete a sink binding
``` ```
kn source binding delete NAME [flags] kn source binding delete NAME
``` ```
### Examples ### Examples
@ -35,5 +35,5 @@ kn source binding delete NAME [flags]
### SEE ALSO ### 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 Show details of a sink binding
``` ```
kn source binding describe NAME [flags] kn source binding describe NAME
``` ```
### Examples ### Examples
@ -36,5 +36,5 @@ kn source binding describe NAME [flags]
### SEE ALSO ### 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 ## kn source binding list
List sink bindings. List sink bindings
### Synopsis ### Synopsis
List sink bindings. List sink bindings
``` ```
kn source binding list [flags] kn source binding list
``` ```
### Examples ### Examples
@ -43,5 +43,5 @@ kn source binding list [flags]
### SEE ALSO ### 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 ## kn source binding update
Update a sink binding. Update a sink binding
### Synopsis ### 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 ### Examples
@ -38,5 +38,5 @@ kn source binding update NAME --subject SCHEDULE --sink SINK --ce-override OVERR
### SEE ALSO ### 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 ## kn source list-types
List available source types List event source types
### Synopsis ### Synopsis
List available source types List event source types
``` ```
kn source list-types [flags] kn source list-types
``` ```
### Examples ### Examples
``` ```
# List available eventing source types # List available event source types
kn source list-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 kn source list-types -o yaml
``` ```
@ -42,5 +42,5 @@ kn source list-types [flags]
### SEE ALSO ### 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 ## kn source list
List available sources List event sources
### Synopsis ### Synopsis
List available sources List event sources
``` ```
kn source list [flags] kn source list
``` ```
### Examples ### Examples
@ -47,5 +47,5 @@ kn source list [flags]
### SEE ALSO ### 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 ## kn source ping
Ping source command group Manage ping sources
### Synopsis ### Synopsis
Ping source command group Manage ping sources
``` ```
kn source ping [flags] kn source ping COMMAND
``` ```
### Options ### Options
@ -26,10 +26,10 @@ kn source ping [flags]
### SEE ALSO ### SEE ALSO
* [kn source](kn_source.md) - Event source command group * [kn source](kn_source.md) - Manage event sources
* [kn source ping create](kn_source_ping_create.md) - Create a Ping source. * [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 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 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 list](kn_source_ping_list.md) - List ping sources
* [kn source ping update](kn_source_ping_update.md) - Update a Ping source. * [kn source ping update](kn_source_ping_update.md) - Update a ping source

View File

@ -1,13 +1,13 @@
## kn source ping create ## kn source ping create
Create a Ping source. Create a ping source
### Synopsis ### 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 ### Examples
@ -39,5 +39,5 @@ kn source ping create NAME --schedule SCHEDULE --sink SINK --data DATA [flags]
### SEE ALSO ### 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 ## kn source ping delete
Delete a Ping source. Delete a ping source
### Synopsis ### Synopsis
Delete a Ping source. Delete a ping source
``` ```
kn source ping delete NAME [flags] kn source ping delete NAME
``` ```
### Examples ### Examples
@ -35,5 +35,5 @@ kn source ping delete NAME [flags]
### SEE ALSO ### 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 ## kn source ping describe
Show details of a Ping source Show details of a ping source
### Synopsis ### 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 ### Examples
@ -36,5 +36,5 @@ kn source ping describe NAME [flags]
### SEE ALSO ### 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 ## kn source ping list
List Ping sources. List ping sources
### Synopsis ### Synopsis
List Ping sources. List ping sources
``` ```
kn source ping list [flags] kn source ping list
``` ```
### Examples ### Examples
@ -43,5 +43,5 @@ kn source ping list [flags]
### SEE ALSO ### 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 ## kn source ping update
Update a Ping source. Update a ping source
### Synopsis ### 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 ### Examples
@ -39,5 +39,5 @@ kn source ping update NAME --schedule SCHEDULE --sink SERVICE --data DATA [flags
### SEE ALSO ### 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 ## kn trigger
Trigger command group Manage event triggers
### Synopsis ### Synopsis
Trigger command group Manage event triggers
``` ```
kn trigger [flags] kn trigger
``` ```
### Options ### Options
@ -26,10 +26,10 @@ kn trigger [flags]
### SEE ALSO ### 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 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 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 * [kn trigger update](kn_trigger_update.md) - Update a trigger

View File

@ -7,7 +7,7 @@ Create a trigger
Create a trigger Create a trigger
``` ```
kn trigger create NAME --broker BROKER --sink SINK [flags] kn trigger create NAME --sink SINK
``` ```
### Examples ### Examples
@ -42,5 +42,5 @@ kn trigger create NAME --broker BROKER --sink SINK [flags]
### SEE ALSO ### 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 ## kn trigger delete
Delete a trigger. Delete a trigger
### Synopsis ### Synopsis
Delete a trigger. Delete a trigger
``` ```
kn trigger delete NAME [flags] kn trigger delete NAME
``` ```
### Examples ### Examples
@ -35,5 +35,5 @@ kn trigger delete NAME [flags]
### SEE ALSO ### 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 Show details of a trigger
``` ```
kn trigger describe NAME [flags] kn trigger describe NAME
``` ```
### Examples ### Examples
@ -36,5 +36,5 @@ kn trigger describe NAME [flags]
### SEE ALSO ### 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 ## kn trigger list
List available triggers. List triggers
### Synopsis ### Synopsis
List available triggers. List triggers
``` ```
kn trigger list [name] [flags] kn trigger list
``` ```
### Examples ### Examples
@ -43,5 +43,5 @@ kn trigger list [name] [flags]
### SEE ALSO ### 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 Update a trigger
``` ```
kn trigger update NAME --filter KEY=VALUE --sink SINK [flags] kn trigger update NAME
``` ```
### Examples ### Examples
@ -46,5 +46,5 @@ kn trigger update NAME --filter KEY=VALUE --sink SINK [flags]
### SEE ALSO ### 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 ## kn version
Prints the client version Show the version of this client
### Synopsis ### Synopsis
Prints the client version Show the version of this client
``` ```
kn version [flags] kn version
``` ```
### Options ### Options
@ -27,5 +27,5 @@ kn version [flags]
### SEE ALSO ### 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 package completion
import ( import (
"fmt"
"os" "os"
"github.com/pkg/errors"
"knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -43,23 +44,23 @@ Supported Shells:
// NewCompletionCommand implements shell auto-completion feature for Bash and Zsh // NewCompletionCommand implements shell auto-completion feature for Bash and Zsh
func NewCompletionCommand(p *commands.KnParams) *cobra.Command { func NewCompletionCommand(p *commands.KnParams) *cobra.Command {
return &cobra.Command{ return &cobra.Command{
Use: "completion [SHELL]", Use: "completion SHELL",
Short: "Output shell completion code", Short: "Output shell completion code",
Long: desc, Long: desc,
ValidArgs: []string{"bash", "zsh"}, ValidArgs: []string{"bash", "zsh"},
Example: eg, Example: eg,
Run: func(cmd *cobra.Command, args []string) { RunE: func(cmd *cobra.Command, args []string) error {
if len(args) == 1 { if len(args) == 1 {
switch args[0] { switch args[0] {
case "bash": case "bash":
cmd.Root().GenBashCompletion(os.Stdout) return cmd.Root().GenBashCompletion(os.Stdout)
case "zsh": case "zsh":
cmd.Root().GenZshCompletion(os.Stdout) return cmd.Root().GenZshCompletion(os.Stdout)
default: default:
fmt.Println("only supports 'bash' or 'zsh' shell completion") return errors.New("'bash' or 'zsh' shell completion is supported")
} }
} else { } 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 ( import (
"testing" "testing"
"knative.dev/client/lib/test"
"knative.dev/client/pkg/kn/commands" "knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/util" "knative.dev/client/pkg/util"
@ -28,31 +29,30 @@ func TestCompletionUsage(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{}) completionCmd := NewCompletionCommand(&commands.KnParams{})
assert.Assert(t, util.ContainsAllIgnoreCase(completionCmd.Use, "completion")) assert.Assert(t, util.ContainsAllIgnoreCase(completionCmd.Use, "completion"))
assert.Assert(t, util.ContainsAllIgnoreCase(completionCmd.Short, "completion", "shell")) 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) { func TestCompletionGeneration(t *testing.T) {
for _, shell := range []string{"bash", "zsh"} { for _, shell := range []string{"bash", "zsh"} {
completionCmd := NewCompletionCommand(&commands.KnParams{}) completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t) c := test.CaptureOutput(t)
completionCmd.Run(&cobra.Command{}, []string{shell}) err := completionCmd.RunE(&cobra.Command{}, []string{shell})
out := c.Close() assert.NilError(t, err)
assert.Assert(t, out != "") stdOut, stdErr := c.Close()
assert.Assert(t, stdErr == "")
assert.Assert(t, stdOut != "")
} }
} }
func TestCompletionNoArg(t *testing.T) { func TestCompletionNoArg(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{}) completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t) err := completionCmd.RunE(&cobra.Command{}, []string{})
completionCmd.Run(&cobra.Command{}, []string{}) assert.Assert(t, util.ContainsAll(err.Error(), "bash", "zsh", "one", "argument"))
out := c.Close()
assert.Assert(t, util.ContainsAll(out, "bash", "zsh", "one", "argument"))
} }
func TestCompletionWrongArg(t *testing.T) { func TestCompletionWrongArg(t *testing.T) {
completionCmd := NewCompletionCommand(&commands.KnParams{}) completionCmd := NewCompletionCommand(&commands.KnParams{})
c := commands.CaptureStdout(t) err := completionCmd.RunE(&cobra.Command{}, []string{"sh"})
completionCmd.Run(&cobra.Command{}, []string{"sh"}) assert.Assert(t, util.ContainsAll(err.Error(), "bash", "zsh", "support"))
out := c.Close()
assert.Assert(t, util.ContainsAll(out, "bash", "zsh", "only", "supports"))
} }

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 - executable
- begin with "kn-" - begin with "kn-"
- Kn's plugin directory - 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 { RunE: func(cmd *cobra.Command, args []string) error {
return listPlugins(cmd, plFlags) return listPlugins(cmd, plFlags)
}, },

View File

@ -23,11 +23,11 @@ import (
func NewPluginCommand(p *commands.KnParams) *cobra.Command { func NewPluginCommand(p *commands.KnParams) *cobra.Command {
pluginCmd := &cobra.Command{ pluginCmd := &cobra.Command{
Use: "plugin", Use: "plugin",
Short: "Plugin command group", Short: "Manage kn plugins",
Long: `Provides utilities for interacting and managing with kn plugins. Long: `Manage kn plugins
Plugins provide extended functionality that is not part of the core kn command-line distribution. 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)) pluginCmd.AddCommand(NewPluginListCommand(p))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -50,7 +50,7 @@ func NewServiceExportCommand(p *commands.KnParams) *cobra.Command {
command := &cobra.Command{ command := &cobra.Command{
Use: "export NAME", Use: "export NAME",
Short: "Export a service.", Short: "Export a service and its revisions",
Example: ` Example: `
# Export a service in YAML format # Export a service in YAML format
kn service export foo -n bar -o yaml 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) serviceListFlags := flags.NewListPrintFlags(ServiceListHandlers)
serviceListCommand := &cobra.Command{ serviceListCommand := &cobra.Command{
Use: "list [name]", Use: "list",
Short: "List available services.", Short: "List services",
Example: ` Example: `
# List all services # List all services
kn service list kn service list

View File

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

View File

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

View File

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

View File

@ -32,8 +32,8 @@ func NewAPIServerCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE", Use: "create NAME --resource RESOURCE --sink SINK",
Short: "Create an ApiServer source.", Short: "Create an api-server source",
Example: ` Example: `
# Create an ApiServerSource 'k8sevents' which consumes Kubernetes events and sends message to service 'mysvc' as a cloudevent # 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`, 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 { func NewAPIServerDeleteCommand(p *commands.KnParams) *cobra.Command {
deleteCommand := &cobra.Command{ deleteCommand := &cobra.Command{
Use: "delete NAME", Use: "delete NAME",
Short: "Delete an ApiServer source.", Short: "Delete an api-server source",
Example: ` Example: `
# Delete an ApiServerSource 'k8sevents' in default namespace # Delete an ApiServerSource 'k8sevents' in default namespace
kn source apiserver delete k8sevents`, kn source apiserver delete k8sevents`,

View File

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

View File

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

View File

@ -32,8 +32,8 @@ func NewAPIServerUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "update NAME --resource RESOURCE --service-account ACCOUNTNAME --sink SINK --mode MODE", Use: "update NAME",
Short: "Update an ApiServer source.", Short: "Update an api-server source",
Example: ` Example: `
# Update an ApiServerSource 'k8sevents' with different service account and sink service # Update an ApiServerSource 'k8sevents' with different service account and sink service
kn source apiserver update k8sevents --service-account newsa --sink svc:newsvc`, 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 // NewBindingCommand is the root command for all binding related commands
func NewBindingCommand(p *commands.KnParams) *cobra.Command { func NewBindingCommand(p *commands.KnParams) *cobra.Command {
bindingCmd := &cobra.Command{ bindingCmd := &cobra.Command{
Use: "binding", Use: "binding COMMAND",
Short: "Sink binding command group", Short: "Manage sink bindings",
} }
bindingCmd.AddCommand(NewBindingCreateCommand(p)) bindingCmd.AddCommand(NewBindingCreateCommand(p))
bindingCmd.AddCommand(NewBindingUpdateCommand(p)) bindingCmd.AddCommand(NewBindingUpdateCommand(p))

View File

@ -32,8 +32,8 @@ func NewBindingCreateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create NAME --subject SUBJECT --sink SINK --ce-override KEY=VALUE", Use: "create NAME --subject SUBJECT --sink SINK",
Short: "Create a sink binding.", Short: "Create a sink binding",
Example: ` Example: `
# Create a sink binding which connects a deployment 'myapp' with a Knative service 'mysvc' # 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`, 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 { func NewBindingDeleteCommand(p *commands.KnParams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "delete NAME", Use: "delete NAME",
Short: "Delete a sink binding.", Short: "Delete a sink binding",
Example: ` Example: `
# Delete a sink binding with name 'my-binding' # Delete a sink binding with name 'my-binding'
kn source binding delete my-binding`, kn source binding delete my-binding`,

View File

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

View File

@ -32,8 +32,8 @@ func NewBindingUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "update NAME --subject SCHEDULE --sink SINK --ce-override OVERRIDE", Use: "update NAME",
Short: "Update a sink binding.", Short: "Update a sink binding",
Example: ` Example: `
# Update the subject of a sink binding 'my-binding' to a new cronjob with label selector 'app=ping' # 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"`, 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) listFlags := flags.NewListPrintFlags(ListHandlers)
listCommand := &cobra.Command{ listCommand := &cobra.Command{
Use: "list", Use: "list",
Short: "List available sources", Short: "List event sources",
Example: listExample, Example: listExample,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
namespace, err := p.GetNamespace(cmd) namespace, err := p.GetNamespace(cmd)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,12 +16,9 @@ package commands
import ( import (
"bytes" "bytes"
"io/ioutil"
"os" "os"
"testing"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"gotest.tools/assert"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
clienttesting "k8s.io/client-go/testing" clienttesting "k8s.io/client-go/testing"
servingv1fake "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake" 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 // NewTestCommand can be used by tes
func NewTestCommand(subCommand *cobra.Command, params *KnParams) *cobra.Command { func NewTestCommand(subCommand *cobra.Command, params *KnParams) *cobra.Command {
rootCmd := &cobra.Command{ rootCmd := &cobra.Command{

View File

@ -20,6 +20,8 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"gotest.tools/assert" "gotest.tools/assert"
"knative.dev/client/lib/test"
) )
func TestCreateTestKnCommand(t *testing.T) { func TestCreateTestKnCommand(t *testing.T) {
@ -56,8 +58,9 @@ func TestCreateDynamicTestKnCommand(t *testing.T) {
} }
func TestCaptureStdout(t *testing.T) { func TestCaptureStdout(t *testing.T) {
c := CaptureStdout(t) c := test.CaptureOutput(t)
fmt.Print("Hello World !") fmt.Print("Hello World !")
out := c.Close() stdOut, stdErr := c.Close()
assert.Equal(t, out, "Hello World !") 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 var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create NAME --broker BROKER --sink SINK", Use: "create NAME --sink SINK",
Short: "Create a trigger", Short: "Create a trigger",
Example: ` Example: `
# Create a trigger 'mytrigger' to declare a subscription to events from default broker. The subscriber is service 'mysvc' # 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 { func NewTriggerDeleteCommand(p *commands.KnParams) *cobra.Command {
TriggerDeleteCommand := &cobra.Command{ TriggerDeleteCommand := &cobra.Command{
Use: "delete NAME", Use: "delete NAME",
Short: "Delete a trigger.", Short: "Delete a trigger",
Example: ` Example: `
# Delete a trigger 'mytrigger' in default namespace # Delete a trigger 'mytrigger' in default namespace
kn trigger delete mytrigger`, kn trigger delete mytrigger`,

View File

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

View File

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

View File

@ -36,7 +36,7 @@ func NewTriggerUpdateCommand(p *commands.KnParams) *cobra.Command {
var sinkFlags flags.SinkFlags var sinkFlags flags.SinkFlags
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "update NAME --filter KEY=VALUE --sink SINK", Use: "update NAME",
Short: "Update a trigger", Short: "Update a trigger",
Example: ` Example: `
# Update the filter which key is 'type' to value 'knative.dev.bar' in a trigger 'mytrigger' # 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 { func NewVersionCommand(p *commands.KnParams) *cobra.Command {
versionCmd := &cobra.Command{ versionCmd := &cobra.Command{
Use: "version", Use: "version",
Short: "Prints the client version", Short: "Show the version of this client",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if cmd.Flags().Changed("output") { if cmd.Flags().Changed("output") {
return printVersionMachineReadable(cmd) return printVersionMachineReadable(cmd)

View File

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

View File

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

View File

@ -15,6 +15,7 @@
package root package root
import ( import (
"errors"
"strings" "strings"
"testing" "testing"
@ -30,7 +31,7 @@ func TestNewRootCommand(t *testing.T) {
assert.Assert(t, rootCmd != nil) assert.Assert(t, rootCmd != nil)
assert.Equal(t, rootCmd.Name(), "kn") 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, util.ContainsAll(rootCmd.Long, "Knative", "Serving", "Eventing"))
assert.Assert(t, rootCmd.DisableAutoGenTag) 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.PersistentFlags().Lookup("kubeconfig") != nil)
assert.Assert(t, rootCmd.RunE == 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) { 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