mirror of
https://github.com/restic/rest-server.git
synced 2025-12-07 09:36:13 -08:00
Update dependencies
This commit is contained in:
2
Gopkg.lock
generated
2
Gopkg.lock
generated
@@ -18,7 +18,7 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/spf13/cobra"
|
name = "github.com/spf13/cobra"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "0dacccfbaabc71b872087c1719c5380d3e185173"
|
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/spf13/pflag"
|
name = "github.com/spf13/pflag"
|
||||||
|
|||||||
427
vendor/github.com/spf13/cobra/README.md
generated
vendored
427
vendor/github.com/spf13/cobra/README.md
generated
vendored
@@ -19,13 +19,33 @@ Many of the most widely used Go projects are built using Cobra including:
|
|||||||
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
|
* [GiantSwarm's swarm](https://github.com/giantswarm/cli)
|
||||||
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
|
* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack)
|
||||||
* [rclone](http://rclone.org/)
|
* [rclone](http://rclone.org/)
|
||||||
|
* [nehm](https://github.com/bogem/nehm)
|
||||||
|
|
||||||
[](https://travis-ci.org/spf13/cobra)
|
[](https://travis-ci.org/spf13/cobra)
|
||||||
[](https://circleci.com/gh/spf13/cobra)
|
[](https://circleci.com/gh/spf13/cobra)
|
||||||
[](https://godoc.org/github.com/spf13/cobra)
|
[](https://godoc.org/github.com/spf13/cobra)
|
||||||
|
|
||||||

|
# Table of Contents
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [Concepts](#concepts)
|
||||||
|
* [Commands](#commands)
|
||||||
|
* [Flags](#flags)
|
||||||
|
- [Installing](#installing)
|
||||||
|
- [Getting Started](#getting-started)
|
||||||
|
* [Using the Cobra Generator](#using-the-cobra-generator)
|
||||||
|
* [Using the Cobra Library](#using-the-cobra-library)
|
||||||
|
* [Working with Flags](#working-with-flags)
|
||||||
|
* [Positional and Custom Arguments](#positional-and-custom-arguments)
|
||||||
|
* [Example](#example)
|
||||||
|
* [Help Command](#help-command)
|
||||||
|
* [Usage Message](#usage-message)
|
||||||
|
* [PreRun and PostRun Hooks](#prerun-and-postrun-hooks)
|
||||||
|
* [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens)
|
||||||
|
* [Generating documentation for your command](#generating-documentation-for-your-command)
|
||||||
|
* [Generating bash completions](#generating-bash-completions)
|
||||||
|
- [Contributing](#contributing)
|
||||||
|
- [License](#license)
|
||||||
|
|
||||||
# Overview
|
# Overview
|
||||||
|
|
||||||
@@ -43,7 +63,6 @@ Cobra provides:
|
|||||||
* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
|
* Easy generation of applications & commands with `cobra init appname` & `cobra add cmdname`
|
||||||
* Intelligent suggestions (`app srver`... did you mean `app server`?)
|
* Intelligent suggestions (`app srver`... did you mean `app server`?)
|
||||||
* Automatic help generation for commands and flags
|
* Automatic help generation for commands and flags
|
||||||
* Automatic detailed help for `app help [command]`
|
|
||||||
* Automatic help flag recognition of `-h`, `--help`, etc.
|
* Automatic help flag recognition of `-h`, `--help`, etc.
|
||||||
* Automatically generated bash autocomplete for your application
|
* Automatically generated bash autocomplete for your application
|
||||||
* Automatically generated man pages for your application
|
* Automatically generated man pages for your application
|
||||||
@@ -51,16 +70,6 @@ Cobra provides:
|
|||||||
* The flexibility to define your own help, usage, etc.
|
* The flexibility to define your own help, usage, etc.
|
||||||
* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
|
* Optional tight integration with [viper](http://github.com/spf13/viper) for 12-factor apps
|
||||||
|
|
||||||
Cobra has an exceptionally clean interface and simple design without needless
|
|
||||||
constructors or initialization methods.
|
|
||||||
|
|
||||||
Applications built with Cobra commands are designed to be as user-friendly as
|
|
||||||
possible. Flags can be placed before or after the command (as long as a
|
|
||||||
confusing space isn’t provided). Both short and long flags can be used. A
|
|
||||||
command need not even be fully typed. Help is automatically generated and
|
|
||||||
available for the application or for a specific command using either the help
|
|
||||||
command or the `--help` flag.
|
|
||||||
|
|
||||||
# Concepts
|
# Concepts
|
||||||
|
|
||||||
Cobra is built on a structure of commands, arguments & flags.
|
Cobra is built on a structure of commands, arguments & flags.
|
||||||
@@ -93,20 +102,11 @@ have children commands and optionally run an action.
|
|||||||
|
|
||||||
In the example above, 'server' is the command.
|
In the example above, 'server' is the command.
|
||||||
|
|
||||||
A Command has the following structure:
|
[More about cobra.Command](https://godoc.org/github.com/spf13/cobra#Command)
|
||||||
|
|
||||||
```go
|
|
||||||
type Command struct {
|
|
||||||
Use string // The one-line usage message.
|
|
||||||
Short string // The short description shown in the 'help' output.
|
|
||||||
Long string // The long message shown in the 'help <this-command>' output.
|
|
||||||
Run func(cmd *Command, args []string) // Run runs the command.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
A Flag is a way to modify the behavior of a command. Cobra supports
|
A flag is a way to modify the behavior of a command. Cobra supports
|
||||||
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
|
fully POSIX-compliant flags as well as the Go [flag package](https://golang.org/pkg/flag/).
|
||||||
A Cobra command can define flags that persist through to children commands
|
A Cobra command can define flags that persist through to children commands
|
||||||
and flags that are only available to that command.
|
and flags that are only available to that command.
|
||||||
@@ -170,106 +170,14 @@ func main() {
|
|||||||
Cobra provides its own program that will create your application and add any
|
Cobra provides its own program that will create your application and add any
|
||||||
commands you want. It's the easiest way to incorporate Cobra into your application.
|
commands you want. It's the easiest way to incorporate Cobra into your application.
|
||||||
|
|
||||||
In order to use the cobra command, compile it using the following command:
|
[Here](https://github.com/spf13/cobra/blob/master/cobra/README.md) you can find more information about it.
|
||||||
|
|
||||||
go get github.com/spf13/cobra/cobra
|
## Using the Cobra Library
|
||||||
|
|
||||||
This will create the cobra executable under your `$GOPATH/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'
|
|
||||||
```
|
|
||||||
|
|
||||||
*Note: Use camelCase (not snake_case/snake-case) for command names.
|
|
||||||
Otherwise, you will encounter errors.
|
|
||||||
For example, `cobra add add-user` is incorrect, but `cobra add addUser` is valid.*
|
|
||||||
|
|
||||||
Once you have run these three commands you would have an app structure similar to
|
|
||||||
the following:
|
|
||||||
|
|
||||||
```
|
|
||||||
▾ 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.
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also use built-in licenses. For example, **GPLv2**, **GPLv3**, **LGPL**,
|
|
||||||
**AGPL**, **MIT**, **2-Clause BSD** or **3-Clause BSD**.
|
|
||||||
|
|
||||||
## 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.
|
You will optionally provide additional commands as you see fit.
|
||||||
|
|
||||||
### Create the root command
|
### Create rootCmd
|
||||||
|
|
||||||
The root command represents your binary itself.
|
|
||||||
|
|
||||||
#### Manually create rootCmd
|
|
||||||
|
|
||||||
Cobra doesn't require any special constructors. Simply create your commands.
|
Cobra doesn't require any special constructors. Simply create your commands.
|
||||||
|
|
||||||
@@ -400,17 +308,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)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Working with Flags
|
## Working with Flags
|
||||||
|
|
||||||
Flags provide modifiers to control how the action command operates.
|
Flags provide modifiers to control how the action command operates.
|
||||||
@@ -446,6 +343,19 @@ A flag can also be assigned locally which will only apply to that specific comma
|
|||||||
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
RootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Local Flag on Parent Commands
|
||||||
|
|
||||||
|
By default Cobra only parses local flags on the target command, any local flags on
|
||||||
|
parent commands are ignored. By enabling `Command.TraverseChildren` Cobra will
|
||||||
|
parse local flags on each command before executing the target command.
|
||||||
|
|
||||||
|
```go
|
||||||
|
command := cobra.Command{
|
||||||
|
Use: "print [OPTIONS] [COMMANDS]",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Bind Flags with Config
|
### Bind Flags with Config
|
||||||
|
|
||||||
You can also bind your flags with [viper](https://github.com/spf13/viper):
|
You can also bind your flags with [viper](https://github.com/spf13/viper):
|
||||||
@@ -569,7 +479,7 @@ a count and a string.`,
|
|||||||
|
|
||||||
For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
|
For a more complete example of a larger application, please checkout [Hugo](http://gohugo.io/).
|
||||||
|
|
||||||
## The Help Command
|
## Help Command
|
||||||
|
|
||||||
Cobra automatically adds a help command to your application when you have subcommands.
|
Cobra automatically adds a help command to your application when you have subcommands.
|
||||||
This will be called when a user runs 'app help'. Additionally, help will also
|
This will be called when a user runs 'app help'. Additionally, help will also
|
||||||
@@ -582,60 +492,28 @@ create' is called. Every command will automatically have the '--help' flag adde
|
|||||||
The following output is automatically generated by Cobra. Nothing beyond the
|
The following output is automatically generated by Cobra. Nothing beyond the
|
||||||
command and flag definitions are needed.
|
command and flag definitions are needed.
|
||||||
|
|
||||||
> hugo help
|
$ cobra help
|
||||||
|
|
||||||
hugo is the main command, used to build your Hugo site.
|
Cobra is a CLI library for Go that empowers applications.
|
||||||
|
This application is a tool to generate the needed files
|
||||||
Hugo is a Fast and Flexible Static Site Generator
|
to quickly create a Cobra application.
|
||||||
built with love by spf13 and friends in Go.
|
|
||||||
|
|
||||||
Complete documentation is available at http://gohugo.io/.
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
hugo [flags]
|
cobra [command]
|
||||||
hugo [command]
|
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
server Hugo runs its own webserver to render the files
|
add Add a command to a Cobra Application
|
||||||
version Print the version number of Hugo
|
help Help about any command
|
||||||
config Print the site configuration
|
init Initialize a Cobra Application
|
||||||
check Check content in the source directory
|
|
||||||
benchmark Benchmark hugo by building a site a number of times.
|
|
||||||
convert Convert your content to different formats
|
|
||||||
new Create new content for your site
|
|
||||||
list Listing out various types of content
|
|
||||||
undraft Undraft changes the content's draft status from 'True' to 'False'
|
|
||||||
genautocomplete Generate shell autocompletion script for Hugo
|
|
||||||
gendoc Generate Markdown documentation for the Hugo CLI.
|
|
||||||
genman Generate man page for Hugo
|
|
||||||
import Import your site from others.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||||
-D, --buildDrafts[=false]: include content marked as draft
|
--config string config file (default is $HOME/.cobra.yaml)
|
||||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
-h, --help help for cobra
|
||||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
-l, --license string name of license for the project
|
||||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
--viper use Viper for configuration (default true)
|
||||||
--config="": config file (default is path/config.yaml|json|toml)
|
|
||||||
-d, --destination="": filesystem path to write files to
|
|
||||||
--disableRSS[=false]: Do not build RSS files
|
|
||||||
--disableSitemap[=false]: Do not build Sitemap file
|
|
||||||
--editor="": edit new content with this editor, if provided
|
|
||||||
--ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
|
|
||||||
--log[=false]: Enable Logging
|
|
||||||
--logFile="": Log File path (if set, logging enabled automatically)
|
|
||||||
--noTimes[=false]: Don't sync modification time of files
|
|
||||||
--pluralizeListTitles[=true]: Pluralize titles in lists using inflect
|
|
||||||
--preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
|
||||||
-s, --source="": filesystem path to read files relative from
|
|
||||||
--stepAnalysis[=false]: display memory and timing of different steps of the program
|
|
||||||
-t, --theme="": theme to use (located in /themes/THEMENAME/)
|
|
||||||
--uglyURLs[=false]: if true, use /filename.html instead of /filename/
|
|
||||||
-v, --verbose[=false]: verbose output
|
|
||||||
--verboseLog[=false]: verbose logging
|
|
||||||
-w, --watch[=false]: watch filesystem for changes and recreate as needed
|
|
||||||
|
|
||||||
Use "hugo [command] --help" for more information about a command.
|
Use "cobra [command] --help" for more information about a command.
|
||||||
|
|
||||||
|
|
||||||
Help is just a command like any other. There is no special logic or behavior
|
Help is just a command like any other. There is no special logic or behavior
|
||||||
@@ -643,36 +521,18 @@ around it. In fact, you can provide your own if you want.
|
|||||||
|
|
||||||
### Defining your own help
|
### Defining your own help
|
||||||
|
|
||||||
You can provide your own Help command or your own template for the default command to use.
|
You can provide your own Help command or your own template for the default command to use
|
||||||
|
with followind functions:
|
||||||
The default help command is
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
func (c *Command) initHelp() {
|
cmd.SetHelpCommand(cmd *Command)
|
||||||
if c.helpCommand == nil {
|
cmd.SetHelpFunc(f func(*Command, []string))
|
||||||
c.helpCommand = &Command{
|
cmd.SetHelpTemplate(s string)
|
||||||
Use: "help [command]",
|
|
||||||
Short: "Help about any command",
|
|
||||||
Long: `Help provides help for any command in the application.
|
|
||||||
Simply type ` + c.Name() + ` help [path to command] for full details.`,
|
|
||||||
Run: c.HelpFunc(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.AddCommand(c.helpCommand)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
You can provide your own command, function or template through the following methods:
|
|
||||||
|
|
||||||
```go
|
|
||||||
command.SetHelpCommand(cmd *Command)
|
|
||||||
command.SetHelpFunc(f func(*Command, []string))
|
|
||||||
command.SetHelpTemplate(s string)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The latter two will also apply to any children commands.
|
The latter two will also apply to any children commands.
|
||||||
|
|
||||||
## Usage
|
## Usage Message
|
||||||
|
|
||||||
When the user provides an invalid flag or invalid command, Cobra responds by
|
When the user provides an invalid flag or invalid command, Cobra responds by
|
||||||
showing the user the 'usage'.
|
showing the user the 'usage'.
|
||||||
@@ -681,71 +541,35 @@ showing the user the 'usage'.
|
|||||||
You may recognize this from the help above. That's because the default help
|
You may recognize this from the help above. That's because the default help
|
||||||
embeds the usage as part of its output.
|
embeds the usage as part of its output.
|
||||||
|
|
||||||
|
$ cobra --invalid
|
||||||
|
Error: unknown flag: --invalid
|
||||||
Usage:
|
Usage:
|
||||||
hugo [flags]
|
cobra [command]
|
||||||
hugo [command]
|
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
server Hugo runs its own webserver to render the files
|
add Add a command to a Cobra Application
|
||||||
version Print the version number of Hugo
|
help Help about any command
|
||||||
config Print the site configuration
|
init Initialize a Cobra Application
|
||||||
check Check content in the source directory
|
|
||||||
benchmark Benchmark hugo by building a site a number of times.
|
|
||||||
convert Convert your content to different formats
|
|
||||||
new Create new content for your site
|
|
||||||
list Listing out various types of content
|
|
||||||
undraft Undraft changes the content's draft status from 'True' to 'False'
|
|
||||||
genautocomplete Generate shell autocompletion script for Hugo
|
|
||||||
gendoc Generate Markdown documentation for the Hugo CLI.
|
|
||||||
genman Generate man page for Hugo
|
|
||||||
import Import your site from others.
|
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-b, --baseURL="": hostname (and path) to the root, e.g. http://spf13.com/
|
-a, --author string author name for copyright attribution (default "YOUR NAME")
|
||||||
-D, --buildDrafts[=false]: include content marked as draft
|
--config string config file (default is $HOME/.cobra.yaml)
|
||||||
-F, --buildFuture[=false]: include content with publishdate in the future
|
-h, --help help for cobra
|
||||||
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
-l, --license string name of license for the project
|
||||||
--canonifyURLs[=false]: if true, all relative URLs will be canonicalized using baseURL
|
--viper use Viper for configuration (default true)
|
||||||
--config="": config file (default is path/config.yaml|json|toml)
|
|
||||||
-d, --destination="": filesystem path to write files to
|
Use "cobra [command] --help" for more information about a command.
|
||||||
--disableRSS[=false]: Do not build RSS files
|
|
||||||
--disableSitemap[=false]: Do not build Sitemap file
|
|
||||||
--editor="": edit new content with this editor, if provided
|
|
||||||
--ignoreCache[=false]: Ignores the cache directory for reading but still writes to it
|
|
||||||
--log[=false]: Enable Logging
|
|
||||||
--logFile="": Log File path (if set, logging enabled automatically)
|
|
||||||
--noTimes[=false]: Don't sync modification time of files
|
|
||||||
--pluralizeListTitles[=true]: Pluralize titles in lists using inflect
|
|
||||||
--preserveTaxonomyNames[=false]: Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
|
||||||
-s, --source="": filesystem path to read files relative from
|
|
||||||
--stepAnalysis[=false]: display memory and timing of different steps of the program
|
|
||||||
-t, --theme="": theme to use (located in /themes/THEMENAME/)
|
|
||||||
--uglyURLs[=false]: if true, use /filename.html instead of /filename/
|
|
||||||
-v, --verbose[=false]: verbose output
|
|
||||||
--verboseLog[=false]: verbose logging
|
|
||||||
-w, --watch[=false]: watch filesystem for changes and recreate as needed
|
|
||||||
|
|
||||||
### Defining your own usage
|
### Defining your own usage
|
||||||
You can provide your own usage function or template for Cobra to use.
|
You can provide your own usage function or template for Cobra to use.
|
||||||
|
|
||||||
The default usage function is:
|
|
||||||
|
|
||||||
```go
|
|
||||||
return func(c *Command) error {
|
|
||||||
err := tmpl(c.Out(), c.UsageTemplate(), c)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Like help, the function and template are overridable through public methods:
|
Like help, the function and template are overridable through public methods:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
command.SetUsageFunc(f func(*Command) error)
|
cmd.SetUsageFunc(f func(*Command) error)
|
||||||
|
cmd.SetUsageTemplate(s string)
|
||||||
command.SetUsageTemplate(s string)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## PreRun or PostRun Hooks
|
## PreRun and PostRun Hooks
|
||||||
|
|
||||||
It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`. The `Persistent*Run` functions will be inherited by children if they do not declare their own. These functions 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:
|
||||||
|
|
||||||
@@ -815,51 +639,19 @@ func main() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
Inside rootCmd PersistentPreRun with args: []
|
||||||
|
Inside rootCmd PreRun with args: []
|
||||||
|
Inside rootCmd Run with args: []
|
||||||
|
Inside rootCmd PostRun with args: []
|
||||||
|
Inside rootCmd PersistentPostRun with args: []
|
||||||
|
|
||||||
## Alternative Error Handling
|
Inside rootCmd PersistentPreRun with args: [arg1 arg2]
|
||||||
|
Inside subCmd PreRun with args: [arg1 arg2]
|
||||||
Cobra also has functions where the return signature is an error. This allows for errors to bubble up to the top,
|
Inside subCmd Run with args: [arg1 arg2]
|
||||||
providing a way to handle the errors in one location. The current list of functions that return an error is:
|
Inside subCmd PostRun with args: [arg1 arg2]
|
||||||
|
Inside subCmd PersistentPostRun with args: [arg1 arg2]
|
||||||
* PersistentPreRunE
|
|
||||||
* PreRunE
|
|
||||||
* RunE
|
|
||||||
* PostRunE
|
|
||||||
* PersistentPostRunE
|
|
||||||
|
|
||||||
If you would like to silence the default `error` and `usage` output in favor of your own, you can set `SilenceUsage`
|
|
||||||
and `SilenceErrors` to `true` on the command. A child command respects these flags if they are set on the parent
|
|
||||||
command.
|
|
||||||
|
|
||||||
**Example Usage using RunE:**
|
|
||||||
|
|
||||||
```go
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var rootCmd = &cobra.Command{
|
|
||||||
Use: "hugo",
|
|
||||||
Short: "Hugo is a very fast static site generator",
|
|
||||||
Long: `A Fast and Flexible Static Site Generator built with
|
|
||||||
love by spf13 and friends in Go.
|
|
||||||
Complete documentation is available at http://hugo.spf13.com`,
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
// Do Stuff Here
|
|
||||||
return errors.New("some random error")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := rootCmd.Execute(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Suggestions when "unknown command" happens
|
## Suggestions when "unknown command" happens
|
||||||
@@ -902,41 +694,28 @@ Did you mean this?
|
|||||||
Run 'kubectl help' for usage.
|
Run 'kubectl help' for usage.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Generating Markdown-formatted documentation for your command
|
## Generating documentation for your command
|
||||||
|
|
||||||
Cobra can generate a Markdown-formatted document based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Markdown Docs](doc/md_docs.md).
|
Cobra can generate documentation based on subcommands, flags, etc. in the following formats:
|
||||||
|
|
||||||
## Generating man pages for your command
|
- [Markdown](doc/md_docs.md)
|
||||||
|
- [ReStructured Text](doc/rest_docs.md)
|
||||||
|
- [Man Page](doc/man_docs.md)
|
||||||
|
|
||||||
Cobra can generate a man page based on the subcommands, flags, etc. A simple example of how to do this for your command can be found in [Man Docs](doc/man_docs.md).
|
## Generating bash completions
|
||||||
|
|
||||||
## Generating bash completions for your command
|
|
||||||
|
|
||||||
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
|
Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md).
|
||||||
|
|
||||||
|
# Contributing
|
||||||
## 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`.
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork it
|
1. Fork it
|
||||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
2. Download your fork to your PC (`git clone https://github.com/your_username/cobra && cd cobra`)
|
||||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
3. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
4. Push to the branch (`git push origin my-new-feature`)
|
4. Make changes and add them (`git add .`)
|
||||||
5. Create new Pull Request
|
5. Commit your changes (`git commit -m 'Add some feature'`)
|
||||||
|
6. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
7. Create new pull request
|
||||||
|
|
||||||
## Contributors
|
# License
|
||||||
|
|
||||||
Names in no particular order:
|
|
||||||
|
|
||||||
* [spf13](https://github.com/spf13),
|
|
||||||
[eparis](https://github.com/eparis),
|
|
||||||
[bep](https://github.com/bep), and many more!
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
Cobra is released under the Apache 2.0 license. See [LICENSE.txt](https://github.com/spf13/cobra/blob/master/LICENSE.txt)
|
||||||
|
|||||||
2
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
2
vendor/github.com/spf13/cobra/bash_completions.go
generated
vendored
@@ -92,7 +92,7 @@ __handle_reply()
|
|||||||
cur="${cur#*=}"
|
cur="${cur#*=}"
|
||||||
${flags_completion[${index}]}
|
${flags_completion[${index}]}
|
||||||
if [ -n "${ZSH_VERSION}" ]; then
|
if [ -n "${ZSH_VERSION}" ]; then
|
||||||
# zfs completion needs --flag= prefix
|
# zsh completion needs --flag= prefix
|
||||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|||||||
151
vendor/github.com/spf13/cobra/command.go
generated
vendored
151
vendor/github.com/spf13/cobra/command.go
generated
vendored
@@ -125,8 +125,9 @@ type Command struct {
|
|||||||
// Must be > 0.
|
// Must be > 0.
|
||||||
SuggestionsMinimumDistance int
|
SuggestionsMinimumDistance int
|
||||||
|
|
||||||
// name is the command name, usually the executable's name.
|
// TraverseChildren parses flags on all parents before executing child command.
|
||||||
name string
|
TraverseChildren bool
|
||||||
|
|
||||||
// commands is the list of commands supported by this program.
|
// commands is the list of commands supported by this program.
|
||||||
commands []*Command
|
commands []*Command
|
||||||
// parent is a parent command for this command.
|
// parent is a parent command for this command.
|
||||||
@@ -475,13 +476,14 @@ func argsMinusFirstX(args []string, x string) []string {
|
|||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFlagArg(arg string) bool {
|
||||||
|
return ((len(arg) >= 3 && arg[1] == '-') ||
|
||||||
|
(len(arg) >= 2 && arg[0] == '-' && arg[1] != '-'))
|
||||||
|
}
|
||||||
|
|
||||||
// Find the target command given the args and command tree
|
// Find the target command given the args and command tree
|
||||||
// Meant to be run on the highest node. Only searches down.
|
// Meant to be run on the highest node. Only searches down.
|
||||||
func (c *Command) Find(args []string) (*Command, []string, error) {
|
func (c *Command) Find(args []string) (*Command, []string, error) {
|
||||||
if c == nil {
|
|
||||||
return nil, nil, fmt.Errorf("Called find() on a nil Command")
|
|
||||||
}
|
|
||||||
|
|
||||||
var innerfind func(*Command, []string) (*Command, []string)
|
var innerfind func(*Command, []string) (*Command, []string)
|
||||||
|
|
||||||
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
|
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
|
||||||
@@ -490,28 +492,11 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
|||||||
return c, innerArgs
|
return c, innerArgs
|
||||||
}
|
}
|
||||||
nextSubCmd := argsWOflags[0]
|
nextSubCmd := argsWOflags[0]
|
||||||
matches := make([]*Command, 0)
|
|
||||||
for _, cmd := range c.commands {
|
cmd := c.findNext(nextSubCmd)
|
||||||
if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match
|
if cmd != nil {
|
||||||
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
||||||
}
|
}
|
||||||
if EnablePrefixMatching {
|
|
||||||
if strings.HasPrefix(cmd.Name(), nextSubCmd) { // prefix match
|
|
||||||
matches = append(matches, cmd)
|
|
||||||
}
|
|
||||||
for _, x := range cmd.Aliases {
|
|
||||||
if strings.HasPrefix(x, nextSubCmd) {
|
|
||||||
matches = append(matches, cmd)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// only accept a single prefix match - multiple matches would be ambiguous
|
|
||||||
if len(matches) == 1 {
|
|
||||||
return innerfind(matches[0], argsMinusFirstX(innerArgs, argsWOflags[0]))
|
|
||||||
}
|
|
||||||
|
|
||||||
return c, innerArgs
|
return c, innerArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,6 +524,66 @@ func (c *Command) findSuggestions(arg string) string {
|
|||||||
return suggestionsString
|
return suggestionsString
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) findNext(next string) *Command {
|
||||||
|
matches := make([]*Command, 0)
|
||||||
|
for _, cmd := range c.commands {
|
||||||
|
if cmd.Name() == next || cmd.HasAlias(next) {
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
if EnablePrefixMatching && cmd.hasNameOrAliasPrefix(next) {
|
||||||
|
matches = append(matches, cmd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(matches) == 1 {
|
||||||
|
return matches[0]
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse the command tree to find the command, and parse args for
|
||||||
|
// each parent.
|
||||||
|
func (c *Command) Traverse(args []string) (*Command, []string, error) {
|
||||||
|
flags := []string{}
|
||||||
|
inFlag := false
|
||||||
|
|
||||||
|
for i, arg := range args {
|
||||||
|
switch {
|
||||||
|
// A long flag with a space separated value
|
||||||
|
case strings.HasPrefix(arg, "--") && !strings.Contains(arg, "="):
|
||||||
|
// TODO: this isn't quite right, we should really check ahead for 'true' or 'false'
|
||||||
|
inFlag = !hasNoOptDefVal(arg[2:], c.Flags())
|
||||||
|
flags = append(flags, arg)
|
||||||
|
continue
|
||||||
|
// A short flag with a space separated value
|
||||||
|
case strings.HasPrefix(arg, "-") && !strings.Contains(arg, "=") && len(arg) == 2 && !shortHasNoOptDefVal(arg[1:], c.Flags()):
|
||||||
|
inFlag = true
|
||||||
|
flags = append(flags, arg)
|
||||||
|
continue
|
||||||
|
// The value for a flag
|
||||||
|
case inFlag:
|
||||||
|
inFlag = false
|
||||||
|
flags = append(flags, arg)
|
||||||
|
continue
|
||||||
|
// A flag without a value, or with an `=` separated value
|
||||||
|
case isFlagArg(arg):
|
||||||
|
flags = append(flags, arg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := c.findNext(arg)
|
||||||
|
if cmd == nil {
|
||||||
|
return c, args, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.ParseFlags(flags); err != nil {
|
||||||
|
return nil, args, err
|
||||||
|
}
|
||||||
|
return cmd.Traverse(args[i+1:])
|
||||||
|
}
|
||||||
|
return c, args, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SuggestionsFor provides suggestions for the typedName.
|
// SuggestionsFor provides suggestions for the typedName.
|
||||||
func (c *Command) SuggestionsFor(typedName string) []string {
|
func (c *Command) SuggestionsFor(typedName string) []string {
|
||||||
suggestions := []string{}
|
suggestions := []string{}
|
||||||
@@ -646,6 +691,9 @@ func (c *Command) execute(a []string) (err error) {
|
|||||||
c.PreRun(c, argWoFlags)
|
c.PreRun(c, argWoFlags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := c.validateRequiredFlags(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if c.RunE != nil {
|
if c.RunE != nil {
|
||||||
if err := c.RunE(c, argWoFlags); err != nil {
|
if err := c.RunE(c, argWoFlags); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -714,7 +762,12 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||||||
args = c.args
|
args = c.args
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, flags, err := c.Find(args)
|
var flags []string
|
||||||
|
if c.TraverseChildren {
|
||||||
|
cmd, flags, err = c.Traverse(args)
|
||||||
|
} else {
|
||||||
|
cmd, flags, err = c.Find(args)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If found parse to a subcommand and then failed, talk about the subcommand
|
// If found parse to a subcommand and then failed, talk about the subcommand
|
||||||
if cmd != nil {
|
if cmd != nil {
|
||||||
@@ -726,6 +779,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||||||
}
|
}
|
||||||
return c, err
|
return c, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cmd.execute(flags)
|
err = cmd.execute(flags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Always show help if requested, even if SilenceErrors is in
|
// Always show help if requested, even if SilenceErrors is in
|
||||||
@@ -757,6 +811,25 @@ func (c *Command) ValidateArgs(args []string) error {
|
|||||||
return c.Args(c, args)
|
return c.Args(c, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Command) validateRequiredFlags() error {
|
||||||
|
flags := c.Flags()
|
||||||
|
missingFlagNames := []string{}
|
||||||
|
flags.VisitAll(func(pflag *flag.Flag) {
|
||||||
|
requiredAnnotation, found := pflag.Annotations[BashCompOneRequiredFlag]
|
||||||
|
if !found {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (requiredAnnotation[0] == "true") && !pflag.Changed {
|
||||||
|
missingFlagNames = append(missingFlagNames, pflag.Name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if len(missingFlagNames) > 0 {
|
||||||
|
return fmt.Errorf(`Required flag(s) "%s" have/has not been set`, strings.Join(missingFlagNames, `", "`))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// InitDefaultHelpFlag adds default help flag to c.
|
// InitDefaultHelpFlag adds default help flag to c.
|
||||||
// It is called automatically by executing the c or by calling help and usage.
|
// It is called automatically by executing the c or by calling help and usage.
|
||||||
// If c already has help flag, it will do nothing.
|
// If c already has help flag, it will do nothing.
|
||||||
@@ -972,15 +1045,12 @@ func (c *Command) DebugFlags() {
|
|||||||
|
|
||||||
// Name returns the command's name: the first word in the use line.
|
// Name returns the command's name: the first word in the use line.
|
||||||
func (c *Command) Name() string {
|
func (c *Command) Name() string {
|
||||||
if c.name == "" {
|
|
||||||
name := c.Use
|
name := c.Use
|
||||||
i := strings.Index(name, " ")
|
i := strings.Index(name, " ")
|
||||||
if i >= 0 {
|
if i >= 0 {
|
||||||
name = name[:i]
|
name = name[:i]
|
||||||
}
|
}
|
||||||
c.name = name
|
return name
|
||||||
}
|
|
||||||
return c.name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HasAlias determines if a given string is an alias of the command.
|
// HasAlias determines if a given string is an alias of the command.
|
||||||
@@ -993,7 +1063,21 @@ func (c *Command) HasAlias(s string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameAndAliases returns string containing name and all aliases
|
// hasNameOrAliasPrefix returns true if the Name or any of aliases start
|
||||||
|
// with prefix
|
||||||
|
func (c *Command) hasNameOrAliasPrefix(prefix string) bool {
|
||||||
|
if strings.HasPrefix(c.Name(), prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, alias := range c.Aliases {
|
||||||
|
if strings.HasPrefix(alias, prefix) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NameAndAliases returns a list of the command name and all aliases
|
||||||
func (c *Command) NameAndAliases() string {
|
func (c *Command) NameAndAliases() string {
|
||||||
return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
|
return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
|
||||||
}
|
}
|
||||||
@@ -1276,6 +1360,9 @@ func (c *Command) ParseFlags(args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if c.flagErrorBuf == nil {
|
||||||
|
c.flagErrorBuf = new(bytes.Buffer)
|
||||||
|
}
|
||||||
beforeErrorBufLen := c.flagErrorBuf.Len()
|
beforeErrorBufLen := c.flagErrorBuf.Len()
|
||||||
c.mergePersistentFlags()
|
c.mergePersistentFlags()
|
||||||
err := c.Flags().Parse(args)
|
err := c.Flags().Parse(args)
|
||||||
|
|||||||
177
vendor/github.com/spf13/cobra/command_test.go
generated
vendored
177
vendor/github.com/spf13/cobra/command_test.go
generated
vendored
@@ -347,3 +347,180 @@ func TestSetHelpCommand(t *testing.T) {
|
|||||||
t.Errorf("Expected to contain %q message, but got %q", correctMessage, output.String())
|
t.Errorf("Expected to contain %q message, but got %q", correctMessage, output.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTraverseWithParentFlags(t *testing.T) {
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "do",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
cmd.Flags().String("foo", "", "foo things")
|
||||||
|
cmd.Flags().BoolP("goo", "g", false, "foo things")
|
||||||
|
|
||||||
|
sub := &Command{Use: "next"}
|
||||||
|
sub.Flags().String("add", "", "add things")
|
||||||
|
cmd.AddCommand(sub)
|
||||||
|
|
||||||
|
c, args, err := cmd.Traverse([]string{"-g", "--foo", "ok", "next", "--add"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error: %s", err)
|
||||||
|
}
|
||||||
|
if len(args) != 1 && args[0] != "--add" {
|
||||||
|
t.Fatalf("wrong args %s", args)
|
||||||
|
}
|
||||||
|
if c.Name() != sub.Name() {
|
||||||
|
t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTraverseNoParentFlags(t *testing.T) {
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "do",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
cmd.Flags().String("foo", "", "foo things")
|
||||||
|
|
||||||
|
sub := &Command{Use: "next"}
|
||||||
|
sub.Flags().String("add", "", "add things")
|
||||||
|
cmd.AddCommand(sub)
|
||||||
|
|
||||||
|
c, args, err := cmd.Traverse([]string{"next"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error: %s", err)
|
||||||
|
}
|
||||||
|
if len(args) != 0 {
|
||||||
|
t.Fatalf("wrong args %s", args)
|
||||||
|
}
|
||||||
|
if c.Name() != sub.Name() {
|
||||||
|
t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTraverseWithBadParentFlags(t *testing.T) {
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "do",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
sub := &Command{Use: "next"}
|
||||||
|
sub.Flags().String("add", "", "add things")
|
||||||
|
cmd.AddCommand(sub)
|
||||||
|
|
||||||
|
expected := "got unknown flag: --add"
|
||||||
|
|
||||||
|
c, _, err := cmd.Traverse([]string{"--add", "ok", "next"})
|
||||||
|
if err == nil || strings.Contains(err.Error(), expected) {
|
||||||
|
t.Fatalf("Expected error %s got %s", expected, err)
|
||||||
|
}
|
||||||
|
if c != nil {
|
||||||
|
t.Fatalf("Expected nil command")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTraverseWithBadChildFlag(t *testing.T) {
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "do",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
cmd.Flags().String("foo", "", "foo things")
|
||||||
|
|
||||||
|
sub := &Command{Use: "next"}
|
||||||
|
cmd.AddCommand(sub)
|
||||||
|
|
||||||
|
// Expect no error because the last commands args shouldn't be parsed in
|
||||||
|
// Traverse
|
||||||
|
c, args, err := cmd.Traverse([]string{"next", "--add"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error: %s", err)
|
||||||
|
}
|
||||||
|
if len(args) != 1 && args[0] != "--add" {
|
||||||
|
t.Fatalf("wrong args %s", args)
|
||||||
|
}
|
||||||
|
if c.Name() != sub.Name() {
|
||||||
|
t.Fatalf("wrong command %q expected %q", c.Name(), sub.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTraverseWithTwoSubcommands(t *testing.T) {
|
||||||
|
cmd := &Command{
|
||||||
|
Use: "do",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
sub := &Command{
|
||||||
|
Use: "sub",
|
||||||
|
TraverseChildren: true,
|
||||||
|
}
|
||||||
|
cmd.AddCommand(sub)
|
||||||
|
|
||||||
|
subsub := &Command{
|
||||||
|
Use: "subsub",
|
||||||
|
}
|
||||||
|
sub.AddCommand(subsub)
|
||||||
|
|
||||||
|
c, _, err := cmd.Traverse([]string{"sub", "subsub"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Expected no error: %s", err)
|
||||||
|
}
|
||||||
|
if c.Name() != subsub.Name() {
|
||||||
|
t.Fatalf("wrong command %q expected %q", c.Name(), subsub.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRequiredFlags(t *testing.T) {
|
||||||
|
c := &Command{Use: "c", Run: func(*Command, []string) {}}
|
||||||
|
output := new(bytes.Buffer)
|
||||||
|
c.SetOutput(output)
|
||||||
|
c.Flags().String("foo1", "", "required foo1")
|
||||||
|
c.MarkFlagRequired("foo1")
|
||||||
|
c.Flags().String("foo2", "", "required foo2")
|
||||||
|
c.MarkFlagRequired("foo2")
|
||||||
|
c.Flags().String("bar", "", "optional bar")
|
||||||
|
|
||||||
|
expected := fmt.Sprintf("Required flag(s) %q, %q have/has not been set", "foo1", "foo2")
|
||||||
|
|
||||||
|
if err := c.Execute(); err != nil {
|
||||||
|
if err.Error() != expected {
|
||||||
|
t.Errorf("expected %v, got %v", expected, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPersistentRequiredFlags(t *testing.T) {
|
||||||
|
parent := &Command{Use: "parent", Run: func(*Command, []string) {}}
|
||||||
|
output := new(bytes.Buffer)
|
||||||
|
parent.SetOutput(output)
|
||||||
|
parent.PersistentFlags().String("foo1", "", "required foo1")
|
||||||
|
parent.MarkPersistentFlagRequired("foo1")
|
||||||
|
parent.PersistentFlags().String("foo2", "", "required foo2")
|
||||||
|
parent.MarkPersistentFlagRequired("foo2")
|
||||||
|
parent.Flags().String("foo3", "", "optional foo3")
|
||||||
|
|
||||||
|
child := &Command{Use: "child", Run: func(*Command, []string) {}}
|
||||||
|
child.Flags().String("bar1", "", "required bar1")
|
||||||
|
child.MarkFlagRequired("bar1")
|
||||||
|
child.Flags().String("bar2", "", "required bar2")
|
||||||
|
child.MarkFlagRequired("bar2")
|
||||||
|
child.Flags().String("bar3", "", "optional bar3")
|
||||||
|
|
||||||
|
parent.AddCommand(child)
|
||||||
|
parent.SetArgs([]string{"child"})
|
||||||
|
|
||||||
|
expected := fmt.Sprintf("Required flag(s) %q, %q, %q, %q have/has not been set", "bar1", "bar2", "foo1", "foo2")
|
||||||
|
|
||||||
|
if err := parent.Execute(); err != nil {
|
||||||
|
if err.Error() != expected {
|
||||||
|
t.Errorf("expected %v, got %v", expected, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestUpdateName checks if c.Name() updates on changed c.Use.
|
||||||
|
// Related to https://github.com/spf13/cobra/pull/422#discussion_r143918343.
|
||||||
|
func TestUpdateName(t *testing.T) {
|
||||||
|
c := &Command{Use: "name xyz"}
|
||||||
|
originalName := c.Name()
|
||||||
|
|
||||||
|
c.Use = "changedName abc"
|
||||||
|
if originalName == c.Name() || c.Name() != "changedName" {
|
||||||
|
t.Error("c.Name() should be updated on changed c.Use")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user