mirror of
https://github.com/restic/rest-server.git
synced 2025-10-19 15:43:21 +00:00
Update dependencies
This commit is contained in:
parent
e4071748b9
commit
132232db69
5 changed files with 405 additions and 362 deletions
2
Gopkg.lock
generated
2
Gopkg.lock
generated
|
@ -18,7 +18,7 @@
|
|||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
revision = "0dacccfbaabc71b872087c1719c5380d3e185173"
|
||||
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
|
||||
|
||||
[[projects]]
|
||||
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)
|
||||
* [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
|
||||
|
||||
|
@ -43,7 +63,6 @@ Cobra provides:
|
|||
* 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
|
||||
|
@ -51,16 +70,6 @@ Cobra provides:
|
|||
* 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.
|
||||
|
@ -93,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.
|
||||
|
@ -170,106 +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 get github.com/spf13/cobra/cobra
|
||||
|
||||
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
|
||||
## Using the Cobra Library
|
||||
|
||||
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.
|
||||
|
||||
|
@ -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
|
||||
|
||||
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")
|
||||
```
|
||||
|
||||
### 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):
|
||||
|
@ -569,7 +479,7 @@ a count and a string.`,
|
|||
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
|
@ -643,36 +521,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 followind 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'.
|
||||
|
@ -681,71 +541,35 @@ 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 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
|
||||
|
||||
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 `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)
|
||||
}
|
||||
}
|
||||
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
|
||||
|
@ -902,41 +694,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).
|
||||
|
||||
|
||||
## 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
|
||||
# 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)
|
||||
|
|
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#*=}"
|
||||
${flags_completion[${index}]}
|
||||
if [ -n "${ZSH_VERSION}" ]; then
|
||||
# zfs completion needs --flag= prefix
|
||||
# zsh completion needs --flag= prefix
|
||||
eval "COMPREPLY=( \"\${COMPREPLY[@]/#/${flag}=}\" )"
|
||||
fi
|
||||
fi
|
||||
|
|
159
vendor/github.com/spf13/cobra/command.go
generated
vendored
159
vendor/github.com/spf13/cobra/command.go
generated
vendored
|
@ -125,8 +125,9 @@ type Command struct {
|
|||
// Must be > 0.
|
||||
SuggestionsMinimumDistance int
|
||||
|
||||
// name is the command name, usually the executable's name.
|
||||
name string
|
||||
// TraverseChildren parses flags on all parents before executing child command.
|
||||
TraverseChildren bool
|
||||
|
||||
// commands is the list of commands supported by this program.
|
||||
commands []*Command
|
||||
// parent is a parent command for this command.
|
||||
|
@ -475,13 +476,14 @@ func argsMinusFirstX(args []string, x string) []string {
|
|||
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
|
||||
// Meant to be run on the highest node. Only searches down.
|
||||
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)
|
||||
|
||||
innerfind = func(c *Command, innerArgs []string) (*Command, []string) {
|
||||
|
@ -490,28 +492,11 @@ func (c *Command) Find(args []string) (*Command, []string, error) {
|
|||
return c, innerArgs
|
||||
}
|
||||
nextSubCmd := argsWOflags[0]
|
||||
matches := make([]*Command, 0)
|
||||
for _, cmd := range c.commands {
|
||||
if cmd.Name() == nextSubCmd || cmd.HasAlias(nextSubCmd) { // exact name or alias match
|
||||
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]))
|
||||
cmd := c.findNext(nextSubCmd)
|
||||
if cmd != nil {
|
||||
return innerfind(cmd, argsMinusFirstX(innerArgs, nextSubCmd))
|
||||
}
|
||||
|
||||
return c, innerArgs
|
||||
}
|
||||
|
||||
|
@ -539,6 +524,66 @@ func (c *Command) findSuggestions(arg string) string {
|
|||
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.
|
||||
func (c *Command) SuggestionsFor(typedName string) []string {
|
||||
suggestions := []string{}
|
||||
|
@ -646,6 +691,9 @@ func (c *Command) execute(a []string) (err error) {
|
|||
c.PreRun(c, argWoFlags)
|
||||
}
|
||||
|
||||
if err := c.validateRequiredFlags(); err != nil {
|
||||
return err
|
||||
}
|
||||
if c.RunE != nil {
|
||||
if err := c.RunE(c, argWoFlags); err != nil {
|
||||
return err
|
||||
|
@ -714,7 +762,12 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
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 found parse to a subcommand and then failed, talk about the subcommand
|
||||
if cmd != nil {
|
||||
|
@ -726,6 +779,7 @@ func (c *Command) ExecuteC() (cmd *Command, err error) {
|
|||
}
|
||||
return c, err
|
||||
}
|
||||
|
||||
err = cmd.execute(flags)
|
||||
if err != nil {
|
||||
// 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)
|
||||
}
|
||||
|
||||
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.
|
||||
// It is called automatically by executing the c or by calling help and usage.
|
||||
// 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.
|
||||
func (c *Command) Name() string {
|
||||
if c.name == "" {
|
||||
name := c.Use
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
c.name = name
|
||||
name := c.Use
|
||||
i := strings.Index(name, " ")
|
||||
if i >= 0 {
|
||||
name = name[:i]
|
||||
}
|
||||
return c.name
|
||||
return name
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return strings.Join(append([]string{c.Name()}, c.Aliases...), ", ")
|
||||
}
|
||||
|
@ -1276,6 +1360,9 @@ func (c *Command) ParseFlags(args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if c.flagErrorBuf == nil {
|
||||
c.flagErrorBuf = new(bytes.Buffer)
|
||||
}
|
||||
beforeErrorBufLen := c.flagErrorBuf.Len()
|
||||
c.mergePersistentFlags()
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue