mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
update vendor spf13/cobra to enforce required flags
This commit is contained in:
parent
b047e8ea0d
commit
ddf97084f5
4
Godeps/Godeps.json
generated
4
Godeps/Godeps.json
generated
@ -2470,11 +2470,11 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra/doc",
|
"ImportPath": "github.com/spf13/cobra/doc",
|
||||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/jwalterweatherman",
|
"ImportPath": "github.com/spf13/jwalterweatherman",
|
||||||
|
@ -328,7 +328,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
"ImportPath": "github.com/spf13/pflag",
|
||||||
|
@ -308,7 +308,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
"ImportPath": "github.com/spf13/pflag",
|
||||||
|
@ -296,7 +296,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/cobra",
|
"ImportPath": "github.com/spf13/cobra",
|
||||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/spf13/pflag",
|
"ImportPath": "github.com/spf13/pflag",
|
||||||
|
13
vendor/github.com/spf13/cobra/.travis.yml
generated
vendored
13
vendor/github.com/spf13/cobra/.travis.yml
generated
vendored
@ -1,11 +1,10 @@
|
|||||||
language: go
|
language: go
|
||||||
go:
|
|
||||||
- 1.4.3
|
|
||||||
- 1.5.4
|
|
||||||
- 1.6.3
|
|
||||||
- tip
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
include:
|
||||||
|
- go: 1.7.6
|
||||||
|
- go: 1.8.3
|
||||||
|
- go: tip
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- go: tip
|
- go: tip
|
||||||
|
|
||||||
@ -16,3 +15,7 @@ before_install:
|
|||||||
script:
|
script:
|
||||||
- PATH=$PATH:$PWD/bin go test -v ./...
|
- PATH=$PATH:$PWD/bin go test -v ./...
|
||||||
- go build
|
- go build
|
||||||
|
- diff -u <(echo -n) <(gofmt -d -s .)
|
||||||
|
- if [ -z $NOVET ]; then
|
||||||
|
diff -u <(echo -n) <(go tool vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint');
|
||||||
|
fi
|
||||||
|
2
vendor/github.com/spf13/cobra/BUILD
generated
vendored
2
vendor/github.com/spf13/cobra/BUILD
generated
vendored
@ -3,9 +3,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
|||||||
go_library(
|
go_library(
|
||||||
name = "go_default_library",
|
name = "go_default_library",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
"args.go",
|
||||||
"bash_completions.go",
|
"bash_completions.go",
|
||||||
"cobra.go",
|
"cobra.go",
|
||||||
"command.go",
|
"command.go",
|
||||||
|
"zsh_completions.go",
|
||||||
] + select({
|
] + select({
|
||||||
"@io_bazel_rules_go//go/platform:android": [
|
"@io_bazel_rules_go//go/platform:android": [
|
||||||
"command_notwin.go",
|
"command_notwin.go",
|
||||||
|
635
vendor/github.com/spf13/cobra/README.md
generated
vendored
635
vendor/github.com/spf13/cobra/README.md
generated
vendored
@ -8,6 +8,7 @@ Many of the most widely used Go projects are built using Cobra including:
|
|||||||
* [Hugo](http://gohugo.io)
|
* [Hugo](http://gohugo.io)
|
||||||
* [rkt](https://github.com/coreos/rkt)
|
* [rkt](https://github.com/coreos/rkt)
|
||||||
* [etcd](https://github.com/coreos/etcd)
|
* [etcd](https://github.com/coreos/etcd)
|
||||||
|
* [Moby (former Docker)](https://github.com/moby/moby)
|
||||||
* [Docker (distribution)](https://github.com/docker/distribution)
|
* [Docker (distribution)](https://github.com/docker/distribution)
|
||||||
* [OpenShift](https://www.openshift.com/)
|
* [OpenShift](https://www.openshift.com/)
|
||||||
* [Delve](https://github.com/derekparker/delve)
|
* [Delve](https://github.com/derekparker/delve)
|
||||||
@ -15,16 +16,36 @@ Many of the most widely used Go projects are built using Cobra including:
|
|||||||
* [CockroachDB](http://www.cockroachlabs.com/)
|
* [CockroachDB](http://www.cockroachlabs.com/)
|
||||||
* [Bleve](http://www.blevesearch.com/)
|
* [Bleve](http://www.blevesearch.com/)
|
||||||
* [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
|
* [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
|
||||||
* [Parse (CLI)](https://parse.com/)
|
|
||||||
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
|
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
|
||||||
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
|
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
|
||||||
|
* [rclone](http://rclone.org/)
|
||||||
|
* [nehm](https://github.com/bogem/nehm)
|
||||||
|
|
||||||
[](https://travis-ci.org/spf13/cobra)
|
[](https://travis-ci.org/spf13/cobra)
|
||||||
[](https://circleci.com/gh/spf13/cobra)
|
[](https://circleci.com/gh/spf13/cobra)
|
||||||
[](https://godoc.org/github.com/spf13/cobra)
|
[](https://godoc.org/github.com/spf13/cobra)
|
||||||
|
|
||||||

|
# Table of Contents
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Concepts](#concepts)
|
||||||
|
* [Commands](#commands)
|
||||||
|
* [Flags](#flags)
|
||||||
|
- [Installing](#installing)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
* [Using the Cobra Generator](#using-the-cobra-generator)
|
||||||
|
* [Using the Cobra Library](#using-the-cobra-library)
|
||||||
|
* [Working with Flags](#working-with-flags)
|
||||||
|
* [Positional and Custom Arguments](#positional-and-custom-arguments)
|
||||||
|
* [Example](#example)
|
||||||
|
* [Help Command](#help-command)
|
||||||
|
* [Usage Message](#usage-message)
|
||||||
|
* [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
|
||||||
|
* [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
|
||||||
|
* [Generating documentation for your command](#generating-documentation-for-your-command)
|
||||||
|
* [Generating bash completions](#generating-bash-completions)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
@ -39,27 +60,16 @@ Cobra provides:
|
|||||||
* Fully POSIX-compliant flags (including short & long versions)
|
* Fully POSIX-compliant flags (including short & long versions)
|
||||||
* Nested subcommands
|
* Nested subcommands
|
||||||
* Global, local and cascading flags
|
* Global, local and cascading flags
|
||||||
* Easy generation of applications & commands with `cobra create appname` & `cobra add cmdname`
|
* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
|
||||||
* Intelligent suggestions (`app srver`... did you mean `app server`?)
|
* Intelligent suggestions (`app srver`... did you mean `app server`?)
|
||||||
* Automatic help generation for commands and flags
|
* Automatic help generation for commands and flags
|
||||||
* Automatic detailed help for `app help [command]`
|
|
||||||
* Automatic help flag recognition of `-h`, `--help`, etc.
|
* Automatic help flag recognition of `-h`, `--help`, etc.
|
||||||
* Automatically generated bash autocomplete for your application
|
* Automatically generated bash autocomplete for your application
|
||||||
* Automatically generated man pages for your application
|
* Automatically generated man pages for your application
|
||||||
* Command aliases so you can change things without breaking them
|
* Command aliases so you can change things without breaking them
|
||||||
* The flexibilty to define your own help, usage, etc.
|
* The flexibility to define your own help, usage, etc.
|
||||||
* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
|
* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
|
||||||
|
|
||||||
Cobra has an exceptionally clean interface and simple design without needless
|
|
||||||
constructors or initialization methods.
|
|
||||||
|
|
||||||
Applications built with Cobra commands are designed to be as user-friendly as
|
|
||||||
possible. Flags can be placed before or after the command (as long as a
|
|
||||||
confusing space isn’t provided). Both short and long flags can be used. A
|
|
||||||
command need not even be fully typed. Help is automatically generated and
|
|
||||||
available for the application or for a specific command using either the help
|
|
||||||
command or the `--help` flag.
|
|
||||||
|
|
||||||
# Concepts
|
# Concepts
|
||||||
|
|
||||||
Cobra is built on a structure of commands, arguments & flags.
|
Cobra is built on a structure of commands, arguments & flags.
|
||||||
@ -78,11 +88,11 @@ A few good real world examples may better illustrate this point.
|
|||||||
|
|
||||||
In the following example, 'server' is a command, and 'port' is a flag:
|
In the following example, 'server' is a command, and 'port' is a flag:
|
||||||
|
|
||||||
> hugo server --port=1313
|
hugo server --port=1313
|
||||||
|
|
||||||
In this command we are telling Git to clone the url bare.
|
In this command we are telling Git to clone the url bare.
|
||||||
|
|
||||||
> git clone URL --bare
|
git clone URL --bare
|
||||||
|
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
@ -92,20 +102,11 @@ have children commands and optionally run an action.
|
|||||||
|
|
||||||
In the example above, 'server' is the command.
|
In the example above, 'server' is the command.
|
||||||
|
|
||||||
A Command has the following structure:
|
[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
|
||||||
|
|
||||||
```go
|
|
||||||
type Command struct {
|
|
||||||
Use string // The one-line usage message.
|
|
||||||
Short string // The short description shown in the 'help' output.
|
|
||||||
Long string // The long message shown in the 'help <this-command>' output.
|
|
||||||
Run func(cmd *Command, args []string) // Run runs the command.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
A Flag is a way to modify the behavior of a command. Cobra supports
|
A flag is a way to modify the behavior of a command. Cobra supports
|
||||||
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
|
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
|
||||||
A Cobra command can define flags that persist through to children commands
|
A Cobra command can define flags that persist through to children commands
|
||||||
and flags that are only available to that command.
|
and flags that are only available to that command.
|
||||||
@ -113,23 +114,15 @@ and flags that are only available to that command.
|
|||||||
In the example above, 'port' is the flag.
|
In the example above, 'port' is the flag.
|
||||||
|
|
||||||
Flag functionality is provided by the [pflag
|
Flag functionality is provided by the [pflag
|
||||||
library](https://github.com/ogier/pflag), a fork of the flag standard library
|
library](https://github.com/spf13/pflag), a fork of the flag standard library
|
||||||
which maintains the same interface while adding POSIX compliance.
|
which maintains the same interface while adding POSIX compliance.
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Cobra works by creating a set of commands and then organizing them into a tree.
|
|
||||||
The tree defines the structure of the application.
|
|
||||||
|
|
||||||
Once each command is defined with its corresponding flags, then the
|
|
||||||
tree is assigned to the commander which is finally executed.
|
|
||||||
|
|
||||||
# Installing
|
# Installing
|
||||||
Using Cobra is easy. First, use `go get` to install the latest version
|
Using Cobra is easy. First, use `go get` to install the latest version
|
||||||
of the library. This command will install the `cobra` generator executible
|
of the library. This command will install the `cobra` generator executable
|
||||||
along with the library:
|
along with the library and its dependencies:
|
||||||
|
|
||||||
> go get -v github.com/spf13/cobra/cobra
|
go get -u github.com/spf13/cobra/cobra
|
||||||
|
|
||||||
Next, include Cobra in your application:
|
Next, include Cobra in your application:
|
||||||
|
|
||||||
@ -139,8 +132,8 @@ import "github.com/spf13/cobra"
|
|||||||
|
|
||||||
# Getting Started
|
# Getting Started
|
||||||
|
|
||||||
While you are welcome to provide your own organization, typically a Cobra based
|
While you are welcome to provide your own organization, typically a Cobra-based
|
||||||
application will follow the following organizational structure.
|
application will follow the following organizational structure:
|
||||||
|
|
||||||
```
|
```
|
||||||
▾ appName/
|
▾ appName/
|
||||||
@ -152,17 +145,22 @@ application will follow the following organizational structure.
|
|||||||
main.go
|
main.go
|
||||||
```
|
```
|
||||||
|
|
||||||
In a Cobra app, typically the main.go file is very bare. It serves, one purpose, to initialize Cobra.
|
In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "{pathToYourApp}/cmd"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"{pathToYourApp}/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := cmd.RootCmd.Execute(); err != nil {
|
if err := cmd.RootCmd.Execute(); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(-1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -172,99 +170,14 @@ func main() {
|
|||||||
Cobra provides its own program that will create your application and add any
|
Cobra provides its own program that will create your application and add any
|
||||||
commands you want. It's the easiest way to incorporate Cobra into your application.
|
commands you want. It's the easiest way to incorporate Cobra into your application.
|
||||||
|
|
||||||
In order to use the cobra command, compile it using the following command:
|
[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
|
||||||
|
|
||||||
> go install github.com/spf13/cobra/cobra
|
## Using the Cobra Library
|
||||||
|
|
||||||
This will create the cobra executable under your go path bin directory!
|
To manually implement Cobra you need to create a bare main.go file and a RootCmd file.
|
||||||
|
|
||||||
### cobra init
|
|
||||||
|
|
||||||
The `cobra init [yourApp]` command will create your initial application code
|
|
||||||
for you. It is a very powerful application that will populate your program with
|
|
||||||
the right structure so you can immediately enjoy all the benefits of Cobra. It
|
|
||||||
will also automatically apply the license you specify to your application.
|
|
||||||
|
|
||||||
Cobra init is pretty smart. You can provide it a full path, or simply a path
|
|
||||||
similar to what is expected in the import.
|
|
||||||
|
|
||||||
```
|
|
||||||
cobra init github.com/spf13/newAppName
|
|
||||||
```
|
|
||||||
|
|
||||||
### cobra add
|
|
||||||
|
|
||||||
Once an application is initialized Cobra can create additional commands for you.
|
|
||||||
Let's say you created an app and you wanted the following commands for it:
|
|
||||||
|
|
||||||
* app serve
|
|
||||||
* app config
|
|
||||||
* app config create
|
|
||||||
|
|
||||||
In your project directory (where your main.go file is) you would run the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
cobra add serve
|
|
||||||
cobra add config
|
|
||||||
cobra add create -p 'configCmd'
|
|
||||||
```
|
|
||||||
|
|
||||||
Once you have run these three commands you would have an app structure that would look like:
|
|
||||||
|
|
||||||
```
|
|
||||||
▾ app/
|
|
||||||
▾ cmd/
|
|
||||||
serve.go
|
|
||||||
config.go
|
|
||||||
create.go
|
|
||||||
main.go
|
|
||||||
```
|
|
||||||
|
|
||||||
at this point you can run `go run main.go` and it would run your app. `go run
|
|
||||||
main.go serve`, `go run main.go config`, `go run main.go config create` along
|
|
||||||
with `go run main.go help serve`, etc would all work.
|
|
||||||
|
|
||||||
Obviously you haven't added your own code to these yet, the commands are ready
|
|
||||||
for you to give them their tasks. Have fun.
|
|
||||||
|
|
||||||
### Configuring the cobra generator
|
|
||||||
|
|
||||||
The cobra generator will be easier to use if you provide a simple configuration
|
|
||||||
file which will help you eliminate providing a bunch of repeated information in
|
|
||||||
flags over and over.
|
|
||||||
|
|
||||||
An example ~/.cobra.yaml file:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
author: Steve Francia <spf@spf13.com>
|
|
||||||
license: MIT
|
|
||||||
```
|
|
||||||
|
|
||||||
You can specify no license by setting `license` to `none` or you can specify
|
|
||||||
a custom license:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
license:
|
|
||||||
header: This file is part of {{ .appName }}.
|
|
||||||
text: |
|
|
||||||
{{ .copyright }}
|
|
||||||
|
|
||||||
This is my license. There are many like it, but this one is mine.
|
|
||||||
My license is my best friend. It is my life. I must master it as I must
|
|
||||||
master my life.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Manually implementing Cobra
|
|
||||||
|
|
||||||
To manually implement cobra you need to create a bare main.go file and a RootCmd file.
|
|
||||||
You will optionally provide additional commands as you see fit.
|
You will optionally provide additional commands as you see fit.
|
||||||
|
|
||||||
### Create the root command
|
### Create rootCmd
|
||||||
|
|
||||||
The root command represents your binary itself.
|
|
||||||
|
|
||||||
|
|
||||||
#### Manually create rootCmd
|
|
||||||
|
|
||||||
Cobra doesn't require any special constructors. Simply create your commands.
|
Cobra doesn't require any special constructors. Simply create your commands.
|
||||||
|
|
||||||
@ -285,9 +198,18 @@ var RootCmd = &cobra.Command{
|
|||||||
|
|
||||||
You will additionally define flags and handle configuration in your init() function.
|
You will additionally define flags and handle configuration in your init() function.
|
||||||
|
|
||||||
for example cmd/root.go:
|
For example cmd/root.go:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
|
RootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
|
||||||
@ -301,6 +223,30 @@ func init() {
|
|||||||
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
|
viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
|
||||||
viper.SetDefault("license", "apache")
|
viper.SetDefault("license", "apache")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initConfig() {
|
||||||
|
// Don't forget to read config either from cfgFile or from home directory!
|
||||||
|
if cfgFile != "" {
|
||||||
|
// Use config file from the flag.
|
||||||
|
viper.SetConfigFile(cfgFile)
|
||||||
|
} else {
|
||||||
|
// Find home directory.
|
||||||
|
home, err := homedir.Dir()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search config in home directory with name ".cobra" (without extension).
|
||||||
|
viper.AddConfigPath(home)
|
||||||
|
viper.SetConfigName(".cobra")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := viper.ReadInConfig(); err != nil {
|
||||||
|
fmt.Println("Can't read config:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create your main.go
|
### Create your main.go
|
||||||
@ -313,17 +259,21 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
|
|||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "{pathToYourApp}/cmd"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"{pathToYourApp}/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if err := cmd.RootCmd.Execute(); err != nil {
|
if err := cmd.RootCmd.Execute(); err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
os.Exit(-1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Create additional commands
|
### Create additional commands
|
||||||
|
|
||||||
Additional commands can be defined and typically are each given their own file
|
Additional commands can be defined and typically are each given their own file
|
||||||
@ -337,6 +287,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -353,30 +304,6 @@ var versionCmd = &cobra.Command{
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Attach command to its parent
|
|
||||||
|
|
||||||
|
|
||||||
If you notice in the above example we attach the command to its parent. In
|
|
||||||
this case the parent is the rootCmd. In this example we are attaching it to the
|
|
||||||
root, but commands can be attached at any level.
|
|
||||||
|
|
||||||
```go
|
|
||||||
RootCmd.AddCommand(versionCmd)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Remove a command from its parent
|
|
||||||
|
|
||||||
Removing a command is not a common action in simple programs, but it allows 3rd
|
|
||||||
parties to customize an existing command tree.
|
|
||||||
|
|
||||||
In this example, we remove the existing `VersionCmd` command of an existing
|
|
||||||
root command, and we replace it with our own version:
|
|
||||||
|
|
||||||
```go
|
|
||||||
mainlib.RootCmd.RemoveCommand(mainlib.VersionCmd)
|
|
||||||
mainlib.RootCmd.AddCommand(versionCmd)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Working with Flags
|
## Working with Flags
|
||||||
|
|
||||||
Flags provide modifiers to control how the action command operates.
|
Flags provide modifiers to control how the action command operates.
|
||||||
@ -412,6 +339,71 @@ A flag can also be assigned locally which will only apply to that specific comma
|
|||||||
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Local Flag on Parent Commands
|
||||||
|
|
||||||
|
By default Cobra only parses local flags on the target command, any local flags on
|
||||||
|
parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
|
||||||
|
parse local flags on each command before executing the target command.
|
||||||
|
|
||||||
|
```go
|
||||||
|
command := cobra.Command{
|
||||||
|
Use: "print [OPTIONS] [COMMANDS]",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bind Flags with Config
|
||||||
|
|
||||||
|
You can also bind your flags with [viper](https://github.com/spf13/viper):
|
||||||
|
```go
|
||||||
|
var author string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
|
||||||
|
viper.BindPFlag("author", RootCmd.PersistentFlags().Lookup("author"))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In this example the persistent flag `author` is bound with `viper`.
|
||||||
|
**Note**, that the variable `author` will not be set to the value from config,
|
||||||
|
when the `--author` flag is not provided by user.
|
||||||
|
|
||||||
|
More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
|
||||||
|
|
||||||
|
## Positional and Custom Arguments
|
||||||
|
|
||||||
|
Validation of positional arguments can be specified using the `Args` field
|
||||||
|
of `Command`.
|
||||||
|
|
||||||
|
The following validators are built in:
|
||||||
|
|
||||||
|
- `NoArgs` - the command will report an error if there are any positional args.
|
||||||
|
- `ArbitraryArgs` - the command will accept any args.
|
||||||
|
- `OnlyValidArgs` - the command will report an error if there are any positional args that are not in the `ValidArgs` field of `Command`.
|
||||||
|
- `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args.
|
||||||
|
- `MaximumNArgs(int)` - the command will report an error if there are more than N positional args.
|
||||||
|
- `ExactArgs(int)` - the command will report an error if there are not exactly N positional args.
|
||||||
|
- `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args.
|
||||||
|
|
||||||
|
An example of setting the custom validator:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var cmd = &cobra.Command{
|
||||||
|
Short: "hello",
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) < 1 {
|
||||||
|
return errors.New("requires at least one arg")
|
||||||
|
}
|
||||||
|
if myapp.IsValidColor(args[0]) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return fmt.Errorf("invalid color specified: %s", args[0])
|
||||||
|
},
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
fmt.Println("Hello, World!")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
@ -435,15 +427,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
var echoTimes int
|
var echoTimes int
|
||||||
|
|
||||||
var cmdPrint = &cobra.Command{
|
var cmdPrint = &cobra.Command{
|
||||||
Use: "print [string to print]",
|
Use: "print [string to print]",
|
||||||
Short: "Print anything to the screen",
|
Short: "Print anything to the screen",
|
||||||
Long: `print is for printing anything back to the screen.
|
Long: `print is for printing anything back to the screen.
|
||||||
For many years people have printed back to the screen.
|
For many years people have printed back to the screen.`,
|
||||||
`,
|
Args: cobra.MinimumNArgs(1),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("Print: " + strings.Join(args, " "))
|
fmt.Println("Print: " + strings.Join(args, " "))
|
||||||
},
|
},
|
||||||
@ -453,8 +444,8 @@ func main() {
|
|||||||
Use: "echo [string to echo]",
|
Use: "echo [string to echo]",
|
||||||
Short: "Echo anything to the screen",
|
Short: "Echo anything to the screen",
|
||||||
Long: `echo is for echoing anything back.
|
Long: `echo is for echoing anything back.
|
||||||
Echo works a lot like print, except it has a child command.
|
Echo works a lot like print, except it has a child command.`,
|
||||||
`,
|
Args: cobra.MinimumNArgs(1),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("Print: " + strings.Join(args, " "))
|
fmt.Println("Print: " + strings.Join(args, " "))
|
||||||
},
|
},
|
||||||
@ -465,6 +456,7 @@ func main() {
|
|||||||
Short: "Echo anything to the screen more times",
|
Short: "Echo anything to the screen more times",
|
||||||
Long: `echo things multiple times back to the user by providing
|
Long: `echo things multiple times back to the user by providing
|
||||||
a count and a string.`,
|
a count and a string.`,
|
||||||
|
Args: cobra.MinimumNArgs(1),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
for i := 0; i < echoTimes; i++ {
|
for i := 0; i < echoTimes; i++ {
|
||||||
fmt.Println("Echo: " + strings.Join(args, " "))
|
fmt.Println("Echo: " + strings.Join(args, " "))
|
||||||
@ -483,7 +475,7 @@ func main() {
|
|||||||
|
|
||||||
For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
|
For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
|
||||||
|
|
||||||
## The Help Command
|
## Help Command
|
||||||
|
|
||||||
Cobra automatically adds a help command to your application when you have subcommands.
|
Cobra automatically adds a help command to your application when you have subcommands.
|
||||||
This will be called when a user runs 'app help'. Additionally, help will also
|
This will be called when a user runs 'app help'. Additionally, help will also
|
||||||
@ -496,60 +488,28 @@ create' is called. Every command will automatically have the '--help' flag adde
|
|||||||
The following output is automatically generated by Cobra. Nothing beyond the
|
The following output is automatically generated by Cobra. Nothing beyond the
|
||||||
command and flag definitions are needed.
|
command and flag definitions are needed.
|
||||||
|
|
||||||
> hugo help
|
$ cobra help
|
||||||
|
|
||||||
hugo is the main command, used to build your Hugo site.
|
Cobra is a CLI library for Go that empowers applications.
|
||||||
|
This application is a tool to generate the needed files
|
||||||
Hugo is a Fast and Flexible Static Site Generator
|
to quickly create a Cobra application.
|
||||||
built with love by spf13 and friends in Go.
|
|
||||||
|
|
||||||
Complete documentation is available at http://gohugo.io/.
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
hugo [flags]
|
cobra [command]
|
||||||
hugo [command]
|
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
server Hugo runs its own webserver to render the files
|
add Add a command to a Cobra Application
|
||||||
version Print the version number of Hugo
|
help Help about any command
|
||||||
config Print the site configuration
|
init Initialize a Cobra Application
|
||||||
check Check content in the source directory
|
|
||||||
benchmark Benchmark hugo by building a site a number of times.
|
|
||||||
convert Convert your content to different formats
|
|
||||||
new Create new content for your site
|
|
||||||
list Listing out various types of content
|
|
||||||
undraft Undraft changes the content's draft status from 'True' to 'False'
|
|
||||||
genautocomplete Generate shell autocompletion script for Hugo
|
|
||||||
gendoc Generate Markdown documentation for the Hugo CLI.
|
|
||||||
genman Generate man page for Hugo
|
|
||||||
import Import your site from others.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||||
-D, --buildDrafts[=false]: include content marked as draft
|
--config string config file (default is $HOME/.cobra.yaml)
|
||||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
-h, --help help for cobra
|
||||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
-l, --license string name of license for the project
|
||||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
--viper use Viper for configuration (default true)
|
||||||
--config="": config file (default is path/config.yaml|json|toml)
|
|
||||||
-d, --destination="": filesystem path to write files to
|
|
||||||
--disableRSS[=false]: Do not build RSS files
|
|
||||||
--disableSitemap[=false]: Do not build Sitemap file
|
|
||||||
--editor="": edit new content with this editor, if provided
|
|
||||||
--ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
|
|
||||||
--log[=false]: Enable Logging
|
|
||||||
--logFile="": Log File path (if set, logging enabled automatically)
|
|
||||||
--noTimes[=false]: Don't sync modification time of files
|
|
||||||
--pluralizeListTitles[=true]: Pluralize titles in lists using inflect
|
|
||||||
--preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
|
||||||
-s, --source="": filesystem path to read files relative from
|
|
||||||
--stepAnalysis[=false]: display memory and timing of different steps of the program
|
|
||||||
-t, --theme="": theme to use (located in /themes/THEMENAME/)
|
|
||||||
--uglyURLs[=false]: if true, use /filename.html instead of /filename/
|
|
||||||
-v, --verbose[=false]: verbose output
|
|
||||||
--verboseLog[=false]: verbose logging
|
|
||||||
-w, --watch[=false]: watch filesystem for changes and recreate as needed
|
|
||||||
|
|
||||||
Use "hugo [command] --help" for more information about a command.
|
Use "cobra [command] --help" for more information about a command.
|
||||||
|
|
||||||
|
|
||||||
Help is just a command like any other. There is no special logic or behavior
|
Help is just a command like any other. There is no special logic or behavior
|
||||||
@ -557,38 +517,18 @@ around it. In fact, you can provide your own if you want.
|
|||||||
|
|
||||||
### Defining your own help
|
### Defining your own help
|
||||||
|
|
||||||
You can provide your own Help command or your own template for the default command to use.
|
You can provide your own Help command or your own template for the default command to use
|
||||||
|
with following functions:
|
||||||
The default help command is
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *Command) initHelp() {
|
cmd.SetHelpCommand(cmd *Command)
|
||||||
if c.helpCommand == nil {
|
cmd.SetHelpFunc(f func(*Command, []string))
|
||||||
c.helpCommand = &Command{
|
cmd.SetHelpTemplate(s string)
|
||||||
Use: "help [command]",
|
|
||||||
Short: "Help about any command",
|
|
||||||
Long: `Help provides help for any command in the application.
|
|
||||||
Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
|
||||||
Run: c.HelpFunc(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.AddCommand(c.helpCommand)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can provide your own command, function or template through the following methods:
|
|
||||||
|
|
||||||
```go
|
|
||||||
command.SetHelpCommand(cmd *Command)
|
|
||||||
|
|
||||||
command.SetHelpFunc(f func(*Command, []string))
|
|
||||||
|
|
||||||
command.SetHelpTemplate(s string)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The latter two will also apply to any children commands.
|
The latter two will also apply to any children commands.
|
||||||
|
|
||||||
## Usage
|
## Usage Message
|
||||||
|
|
||||||
When the user provides an invalid flag or invalid command, Cobra responds by
|
When the user provides an invalid flag or invalid command, Cobra responds by
|
||||||
showing the user the 'usage'.
|
showing the user the 'usage'.
|
||||||
@ -597,73 +537,37 @@ showing the user the 'usage'.
|
|||||||
You may recognize this from the help above. That's because the default help
|
You may recognize this from the help above. That's because the default help
|
||||||
embeds the usage as part of its output.
|
embeds the usage as part of its output.
|
||||||
|
|
||||||
|
$ cobra --invalid
|
||||||
|
Error: unknown flag: --invalid
|
||||||
Usage:
|
Usage:
|
||||||
hugo [flags]
|
cobra [command]
|
||||||
hugo [command]
|
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
server Hugo runs its own webserver to render the files
|
add Add a command to a Cobra Application
|
||||||
version Print the version number of Hugo
|
help Help about any command
|
||||||
config Print the site configuration
|
init Initialize a Cobra Application
|
||||||
check Check content in the source directory
|
|
||||||
benchmark Benchmark hugo by building a site a number of times.
|
|
||||||
convert Convert your content to different formats
|
|
||||||
new Create new content for your site
|
|
||||||
list Listing out various types of content
|
|
||||||
undraft Undraft changes the content's draft status from 'True' to 'False'
|
|
||||||
genautocomplete Generate shell autocompletion script for Hugo
|
|
||||||
gendoc Generate Markdown documentation for the Hugo CLI.
|
|
||||||
genman Generate man page for Hugo
|
|
||||||
import Import your site from others.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||||
-D, --buildDrafts[=false]: include content marked as draft
|
--config string config file (default is $HOME/.cobra.yaml)
|
||||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
-h, --help help for cobra
|
||||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
-l, --license string name of license for the project
|
||||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
--viper use Viper for configuration (default true)
|
||||||
--config="": config file (default is path/config.yaml|json|toml)
|
|
||||||
-d, --destination="": filesystem path to write files to
|
Use "cobra [command] --help" for more information about a command.
|
||||||
--disableRSS[=false]: Do not build RSS files
|
|
||||||
--disableSitemap[=false]: Do not build Sitemap file
|
|
||||||
--editor="": edit new content with this editor, if provided
|
|
||||||
--ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
|
|
||||||
--log[=false]: Enable Logging
|
|
||||||
--logFile="": Log File path (if set, logging enabled automatically)
|
|
||||||
--noTimes[=false]: Don't sync modification time of files
|
|
||||||
--pluralizeListTitles[=true]: Pluralize titles in lists using inflect
|
|
||||||
--preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
|
||||||
-s, --source="": filesystem path to read files relative from
|
|
||||||
--stepAnalysis[=false]: display memory and timing of different steps of the program
|
|
||||||
-t, --theme="": theme to use (located in /themes/THEMENAME/)
|
|
||||||
--uglyURLs[=false]: if true, use /filename.html instead of /filename/
|
|
||||||
-v, --verbose[=false]: verbose output
|
|
||||||
--verboseLog[=false]: verbose logging
|
|
||||||
-w, --watch[=false]: watch filesystem for changes and recreate as needed
|
|
||||||
|
|
||||||
### Defining your own usage
|
### Defining your own usage
|
||||||
You can provide your own usage function or template for Cobra to use.
|
You can provide your own usage function or template for Cobra to use.
|
||||||
|
|
||||||
The default usage function is:
|
|
||||||
|
|
||||||
```go
|
|
||||||
return func(c *Command) error {
|
|
||||||
err := tmpl(c.Out(), c.UsageTemplate(), c)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Like help, the function and template are overridable through public methods:
|
Like help, the function and template are overridable through public methods:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
command.SetUsageFunc(f func(*Command) error)
|
cmd.SetUsageFunc(f func(*Command) error)
|
||||||
|
cmd.SetUsageTemplate(s string)
|
||||||
command.SetUsageTemplate(s string)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## PreRun or PostRun Hooks
|
## PreRun and PostRun Hooks
|
||||||
|
|
||||||
It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherrited by children if they do not declare their own. These function are run in the following order:
|
It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions are run in the following order:
|
||||||
|
|
||||||
- `PersistentPreRun`
|
- `PersistentPreRun`
|
||||||
- `PreRun`
|
- `PreRun`
|
||||||
@ -724,58 +628,26 @@ func main() {
|
|||||||
rootCmd.AddCommand(subCmd)
|
rootCmd.AddCommand(subCmd)
|
||||||
|
|
||||||
rootCmd.SetArgs([]string{""})
|
rootCmd.SetArgs([]string{""})
|
||||||
_ = rootCmd.Execute()
|
rootCmd.Execute()
|
||||||
fmt.Print("\n")
|
fmt.Println()
|
||||||
rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
|
rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
|
||||||
_ = rootCmd.Execute()
|
rootCmd.Execute()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
Inside rootCmd PersistentPreRun with args: []
|
||||||
|
Inside rootCmd PreRun with args: []
|
||||||
|
Inside rootCmd Run with args: []
|
||||||
|
Inside rootCmd PostRun with args: []
|
||||||
|
Inside rootCmd PersistentPostRun with args: []
|
||||||
|
|
||||||
## Alternative Error Handling
|
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
|
||||||
|
Inside subCmd PreRun with args: [arg1 arg2]
|
||||||
Cobra also has functions where the return signature is an error. This allows for errors to bubble up to the top,
|
Inside subCmd Run with args: [arg1 arg2]
|
||||||
providing a way to handle the errors in one location. The current list of functions that return an error is:
|
Inside subCmd PostRun with args: [arg1 arg2]
|
||||||
|
Inside subCmd PersistentPostRun with args: [arg1 arg2]
|
||||||
* PersistentPreRunE
|
|
||||||
* PreRunE
|
|
||||||
* RunE
|
|
||||||
* PostRunE
|
|
||||||
* PersistentPostRunE
|
|
||||||
|
|
||||||
If you would like to silence the default `error` and `usage` output in favor of your own, you can set `SilenceUsage`
|
|
||||||
and `SilenceErrors` to `false` on the command. A child command respects these flags if they are set on the parent
|
|
||||||
command.
|
|
||||||
|
|
||||||
**Example Usage using RunE:**
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var rootCmd = &cobra.Command{
|
|
||||||
Use: "hugo",
|
|
||||||
Short: "Hugo is a very fast static site generator",
|
|
||||||
Long: `A Fast and Flexible Static Site Generator built with
|
|
||||||
love by spf13 and friends in Go.
|
|
||||||
Complete documentation is available at http://hugo.spf13.com`,
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
// Do Stuff Here
|
|
||||||
return errors.New("some random error")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Suggestions when "unknown command" happens
|
## Suggestions when "unknown command" happens
|
||||||
@ -818,81 +690,28 @@ Did you mean this?
|
|||||||
Run 'kubectl help' for usage.
|
Run 'kubectl help' for usage.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating Markdown-formatted documentation for your command
|
## Generating documentation for your command
|
||||||
|
|
||||||
Cobra can generate a Markdown-formatted document based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Markdown Docs](doc/md_docs.md).
|
Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
|
||||||
|
|
||||||
## Generating man pages for your command
|
- [Markdown](doc/md_docs.md)
|
||||||
|
- [ReStructured Text](doc/rest_docs.md)
|
||||||
|
- [Man Page](doc/man_docs.md)
|
||||||
|
|
||||||
Cobra can generate a man page based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Man Docs](doc/man_docs.md).
|
## Generating bash completions
|
||||||
|
|
||||||
## Generating bash completions for your command
|
|
||||||
|
|
||||||
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
|
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
|
||||||
|
|
||||||
## Debugging
|
# Contributing
|
||||||
|
|
||||||
Cobra provides a ‘DebugFlags’ method on a command which, when called, will print
|
|
||||||
out everything Cobra knows about the flags for each command.
|
|
||||||
|
|
||||||
### Example
|
|
||||||
|
|
||||||
```go
|
|
||||||
command.DebugFlags()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Release Notes
|
|
||||||
* **0.9.0** June 17, 2014
|
|
||||||
* flags can appears anywhere in the args (provided they are unambiguous)
|
|
||||||
* --help prints usage screen for app or command
|
|
||||||
* Prefix matching for commands
|
|
||||||
* Cleaner looking help and usage output
|
|
||||||
* Extensive test suite
|
|
||||||
* **0.8.0** Nov 5, 2013
|
|
||||||
* Reworked interface to remove commander completely
|
|
||||||
* Command now primary structure
|
|
||||||
* No initialization needed
|
|
||||||
* Usage & Help templates & functions definable at any level
|
|
||||||
* Updated Readme
|
|
||||||
* **0.7.0** Sept 24, 2013
|
|
||||||
* Needs more eyes
|
|
||||||
* Test suite
|
|
||||||
* Support for automatic error messages
|
|
||||||
* Support for help command
|
|
||||||
* Support for printing to any io.Writer instead of os.Stderr
|
|
||||||
* Support for persistent flags which cascade down tree
|
|
||||||
* Ready for integration into Hugo
|
|
||||||
* **0.1.0** Sept 3, 2013
|
|
||||||
* Implement first draft
|
|
||||||
|
|
||||||
## Extensions
|
|
||||||
|
|
||||||
Libraries for extending Cobra:
|
|
||||||
|
|
||||||
* [cmdns](https://github.com/gosuri/cmdns): Enables name spacing a command's immediate children. It provides an alternative way to structure subcommands, similar to `heroku apps:create` and `ovrclk clusters:launch`.
|
|
||||||
|
|
||||||
## ToDo
|
|
||||||
* Launch proper documentation site
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork it
|
1. Fork it
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
3. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
4. Make changes and add them (`git add .`)
|
||||||
5. Create new Pull Request
|
5. Commit your changes (`git commit -m 'Add some feature'`)
|
||||||
|
6. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
7. Create new pull request
|
||||||
|
|
||||||
## Contributors
|
# License
|
||||||
|
|
||||||
Names in no particular order:
|
|
||||||
|
|
||||||
* [spf13](https://github.com/spf13),
|
|
||||||
[eparis](https://github.com/eparis),
|
|
||||||
[bep](https://github.com/bep), and many more!
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
|
||||||
|
89
vendor/github.com/spf13/cobra/args.go
generated
vendored
Normal file
89
vendor/github.com/spf13/cobra/args.go
generated
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package cobra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PositionalArgs func(cmd *Command, args []string) error
|
||||||
|
|
||||||
|
// Legacy arg validation has the following behaviour:
|
||||||
|
// - root commands with no subcommands can take arbitrary arguments
|
||||||
|
// - root commands with subcommands will do subcommand validity checking
|
||||||
|
// - subcommands will always accept arbitrary arguments
|
||||||
|
func legacyArgs(cmd *Command, args []string) error {
|
||||||
|
// no subcommand, always take args
|
||||||
|
if !cmd.HasSubCommands() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// root command with subcommands, do subcommand checking.
|
||||||
|
if !cmd.HasParent() && len(args) > 0 {
|
||||||
|
return fmt.Errorf("unknown command %q for %q%s", args[0], cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoArgs returns an error if any args are included.
|
||||||
|
func NoArgs(cmd *Command, args []string) error {
|
||||||
|
if len(args) > 0 {
|
||||||
|
return fmt.Errorf("unknown command %q for %q", args[0], cmd.CommandPath())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyValidArgs returns an error if any args are not in the list of ValidArgs.
|
||||||
|
func OnlyValidArgs(cmd *Command, args []string) error {
|
||||||
|
if len(cmd.ValidArgs) > 0 {
|
||||||
|
for _, v := range args {
|
||||||
|
if !stringInSlice(v, cmd.ValidArgs) {
|
||||||
|
return fmt.Errorf("invalid argument %q for %q%s", v, cmd.CommandPath(), cmd.findSuggestions(args[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArbitraryArgs never returns an error.
|
||||||
|
func ArbitraryArgs(cmd *Command, args []string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinimumNArgs returns an error if there is not at least N args.
|
||||||
|
func MinimumNArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) < n {
|
||||||
|
return fmt.Errorf("requires at least %d arg(s), only received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MaximumNArgs returns an error if there are more than N args.
|
||||||
|
func MaximumNArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) > n {
|
||||||
|
return fmt.Errorf("accepts at most %d arg(s), received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExactArgs returns an error if there are not exactly n args.
|
||||||
|
func ExactArgs(n int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) != n {
|
||||||
|
return fmt.Errorf("accepts %d arg(s), received %d", n, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RangeArgs returns an error if the number of args is not within the expected range.
|
||||||
|
func RangeArgs(min int, max int) PositionalArgs {
|
||||||
|
return func(cmd *Command, args []string) error {
|
||||||
|
if len(args) < min || len(args) > max {
|
||||||
|
return fmt.Errorf("accepts between %d and %d arg(s), received %d", min, max, len(args))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
315
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
315
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package cobra
|
package cobra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -10,19 +11,17 @@ import (
|
|||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Annotations for Bash completion.
|
||||||
const (
|
const (
|
||||||
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions"
|
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
|
||||||
BashCompCustom = "cobra_annotation_bash_completion_custom"
|
BashCompCustom = "cobra_annotation_bash_completion_custom"
|
||||||
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
|
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
|
||||||
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
|
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
|
||||||
)
|
)
|
||||||
|
|
||||||
func preamble(out io.Writer, name string) error {
|
func writePreamble(buf *bytes.Buffer, name string) {
|
||||||
_, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
|
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
|
||||||
if err != nil {
|
buf.WriteString(`
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprint(out, `
|
|
||||||
__debug()
|
__debug()
|
||||||
{
|
{
|
||||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||||
@ -87,13 +86,13 @@ __handle_reply()
|
|||||||
local index flag
|
local index flag
|
||||||
flag="${cur%%=*}"
|
flag="${cur%%=*}"
|
||||||
__index_of_word "${flag}" "${flags_with_completion[@]}"
|
__index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||||
if [[ ${index} -ge 0 ]]; then
|
|
||||||
COMPREPLY=()
|
COMPREPLY=()
|
||||||
|
if [[ ${index} -ge 0 ]]; then
|
||||||
PREFIX=""
|
PREFIX=""
|
||||||
cur="${cur#*=}"
|
cur="${cur#*=}"
|
||||||
${flags_completion[${index}]}
|
${flags_completion[${index}]}
|
||||||
if [ -n "${ZSH_VERSION}" ]; then
|
if [ -n "${ZSH_VERSION}" ]; then
|
||||||
# zfs completion needs --flag= prefix
|
# zsh completion needs --flag= prefix
|
||||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -133,7 +132,10 @@ __handle_reply()
|
|||||||
declare -F __custom_func >/dev/null && __custom_func
|
declare -F __custom_func >/dev/null && __custom_func
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# available in bash-completion >= 2, not always present on macOS
|
||||||
|
if declare -F __ltrim_colon_completions >/dev/null; then
|
||||||
__ltrim_colon_completions "$cur"
|
__ltrim_colon_completions "$cur"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# The arguments should be in the form "ext1|ext2|extn"
|
# The arguments should be in the form "ext1|ext2|extn"
|
||||||
@ -224,7 +226,7 @@ __handle_command()
|
|||||||
fi
|
fi
|
||||||
c=$((c+1))
|
c=$((c+1))
|
||||||
__debug "${FUNCNAME[0]}: looking for ${next_command}"
|
__debug "${FUNCNAME[0]}: looking for ${next_command}"
|
||||||
declare -F $next_command >/dev/null && $next_command
|
declare -F "$next_command" >/dev/null && $next_command
|
||||||
}
|
}
|
||||||
|
|
||||||
__handle_word()
|
__handle_word()
|
||||||
@ -247,16 +249,12 @@ __handle_word()
|
|||||||
}
|
}
|
||||||
|
|
||||||
`)
|
`)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postscript(w io.Writer, name string) error {
|
func writePostscript(buf *bytes.Buffer, name string) {
|
||||||
name = strings.Replace(name, ":", "__", -1)
|
name = strings.Replace(name, ":", "__", -1)
|
||||||
_, err := fmt.Fprintf(w, "__start_%s()\n", name)
|
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
|
||||||
if err != nil {
|
buf.WriteString(fmt.Sprintf(`{
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(w, `{
|
|
||||||
local cur prev words cword
|
local cur prev words cword
|
||||||
declare -A flaghash 2>/dev/null || :
|
declare -A flaghash 2>/dev/null || :
|
||||||
if declare -F _init_completion >/dev/null 2>&1; then
|
if declare -F _init_completion >/dev/null 2>&1; then
|
||||||
@ -280,318 +278,227 @@ func postscript(w io.Writer, name string) error {
|
|||||||
__handle_word
|
__handle_word
|
||||||
}
|
}
|
||||||
|
|
||||||
`, name)
|
`, name))
|
||||||
if err != nil {
|
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
|
|
||||||
complete -o default -F __start_%s %s
|
complete -o default -F __start_%s %s
|
||||||
else
|
else
|
||||||
complete -o default -o nospace -F __start_%s %s
|
complete -o default -o nospace -F __start_%s %s
|
||||||
fi
|
fi
|
||||||
|
|
||||||
`, name, name, name, name)
|
`, name, name, name, name))
|
||||||
if err != nil {
|
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeCommands(cmd *Command, w io.Writer) error {
|
func writeCommands(buf *bytes.Buffer, cmd *Command) {
|
||||||
if _, err := fmt.Fprintf(w, " commands=()\n"); err != nil {
|
buf.WriteString(" commands=()\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, err := fmt.Fprintf(w, " commands+=(%q)\n", c.Name()); err != nil {
|
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
buf.WriteString("\n")
|
||||||
_, err := fmt.Fprintf(w, "\n")
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFlagHandler(name string, annotations map[string][]string, w io.Writer) error {
|
func writeFlagHandler(buf *bytes.Buffer, name string, annotations map[string][]string) {
|
||||||
for key, value := range annotations {
|
for key, value := range annotations {
|
||||||
switch key {
|
switch key {
|
||||||
case BashCompFilenameExt:
|
case BashCompFilenameExt:
|
||||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
|
var ext string
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
|
ext = "__handle_filename_extension_flag " + strings.Join(value, "|")
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
|
||||||
} else {
|
} else {
|
||||||
ext := "_filedir"
|
ext = "_filedir"
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||||
case BashCompCustom:
|
case BashCompCustom:
|
||||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
handlers := strings.Join(value, "; ")
|
handlers := strings.Join(value, "; ")
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", handlers)
|
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
|
||||||
} else {
|
} else {
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(:)\n")
|
buf.WriteString(" flags_completion+=(:)\n")
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
case BashCompSubdirsInDir:
|
case BashCompSubdirsInDir:
|
||||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||||
|
|
||||||
|
var ext string
|
||||||
if len(value) == 1 {
|
if len(value) == 1 {
|
||||||
ext := "__handle_subdirs_in_dir_flag " + value[0]
|
ext = "__handle_subdirs_in_dir_flag " + value[0]
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
|
||||||
} else {
|
} else {
|
||||||
ext := "_filedir -d"
|
ext = "_filedir -d"
|
||||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
|
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||||
b := (len(flag.NoOptDefVal) > 0)
|
|
||||||
name := flag.Shorthand
|
name := flag.Shorthand
|
||||||
format := " "
|
format := " "
|
||||||
if !b {
|
if len(flag.NoOptDefVal) == 0 {
|
||||||
format += "two_word_"
|
format += "two_word_"
|
||||||
}
|
}
|
||||||
format += "flags+=(\"-%s\")\n"
|
format += "flags+=(\"-%s\")\n"
|
||||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
buf.WriteString(fmt.Sprintf(format, name))
|
||||||
return err
|
writeFlagHandler(buf, "-"+name, flag.Annotations)
|
||||||
}
|
|
||||||
return writeFlagHandler("-"+name, flag.Annotations, w)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFlag(flag *pflag.Flag, w io.Writer) error {
|
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||||
b := (len(flag.NoOptDefVal) > 0)
|
|
||||||
name := flag.Name
|
name := flag.Name
|
||||||
format := " flags+=(\"--%s"
|
format := " flags+=(\"--%s"
|
||||||
if !b {
|
if len(flag.NoOptDefVal) == 0 {
|
||||||
format += "="
|
format += "="
|
||||||
}
|
}
|
||||||
format += "\")\n"
|
format += "\")\n"
|
||||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
buf.WriteString(fmt.Sprintf(format, name))
|
||||||
return err
|
writeFlagHandler(buf, "--"+name, flag.Annotations)
|
||||||
}
|
|
||||||
return writeFlagHandler("--"+name, flag.Annotations, w)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
|
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||||
b := (len(flag.NoOptDefVal) > 0)
|
|
||||||
name := flag.Name
|
name := flag.Name
|
||||||
format := " local_nonpersistent_flags+=(\"--%s"
|
format := " local_nonpersistent_flags+=(\"--%s"
|
||||||
if !b {
|
if len(flag.NoOptDefVal) == 0 {
|
||||||
format += "="
|
format += "="
|
||||||
}
|
}
|
||||||
format += "\")\n"
|
format += "\")\n"
|
||||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
buf.WriteString(fmt.Sprintf(format, name))
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeFlags(cmd *Command, w io.Writer) error {
|
func writeFlags(buf *bytes.Buffer, cmd *Command) {
|
||||||
_, err := fmt.Fprintf(w, ` flags=()
|
buf.WriteString(` flags=()
|
||||||
two_word_flags=()
|
two_word_flags=()
|
||||||
local_nonpersistent_flags=()
|
local_nonpersistent_flags=()
|
||||||
flags_with_completion=()
|
flags_with_completion=()
|
||||||
flags_completion=()
|
flags_completion=()
|
||||||
|
|
||||||
`)
|
`)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
localNonPersistentFlags := cmd.LocalNonPersistentFlags()
|
localNonPersistentFlags := cmd.LocalNonPersistentFlags()
|
||||||
var visitErr error
|
|
||||||
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||||
if err := writeFlag(flag, w); err != nil {
|
if nonCompletableFlag(flag) {
|
||||||
visitErr = err
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
writeFlag(buf, flag)
|
||||||
if len(flag.Shorthand) > 0 {
|
if len(flag.Shorthand) > 0 {
|
||||||
if err := writeShortFlag(flag, w); err != nil {
|
writeShortFlag(buf, flag)
|
||||||
visitErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if localNonPersistentFlags.Lookup(flag.Name) != nil {
|
if localNonPersistentFlags.Lookup(flag.Name) != nil {
|
||||||
if err := writeLocalNonPersistentFlag(flag, w); err != nil {
|
writeLocalNonPersistentFlag(buf, flag)
|
||||||
visitErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if visitErr != nil {
|
|
||||||
return visitErr
|
|
||||||
}
|
|
||||||
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||||
if err := writeFlag(flag, w); err != nil {
|
if nonCompletableFlag(flag) {
|
||||||
visitErr = err
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
writeFlag(buf, flag)
|
||||||
if len(flag.Shorthand) > 0 {
|
if len(flag.Shorthand) > 0 {
|
||||||
if err := writeShortFlag(flag, w); err != nil {
|
writeShortFlag(buf, flag)
|
||||||
visitErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
if visitErr != nil {
|
|
||||||
return visitErr
|
buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = fmt.Fprintf(w, "\n")
|
func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
||||||
return err
|
buf.WriteString(" must_have_one_flag=()\n")
|
||||||
}
|
|
||||||
|
|
||||||
func writeRequiredFlag(cmd *Command, w io.Writer) error {
|
|
||||||
if _, err := fmt.Fprintf(w, " must_have_one_flag=()\n"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
flags := cmd.NonInheritedFlags()
|
flags := cmd.NonInheritedFlags()
|
||||||
var visitErr error
|
|
||||||
flags.VisitAll(func(flag *pflag.Flag) {
|
flags.VisitAll(func(flag *pflag.Flag) {
|
||||||
|
if nonCompletableFlag(flag) {
|
||||||
|
return
|
||||||
|
}
|
||||||
for key := range flag.Annotations {
|
for key := range flag.Annotations {
|
||||||
switch key {
|
switch key {
|
||||||
case BashCompOneRequiredFlag:
|
case BashCompOneRequiredFlag:
|
||||||
format := " must_have_one_flag+=(\"--%s"
|
format := " must_have_one_flag+=(\"--%s"
|
||||||
b := (flag.Value.Type() == "bool")
|
if flag.Value.Type() != "bool" {
|
||||||
if !b {
|
|
||||||
format += "="
|
format += "="
|
||||||
}
|
}
|
||||||
format += "\")\n"
|
format += "\")\n"
|
||||||
if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
|
buf.WriteString(fmt.Sprintf(format, flag.Name))
|
||||||
visitErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(flag.Shorthand) > 0 {
|
if len(flag.Shorthand) > 0 {
|
||||||
if _, err := fmt.Fprintf(w, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
|
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
|
||||||
visitErr = err
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return visitErr
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeRequiredNouns(cmd *Command, w io.Writer) error {
|
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
||||||
if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
|
buf.WriteString(" must_have_one_noun=()\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
||||||
for _, value := range cmd.ValidArgs {
|
for _, value := range cmd.ValidArgs {
|
||||||
if _, err := fmt.Fprintf(w, " must_have_one_noun+=(%q)\n", value); err != nil {
|
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeArgAliases(cmd *Command, w io.Writer) error {
|
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
|
||||||
if _, err := fmt.Fprintf(w, " noun_aliases=()\n"); err != nil {
|
buf.WriteString(" noun_aliases=()\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
sort.Sort(sort.StringSlice(cmd.ArgAliases))
|
sort.Sort(sort.StringSlice(cmd.ArgAliases))
|
||||||
for _, value := range cmd.ArgAliases {
|
for _, value := range cmd.ArgAliases {
|
||||||
if _, err := fmt.Fprintf(w, " noun_aliases+=(%q)\n", value); err != nil {
|
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func gen(cmd *Command, w io.Writer) error {
|
func gen(buf *bytes.Buffer, cmd *Command) {
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := gen(c, w); err != nil {
|
gen(buf, c)
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
commandName := cmd.CommandPath()
|
commandName := cmd.CommandPath()
|
||||||
commandName = strings.Replace(commandName, " ", "_", -1)
|
commandName = strings.Replace(commandName, " ", "_", -1)
|
||||||
commandName = strings.Replace(commandName, ":", "__", -1)
|
commandName = strings.Replace(commandName, ":", "__", -1)
|
||||||
if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
|
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
|
||||||
return err
|
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
|
||||||
}
|
writeCommands(buf, cmd)
|
||||||
if _, err := fmt.Fprintf(w, " last_command=%q\n", commandName); err != nil {
|
writeFlags(buf, cmd)
|
||||||
return err
|
writeRequiredFlag(buf, cmd)
|
||||||
}
|
writeRequiredNouns(buf, cmd)
|
||||||
if err := writeCommands(cmd, w); err != nil {
|
writeArgAliases(buf, cmd)
|
||||||
return err
|
buf.WriteString("}\n\n")
|
||||||
}
|
|
||||||
if err := writeFlags(cmd, w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := writeRequiredFlag(cmd, w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := writeRequiredNouns(cmd, w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := writeArgAliases(cmd, w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := fmt.Fprintf(w, "}\n\n"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cmd *Command) GenBashCompletion(w io.Writer) error {
|
// GenBashCompletion generates bash completion file and writes to the passed writer.
|
||||||
if err := preamble(w, cmd.Name()); err != nil {
|
func (c *Command) GenBashCompletion(w io.Writer) error {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
writePreamble(buf, c.Name())
|
||||||
|
if len(c.BashCompletionFunction) > 0 {
|
||||||
|
buf.WriteString(c.BashCompletionFunction + "\n")
|
||||||
|
}
|
||||||
|
gen(buf, c)
|
||||||
|
writePostscript(buf, c.Name())
|
||||||
|
|
||||||
|
_, err := buf.WriteTo(w)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(cmd.BashCompletionFunction) > 0 {
|
|
||||||
if _, err := fmt.Fprintf(w, "%s\n", cmd.BashCompletionFunction); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := gen(cmd, w); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return postscript(w, cmd.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cmd *Command) GenBashCompletionFile(filename string) error {
|
func nonCompletableFlag(flag *pflag.Flag) bool {
|
||||||
|
return flag.Hidden || len(flag.Deprecated) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenBashCompletionFile generates bash completion file.
|
||||||
|
func (c *Command) GenBashCompletionFile(filename string) error {
|
||||||
outFile, err := os.Create(filename)
|
outFile, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer outFile.Close()
|
defer outFile.Close()
|
||||||
|
|
||||||
return cmd.GenBashCompletion(outFile)
|
return c.GenBashCompletion(outFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
|
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
|
||||||
func (cmd *Command) MarkFlagRequired(name string) error {
|
func (c *Command) MarkFlagRequired(name string) error {
|
||||||
return MarkFlagRequired(cmd.Flags(), name)
|
return MarkFlagRequired(c.Flags(), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
|
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
|
||||||
func (cmd *Command) MarkPersistentFlagRequired(name string) error {
|
func (c *Command) MarkPersistentFlagRequired(name string) error {
|
||||||
return MarkFlagRequired(cmd.PersistentFlags(), name)
|
return MarkFlagRequired(c.PersistentFlags(), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
|
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag in the flag set, if it exists.
|
||||||
@ -601,20 +508,20 @@ func MarkFlagRequired(flags *pflag.FlagSet, name string) error {
|
|||||||
|
|
||||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
|
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists.
|
||||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||||
func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
|
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||||
return MarkFlagFilename(cmd.Flags(), name, extensions...)
|
return MarkFlagFilename(c.Flags(), name, extensions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
||||||
// Generated bash autocompletion will call the bash function f for the flag.
|
// Generated bash autocompletion will call the bash function f for the flag.
|
||||||
func (cmd *Command) MarkFlagCustom(name string, f string) error {
|
func (c *Command) MarkFlagCustom(name string, f string) error {
|
||||||
return MarkFlagCustom(cmd.Flags(), name, f)
|
return MarkFlagCustom(c.Flags(), name, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
|
// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists.
|
||||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||||
func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||||
return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
|
return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
|
// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists.
|
||||||
|
4
vendor/github.com/spf13/cobra/bash_completions.md
generated
vendored
4
vendor/github.com/spf13/cobra/bash_completions.md
generated
vendored
@ -18,7 +18,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
That will get you completions of subcommands and flags. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
|
`out.sh` will get you completions of subcommands and flags. Copy it to `/etc/bash_completion.d/` as described [here](https://debian-administration.org/article/316/An_introduction_to_bash_completion_part_1) and reset your terminal to use autocompletion. If you make additional annotations to your code, you can get even more intelligent and flexible behavior.
|
||||||
|
|
||||||
## Creating your own custom functions
|
## Creating your own custom functions
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ node pod replicationcontroller service
|
|||||||
|
|
||||||
If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
|
If your nouns have a number of aliases, you can define them alongside `ValidArgs` using `ArgAliases`:
|
||||||
|
|
||||||
```go`
|
```go
|
||||||
argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
|
argAliases []string = { "pods", "nodes", "services", "svc", "replicationcontrollers", "rc" }
|
||||||
|
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
42
vendor/github.com/spf13/cobra/cobra.go
generated
vendored
42
vendor/github.com/spf13/cobra/cobra.go
generated
vendored
@ -29,6 +29,7 @@ import (
|
|||||||
var templateFuncs = template.FuncMap{
|
var templateFuncs = template.FuncMap{
|
||||||
"trim": strings.TrimSpace,
|
"trim": strings.TrimSpace,
|
||||||
"trimRightSpace": trimRightSpace,
|
"trimRightSpace": trimRightSpace,
|
||||||
|
"trimTrailingWhitespaces": trimRightSpace,
|
||||||
"appendIfNotPresent": appendIfNotPresent,
|
"appendIfNotPresent": appendIfNotPresent,
|
||||||
"rpad": rpad,
|
"rpad": rpad,
|
||||||
"gt": Gt,
|
"gt": Gt,
|
||||||
@ -37,21 +38,31 @@ var templateFuncs = template.FuncMap{
|
|||||||
|
|
||||||
var initializers []func()
|
var initializers []func()
|
||||||
|
|
||||||
// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
|
// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
|
||||||
// Set this to true to enable it
|
// to automatically enable in CLI tools.
|
||||||
|
// Set this to true to enable it.
|
||||||
var EnablePrefixMatching = false
|
var EnablePrefixMatching = false
|
||||||
|
|
||||||
// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
|
// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
|
||||||
// To disable sorting, set it to false.
|
// To disable sorting, set it to false.
|
||||||
var EnableCommandSorting = true
|
var EnableCommandSorting = true
|
||||||
|
|
||||||
|
// MousetrapHelpText enables an information splash screen on Windows
|
||||||
|
// if the CLI is started from explorer.exe.
|
||||||
|
// To disable the mousetrap, just set this variable to blank string ("").
|
||||||
|
// Works only on Microsoft Windows.
|
||||||
|
var MousetrapHelpText string = `This is a command line tool.
|
||||||
|
|
||||||
|
You need to open cmd.exe and run it from there.
|
||||||
|
`
|
||||||
|
|
||||||
// AddTemplateFunc adds a template function that's available to Usage and Help
|
// AddTemplateFunc adds a template function that's available to Usage and Help
|
||||||
// template generation.
|
// template generation.
|
||||||
func AddTemplateFunc(name string, tmplFunc interface{}) {
|
func AddTemplateFunc(name string, tmplFunc interface{}) {
|
||||||
templateFuncs[name] = tmplFunc
|
templateFuncs[name] = tmplFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
//AddTemplateFuncs adds multiple template functions availalble to Usage and
|
// AddTemplateFuncs adds multiple template functions that are available to Usage and
|
||||||
// Help template generation.
|
// Help template generation.
|
||||||
func AddTemplateFuncs(tmplFuncs template.FuncMap) {
|
func AddTemplateFuncs(tmplFuncs template.FuncMap) {
|
||||||
for k, v := range tmplFuncs {
|
for k, v := range tmplFuncs {
|
||||||
@ -61,11 +72,11 @@ func AddTemplateFuncs(tmplFuncs template.FuncMap) {
|
|||||||
|
|
||||||
// OnInitialize takes a series of func() arguments and appends them to a slice of func().
|
// OnInitialize takes a series of func() arguments and appends them to a slice of func().
|
||||||
func OnInitialize(y ...func()) {
|
func OnInitialize(y ...func()) {
|
||||||
for _, x := range y {
|
initializers = append(initializers, y...)
|
||||||
initializers = append(initializers, x)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME Gt is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||||
|
|
||||||
// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
|
// Gt takes two types and checks whether the first type is greater than the second. In case of types Arrays, Chans,
|
||||||
// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
|
// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
|
||||||
// ints and then compared.
|
// ints and then compared.
|
||||||
@ -96,6 +107,8 @@ func Gt(a interface{}, b interface{}) bool {
|
|||||||
return left > right
|
return left > right
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME Eq is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||||
|
|
||||||
// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
|
// Eq takes two types and checks whether they are equal. Supported types are int and string. Unsupported types will panic.
|
||||||
func Eq(a interface{}, b interface{}) bool {
|
func Eq(a interface{}, b interface{}) bool {
|
||||||
av := reflect.ValueOf(a)
|
av := reflect.ValueOf(a)
|
||||||
@ -116,7 +129,9 @@ func trimRightSpace(s string) string {
|
|||||||
return strings.TrimRightFunc(s, unicode.IsSpace)
|
return strings.TrimRightFunc(s, unicode.IsSpace)
|
||||||
}
|
}
|
||||||
|
|
||||||
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s
|
// FIXME appendIfNotPresent is unused by cobra and should be removed in a version 2. It exists only for compatibility with users of cobra.
|
||||||
|
|
||||||
|
// appendIfNotPresent will append stringToAppend to the end of s, but only if it's not yet present in s.
|
||||||
func appendIfNotPresent(s, stringToAppend string) string {
|
func appendIfNotPresent(s, stringToAppend string) string {
|
||||||
if strings.Contains(s, stringToAppend) {
|
if strings.Contains(s, stringToAppend) {
|
||||||
return s
|
return s
|
||||||
@ -124,7 +139,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
|
|||||||
return s + " " + stringToAppend
|
return s + " " + stringToAppend
|
||||||
}
|
}
|
||||||
|
|
||||||
//rpad adds padding to the right of a string
|
// rpad adds padding to the right of a string.
|
||||||
func rpad(s string, padding int) string {
|
func rpad(s string, padding int) string {
|
||||||
template := fmt.Sprintf("%%-%ds", padding)
|
template := fmt.Sprintf("%%-%ds", padding)
|
||||||
return fmt.Sprintf(template, s)
|
return fmt.Sprintf(template, s)
|
||||||
@ -138,7 +153,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
|
|||||||
return t.Execute(w, data)
|
return t.Execute(w, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ld compares two strings and returns the levenshtein distance between them
|
// ld compares two strings and returns the levenshtein distance between them.
|
||||||
func ld(s, t string, ignoreCase bool) int {
|
func ld(s, t string, ignoreCase bool) int {
|
||||||
if ignoreCase {
|
if ignoreCase {
|
||||||
s = strings.ToLower(s)
|
s = strings.ToLower(s)
|
||||||
@ -173,3 +188,12 @@ func ld(s, t string, ignoreCase bool) int {
|
|||||||
}
|
}
|
||||||
return d[len(s)][len(t)]
|
return d[len(s)][len(t)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func stringInSlice(a string, list []string) bool {
|
||||||
|
for _, b := range list {
|
||||||
|
if b == a {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
880
vendor/github.com/spf13/cobra/command.go
generated
vendored
880
vendor/github.com/spf13/cobra/command.go
generated
vendored
File diff suppressed because it is too large
Load Diff
8
vendor/github.com/spf13/cobra/command_win.go
generated
vendored
8
vendor/github.com/spf13/cobra/command_win.go
generated
vendored
@ -11,14 +11,8 @@ import (
|
|||||||
|
|
||||||
var preExecHookFn = preExecHook
|
var preExecHookFn = preExecHook
|
||||||
|
|
||||||
// enables an information splash screen on Windows if the CLI is started from explorer.exe.
|
|
||||||
var MousetrapHelpText string = `This is a command line tool
|
|
||||||
|
|
||||||
You need to open cmd.exe and run it from there.
|
|
||||||
`
|
|
||||||
|
|
||||||
func preExecHook(c *Command) {
|
func preExecHook(c *Command) {
|
||||||
if mousetrap.StartedByExplorer() {
|
if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
|
||||||
c.Print(MousetrapHelpText)
|
c.Print(MousetrapHelpText)
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
|
3
vendor/github.com/spf13/cobra/doc/BUILD
generated
vendored
3
vendor/github.com/spf13/cobra/doc/BUILD
generated
vendored
@ -5,7 +5,9 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"man_docs.go",
|
"man_docs.go",
|
||||||
"md_docs.go",
|
"md_docs.go",
|
||||||
|
"rest_docs.go",
|
||||||
"util.go",
|
"util.go",
|
||||||
|
"yaml_docs.go",
|
||||||
],
|
],
|
||||||
importpath = "github.com/spf13/cobra/doc",
|
importpath = "github.com/spf13/cobra/doc",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
@ -13,6 +15,7 @@ go_library(
|
|||||||
"//vendor/github.com/cpuguy83/go-md2man/md2man:go_default_library",
|
"//vendor/github.com/cpuguy83/go-md2man/md2man:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||||
|
"//vendor/gopkg.in/yaml.v2:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
73
vendor/github.com/spf13/cobra/doc/man_docs.go
generated
vendored
73
vendor/github.com/spf13/cobra/doc/man_docs.go
generated
vendored
@ -23,21 +23,21 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
mangen "github.com/cpuguy83/go-md2man/md2man"
|
"github.com/cpuguy83/go-md2man/md2man"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenManTree will generate a man page for this command and all descendants
|
// GenManTree will generate a man page for this command and all descendants
|
||||||
// in the directory given. The header may be nil. This function may not work
|
// in the directory given. The header may be nil. This function may not work
|
||||||
// correctly if your command names have - in them. If you have `cmd` with two
|
// correctly if your command names have `-` in them. If you have `cmd` with two
|
||||||
// subcmds, `sub` and `sub-third`. And `sub` has a subcommand called `third`
|
// subcmds, `sub` and `sub-third`, and `sub` has a subcommand called `third`
|
||||||
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
||||||
func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
|
func GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
|
||||||
return GenManTreeFromOpts(cmd, GenManTreeOptions{
|
return GenManTreeFromOpts(cmd, GenManTreeOptions{
|
||||||
Header: header,
|
Header: header,
|
||||||
Path: dir,
|
Path: dir,
|
||||||
CommandSeparator: "_",
|
CommandSeparator: "-",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error {
|
|||||||
header = &GenManHeader{}
|
header = &GenManHeader{}
|
||||||
}
|
}
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := GenManTreeFromOpts(c, opts); err != nil {
|
if err := GenManTreeFromOpts(c, opts); err != nil {
|
||||||
@ -77,6 +77,8 @@ func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error {
|
|||||||
return GenMan(cmd, &headerCopy, f)
|
return GenMan(cmd, &headerCopy, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenManTreeOptions is the options for generating the man pages.
|
||||||
|
// Used only in GenManTreeFromOpts.
|
||||||
type GenManTreeOptions struct {
|
type GenManTreeOptions struct {
|
||||||
Header *GenManHeader
|
Header *GenManHeader
|
||||||
Path string
|
Path string
|
||||||
@ -105,7 +107,7 @@ func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error {
|
|||||||
fillHeader(header, cmd.CommandPath())
|
fillHeader(header, cmd.CommandPath())
|
||||||
|
|
||||||
b := genMan(cmd, header)
|
b := genMan(cmd, header)
|
||||||
_, err := w.Write(mangen.Render(b))
|
_, err := w.Write(md2man.Render(b))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,25 +128,25 @@ func fillHeader(header *GenManHeader, name string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPreamble(out io.Writer, header *GenManHeader, cmd *cobra.Command, dashedName string) {
|
func manPreamble(buf *bytes.Buffer, header *GenManHeader, cmd *cobra.Command, dashedName string) {
|
||||||
description := cmd.Long
|
description := cmd.Long
|
||||||
if len(description) == 0 {
|
if len(description) == 0 {
|
||||||
description = cmd.Short
|
description = cmd.Short
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprintf(out, `%% %s(%s)%s
|
buf.WriteString(fmt.Sprintf(`%% %s(%s)%s
|
||||||
%% %s
|
%% %s
|
||||||
%% %s
|
%% %s
|
||||||
# NAME
|
# NAME
|
||||||
`, header.Title, header.Section, header.date, header.Source, header.Manual)
|
`, header.Title, header.Section, header.date, header.Source, header.Manual))
|
||||||
fmt.Fprintf(out, "%s \\- %s\n\n", dashedName, cmd.Short)
|
buf.WriteString(fmt.Sprintf("%s \\- %s\n\n", dashedName, cmd.Short))
|
||||||
fmt.Fprintf(out, "# SYNOPSIS\n")
|
buf.WriteString("# SYNOPSIS\n")
|
||||||
fmt.Fprintf(out, "**%s**\n\n", cmd.UseLine())
|
buf.WriteString(fmt.Sprintf("**%s**\n\n", cmd.UseLine()))
|
||||||
fmt.Fprintf(out, "# DESCRIPTION\n")
|
buf.WriteString("# DESCRIPTION\n")
|
||||||
fmt.Fprintf(out, "%s\n\n", description)
|
buf.WriteString(description + "\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPrintFlags(out io.Writer, flags *pflag.FlagSet) {
|
func manPrintFlags(buf *bytes.Buffer, flags *pflag.FlagSet) {
|
||||||
flags.VisitAll(func(flag *pflag.Flag) {
|
flags.VisitAll(func(flag *pflag.Flag) {
|
||||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||||
return
|
return
|
||||||
@ -156,38 +158,41 @@ func manPrintFlags(out io.Writer, flags *pflag.FlagSet) {
|
|||||||
format = fmt.Sprintf("**--%s**", flag.Name)
|
format = fmt.Sprintf("**--%s**", flag.Name)
|
||||||
}
|
}
|
||||||
if len(flag.NoOptDefVal) > 0 {
|
if len(flag.NoOptDefVal) > 0 {
|
||||||
format = format + "["
|
format += "["
|
||||||
}
|
}
|
||||||
if flag.Value.Type() == "string" {
|
if flag.Value.Type() == "string" {
|
||||||
// put quotes on the value
|
// put quotes on the value
|
||||||
format = format + "=%q"
|
format += "=%q"
|
||||||
} else {
|
} else {
|
||||||
format = format + "=%s"
|
format += "=%s"
|
||||||
}
|
}
|
||||||
if len(flag.NoOptDefVal) > 0 {
|
if len(flag.NoOptDefVal) > 0 {
|
||||||
format = format + "]"
|
format += "]"
|
||||||
}
|
}
|
||||||
format = format + "\n\t%s\n\n"
|
format += "\n\t%s\n\n"
|
||||||
fmt.Fprintf(out, format, flag.DefValue, flag.Usage)
|
buf.WriteString(fmt.Sprintf(format, flag.DefValue, flag.Usage))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func manPrintOptions(out io.Writer, command *cobra.Command) {
|
func manPrintOptions(buf *bytes.Buffer, command *cobra.Command) {
|
||||||
flags := command.NonInheritedFlags()
|
flags := command.NonInheritedFlags()
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
fmt.Fprintf(out, "# OPTIONS\n")
|
buf.WriteString("# OPTIONS\n")
|
||||||
manPrintFlags(out, flags)
|
manPrintFlags(buf, flags)
|
||||||
fmt.Fprintf(out, "\n")
|
buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
flags = command.InheritedFlags()
|
flags = command.InheritedFlags()
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n")
|
buf.WriteString("# OPTIONS INHERITED FROM PARENT COMMANDS\n")
|
||||||
manPrintFlags(out, flags)
|
manPrintFlags(buf, flags)
|
||||||
fmt.Fprintf(out, "\n")
|
buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
||||||
|
cmd.InitDefaultHelpCmd()
|
||||||
|
cmd.InitDefaultHelpFlag()
|
||||||
|
|
||||||
// something like `rootcmd-subcmd1-subcmd2`
|
// something like `rootcmd-subcmd1-subcmd2`
|
||||||
dashCommandName := strings.Replace(cmd.CommandPath(), " ", "-", -1)
|
dashCommandName := strings.Replace(cmd.CommandPath(), " ", "-", -1)
|
||||||
|
|
||||||
@ -196,11 +201,11 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
|||||||
manPreamble(buf, header, cmd, dashCommandName)
|
manPreamble(buf, header, cmd, dashCommandName)
|
||||||
manPrintOptions(buf, cmd)
|
manPrintOptions(buf, cmd)
|
||||||
if len(cmd.Example) > 0 {
|
if len(cmd.Example) > 0 {
|
||||||
fmt.Fprintf(buf, "# EXAMPLE\n")
|
buf.WriteString("# EXAMPLE\n")
|
||||||
fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example)
|
buf.WriteString(fmt.Sprintf("```\n%s\n```\n", cmd.Example))
|
||||||
}
|
}
|
||||||
if hasSeeAlso(cmd) {
|
if hasSeeAlso(cmd) {
|
||||||
fmt.Fprintf(buf, "# SEE ALSO\n")
|
buf.WriteString("# SEE ALSO\n")
|
||||||
seealsos := make([]string, 0)
|
seealsos := make([]string, 0)
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
parentPath := cmd.Parent().CommandPath()
|
parentPath := cmd.Parent().CommandPath()
|
||||||
@ -216,16 +221,16 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
|||||||
children := cmd.Commands()
|
children := cmd.Commands()
|
||||||
sort.Sort(byName(children))
|
sort.Sort(byName(children))
|
||||||
for _, c := range children {
|
for _, c := range children {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
|
seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
|
||||||
seealsos = append(seealsos, seealso)
|
seealsos = append(seealsos, seealso)
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", "))
|
buf.WriteString(strings.Join(seealsos, ", ") + "\n")
|
||||||
}
|
}
|
||||||
if !cmd.DisableAutoGenTag {
|
if !cmd.DisableAutoGenTag {
|
||||||
fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006"))
|
buf.WriteString(fmt.Sprintf("# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006")))
|
||||||
}
|
}
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
11
vendor/github.com/spf13/cobra/doc/man_docs.md
generated
vendored
11
vendor/github.com/spf13/cobra/doc/man_docs.md
generated
vendored
@ -6,6 +6,8 @@ Generating man pages from a cobra command is incredibly easy. An example is as f
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/cobra/doc"
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
@ -15,12 +17,15 @@ func main() {
|
|||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "my test program",
|
Short: "my test program",
|
||||||
}
|
}
|
||||||
header := &cobra.GenManHeader{
|
header := &doc.GenManHeader{
|
||||||
Title: "MINE",
|
Title: "MINE",
|
||||||
Section: "3",
|
Section: "3",
|
||||||
}
|
}
|
||||||
doc.GenManTree(cmd, header, "/tmp")
|
err := doc.GenManTree(cmd, header, "/tmp")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
That will get you a man page `/tmp/test.1`
|
That will get you a man page `/tmp/test.3`
|
||||||
|
94
vendor/github.com/spf13/cobra/doc/md_docs.go
generated
vendored
94
vendor/github.com/spf13/cobra/doc/md_docs.go
generated
vendored
@ -14,6 +14,7 @@
|
|||||||
package doc
|
package doc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
@ -25,38 +26,36 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
func printOptions(w io.Writer, cmd *cobra.Command, name string) error {
|
func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error {
|
||||||
flags := cmd.NonInheritedFlags()
|
flags := cmd.NonInheritedFlags()
|
||||||
flags.SetOutput(w)
|
flags.SetOutput(buf)
|
||||||
if flags.HasFlags() {
|
if flags.HasFlags() {
|
||||||
if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil {
|
buf.WriteString("### Options\n\n```\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
flags.PrintDefaults()
|
flags.PrintDefaults()
|
||||||
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
buf.WriteString("```\n\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parentFlags := cmd.InheritedFlags()
|
parentFlags := cmd.InheritedFlags()
|
||||||
parentFlags.SetOutput(w)
|
parentFlags.SetOutput(buf)
|
||||||
if parentFlags.HasFlags() {
|
if parentFlags.HasFlags() {
|
||||||
if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil {
|
buf.WriteString("### Options inherited from parent commands\n\n```\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
parentFlags.PrintDefaults()
|
parentFlags.PrintDefaults()
|
||||||
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
buf.WriteString("```\n\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenMarkdown creates markdown output.
|
||||||
func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
|
func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||||
return GenMarkdownCustom(cmd, w, func(s string) string { return s })
|
return GenMarkdownCustom(cmd, w, func(s string) string { return s })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenMarkdownCustom creates custom markdown output.
|
||||||
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
|
func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
|
||||||
|
cmd.InitDefaultHelpCmd()
|
||||||
|
cmd.InitDefaultHelpFlag()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
name := cmd.CommandPath()
|
name := cmd.CommandPath()
|
||||||
|
|
||||||
short := cmd.Short
|
short := cmd.Short
|
||||||
@ -65,49 +64,31 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string)
|
|||||||
long = short
|
long = short
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := fmt.Fprintf(w, "## %s\n\n", name); err != nil {
|
buf.WriteString("## " + name + "\n\n")
|
||||||
return err
|
buf.WriteString(short + "\n\n")
|
||||||
}
|
buf.WriteString("### Synopsis\n\n")
|
||||||
if _, err := fmt.Fprintf(w, "%s\n\n", short); err != nil {
|
buf.WriteString("\n" + long + "\n\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := fmt.Fprintf(w, "### Synopsis\n\n"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := fmt.Fprintf(w, "\n%s\n\n", long); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.Runnable() {
|
if cmd.Runnable() {
|
||||||
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil {
|
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine()))
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cmd.Example) > 0 {
|
if len(cmd.Example) > 0 {
|
||||||
if _, err := fmt.Fprintf(w, "### Examples\n\n"); err != nil {
|
buf.WriteString("### Examples\n\n")
|
||||||
return err
|
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
|
||||||
}
|
|
||||||
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.Example); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := printOptions(w, cmd, name); err != nil {
|
if err := printOptions(buf, cmd, name); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if hasSeeAlso(cmd) {
|
if hasSeeAlso(cmd) {
|
||||||
if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil {
|
buf.WriteString("### SEE ALSO\n")
|
||||||
return err
|
|
||||||
}
|
|
||||||
if cmd.HasParent() {
|
if cmd.HasParent() {
|
||||||
parent := cmd.Parent()
|
parent := cmd.Parent()
|
||||||
pname := parent.CommandPath()
|
pname := parent.CommandPath()
|
||||||
link := pname + ".md"
|
link := pname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short); err != nil {
|
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short))
|
||||||
return err
|
|
||||||
}
|
|
||||||
cmd.VisitParents(func(c *cobra.Command) {
|
cmd.VisitParents(func(c *cobra.Command) {
|
||||||
if c.DisableAutoGenTag {
|
if c.DisableAutoGenTag {
|
||||||
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
||||||
@ -119,37 +100,40 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string)
|
|||||||
sort.Sort(byName(children))
|
sort.Sort(byName(children))
|
||||||
|
|
||||||
for _, child := range children {
|
for _, child := range children {
|
||||||
if !child.IsAvailableCommand() || child.IsHelpCommand() {
|
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
cname := name + " " + child.Name()
|
cname := name + " " + child.Name()
|
||||||
link := cname + ".md"
|
link := cname + ".md"
|
||||||
link = strings.Replace(link, " ", "_", -1)
|
link = strings.Replace(link, " ", "_", -1)
|
||||||
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short); err != nil {
|
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short))
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if _, err := fmt.Fprintf(w, "\n"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
buf.WriteString("\n")
|
||||||
}
|
}
|
||||||
if !cmd.DisableAutoGenTag {
|
if !cmd.DisableAutoGenTag {
|
||||||
if _, err := fmt.Fprintf(w, "###### Auto generated by spf13/cobra on %s\n", time.Now().Format("2-Jan-2006")); err != nil {
|
buf.WriteString("###### Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "\n")
|
||||||
|
}
|
||||||
|
_, err := buf.WriteTo(w)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// GenMarkdownTree will generate a markdown page for this command and all
|
||||||
|
// descendants in the directory given. The header may be nil.
|
||||||
|
// This function may not work correctly if your command names have `-` in them.
|
||||||
|
// If you have `cmd` with two subcmds, `sub` and `sub-third`,
|
||||||
|
// and `sub` has a subcommand called `third`, it is undefined which
|
||||||
|
// help output will be in the file `cmd-sub-third.1`.
|
||||||
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
func GenMarkdownTree(cmd *cobra.Command, dir string) error {
|
||||||
identity := func(s string) string { return s }
|
identity := func(s string) string { return s }
|
||||||
emptyStr := func(s string) string { return "" }
|
emptyStr := func(s string) string { return "" }
|
||||||
return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
|
return GenMarkdownTreeCustom(cmd, dir, emptyStr, identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GenMarkdownTreeCustom is the the same as GenMarkdownTree, but
|
||||||
|
// with custom filePrepender and linkHandler.
|
||||||
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
|
func GenMarkdownTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
|
if err := GenMarkdownTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
|
||||||
|
23
vendor/github.com/spf13/cobra/doc/md_docs.md
generated
vendored
23
vendor/github.com/spf13/cobra/doc/md_docs.md
generated
vendored
@ -6,6 +6,8 @@ Generating man pages from a cobra command is incredibly easy. An example is as f
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/cobra/doc"
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
@ -15,7 +17,10 @@ func main() {
|
|||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "my test program",
|
Short: "my test program",
|
||||||
}
|
}
|
||||||
doc.GenMarkdownTree(cmd, "/tmp")
|
err := doc.GenMarkdownTree(cmd, "/tmp")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -29,18 +34,22 @@ This program can actually generate docs for the kubectl command in the kubernete
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
|
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
|
||||||
"github.com/spf13/cobra/doc"
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
cmd := kubectlcmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||||
doc.GenMarkdownTree(cmd, "./")
|
err := doc.GenMarkdownTree(kubectl, "./")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -52,7 +61,10 @@ You may wish to have more control over the output, or only generate for a single
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
out := new(bytes.Buffer)
|
out := new(bytes.Buffer)
|
||||||
doc.GenMarkdown(cmd, out)
|
err := doc.GenMarkdown(cmd, out)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
This will write the markdown doc for ONLY "cmd" into the out, buffer.
|
||||||
@ -101,4 +113,3 @@ linkHandler := func(name string) string {
|
|||||||
return "/commands/" + strings.ToLower(base) + "/"
|
return "/commands/" + strings.ToLower(base) + "/"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
185
vendor/github.com/spf13/cobra/doc/rest_docs.go
generated
vendored
Normal file
185
vendor/github.com/spf13/cobra/doc/rest_docs.go
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
//Copyright 2015 Red Hat Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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 doc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
func printOptionsReST(buf *bytes.Buffer, cmd *cobra.Command, name string) error {
|
||||||
|
flags := cmd.NonInheritedFlags()
|
||||||
|
flags.SetOutput(buf)
|
||||||
|
if flags.HasFlags() {
|
||||||
|
buf.WriteString("Options\n")
|
||||||
|
buf.WriteString("~~~~~~~\n\n::\n\n")
|
||||||
|
flags.PrintDefaults()
|
||||||
|
buf.WriteString("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
parentFlags := cmd.InheritedFlags()
|
||||||
|
parentFlags.SetOutput(buf)
|
||||||
|
if parentFlags.HasFlags() {
|
||||||
|
buf.WriteString("Options inherited from parent commands\n")
|
||||||
|
buf.WriteString("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n")
|
||||||
|
parentFlags.PrintDefaults()
|
||||||
|
buf.WriteString("\n")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// linkHandler for default ReST hyperlink markup
|
||||||
|
func defaultLinkHandler(name, ref string) string {
|
||||||
|
return fmt.Sprintf("`%s <%s.rst>`_", name, ref)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenReST creates reStructured Text output.
|
||||||
|
func GenReST(cmd *cobra.Command, w io.Writer) error {
|
||||||
|
return GenReSTCustom(cmd, w, defaultLinkHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenReSTCustom creates custom reStructured Text output.
|
||||||
|
func GenReSTCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string, string) string) error {
|
||||||
|
cmd.InitDefaultHelpCmd()
|
||||||
|
cmd.InitDefaultHelpFlag()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
name := cmd.CommandPath()
|
||||||
|
|
||||||
|
short := cmd.Short
|
||||||
|
long := cmd.Long
|
||||||
|
if len(long) == 0 {
|
||||||
|
long = short
|
||||||
|
}
|
||||||
|
ref := strings.Replace(name, " ", "_", -1)
|
||||||
|
|
||||||
|
buf.WriteString(".. _" + ref + ":\n\n")
|
||||||
|
buf.WriteString(name + "\n")
|
||||||
|
buf.WriteString(strings.Repeat("-", len(name)) + "\n\n")
|
||||||
|
buf.WriteString(short + "\n\n")
|
||||||
|
buf.WriteString("Synopsis\n")
|
||||||
|
buf.WriteString("~~~~~~~~\n\n")
|
||||||
|
buf.WriteString("\n" + long + "\n\n")
|
||||||
|
|
||||||
|
if cmd.Runnable() {
|
||||||
|
buf.WriteString(fmt.Sprintf("::\n\n %s\n\n", cmd.UseLine()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cmd.Example) > 0 {
|
||||||
|
buf.WriteString("Examples\n")
|
||||||
|
buf.WriteString("~~~~~~~~\n\n")
|
||||||
|
buf.WriteString(fmt.Sprintf("::\n\n%s\n\n", indentString(cmd.Example, " ")))
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := printOptionsReST(buf, cmd, name); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if hasSeeAlso(cmd) {
|
||||||
|
buf.WriteString("SEE ALSO\n")
|
||||||
|
buf.WriteString("~~~~~~~~\n\n")
|
||||||
|
if cmd.HasParent() {
|
||||||
|
parent := cmd.Parent()
|
||||||
|
pname := parent.CommandPath()
|
||||||
|
ref = strings.Replace(pname, " ", "_", -1)
|
||||||
|
buf.WriteString(fmt.Sprintf("* %s \t - %s\n", linkHandler(pname, ref), parent.Short))
|
||||||
|
cmd.VisitParents(func(c *cobra.Command) {
|
||||||
|
if c.DisableAutoGenTag {
|
||||||
|
cmd.DisableAutoGenTag = c.DisableAutoGenTag
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
children := cmd.Commands()
|
||||||
|
sort.Sort(byName(children))
|
||||||
|
|
||||||
|
for _, child := range children {
|
||||||
|
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cname := name + " " + child.Name()
|
||||||
|
ref = strings.Replace(cname, " ", "_", -1)
|
||||||
|
buf.WriteString(fmt.Sprintf("* %s \t - %s\n", linkHandler(cname, ref), child.Short))
|
||||||
|
}
|
||||||
|
buf.WriteString("\n")
|
||||||
|
}
|
||||||
|
if !cmd.DisableAutoGenTag {
|
||||||
|
buf.WriteString("*Auto generated by spf13/cobra on " + time.Now().Format("2-Jan-2006") + "*\n")
|
||||||
|
}
|
||||||
|
_, err := buf.WriteTo(w)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenReSTTree will generate a ReST page for this command and all
|
||||||
|
// descendants in the directory given.
|
||||||
|
// This function may not work correctly if your command names have `-` in them.
|
||||||
|
// If you have `cmd` with two subcmds, `sub` and `sub-third`,
|
||||||
|
// and `sub` has a subcommand called `third`, it is undefined which
|
||||||
|
// help output will be in the file `cmd-sub-third.1`.
|
||||||
|
func GenReSTTree(cmd *cobra.Command, dir string) error {
|
||||||
|
emptyStr := func(s string) string { return "" }
|
||||||
|
return GenReSTTreeCustom(cmd, dir, emptyStr, defaultLinkHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenReSTTreeCustom is the the same as GenReSTTree, but
|
||||||
|
// with custom filePrepender and linkHandler.
|
||||||
|
func GenReSTTreeCustom(cmd *cobra.Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error {
|
||||||
|
for _, c := range cmd.Commands() {
|
||||||
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := GenReSTTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".rst"
|
||||||
|
filename := filepath.Join(dir, basename)
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := GenReSTCustom(cmd, f, linkHandler); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// adapted from: https://github.com/kr/text/blob/main/indent.go
|
||||||
|
func indentString(s, p string) string {
|
||||||
|
var res []byte
|
||||||
|
b := []byte(s)
|
||||||
|
prefix := []byte(p)
|
||||||
|
bol := true
|
||||||
|
for _, c := range b {
|
||||||
|
if bol && c != '\n' {
|
||||||
|
res = append(res, prefix...)
|
||||||
|
}
|
||||||
|
res = append(res, c)
|
||||||
|
bol = c == '\n'
|
||||||
|
}
|
||||||
|
return string(res)
|
||||||
|
}
|
114
vendor/github.com/spf13/cobra/doc/rest_docs.md
generated
vendored
Normal file
114
vendor/github.com/spf13/cobra/doc/rest_docs.md
generated
vendored
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
# Generating ReStructured Text Docs For Your Own cobra.Command
|
||||||
|
|
||||||
|
Generating ReST pages from a cobra command is incredibly easy. An example is as follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "test",
|
||||||
|
Short: "my test program",
|
||||||
|
}
|
||||||
|
err := doc.GenReSTTree(cmd, "/tmp")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
That will get you a ReST document `/tmp/test.rst`
|
||||||
|
|
||||||
|
## Generate ReST docs for the entire command tree
|
||||||
|
|
||||||
|
This program can actually generate docs for the kubectl command in the kubernetes project
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||||
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||||
|
err := doc.GenReSTTree(kubectl, "./")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate a whole series of files, one for each command in the tree, in the directory specified (in this case "./")
|
||||||
|
|
||||||
|
## Generate ReST docs for a single command
|
||||||
|
|
||||||
|
You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenReST` instead of `GenReSTTree`
|
||||||
|
|
||||||
|
```go
|
||||||
|
out := new(bytes.Buffer)
|
||||||
|
err := doc.GenReST(cmd, out)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will write the ReST doc for ONLY "cmd" into the out, buffer.
|
||||||
|
|
||||||
|
## Customize the output
|
||||||
|
|
||||||
|
Both `GenReST` and `GenReSTTree` have alternate versions with callbacks to get some control of the output:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenReSTTreeCustom(cmd *Command, dir string, filePrepender func(string) string, linkHandler func(string, string) string) error {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenReSTCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string, string) string) error {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `filePrepender` will prepend the return value given the full filepath to the rendered ReST file. A common use case is to add front matter to use the generated documentation with [Hugo](http://gohugo.io/):
|
||||||
|
|
||||||
|
```go
|
||||||
|
const fmTemplate = `---
|
||||||
|
date: %s
|
||||||
|
title: "%s"
|
||||||
|
slug: %s
|
||||||
|
url: %s
|
||||||
|
---
|
||||||
|
`
|
||||||
|
filePrepender := func(filename string) string {
|
||||||
|
now := time.Now().Format(time.RFC3339)
|
||||||
|
name := filepath.Base(filename)
|
||||||
|
base := strings.TrimSuffix(name, path.Ext(name))
|
||||||
|
url := "/commands/" + strings.ToLower(base) + "/"
|
||||||
|
return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `linkHandler` can be used to customize the rendered links to the commands, given a command name and reference. This is useful while converting rst to html or while generating documentation with tools like Sphinx where `:ref:` is used:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Sphinx cross-referencing format
|
||||||
|
linkHandler := func(name, ref string) string {
|
||||||
|
return fmt.Sprintf(":ref:`%s <%s>`", name, ref)
|
||||||
|
}
|
||||||
|
```
|
17
vendor/github.com/spf13/cobra/doc/util.go
generated
vendored
17
vendor/github.com/spf13/cobra/doc/util.go
generated
vendored
@ -13,7 +13,11 @@
|
|||||||
|
|
||||||
package doc
|
package doc
|
||||||
|
|
||||||
import "github.com/spf13/cobra"
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
// Test to see if we have a reason to print See Also information in docs
|
// Test to see if we have a reason to print See Also information in docs
|
||||||
// Basically this is a test for a parent commend or a subcommand which is
|
// Basically this is a test for a parent commend or a subcommand which is
|
||||||
@ -23,7 +27,7 @@ func hasSeeAlso(cmd *cobra.Command) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
for _, c := range cmd.Commands() {
|
for _, c := range cmd.Commands() {
|
||||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -31,6 +35,15 @@ func hasSeeAlso(cmd *cobra.Command) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Temporary workaround for yaml lib generating incorrect yaml with long strings
|
||||||
|
// that do not contain \n.
|
||||||
|
func forceMultiLine(s string) string {
|
||||||
|
if len(s) > 60 && !strings.Contains(s, "\n") {
|
||||||
|
s = s + "\n"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
type byName []*cobra.Command
|
type byName []*cobra.Command
|
||||||
|
|
||||||
func (s byName) Len() int { return len(s) }
|
func (s byName) Len() int { return len(s) }
|
||||||
|
169
vendor/github.com/spf13/cobra/doc/yaml_docs.go
generated
vendored
Normal file
169
vendor/github.com/spf13/cobra/doc/yaml_docs.go
generated
vendored
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2016 French Ben. All rights reserved.
|
||||||
|
//
|
||||||
|
// 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 doc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type cmdOption struct {
|
||||||
|
Name string
|
||||||
|
Shorthand string `yaml:",omitempty"`
|
||||||
|
DefaultValue string `yaml:"default_value,omitempty"`
|
||||||
|
Usage string `yaml:",omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type cmdDoc struct {
|
||||||
|
Name string
|
||||||
|
Synopsis string `yaml:",omitempty"`
|
||||||
|
Description string `yaml:",omitempty"`
|
||||||
|
Options []cmdOption `yaml:",omitempty"`
|
||||||
|
InheritedOptions []cmdOption `yaml:"inherited_options,omitempty"`
|
||||||
|
Example string `yaml:",omitempty"`
|
||||||
|
SeeAlso []string `yaml:"see_also,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenYamlTree creates yaml structured ref files for this command and all descendants
|
||||||
|
// in the directory given. This function may not work
|
||||||
|
// correctly if your command names have `-` in them. If you have `cmd` with two
|
||||||
|
// subcmds, `sub` and `sub-third`, and `sub` has a subcommand called `third`
|
||||||
|
// it is undefined which help output will be in the file `cmd-sub-third.1`.
|
||||||
|
func GenYamlTree(cmd *cobra.Command, dir string) error {
|
||||||
|
identity := func(s string) string { return s }
|
||||||
|
emptyStr := func(s string) string { return "" }
|
||||||
|
return GenYamlTreeCustom(cmd, dir, emptyStr, identity)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenYamlTreeCustom creates yaml structured ref files.
|
||||||
|
func GenYamlTreeCustom(cmd *cobra.Command, dir string, filePrepender, linkHandler func(string) string) error {
|
||||||
|
for _, c := range cmd.Commands() {
|
||||||
|
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := GenYamlTreeCustom(c, dir, filePrepender, linkHandler); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
basename := strings.Replace(cmd.CommandPath(), " ", "_", -1) + ".yaml"
|
||||||
|
filename := filepath.Join(dir, basename)
|
||||||
|
f, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if _, err := io.WriteString(f, filePrepender(filename)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := GenYamlCustom(cmd, f, linkHandler); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenYaml creates yaml output.
|
||||||
|
func GenYaml(cmd *cobra.Command, w io.Writer) error {
|
||||||
|
return GenYamlCustom(cmd, w, func(s string) string { return s })
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenYamlCustom creates custom yaml output.
|
||||||
|
func GenYamlCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string) string) error {
|
||||||
|
cmd.InitDefaultHelpCmd()
|
||||||
|
cmd.InitDefaultHelpFlag()
|
||||||
|
|
||||||
|
yamlDoc := cmdDoc{}
|
||||||
|
yamlDoc.Name = cmd.CommandPath()
|
||||||
|
|
||||||
|
yamlDoc.Synopsis = forceMultiLine(cmd.Short)
|
||||||
|
yamlDoc.Description = forceMultiLine(cmd.Long)
|
||||||
|
|
||||||
|
if len(cmd.Example) > 0 {
|
||||||
|
yamlDoc.Example = cmd.Example
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := cmd.NonInheritedFlags()
|
||||||
|
if flags.HasFlags() {
|
||||||
|
yamlDoc.Options = genFlagResult(flags)
|
||||||
|
}
|
||||||
|
flags = cmd.InheritedFlags()
|
||||||
|
if flags.HasFlags() {
|
||||||
|
yamlDoc.InheritedOptions = genFlagResult(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasSeeAlso(cmd) {
|
||||||
|
result := []string{}
|
||||||
|
if cmd.HasParent() {
|
||||||
|
parent := cmd.Parent()
|
||||||
|
result = append(result, parent.CommandPath()+" - "+parent.Short)
|
||||||
|
}
|
||||||
|
children := cmd.Commands()
|
||||||
|
sort.Sort(byName(children))
|
||||||
|
for _, child := range children {
|
||||||
|
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, child.Name()+" - "+child.Short)
|
||||||
|
}
|
||||||
|
yamlDoc.SeeAlso = result
|
||||||
|
}
|
||||||
|
|
||||||
|
final, err := yaml.Marshal(&yamlDoc)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(final); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func genFlagResult(flags *pflag.FlagSet) []cmdOption {
|
||||||
|
var result []cmdOption
|
||||||
|
|
||||||
|
flags.VisitAll(func(flag *pflag.Flag) {
|
||||||
|
// Todo, when we mark a shorthand is deprecated, but specify an empty message.
|
||||||
|
// The flag.ShorthandDeprecated is empty as the shorthand is deprecated.
|
||||||
|
// Using len(flag.ShorthandDeprecated) > 0 can't handle this, others are ok.
|
||||||
|
if !(len(flag.ShorthandDeprecated) > 0) && len(flag.Shorthand) > 0 {
|
||||||
|
opt := cmdOption{
|
||||||
|
flag.Name,
|
||||||
|
flag.Shorthand,
|
||||||
|
flag.DefValue,
|
||||||
|
forceMultiLine(flag.Usage),
|
||||||
|
}
|
||||||
|
result = append(result, opt)
|
||||||
|
} else {
|
||||||
|
opt := cmdOption{
|
||||||
|
Name: flag.Name,
|
||||||
|
DefaultValue: forceMultiLine(flag.DefValue),
|
||||||
|
Usage: forceMultiLine(flag.Usage),
|
||||||
|
}
|
||||||
|
result = append(result, opt)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
112
vendor/github.com/spf13/cobra/doc/yaml_docs.md
generated
vendored
Normal file
112
vendor/github.com/spf13/cobra/doc/yaml_docs.md
generated
vendored
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
# Generating Yaml Docs For Your Own cobra.Command
|
||||||
|
|
||||||
|
Generating yaml files from a cobra command is incredibly easy. An example is as follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "test",
|
||||||
|
Short: "my test program",
|
||||||
|
}
|
||||||
|
err := doc.GenYamlTree(cmd, "/tmp")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
That will get you a Yaml document `/tmp/test.yaml`
|
||||||
|
|
||||||
|
## Generate yaml docs for the entire command tree
|
||||||
|
|
||||||
|
This program can actually generate docs for the kubectl command in the kubernetes project
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||||
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra/doc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||||
|
err := doc.GenYamlTree(kubectl, "./")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This will generate a whole series of files, one for each command in the tree, in the directory specified (in this case "./")
|
||||||
|
|
||||||
|
## Generate yaml docs for a single command
|
||||||
|
|
||||||
|
You may wish to have more control over the output, or only generate for a single command, instead of the entire command tree. If this is the case you may prefer to `GenYaml` instead of `GenYamlTree`
|
||||||
|
|
||||||
|
```go
|
||||||
|
out := new(bytes.Buffer)
|
||||||
|
doc.GenYaml(cmd, out)
|
||||||
|
```
|
||||||
|
|
||||||
|
This will write the yaml doc for ONLY "cmd" into the out, buffer.
|
||||||
|
|
||||||
|
## Customize the output
|
||||||
|
|
||||||
|
Both `GenYaml` and `GenYamlTree` have alternate versions with callbacks to get some control of the output:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenYamlTreeCustom(cmd *Command, dir string, filePrepender, linkHandler func(string) string) error {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GenYamlCustom(cmd *Command, out *bytes.Buffer, linkHandler func(string) string) error {
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `filePrepender` will prepend the return value given the full filepath to the rendered Yaml file. A common use case is to add front matter to use the generated documentation with [Hugo](http://gohugo.io/):
|
||||||
|
|
||||||
|
```go
|
||||||
|
const fmTemplate = `---
|
||||||
|
date: %s
|
||||||
|
title: "%s"
|
||||||
|
slug: %s
|
||||||
|
url: %s
|
||||||
|
---
|
||||||
|
`
|
||||||
|
|
||||||
|
filePrepender := func(filename string) string {
|
||||||
|
now := time.Now().Format(time.RFC3339)
|
||||||
|
name := filepath.Base(filename)
|
||||||
|
base := strings.TrimSuffix(name, path.Ext(name))
|
||||||
|
url := "/commands/" + strings.ToLower(base) + "/"
|
||||||
|
return fmt.Sprintf(fmTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `linkHandler` can be used to customize the rendered internal links to the commands, given a filename:
|
||||||
|
|
||||||
|
```go
|
||||||
|
linkHandler := func(name string) string {
|
||||||
|
base := strings.TrimSuffix(name, path.Ext(name))
|
||||||
|
return "/commands/" + strings.ToLower(base) + "/"
|
||||||
|
}
|
||||||
|
```
|
126
vendor/github.com/spf13/cobra/zsh_completions.go
generated
vendored
Normal file
126
vendor/github.com/spf13/cobra/zsh_completions.go
generated
vendored
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package cobra
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GenZshCompletionFile generates zsh completion file.
|
||||||
|
func (c *Command) GenZshCompletionFile(filename string) error {
|
||||||
|
outFile, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer outFile.Close()
|
||||||
|
|
||||||
|
return c.GenZshCompletion(outFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenZshCompletion generates a zsh completion file and writes to the passed writer.
|
||||||
|
func (c *Command) GenZshCompletion(w io.Writer) error {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
|
||||||
|
writeHeader(buf, c)
|
||||||
|
maxDepth := maxDepth(c)
|
||||||
|
writeLevelMapping(buf, maxDepth)
|
||||||
|
writeLevelCases(buf, maxDepth, c)
|
||||||
|
|
||||||
|
_, err := buf.WriteTo(w)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeHeader(w io.Writer, cmd *Command) {
|
||||||
|
fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func maxDepth(c *Command) int {
|
||||||
|
if len(c.Commands()) == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
maxDepthSub := 0
|
||||||
|
for _, s := range c.Commands() {
|
||||||
|
subDepth := maxDepth(s)
|
||||||
|
if subDepth > maxDepthSub {
|
||||||
|
maxDepthSub = subDepth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1 + maxDepthSub
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeLevelMapping(w io.Writer, numLevels int) {
|
||||||
|
fmt.Fprintln(w, `_arguments \`)
|
||||||
|
for i := 1; i <= numLevels; i++ {
|
||||||
|
fmt.Fprintf(w, ` '%d: :->level%d' \`, i, i)
|
||||||
|
fmt.Fprintln(w)
|
||||||
|
}
|
||||||
|
fmt.Fprintf(w, ` '%d: :%s'`, numLevels+1, "_files")
|
||||||
|
fmt.Fprintln(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeLevelCases(w io.Writer, maxDepth int, root *Command) {
|
||||||
|
fmt.Fprintln(w, "case $state in")
|
||||||
|
defer fmt.Fprintln(w, "esac")
|
||||||
|
|
||||||
|
for i := 1; i <= maxDepth; i++ {
|
||||||
|
fmt.Fprintf(w, " level%d)\n", i)
|
||||||
|
writeLevel(w, root, i)
|
||||||
|
fmt.Fprintln(w, " ;;")
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w, " *)")
|
||||||
|
fmt.Fprintln(w, " _arguments '*: :_files'")
|
||||||
|
fmt.Fprintln(w, " ;;")
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeLevel(w io.Writer, root *Command, i int) {
|
||||||
|
fmt.Fprintf(w, " case $words[%d] in\n", i)
|
||||||
|
defer fmt.Fprintln(w, " esac")
|
||||||
|
|
||||||
|
commands := filterByLevel(root, i)
|
||||||
|
byParent := groupByParent(commands)
|
||||||
|
|
||||||
|
for p, c := range byParent {
|
||||||
|
names := names(c)
|
||||||
|
fmt.Fprintf(w, " %s)\n", p)
|
||||||
|
fmt.Fprintf(w, " _arguments '%d: :(%s)'\n", i, strings.Join(names, " "))
|
||||||
|
fmt.Fprintln(w, " ;;")
|
||||||
|
}
|
||||||
|
fmt.Fprintln(w, " *)")
|
||||||
|
fmt.Fprintln(w, " _arguments '*: :_files'")
|
||||||
|
fmt.Fprintln(w, " ;;")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterByLevel(c *Command, l int) []*Command {
|
||||||
|
cs := make([]*Command, 0)
|
||||||
|
if l == 0 {
|
||||||
|
cs = append(cs, c)
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
for _, s := range c.Commands() {
|
||||||
|
cs = append(cs, filterByLevel(s, l-1)...)
|
||||||
|
}
|
||||||
|
return cs
|
||||||
|
}
|
||||||
|
|
||||||
|
func groupByParent(commands []*Command) map[string][]*Command {
|
||||||
|
m := make(map[string][]*Command)
|
||||||
|
for _, c := range commands {
|
||||||
|
parent := c.Parent()
|
||||||
|
if parent == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m[parent.Name()] = append(m[parent.Name()], c)
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func names(commands []*Command) []string {
|
||||||
|
ns := make([]string, len(commands))
|
||||||
|
for i, c := range commands {
|
||||||
|
ns[i] = c.Name()
|
||||||
|
}
|
||||||
|
return ns
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user