mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +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",
|
||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
||||
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/cobra/doc",
|
||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
||||
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/jwalterweatherman",
|
||||
|
@ -328,7 +328,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/cobra",
|
||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
||||
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
|
@ -308,7 +308,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/cobra",
|
||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
||||
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/pflag",
|
||||
|
@ -296,7 +296,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/spf13/cobra",
|
||||
"Rev": "f62e98d28ab7ad31d707ba837a966378465c7b57"
|
||||
"Rev": "19e54c4a2b8a78c9d54b2bed61b1a6c5e1bfcf6f"
|
||||
},
|
||||
{
|
||||
"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
|
||||
go:
|
||||
- 1.4.3
|
||||
- 1.5.4
|
||||
- 1.6.3
|
||||
- tip
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: 1.7.6
|
||||
- go: 1.8.3
|
||||
- go: tip
|
||||
allow_failures:
|
||||
- go: tip
|
||||
|
||||
@ -16,3 +15,7 @@ before_install:
|
||||
script:
|
||||
- PATH=$PATH:$PWD/bin go test -v ./...
|
||||
- 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(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"args.go",
|
||||
"bash_completions.go",
|
||||
"cobra.go",
|
||||
"command.go",
|
||||
"zsh_completions.go",
|
||||
] + select({
|
||||
"@io_bazel_rules_go//go/platform:android": [
|
||||
"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)
|
||||
* [rkt](https://github.com/coreos/rkt)
|
||||
* [etcd](https://github.com/coreos/etcd)
|
||||
* [Moby (former Docker)](https://github.com/moby/moby)
|
||||
* [Docker (distribution)](https://github.com/docker/distribution)
|
||||
* [OpenShift](https://www.openshift.com/)
|
||||
* [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/)
|
||||
* [Bleve](http://www.blevesearch.com/)
|
||||
* [ProjectAtomic (enterprise)](http://www.projectatomic.io/)
|
||||
* [Parse (CLI)](https://parse.com/)
|
||||
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
|
||||
* [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://circleci.com/gh/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
|
||||
|
||||
@ -39,27 +60,16 @@ Cobra provides:
|
||||
* Fully POSIX-compliant flags (including short & long versions)
|
||||
* Nested subcommands
|
||||
* 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`?)
|
||||
* Automatic help generation for commands and flags
|
||||
* Automatic detailed help for `app help [command]`
|
||||
* Automatic help flag recognition of `-h`, `--help`, etc.
|
||||
* Automatically generated bash autocomplete for your application
|
||||
* Automatically generated man pages for your application
|
||||
* 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
|
||||
|
||||
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
|
||||
|
||||
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:
|
||||
|
||||
> hugo server --port=1313
|
||||
hugo server --port=1313
|
||||
|
||||
In this command we are telling Git to clone the url bare.
|
||||
|
||||
> git clone URL --bare
|
||||
git clone URL --bare
|
||||
|
||||
## Commands
|
||||
|
||||
@ -92,20 +102,11 @@ have children commands and optionally run an action.
|
||||
|
||||
In the example above, 'server' is the command.
|
||||
|
||||
A Command has the following structure:
|
||||
|
||||
```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.
|
||||
}
|
||||
```
|
||||
[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
|
||||
|
||||
## 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/).
|
||||
A Cobra command can define flags that persist through to children commands
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## 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
|
||||
Using Cobra is easy. First, use `go get` to install the latest version
|
||||
of the library. This command will install the `cobra` generator executible
|
||||
along with the library:
|
||||
of the library. This command will install the `cobra` generator executable
|
||||
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:
|
||||
|
||||
@ -139,8 +132,8 @@ import "github.com/spf13/cobra"
|
||||
|
||||
# Getting Started
|
||||
|
||||
While you are welcome to provide your own organization, typically a Cobra based
|
||||
application will follow the following organizational structure.
|
||||
While you are welcome to provide your own organization, typically a Cobra-based
|
||||
application will follow the following organizational structure:
|
||||
|
||||
```
|
||||
▾ appName/
|
||||
@ -152,17 +145,22 @@ application will follow the following organizational structure.
|
||||
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
|
||||
package main
|
||||
|
||||
import "{pathToYourApp}/cmd"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"{pathToYourApp}/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := cmd.RootCmd.Execute(); err != nil {
|
||||
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
|
||||
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!
|
||||
|
||||
### 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.
|
||||
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.
|
||||
|
||||
### Create the root command
|
||||
|
||||
The root command represents your binary itself.
|
||||
|
||||
|
||||
#### Manually create rootCmd
|
||||
### Create rootCmd
|
||||
|
||||
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.
|
||||
|
||||
for example cmd/root.go:
|
||||
For example cmd/root.go:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
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("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
|
||||
@ -313,17 +259,21 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose,
|
||||
```go
|
||||
package main
|
||||
|
||||
import "{pathToYourApp}/cmd"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"{pathToYourApp}/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := cmd.RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(-1)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Create additional commands
|
||||
|
||||
Additional commands can be defined and typically are each given their own file
|
||||
@ -337,6 +287,7 @@ package cmd
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
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")
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
@ -435,15 +427,14 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var echoTimes int
|
||||
|
||||
var cmdPrint = &cobra.Command{
|
||||
Use: "print [string to print]",
|
||||
Short: "Print anything 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) {
|
||||
fmt.Println("Print: " + strings.Join(args, " "))
|
||||
},
|
||||
@ -453,8 +444,8 @@ func main() {
|
||||
Use: "echo [string to echo]",
|
||||
Short: "Echo anything to the screen",
|
||||
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) {
|
||||
fmt.Println("Print: " + strings.Join(args, " "))
|
||||
},
|
||||
@ -465,6 +456,7 @@ func main() {
|
||||
Short: "Echo anything to the screen more times",
|
||||
Long: `echo things multiple times back to the user by providing
|
||||
a count and a string.`,
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
for i := 0; i < echoTimes; i++ {
|
||||
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/).
|
||||
|
||||
## The Help Command
|
||||
## Help Command
|
||||
|
||||
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
|
||||
@ -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
|
||||
command and flag definitions are needed.
|
||||
|
||||
> hugo help
|
||||
$ cobra help
|
||||
|
||||
hugo is the main command, used to build your Hugo site.
|
||||
|
||||
Hugo is a Fast and Flexible Static Site Generator
|
||||
built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at http://gohugo.io/.
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.
|
||||
|
||||
Usage:
|
||||
hugo [flags]
|
||||
hugo [command]
|
||||
cobra [command]
|
||||
|
||||
Available Commands:
|
||||
server Hugo runs its own webserver to render the files
|
||||
version Print the version number of Hugo
|
||||
config Print the site configuration
|
||||
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.
|
||||
add Add a command to a Cobra Application
|
||||
help Help about any command
|
||||
init Initialize a Cobra Application
|
||||
|
||||
Flags:
|
||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts[=false]: include content marked as draft
|
||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
||||
--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
|
||||
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||
--config string config file (default is $HOME/.cobra.yaml)
|
||||
-h, --help help for cobra
|
||||
-l, --license string name of license for the project
|
||||
--viper use Viper for configuration (default true)
|
||||
|
||||
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
|
||||
@ -557,38 +517,18 @@ around it. In fact, you can provide your own if you want.
|
||||
|
||||
### Defining your own help
|
||||
|
||||
You can provide your own Help command or your own template for the default command to use.
|
||||
|
||||
The default help command is
|
||||
You can provide your own Help command or your own template for the default command to use
|
||||
with following functions:
|
||||
|
||||
```go
|
||||
func (c *Command) initHelp() {
|
||||
if c.helpCommand == nil {
|
||||
c.helpCommand = &Command{
|
||||
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)
|
||||
cmd.SetHelpCommand(cmd *Command)
|
||||
cmd.SetHelpFunc(f func(*Command, []string))
|
||||
cmd.SetHelpTemplate(s string)
|
||||
```
|
||||
|
||||
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
|
||||
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
|
||||
embeds the usage as part of its output.
|
||||
|
||||
$ cobra --invalid
|
||||
Error: unknown flag: --invalid
|
||||
Usage:
|
||||
hugo [flags]
|
||||
hugo [command]
|
||||
cobra [command]
|
||||
|
||||
Available Commands:
|
||||
server Hugo runs its own webserver to render the files
|
||||
version Print the version number of Hugo
|
||||
config Print the site configuration
|
||||
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.
|
||||
add Add a command to a Cobra Application
|
||||
help Help about any command
|
||||
init Initialize a Cobra Application
|
||||
|
||||
Flags:
|
||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts[=false]: include content marked as draft
|
||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
||||
--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
|
||||
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||
--config string config file (default is $HOME/.cobra.yaml)
|
||||
-h, --help help for cobra
|
||||
-l, --license string name of license for the project
|
||||
--viper use Viper for configuration (default true)
|
||||
|
||||
Use "cobra [command] --help" for more information about a command.
|
||||
|
||||
### Defining your own usage
|
||||
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:
|
||||
|
||||
```go
|
||||
command.SetUsageFunc(f func(*Command) error)
|
||||
|
||||
command.SetUsageTemplate(s string)
|
||||
cmd.SetUsageFunc(f func(*Command) error)
|
||||
cmd.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`
|
||||
- `PreRun`
|
||||
@ -724,58 +628,26 @@ func main() {
|
||||
rootCmd.AddCommand(subCmd)
|
||||
|
||||
rootCmd.SetArgs([]string{""})
|
||||
_ = rootCmd.Execute()
|
||||
fmt.Print("\n")
|
||||
rootCmd.Execute()
|
||||
fmt.Println()
|
||||
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
|
||||
|
||||
Cobra also has functions where the return signature is an error. This allows for errors to bubble up to the top,
|
||||
providing a way to handle the errors in one location. The current list of functions that return an error is:
|
||||
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
|
||||
Inside subCmd PreRun with args: [arg1 arg2]
|
||||
Inside subCmd Run with args: [arg1 arg2]
|
||||
Inside subCmd PostRun with args: [arg1 arg2]
|
||||
Inside subCmd PersistentPostRun with args: [arg1 arg2]
|
||||
```
|
||||
|
||||
## Suggestions when "unknown command" happens
|
||||
@ -818,81 +690,28 @@ Did you mean this?
|
||||
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 for your command
|
||||
## Generating bash completions
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
# Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
|
||||
3. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
4. Make changes and add them (`git add .`)
|
||||
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
|
||||
|
||||
Names in no particular order:
|
||||
|
||||
* [spf13](https://github.com/spf13),
|
||||
[eparis](https://github.com/eparis),
|
||||
[bep](https://github.com/bep), and many more!
|
||||
|
||||
## License
|
||||
# License
|
||||
|
||||
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -10,19 +11,17 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// Annotations for Bash completion.
|
||||
const (
|
||||
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extentions"
|
||||
BashCompFilenameExt = "cobra_annotation_bash_completion_filename_extensions"
|
||||
BashCompCustom = "cobra_annotation_bash_completion_custom"
|
||||
BashCompOneRequiredFlag = "cobra_annotation_bash_completion_one_required_flag"
|
||||
BashCompSubdirsInDir = "cobra_annotation_bash_completion_subdirs_in_dir"
|
||||
)
|
||||
|
||||
func preamble(out io.Writer, name string) error {
|
||||
_, err := fmt.Fprintf(out, "# bash completion for %-36s -*- shell-script -*-\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprint(out, `
|
||||
func writePreamble(buf *bytes.Buffer, name string) {
|
||||
buf.WriteString(fmt.Sprintf("# bash completion for %-36s -*- shell-script -*-\n", name))
|
||||
buf.WriteString(`
|
||||
__debug()
|
||||
{
|
||||
if [[ -n ${BASH_COMP_DEBUG_FILE} ]]; then
|
||||
@ -87,13 +86,13 @@ __handle_reply()
|
||||
local index flag
|
||||
flag="${cur%%=*}"
|
||||
__index_of_word "${flag}" "${flags_with_completion[@]}"
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
COMPREPLY=()
|
||||
if [[ ${index} -ge 0 ]]; then
|
||||
PREFIX=""
|
||||
cur="${cur#*=}"
|
||||
${flags_completion[${index}]}
|
||||
if [ -n "${ZSH_VERSION}" ]; then
|
||||
# zfs completion needs --flag= prefix
|
||||
# zsh completion needs --flag= prefix
|
||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||
fi
|
||||
fi
|
||||
@ -133,7 +132,10 @@ __handle_reply()
|
||||
declare -F __custom_func >/dev/null && __custom_func
|
||||
fi
|
||||
|
||||
# available in bash-completion >= 2, not always present on macOS
|
||||
if declare -F __ltrim_colon_completions >/dev/null; then
|
||||
__ltrim_colon_completions "$cur"
|
||||
fi
|
||||
}
|
||||
|
||||
# The arguments should be in the form "ext1|ext2|extn"
|
||||
@ -224,7 +226,7 @@ __handle_command()
|
||||
fi
|
||||
c=$((c+1))
|
||||
__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()
|
||||
@ -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)
|
||||
_, err := fmt.Fprintf(w, "__start_%s()\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, `{
|
||||
buf.WriteString(fmt.Sprintf("__start_%s()\n", name))
|
||||
buf.WriteString(fmt.Sprintf(`{
|
||||
local cur prev words cword
|
||||
declare -A flaghash 2>/dev/null || :
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
@ -280,318 +278,227 @@ func postscript(w io.Writer, name string) error {
|
||||
__handle_word
|
||||
}
|
||||
|
||||
`, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, `if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
`, name))
|
||||
buf.WriteString(fmt.Sprintf(`if [[ $(type -t compopt) = "builtin" ]]; then
|
||||
complete -o default -F __start_%s %s
|
||||
else
|
||||
complete -o default -o nospace -F __start_%s %s
|
||||
fi
|
||||
|
||||
`, name, name, name, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = fmt.Fprintf(w, "# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
return err
|
||||
`, name, name, name, name))
|
||||
buf.WriteString("# ex: ts=4 sw=4 et filetype=sh\n")
|
||||
}
|
||||
|
||||
func writeCommands(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " commands=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeCommands(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" commands=()\n")
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||
continue
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, " commands+=(%q)\n", c.Name()); err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name()))
|
||||
}
|
||||
}
|
||||
_, err := fmt.Fprintf(w, "\n")
|
||||
return err
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
|
||||
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 {
|
||||
switch key {
|
||||
case BashCompFilenameExt:
|
||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
|
||||
var ext string
|
||||
if len(value) > 0 {
|
||||
ext := "__handle_filename_extension_flag " + strings.Join(value, "|")
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
ext = "__handle_filename_extension_flag " + strings.Join(value, "|")
|
||||
} else {
|
||||
ext := "_filedir"
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
ext = "_filedir"
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
case BashCompCustom:
|
||||
_, err := fmt.Fprintf(w, " flags_with_completion+=(%q)\n", name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" flags_with_completion+=(%q)\n", name))
|
||||
if len(value) > 0 {
|
||||
handlers := strings.Join(value, "; ")
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", handlers)
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", handlers))
|
||||
} else {
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(:)\n")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
buf.WriteString(" flags_completion+=(:)\n")
|
||||
}
|
||||
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 {
|
||||
ext := "__handle_subdirs_in_dir_flag " + value[0]
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
ext = "__handle_subdirs_in_dir_flag " + value[0]
|
||||
} else {
|
||||
ext := "_filedir -d"
|
||||
_, err = fmt.Fprintf(w, " flags_completion+=(%q)\n", ext)
|
||||
ext = "_filedir -d"
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf(" flags_completion+=(%q)\n", ext))
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeShortFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeShortFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||
name := flag.Shorthand
|
||||
format := " "
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "two_word_"
|
||||
}
|
||||
format += "flags+=(\"-%s\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeFlagHandler("-"+name, flag.Annotations, w)
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
writeFlagHandler(buf, "-"+name, flag.Annotations)
|
||||
}
|
||||
|
||||
func writeFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||
name := flag.Name
|
||||
format := " flags+=(\"--%s"
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return writeFlagHandler("--"+name, flag.Annotations, w)
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
writeFlagHandler(buf, "--"+name, flag.Annotations)
|
||||
}
|
||||
|
||||
func writeLocalNonPersistentFlag(flag *pflag.Flag, w io.Writer) error {
|
||||
b := (len(flag.NoOptDefVal) > 0)
|
||||
func writeLocalNonPersistentFlag(buf *bytes.Buffer, flag *pflag.Flag) {
|
||||
name := flag.Name
|
||||
format := " local_nonpersistent_flags+=(\"--%s"
|
||||
if !b {
|
||||
if len(flag.NoOptDefVal) == 0 {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, name); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
buf.WriteString(fmt.Sprintf(format, name))
|
||||
}
|
||||
|
||||
func writeFlags(cmd *Command, w io.Writer) error {
|
||||
_, err := fmt.Fprintf(w, ` flags=()
|
||||
func writeFlags(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(` flags=()
|
||||
two_word_flags=()
|
||||
local_nonpersistent_flags=()
|
||||
flags_with_completion=()
|
||||
flags_completion=()
|
||||
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
localNonPersistentFlags := cmd.LocalNonPersistentFlags()
|
||||
var visitErr error
|
||||
cmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||
if err := writeFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
writeFlag(buf, flag)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if err := writeShortFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeShortFlag(buf, flag)
|
||||
}
|
||||
if localNonPersistentFlags.Lookup(flag.Name) != nil {
|
||||
if err := writeLocalNonPersistentFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeLocalNonPersistentFlag(buf, flag)
|
||||
}
|
||||
})
|
||||
if visitErr != nil {
|
||||
return visitErr
|
||||
}
|
||||
cmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
|
||||
if err := writeFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
writeFlag(buf, flag)
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if err := writeShortFlag(flag, w); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
writeShortFlag(buf, flag)
|
||||
}
|
||||
})
|
||||
if visitErr != nil {
|
||||
return visitErr
|
||||
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
|
||||
_, err = fmt.Fprintf(w, "\n")
|
||||
return err
|
||||
}
|
||||
|
||||
func writeRequiredFlag(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_flag=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeRequiredFlag(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_flag=()\n")
|
||||
flags := cmd.NonInheritedFlags()
|
||||
var visitErr error
|
||||
flags.VisitAll(func(flag *pflag.Flag) {
|
||||
if nonCompletableFlag(flag) {
|
||||
return
|
||||
}
|
||||
for key := range flag.Annotations {
|
||||
switch key {
|
||||
case BashCompOneRequiredFlag:
|
||||
format := " must_have_one_flag+=(\"--%s"
|
||||
b := (flag.Value.Type() == "bool")
|
||||
if !b {
|
||||
if flag.Value.Type() != "bool" {
|
||||
format += "="
|
||||
}
|
||||
format += "\")\n"
|
||||
if _, err := fmt.Fprintf(w, format, flag.Name); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(format, flag.Name))
|
||||
|
||||
if len(flag.Shorthand) > 0 {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_flag+=(\"-%s\")\n", flag.Shorthand); err != nil {
|
||||
visitErr = err
|
||||
return
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_flag+=(\"-%s\")\n", flag.Shorthand))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return visitErr
|
||||
}
|
||||
|
||||
func writeRequiredNouns(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_noun=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" must_have_one_noun=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ValidArgs))
|
||||
for _, value := range cmd.ValidArgs {
|
||||
if _, err := fmt.Fprintf(w, " must_have_one_noun+=(%q)\n", value); err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf(" must_have_one_noun+=(%q)\n", value))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeArgAliases(cmd *Command, w io.Writer) error {
|
||||
if _, err := fmt.Fprintf(w, " noun_aliases=()\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
func writeArgAliases(buf *bytes.Buffer, cmd *Command) {
|
||||
buf.WriteString(" noun_aliases=()\n")
|
||||
sort.Sort(sort.StringSlice(cmd.ArgAliases))
|
||||
for _, value := range cmd.ArgAliases {
|
||||
if _, err := fmt.Fprintf(w, " noun_aliases+=(%q)\n", value); err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf(" noun_aliases+=(%q)\n", value))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func gen(cmd *Command, w io.Writer) error {
|
||||
func gen(buf *bytes.Buffer, cmd *Command) {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c == cmd.helpCommand {
|
||||
continue
|
||||
}
|
||||
if err := gen(c, w); err != nil {
|
||||
return err
|
||||
}
|
||||
gen(buf, c)
|
||||
}
|
||||
commandName := cmd.CommandPath()
|
||||
commandName = strings.Replace(commandName, " ", "_", -1)
|
||||
commandName = strings.Replace(commandName, ":", "__", -1)
|
||||
if _, err := fmt.Fprintf(w, "_%s()\n{\n", commandName); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, " last_command=%q\n", commandName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := writeCommands(cmd, w); err != nil {
|
||||
return err
|
||||
}
|
||||
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
|
||||
buf.WriteString(fmt.Sprintf("_%s()\n{\n", commandName))
|
||||
buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName))
|
||||
writeCommands(buf, cmd)
|
||||
writeFlags(buf, cmd)
|
||||
writeRequiredFlag(buf, cmd)
|
||||
writeRequiredNouns(buf, cmd)
|
||||
writeArgAliases(buf, cmd)
|
||||
buf.WriteString("}\n\n")
|
||||
}
|
||||
|
||||
func (cmd *Command) GenBashCompletion(w io.Writer) error {
|
||||
if err := preamble(w, cmd.Name()); err != nil {
|
||||
// GenBashCompletion generates bash completion file and writes to the passed writer.
|
||||
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
|
||||
}
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer outFile.Close()
|
||||
|
||||
return cmd.GenBashCompletion(outFile)
|
||||
return c.GenBashCompletion(outFile)
|
||||
}
|
||||
|
||||
// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag, if it exists.
|
||||
func (cmd *Command) MarkFlagRequired(name string) error {
|
||||
return MarkFlagRequired(cmd.Flags(), name)
|
||||
func (c *Command) MarkFlagRequired(name string) error {
|
||||
return MarkFlagRequired(c.Flags(), name)
|
||||
}
|
||||
|
||||
// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag, if it exists.
|
||||
func (cmd *Command) MarkPersistentFlagRequired(name string) error {
|
||||
return MarkFlagRequired(cmd.PersistentFlags(), name)
|
||||
func (c *Command) MarkPersistentFlagRequired(name string) error {
|
||||
return MarkFlagRequired(c.PersistentFlags(), name)
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided.
|
||||
func (cmd *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(cmd.Flags(), name, extensions...)
|
||||
func (c *Command) MarkFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(c.Flags(), name, extensions...)
|
||||
}
|
||||
|
||||
// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists.
|
||||
// Generated bash autocompletion will call the bash function f for the flag.
|
||||
func (cmd *Command) MarkFlagCustom(name string, f string) error {
|
||||
return MarkFlagCustom(cmd.Flags(), name, f)
|
||||
func (c *Command) MarkFlagCustom(name string, f string) error {
|
||||
return MarkFlagCustom(c.Flags(), name, f)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (cmd *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(cmd.PersistentFlags(), name, extensions...)
|
||||
func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error {
|
||||
return MarkFlagFilename(c.PersistentFlags(), name, extensions...)
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
@ -106,7 +106,7 @@ node pod replicationcontroller service
|
||||
|
||||
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" }
|
||||
|
||||
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{
|
||||
"trim": strings.TrimSpace,
|
||||
"trimRightSpace": trimRightSpace,
|
||||
"trimTrailingWhitespaces": trimRightSpace,
|
||||
"appendIfNotPresent": appendIfNotPresent,
|
||||
"rpad": rpad,
|
||||
"gt": Gt,
|
||||
@ -37,21 +38,31 @@ var templateFuncs = template.FuncMap{
|
||||
|
||||
var initializers []func()
|
||||
|
||||
// automatic prefix matching can be a dangerous thing to automatically enable in CLI tools.
|
||||
// Set this to true to enable it
|
||||
// EnablePrefixMatching allows to set automatic prefix matching. Automatic prefix matching can be a dangerous thing
|
||||
// to automatically enable in CLI tools.
|
||||
// Set this to true to enable it.
|
||||
var EnablePrefixMatching = false
|
||||
|
||||
// EnableCommandSorting controls sorting of the slice of commands, which is turned on by default.
|
||||
// To disable sorting, set it to false.
|
||||
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
|
||||
// template generation.
|
||||
func AddTemplateFunc(name string, tmplFunc interface{}) {
|
||||
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.
|
||||
func AddTemplateFuncs(tmplFuncs template.FuncMap) {
|
||||
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().
|
||||
func OnInitialize(y ...func()) {
|
||||
for _, x := range y {
|
||||
initializers = append(initializers, x)
|
||||
}
|
||||
initializers = append(initializers, y...)
|
||||
}
|
||||
|
||||
// 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,
|
||||
// Maps and Slices, Gt will compare their lengths. Ints are compared directly while strings are first parsed as
|
||||
// ints and then compared.
|
||||
@ -96,6 +107,8 @@ func Gt(a interface{}, b interface{}) bool {
|
||||
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.
|
||||
func Eq(a interface{}, b interface{}) bool {
|
||||
av := reflect.ValueOf(a)
|
||||
@ -116,7 +129,9 @@ func trimRightSpace(s string) string {
|
||||
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 {
|
||||
if strings.Contains(s, stringToAppend) {
|
||||
return s
|
||||
@ -124,7 +139,7 @@ func appendIfNotPresent(s, stringToAppend string) string {
|
||||
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 {
|
||||
template := fmt.Sprintf("%%-%ds", padding)
|
||||
return fmt.Sprintf(template, s)
|
||||
@ -138,7 +153,7 @@ func tmpl(w io.Writer, text string, data interface{}) error {
|
||||
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 {
|
||||
if ignoreCase {
|
||||
s = strings.ToLower(s)
|
||||
@ -173,3 +188,12 @@ func ld(s, t string, ignoreCase bool) int {
|
||||
}
|
||||
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
|
||||
|
||||
// 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) {
|
||||
if mousetrap.StartedByExplorer() {
|
||||
if MousetrapHelpText != "" && mousetrap.StartedByExplorer() {
|
||||
c.Print(MousetrapHelpText)
|
||||
time.Sleep(5 * time.Second)
|
||||
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 = [
|
||||
"man_docs.go",
|
||||
"md_docs.go",
|
||||
"rest_docs.go",
|
||||
"util.go",
|
||||
"yaml_docs.go",
|
||||
],
|
||||
importpath = "github.com/spf13/cobra/doc",
|
||||
visibility = ["//visibility:public"],
|
||||
@ -13,6 +15,7 @@ go_library(
|
||||
"//vendor/github.com/cpuguy83/go-md2man/md2man:go_default_library",
|
||||
"//vendor/github.com/spf13/cobra: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"
|
||||
"time"
|
||||
|
||||
mangen "github.com/cpuguy83/go-md2man/md2man"
|
||||
"github.com/cpuguy83/go-md2man/md2man"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
// 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
|
||||
// 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`
|
||||
// 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 GenManTree(cmd *cobra.Command, header *GenManHeader, dir string) error {
|
||||
return GenManTreeFromOpts(cmd, GenManTreeOptions{
|
||||
Header: header,
|
||||
Path: dir,
|
||||
CommandSeparator: "_",
|
||||
CommandSeparator: "-",
|
||||
})
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error {
|
||||
header = &GenManHeader{}
|
||||
}
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
if err := GenManTreeFromOpts(c, opts); err != nil {
|
||||
@ -77,6 +77,8 @@ func GenManTreeFromOpts(cmd *cobra.Command, opts GenManTreeOptions) error {
|
||||
return GenMan(cmd, &headerCopy, f)
|
||||
}
|
||||
|
||||
// GenManTreeOptions is the options for generating the man pages.
|
||||
// Used only in GenManTreeFromOpts.
|
||||
type GenManTreeOptions struct {
|
||||
Header *GenManHeader
|
||||
Path string
|
||||
@ -105,7 +107,7 @@ func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error {
|
||||
fillHeader(header, cmd.CommandPath())
|
||||
|
||||
b := genMan(cmd, header)
|
||||
_, err := w.Write(mangen.Render(b))
|
||||
_, err := w.Write(md2man.Render(b))
|
||||
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
|
||||
if len(description) == 0 {
|
||||
description = cmd.Short
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, `%% %s(%s)%s
|
||||
buf.WriteString(fmt.Sprintf(`%% %s(%s)%s
|
||||
%% %s
|
||||
%% %s
|
||||
# NAME
|
||||
`, header.Title, header.Section, header.date, header.Source, header.Manual)
|
||||
fmt.Fprintf(out, "%s \\- %s\n\n", dashedName, cmd.Short)
|
||||
fmt.Fprintf(out, "# SYNOPSIS\n")
|
||||
fmt.Fprintf(out, "**%s**\n\n", cmd.UseLine())
|
||||
fmt.Fprintf(out, "# DESCRIPTION\n")
|
||||
fmt.Fprintf(out, "%s\n\n", description)
|
||||
`, header.Title, header.Section, header.date, header.Source, header.Manual))
|
||||
buf.WriteString(fmt.Sprintf("%s \\- %s\n\n", dashedName, cmd.Short))
|
||||
buf.WriteString("# SYNOPSIS\n")
|
||||
buf.WriteString(fmt.Sprintf("**%s**\n\n", cmd.UseLine()))
|
||||
buf.WriteString("# DESCRIPTION\n")
|
||||
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) {
|
||||
if len(flag.Deprecated) > 0 || flag.Hidden {
|
||||
return
|
||||
@ -156,38 +158,41 @@ func manPrintFlags(out io.Writer, flags *pflag.FlagSet) {
|
||||
format = fmt.Sprintf("**--%s**", flag.Name)
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
format = format + "["
|
||||
format += "["
|
||||
}
|
||||
if flag.Value.Type() == "string" {
|
||||
// put quotes on the value
|
||||
format = format + "=%q"
|
||||
format += "=%q"
|
||||
} else {
|
||||
format = format + "=%s"
|
||||
format += "=%s"
|
||||
}
|
||||
if len(flag.NoOptDefVal) > 0 {
|
||||
format = format + "]"
|
||||
format += "]"
|
||||
}
|
||||
format = format + "\n\t%s\n\n"
|
||||
fmt.Fprintf(out, format, flag.DefValue, flag.Usage)
|
||||
format += "\n\t%s\n\n"
|
||||
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()
|
||||
if flags.HasFlags() {
|
||||
fmt.Fprintf(out, "# OPTIONS\n")
|
||||
manPrintFlags(out, flags)
|
||||
fmt.Fprintf(out, "\n")
|
||||
buf.WriteString("# OPTIONS\n")
|
||||
manPrintFlags(buf, flags)
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
flags = command.InheritedFlags()
|
||||
if flags.HasFlags() {
|
||||
fmt.Fprintf(out, "# OPTIONS INHERITED FROM PARENT COMMANDS\n")
|
||||
manPrintFlags(out, flags)
|
||||
fmt.Fprintf(out, "\n")
|
||||
buf.WriteString("# OPTIONS INHERITED FROM PARENT COMMANDS\n")
|
||||
manPrintFlags(buf, flags)
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
||||
cmd.InitDefaultHelpCmd()
|
||||
cmd.InitDefaultHelpFlag()
|
||||
|
||||
// something like `rootcmd-subcmd1-subcmd2`
|
||||
dashCommandName := strings.Replace(cmd.CommandPath(), " ", "-", -1)
|
||||
|
||||
@ -196,11 +201,11 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
||||
manPreamble(buf, header, cmd, dashCommandName)
|
||||
manPrintOptions(buf, cmd)
|
||||
if len(cmd.Example) > 0 {
|
||||
fmt.Fprintf(buf, "# EXAMPLE\n")
|
||||
fmt.Fprintf(buf, "```\n%s\n```\n", cmd.Example)
|
||||
buf.WriteString("# EXAMPLE\n")
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n", cmd.Example))
|
||||
}
|
||||
if hasSeeAlso(cmd) {
|
||||
fmt.Fprintf(buf, "# SEE ALSO\n")
|
||||
buf.WriteString("# SEE ALSO\n")
|
||||
seealsos := make([]string, 0)
|
||||
if cmd.HasParent() {
|
||||
parentPath := cmd.Parent().CommandPath()
|
||||
@ -216,16 +221,16 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
|
||||
children := cmd.Commands()
|
||||
sort.Sort(byName(children))
|
||||
for _, c := range children {
|
||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
|
||||
seealsos = append(seealsos, seealso)
|
||||
}
|
||||
fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", "))
|
||||
buf.WriteString(strings.Join(seealsos, ", ") + "\n")
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/cobra/doc"
|
||||
)
|
||||
@ -15,12 +17,15 @@ func main() {
|
||||
Use: "test",
|
||||
Short: "my test program",
|
||||
}
|
||||
header := &cobra.GenManHeader{
|
||||
header := &doc.GenManHeader{
|
||||
Title: "MINE",
|
||||
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
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@ -25,38 +26,36 @@ import (
|
||||
"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.SetOutput(w)
|
||||
flags.SetOutput(buf)
|
||||
if flags.HasFlags() {
|
||||
if _, err := fmt.Fprintf(w, "### Options\n\n```\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("### Options\n\n```\n")
|
||||
flags.PrintDefaults()
|
||||
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("```\n\n")
|
||||
}
|
||||
|
||||
parentFlags := cmd.InheritedFlags()
|
||||
parentFlags.SetOutput(w)
|
||||
parentFlags.SetOutput(buf)
|
||||
if parentFlags.HasFlags() {
|
||||
if _, err := fmt.Fprintf(w, "### Options inherited from parent commands\n\n```\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("### Options inherited from parent commands\n\n```\n")
|
||||
parentFlags.PrintDefaults()
|
||||
if _, err := fmt.Fprintf(w, "```\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("```\n\n")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenMarkdown creates markdown output.
|
||||
func GenMarkdown(cmd *cobra.Command, w io.Writer) error {
|
||||
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 {
|
||||
cmd.InitDefaultHelpCmd()
|
||||
cmd.InitDefaultHelpFlag()
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
name := cmd.CommandPath()
|
||||
|
||||
short := cmd.Short
|
||||
@ -65,49 +64,31 @@ func GenMarkdownCustom(cmd *cobra.Command, w io.Writer, linkHandler func(string)
|
||||
long = short
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "## %s\n\n", name); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "%s\n\n", short); err != nil {
|
||||
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
|
||||
}
|
||||
buf.WriteString("## " + name + "\n\n")
|
||||
buf.WriteString(short + "\n\n")
|
||||
buf.WriteString("### Synopsis\n\n")
|
||||
buf.WriteString("\n" + long + "\n\n")
|
||||
|
||||
if cmd.Runnable() {
|
||||
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.UseLine()); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.UseLine()))
|
||||
}
|
||||
|
||||
if len(cmd.Example) > 0 {
|
||||
if _, err := fmt.Fprintf(w, "### Examples\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "```\n%s\n```\n\n", cmd.Example); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("### Examples\n\n")
|
||||
buf.WriteString(fmt.Sprintf("```\n%s\n```\n\n", cmd.Example))
|
||||
}
|
||||
|
||||
if err := printOptions(w, cmd, name); err != nil {
|
||||
if err := printOptions(buf, cmd, name); err != nil {
|
||||
return err
|
||||
}
|
||||
if hasSeeAlso(cmd) {
|
||||
if _, err := fmt.Fprintf(w, "### SEE ALSO\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString("### SEE ALSO\n")
|
||||
if cmd.HasParent() {
|
||||
parent := cmd.Parent()
|
||||
pname := parent.CommandPath()
|
||||
link := pname + ".md"
|
||||
link = strings.Replace(link, " ", "_", -1)
|
||||
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short); err != nil {
|
||||
return err
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", pname, linkHandler(link), parent.Short))
|
||||
cmd.VisitParents(func(c *cobra.Command) {
|
||||
if 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))
|
||||
|
||||
for _, child := range children {
|
||||
if !child.IsAvailableCommand() || child.IsHelpCommand() {
|
||||
if !child.IsAvailableCommand() || child.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
cname := name + " " + child.Name()
|
||||
link := cname + ".md"
|
||||
link = strings.Replace(link, " ", "_", -1)
|
||||
if _, err := fmt.Fprintf(w, "* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if _, err := fmt.Fprintf(w, "\n"); err != nil {
|
||||
return err
|
||||
buf.WriteString(fmt.Sprintf("* [%s](%s)\t - %s\n", cname, linkHandler(link), child.Short))
|
||||
}
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
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 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 {
|
||||
identity := func(s string) string { return s }
|
||||
emptyStr := func(s string) string { return "" }
|
||||
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 {
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/cobra/doc"
|
||||
)
|
||||
@ -15,7 +17,10 @@ func main() {
|
||||
Use: "test",
|
||||
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
|
||||
|
||||
import (
|
||||
"log"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
kubectlcmd "k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
|
||||
"github.com/spf13/cobra/doc"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cmd := kubectlcmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
doc.GenMarkdownTree(cmd, "./")
|
||||
kubectl := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, ioutil.Discard, ioutil.Discard)
|
||||
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
|
||||
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.
|
||||
@ -101,4 +113,3 @@ linkHandler := func(name string) string {
|
||||
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
|
||||
|
||||
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
|
||||
// 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
|
||||
}
|
||||
for _, c := range cmd.Commands() {
|
||||
if !c.IsAvailableCommand() || c.IsHelpCommand() {
|
||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
||||
continue
|
||||
}
|
||||
return true
|
||||
@ -31,6 +35,15 @@ func hasSeeAlso(cmd *cobra.Command) bool {
|
||||
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
|
||||
|
||||
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