mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	* Use vendored go-swagger (#8087) * Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net> * re-generate swagger file
This commit is contained in:
		
				
					committed by
					
						
						Lauris BH
					
				
			
			
				
	
			
			
			
						parent
						
							2f71571305
						
					
				
				
					commit
					c4d8d53a6d
				
			
							
								
								
									
										44
									
								
								vendor/github.com/jessevdk/go-flags/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								vendor/github.com/jessevdk/go-flags/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
			
		||||
language: go
 | 
			
		||||
 | 
			
		||||
os:
 | 
			
		||||
  - linux
 | 
			
		||||
  - osx
 | 
			
		||||
 | 
			
		||||
go:
 | 
			
		||||
  - 1.x
 | 
			
		||||
  - 1.7.x
 | 
			
		||||
  - 1.8.x
 | 
			
		||||
  - 1.9.x
 | 
			
		||||
  - 1.10.x
 | 
			
		||||
 | 
			
		||||
install:
 | 
			
		||||
  # go-flags
 | 
			
		||||
  - go get -d -v ./...
 | 
			
		||||
  - go build -v ./...
 | 
			
		||||
 | 
			
		||||
  # linting
 | 
			
		||||
  - go get github.com/golang/lint/golint
 | 
			
		||||
 | 
			
		||||
  # code coverage
 | 
			
		||||
  - go get golang.org/x/tools/cmd/cover
 | 
			
		||||
  - go get github.com/onsi/ginkgo/ginkgo
 | 
			
		||||
  - go get github.com/modocache/gover
 | 
			
		||||
  - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then go get github.com/mattn/goveralls; fi
 | 
			
		||||
 | 
			
		||||
script:
 | 
			
		||||
  # go-flags
 | 
			
		||||
  - $(exit $(gofmt -l . | wc -l))
 | 
			
		||||
  - go test -v ./...
 | 
			
		||||
 | 
			
		||||
  # linting
 | 
			
		||||
  - go tool vet -all=true -v=true . || true
 | 
			
		||||
  - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/golint ./...
 | 
			
		||||
 | 
			
		||||
  # code coverage
 | 
			
		||||
  - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/ginkgo -r -cover
 | 
			
		||||
  - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/gover
 | 
			
		||||
  - if [ "$TRAVIS_SECURE_ENV_VARS" = "true" ]; then $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=gover.coverprofile -service=travis-ci -repotoken $COVERALLS_TOKEN; fi
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  # coveralls.io
 | 
			
		||||
  secure: "RCYbiB4P0RjQRIoUx/vG/AjP3mmYCbzOmr86DCww1Z88yNcy3hYr3Cq8rpPtYU5v0g7wTpu4adaKIcqRE9xknYGbqj3YWZiCoBP1/n4Z+9sHW3Dsd9D/GRGeHUus0laJUGARjWoCTvoEtOgTdGQDoX7mH+pUUY0FBltNYUdOiiU="
 | 
			
		||||
							
								
								
									
										26
									
								
								vendor/github.com/jessevdk/go-flags/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								vendor/github.com/jessevdk/go-flags/LICENSE
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
Copyright (c) 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are
 | 
			
		||||
met:
 | 
			
		||||
 | 
			
		||||
   * Redistributions of source code must retain the above copyright
 | 
			
		||||
     notice, this list of conditions and the following disclaimer.
 | 
			
		||||
   * Redistributions in binary form must reproduce the above
 | 
			
		||||
     copyright notice, this list of conditions and the following disclaimer
 | 
			
		||||
     in the documentation and/or other materials provided with the
 | 
			
		||||
     distribution.
 | 
			
		||||
   * Neither the name of Google Inc. nor the names of its
 | 
			
		||||
     contributors may be used to endorse or promote products derived from
 | 
			
		||||
     this software without specific prior written permission.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | 
			
		||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | 
			
		||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | 
			
		||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | 
			
		||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | 
			
		||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | 
			
		||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | 
			
		||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/github.com/jessevdk/go-flags/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/github.com/jessevdk/go-flags/README.md
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
go-flags: a go library for parsing command line arguments
 | 
			
		||||
=========================================================
 | 
			
		||||
 | 
			
		||||
[](https://godoc.org/github.com/jessevdk/go-flags) [](https://travis-ci.org/jessevdk/go-flags) [](https://coveralls.io/r/jessevdk/go-flags?branch=master)
 | 
			
		||||
 | 
			
		||||
This library provides similar functionality to the builtin flag library of
 | 
			
		||||
go, but provides much more functionality and nicer formatting. From the
 | 
			
		||||
documentation:
 | 
			
		||||
 | 
			
		||||
Package flags provides an extensive command line option parser.
 | 
			
		||||
The flags package is similar in functionality to the go builtin flag package
 | 
			
		||||
but provides more options and uses reflection to provide a convenient and
 | 
			
		||||
succinct way of specifying command line options.
 | 
			
		||||
 | 
			
		||||
Supported features:
 | 
			
		||||
* Options with short names (-v)
 | 
			
		||||
* Options with long names (--verbose)
 | 
			
		||||
* Options with and without arguments (bool v.s. other type)
 | 
			
		||||
* Options with optional arguments and default values
 | 
			
		||||
* Multiple option groups each containing a set of options
 | 
			
		||||
* Generate and print well-formatted help message
 | 
			
		||||
* Passing remaining command line arguments after -- (optional)
 | 
			
		||||
* Ignoring unknown command line options (optional)
 | 
			
		||||
* Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
 | 
			
		||||
* Supports multiple short options -aux
 | 
			
		||||
* Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
 | 
			
		||||
* Supports same option multiple times (can store in slice or last option counts)
 | 
			
		||||
* Supports maps
 | 
			
		||||
* Supports function callbacks
 | 
			
		||||
* Supports namespaces for (nested) option groups
 | 
			
		||||
 | 
			
		||||
The flags package uses structs, reflection and struct field tags
 | 
			
		||||
to allow users to specify command line options. This results in very simple
 | 
			
		||||
and concise specification of your application options. For example:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
type Options struct {
 | 
			
		||||
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
This specifies one option with a short name -v and a long name --verbose.
 | 
			
		||||
When either -v or --verbose is found on the command line, a 'true' value
 | 
			
		||||
will be appended to the Verbose field. e.g. when specifying -vvv, the
 | 
			
		||||
resulting value of Verbose will be {[true, true, true]}.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
--------
 | 
			
		||||
```go
 | 
			
		||||
var opts struct {
 | 
			
		||||
	// Slice of bool will append 'true' each time the option
 | 
			
		||||
	// is encountered (can be set multiple times, like -vvv)
 | 
			
		||||
	Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
 | 
			
		||||
 | 
			
		||||
	// Example of automatic marshalling to desired type (uint)
 | 
			
		||||
	Offset uint `long:"offset" description:"Offset"`
 | 
			
		||||
 | 
			
		||||
	// Example of a callback, called each time the option is found.
 | 
			
		||||
	Call func(string) `short:"c" description:"Call phone number"`
 | 
			
		||||
 | 
			
		||||
	// Example of a required flag
 | 
			
		||||
	Name string `short:"n" long:"name" description:"A name" required:"true"`
 | 
			
		||||
 | 
			
		||||
	// Example of a value name
 | 
			
		||||
	File string `short:"f" long:"file" description:"A file" value-name:"FILE"`
 | 
			
		||||
 | 
			
		||||
	// Example of a pointer
 | 
			
		||||
	Ptr *int `short:"p" description:"A pointer to an integer"`
 | 
			
		||||
 | 
			
		||||
	// Example of a slice of strings
 | 
			
		||||
	StringSlice []string `short:"s" description:"A slice of strings"`
 | 
			
		||||
 | 
			
		||||
	// Example of a slice of pointers
 | 
			
		||||
	PtrSlice []*string `long:"ptrslice" description:"A slice of pointers to string"`
 | 
			
		||||
 | 
			
		||||
	// Example of a map
 | 
			
		||||
	IntMap map[string]int `long:"intmap" description:"A map from string to int"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Callback which will invoke callto:<argument> to call a number.
 | 
			
		||||
// Note that this works just on OS X (and probably only with
 | 
			
		||||
// Skype) but it shows the idea.
 | 
			
		||||
opts.Call = func(num string) {
 | 
			
		||||
	cmd := exec.Command("open", "callto:"+num)
 | 
			
		||||
	cmd.Start()
 | 
			
		||||
	cmd.Process.Release()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Make some fake arguments to parse.
 | 
			
		||||
args := []string{
 | 
			
		||||
	"-vv",
 | 
			
		||||
	"--offset=5",
 | 
			
		||||
	"-n", "Me",
 | 
			
		||||
	"-p", "3",
 | 
			
		||||
	"-s", "hello",
 | 
			
		||||
	"-s", "world",
 | 
			
		||||
	"--ptrslice", "hello",
 | 
			
		||||
	"--ptrslice", "world",
 | 
			
		||||
	"--intmap", "a:1",
 | 
			
		||||
	"--intmap", "b:5",
 | 
			
		||||
	"arg1",
 | 
			
		||||
	"arg2",
 | 
			
		||||
	"arg3",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse flags from `args'. Note that here we use flags.ParseArgs for
 | 
			
		||||
// the sake of making a working example. Normally, you would simply use
 | 
			
		||||
// flags.Parse(&opts) which uses os.Args
 | 
			
		||||
args, err := flags.ParseArgs(&opts, args)
 | 
			
		||||
 | 
			
		||||
if err != nil {
 | 
			
		||||
	panic(err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fmt.Printf("Verbosity: %v\n", opts.Verbose)
 | 
			
		||||
fmt.Printf("Offset: %d\n", opts.Offset)
 | 
			
		||||
fmt.Printf("Name: %s\n", opts.Name)
 | 
			
		||||
fmt.Printf("Ptr: %d\n", *opts.Ptr)
 | 
			
		||||
fmt.Printf("StringSlice: %v\n", opts.StringSlice)
 | 
			
		||||
fmt.Printf("PtrSlice: [%v %v]\n", *opts.PtrSlice[0], *opts.PtrSlice[1])
 | 
			
		||||
fmt.Printf("IntMap: [a:%v b:%v]\n", opts.IntMap["a"], opts.IntMap["b"])
 | 
			
		||||
fmt.Printf("Remaining args: %s\n", strings.Join(args, " "))
 | 
			
		||||
 | 
			
		||||
// Output: Verbosity: [true true]
 | 
			
		||||
// Offset: 5
 | 
			
		||||
// Name: Me
 | 
			
		||||
// Ptr: 3
 | 
			
		||||
// StringSlice: [hello world]
 | 
			
		||||
// PtrSlice: [hello world]
 | 
			
		||||
// IntMap: [a:1 b:5]
 | 
			
		||||
// Remaining args: arg1 arg2 arg3
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
More information can be found in the godocs: <http://godoc.org/github.com/jessevdk/go-flags>
 | 
			
		||||
							
								
								
									
										27
									
								
								vendor/github.com/jessevdk/go-flags/arg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								vendor/github.com/jessevdk/go-flags/arg.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Arg represents a positional argument on the command line.
 | 
			
		||||
type Arg struct {
 | 
			
		||||
	// The name of the positional argument (used in the help)
 | 
			
		||||
	Name string
 | 
			
		||||
 | 
			
		||||
	// A description of the positional argument (used in the help)
 | 
			
		||||
	Description string
 | 
			
		||||
 | 
			
		||||
	// The minimal number of required positional arguments
 | 
			
		||||
	Required int
 | 
			
		||||
 | 
			
		||||
	// The maximum number of required positional arguments
 | 
			
		||||
	RequiredMaximum int
 | 
			
		||||
 | 
			
		||||
	value reflect.Value
 | 
			
		||||
	tag   multiTag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *Arg) isRemaining() bool {
 | 
			
		||||
	return a.value.Type().Kind() == reflect.Slice
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/github.com/jessevdk/go-flags/check_crosscompile.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/jessevdk/go-flags/check_crosscompile.sh
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo '# linux arm7'
 | 
			
		||||
GOARM=7 GOARCH=arm GOOS=linux go build
 | 
			
		||||
echo '# linux arm5'
 | 
			
		||||
GOARM=5 GOARCH=arm GOOS=linux go build
 | 
			
		||||
echo '# windows 386'
 | 
			
		||||
GOARCH=386 GOOS=windows go build
 | 
			
		||||
echo '# windows amd64'
 | 
			
		||||
GOARCH=amd64 GOOS=windows go build
 | 
			
		||||
echo '# darwin'
 | 
			
		||||
GOARCH=amd64 GOOS=darwin go build
 | 
			
		||||
echo '# freebsd'
 | 
			
		||||
GOARCH=amd64 GOOS=freebsd go build
 | 
			
		||||
							
								
								
									
										59
									
								
								vendor/github.com/jessevdk/go-flags/closest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								vendor/github.com/jessevdk/go-flags/closest.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
func levenshtein(s string, t string) int {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		return len(t)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(t) == 0 {
 | 
			
		||||
		return len(s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dists := make([][]int, len(s)+1)
 | 
			
		||||
	for i := range dists {
 | 
			
		||||
		dists[i] = make([]int, len(t)+1)
 | 
			
		||||
		dists[i][0] = i
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for j := range t {
 | 
			
		||||
		dists[0][j] = j
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, sc := range s {
 | 
			
		||||
		for j, tc := range t {
 | 
			
		||||
			if sc == tc {
 | 
			
		||||
				dists[i+1][j+1] = dists[i][j]
 | 
			
		||||
			} else {
 | 
			
		||||
				dists[i+1][j+1] = dists[i][j] + 1
 | 
			
		||||
				if dists[i+1][j] < dists[i+1][j+1] {
 | 
			
		||||
					dists[i+1][j+1] = dists[i+1][j] + 1
 | 
			
		||||
				}
 | 
			
		||||
				if dists[i][j+1] < dists[i+1][j+1] {
 | 
			
		||||
					dists[i+1][j+1] = dists[i][j+1] + 1
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dists[len(s)][len(t)]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func closestChoice(cmd string, choices []string) (string, int) {
 | 
			
		||||
	if len(choices) == 0 {
 | 
			
		||||
		return "", 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	mincmd := -1
 | 
			
		||||
	mindist := -1
 | 
			
		||||
 | 
			
		||||
	for i, c := range choices {
 | 
			
		||||
		l := levenshtein(cmd, c)
 | 
			
		||||
 | 
			
		||||
		if mincmd < 0 || l < mindist {
 | 
			
		||||
			mindist = l
 | 
			
		||||
			mincmd = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return choices[mincmd], mindist
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										465
									
								
								vendor/github.com/jessevdk/go-flags/command.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										465
									
								
								vendor/github.com/jessevdk/go-flags/command.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,465 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Command represents an application command. Commands can be added to the
 | 
			
		||||
// parser (which itself is a command) and are selected/executed when its name
 | 
			
		||||
// is specified on the command line. The Command type embeds a Group and
 | 
			
		||||
// therefore also carries a set of command specific options.
 | 
			
		||||
type Command struct {
 | 
			
		||||
	// Embedded, see Group for more information
 | 
			
		||||
	*Group
 | 
			
		||||
 | 
			
		||||
	// The name by which the command can be invoked
 | 
			
		||||
	Name string
 | 
			
		||||
 | 
			
		||||
	// The active sub command (set by parsing) or nil
 | 
			
		||||
	Active *Command
 | 
			
		||||
 | 
			
		||||
	// Whether subcommands are optional
 | 
			
		||||
	SubcommandsOptional bool
 | 
			
		||||
 | 
			
		||||
	// Aliases for the command
 | 
			
		||||
	Aliases []string
 | 
			
		||||
 | 
			
		||||
	// Whether positional arguments are required
 | 
			
		||||
	ArgsRequired bool
 | 
			
		||||
 | 
			
		||||
	commands            []*Command
 | 
			
		||||
	hasBuiltinHelpGroup bool
 | 
			
		||||
	args                []*Arg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Commander is an interface which can be implemented by any command added in
 | 
			
		||||
// the options. When implemented, the Execute method will be called for the last
 | 
			
		||||
// specified (sub)command providing the remaining command line arguments.
 | 
			
		||||
type Commander interface {
 | 
			
		||||
	// Execute will be called for the last active (sub)command. The
 | 
			
		||||
	// args argument contains the remaining command line arguments. The
 | 
			
		||||
	// error that Execute returns will be eventually passed out of the
 | 
			
		||||
	// Parse method of the Parser.
 | 
			
		||||
	Execute(args []string) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Usage is an interface which can be implemented to show a custom usage string
 | 
			
		||||
// in the help message shown for a command.
 | 
			
		||||
type Usage interface {
 | 
			
		||||
	// Usage is called for commands to allow customized printing of command
 | 
			
		||||
	// usage in the generated help message.
 | 
			
		||||
	Usage() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type lookup struct {
 | 
			
		||||
	shortNames map[string]*Option
 | 
			
		||||
	longNames  map[string]*Option
 | 
			
		||||
 | 
			
		||||
	commands map[string]*Command
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddCommand adds a new command to the parser with the given name and data. The
 | 
			
		||||
// data needs to be a pointer to a struct from which the fields indicate which
 | 
			
		||||
// options are in the command. The provided data can implement the Command and
 | 
			
		||||
// Usage interfaces.
 | 
			
		||||
func (c *Command) AddCommand(command string, shortDescription string, longDescription string, data interface{}) (*Command, error) {
 | 
			
		||||
	cmd := newCommand(command, shortDescription, longDescription, data)
 | 
			
		||||
 | 
			
		||||
	cmd.parent = c
 | 
			
		||||
 | 
			
		||||
	if err := cmd.scan(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.commands = append(c.commands, cmd)
 | 
			
		||||
	return cmd, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddGroup adds a new group to the command with the given name and data. The
 | 
			
		||||
// data needs to be a pointer to a struct from which the fields indicate which
 | 
			
		||||
// options are in the group.
 | 
			
		||||
func (c *Command) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) {
 | 
			
		||||
	group := newGroup(shortDescription, longDescription, data)
 | 
			
		||||
 | 
			
		||||
	group.parent = c
 | 
			
		||||
 | 
			
		||||
	if err := group.scanType(c.scanSubcommandHandler(group)); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.groups = append(c.groups, group)
 | 
			
		||||
	return group, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Commands returns a list of subcommands of this command.
 | 
			
		||||
func (c *Command) Commands() []*Command {
 | 
			
		||||
	return c.commands
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find locates the subcommand with the given name and returns it. If no such
 | 
			
		||||
// command can be found Find will return nil.
 | 
			
		||||
func (c *Command) Find(name string) *Command {
 | 
			
		||||
	for _, cc := range c.commands {
 | 
			
		||||
		if cc.match(name) {
 | 
			
		||||
			return cc
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindOptionByLongName finds an option that is part of the command, or any of
 | 
			
		||||
// its parent commands, by matching its long name (including the option
 | 
			
		||||
// namespace).
 | 
			
		||||
func (c *Command) FindOptionByLongName(longName string) (option *Option) {
 | 
			
		||||
	for option == nil && c != nil {
 | 
			
		||||
		option = c.Group.FindOptionByLongName(longName)
 | 
			
		||||
 | 
			
		||||
		c, _ = c.parent.(*Command)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return option
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindOptionByShortName finds an option that is part of the command, or any of
 | 
			
		||||
// its parent commands, by matching its long name (including the option
 | 
			
		||||
// namespace).
 | 
			
		||||
func (c *Command) FindOptionByShortName(shortName rune) (option *Option) {
 | 
			
		||||
	for option == nil && c != nil {
 | 
			
		||||
		option = c.Group.FindOptionByShortName(shortName)
 | 
			
		||||
 | 
			
		||||
		c, _ = c.parent.(*Command)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return option
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Args returns a list of positional arguments associated with this command.
 | 
			
		||||
func (c *Command) Args() []*Arg {
 | 
			
		||||
	ret := make([]*Arg, len(c.args))
 | 
			
		||||
	copy(ret, c.args)
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newCommand(name string, shortDescription string, longDescription string, data interface{}) *Command {
 | 
			
		||||
	return &Command{
 | 
			
		||||
		Group: newGroup(shortDescription, longDescription, data),
 | 
			
		||||
		Name:  name,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) scanSubcommandHandler(parentg *Group) scanHandler {
 | 
			
		||||
	f := func(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
 | 
			
		||||
		mtag := newMultiTag(string(sfield.Tag))
 | 
			
		||||
 | 
			
		||||
		if err := mtag.Parse(); err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		positional := mtag.Get("positional-args")
 | 
			
		||||
 | 
			
		||||
		if len(positional) != 0 {
 | 
			
		||||
			stype := realval.Type()
 | 
			
		||||
 | 
			
		||||
			for i := 0; i < stype.NumField(); i++ {
 | 
			
		||||
				field := stype.Field(i)
 | 
			
		||||
 | 
			
		||||
				m := newMultiTag((string(field.Tag)))
 | 
			
		||||
 | 
			
		||||
				if err := m.Parse(); err != nil {
 | 
			
		||||
					return true, err
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				name := m.Get("positional-arg-name")
 | 
			
		||||
 | 
			
		||||
				if len(name) == 0 {
 | 
			
		||||
					name = field.Name
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				required := -1
 | 
			
		||||
				requiredMaximum := -1
 | 
			
		||||
 | 
			
		||||
				sreq := m.Get("required")
 | 
			
		||||
 | 
			
		||||
				if sreq != "" {
 | 
			
		||||
					required = 1
 | 
			
		||||
 | 
			
		||||
					rng := strings.SplitN(sreq, "-", 2)
 | 
			
		||||
 | 
			
		||||
					if len(rng) > 1 {
 | 
			
		||||
						if preq, err := strconv.ParseInt(rng[0], 10, 32); err == nil {
 | 
			
		||||
							required = int(preq)
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if preq, err := strconv.ParseInt(rng[1], 10, 32); err == nil {
 | 
			
		||||
							requiredMaximum = int(preq)
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						if preq, err := strconv.ParseInt(sreq, 10, 32); err == nil {
 | 
			
		||||
							required = int(preq)
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				arg := &Arg{
 | 
			
		||||
					Name:            name,
 | 
			
		||||
					Description:     m.Get("description"),
 | 
			
		||||
					Required:        required,
 | 
			
		||||
					RequiredMaximum: requiredMaximum,
 | 
			
		||||
 | 
			
		||||
					value: realval.Field(i),
 | 
			
		||||
					tag:   m,
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				c.args = append(c.args, arg)
 | 
			
		||||
 | 
			
		||||
				if len(mtag.Get("required")) != 0 {
 | 
			
		||||
					c.ArgsRequired = true
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		subcommand := mtag.Get("command")
 | 
			
		||||
 | 
			
		||||
		if len(subcommand) != 0 {
 | 
			
		||||
			var ptrval reflect.Value
 | 
			
		||||
 | 
			
		||||
			if realval.Kind() == reflect.Ptr {
 | 
			
		||||
				ptrval = realval
 | 
			
		||||
 | 
			
		||||
				if ptrval.IsNil() {
 | 
			
		||||
					ptrval.Set(reflect.New(ptrval.Type().Elem()))
 | 
			
		||||
				}
 | 
			
		||||
			} else {
 | 
			
		||||
				ptrval = realval.Addr()
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			shortDescription := mtag.Get("description")
 | 
			
		||||
			longDescription := mtag.Get("long-description")
 | 
			
		||||
			subcommandsOptional := mtag.Get("subcommands-optional")
 | 
			
		||||
			aliases := mtag.GetMany("alias")
 | 
			
		||||
 | 
			
		||||
			subc, err := c.AddCommand(subcommand, shortDescription, longDescription, ptrval.Interface())
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return true, err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			subc.Hidden = mtag.Get("hidden") != ""
 | 
			
		||||
 | 
			
		||||
			if len(subcommandsOptional) > 0 {
 | 
			
		||||
				subc.SubcommandsOptional = true
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(aliases) > 0 {
 | 
			
		||||
				subc.Aliases = aliases
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true, nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return parentg.scanSubGroupHandler(realval, sfield)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return f
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) scan() error {
 | 
			
		||||
	return c.scanType(c.scanSubcommandHandler(c.Group))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) eachOption(f func(*Command, *Group, *Option)) {
 | 
			
		||||
	c.eachCommand(func(c *Command) {
 | 
			
		||||
		c.eachGroup(func(g *Group) {
 | 
			
		||||
			for _, option := range g.options {
 | 
			
		||||
				f(c, g, option)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) eachCommand(f func(*Command), recurse bool) {
 | 
			
		||||
	f(c)
 | 
			
		||||
 | 
			
		||||
	for _, cc := range c.commands {
 | 
			
		||||
		if recurse {
 | 
			
		||||
			cc.eachCommand(f, true)
 | 
			
		||||
		} else {
 | 
			
		||||
			f(cc)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) eachActiveGroup(f func(cc *Command, g *Group)) {
 | 
			
		||||
	c.eachGroup(func(g *Group) {
 | 
			
		||||
		f(c, g)
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if c.Active != nil {
 | 
			
		||||
		c.Active.eachActiveGroup(f)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) addHelpGroups(showHelp func() error) {
 | 
			
		||||
	if !c.hasBuiltinHelpGroup {
 | 
			
		||||
		c.addHelpGroup(showHelp)
 | 
			
		||||
		c.hasBuiltinHelpGroup = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, cc := range c.commands {
 | 
			
		||||
		cc.addHelpGroups(showHelp)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) makeLookup() lookup {
 | 
			
		||||
	ret := lookup{
 | 
			
		||||
		shortNames: make(map[string]*Option),
 | 
			
		||||
		longNames:  make(map[string]*Option),
 | 
			
		||||
		commands:   make(map[string]*Command),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	parent := c.parent
 | 
			
		||||
 | 
			
		||||
	var parents []*Command
 | 
			
		||||
 | 
			
		||||
	for parent != nil {
 | 
			
		||||
		if cmd, ok := parent.(*Command); ok {
 | 
			
		||||
			parents = append(parents, cmd)
 | 
			
		||||
			parent = cmd.parent
 | 
			
		||||
		} else {
 | 
			
		||||
			parent = nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := len(parents) - 1; i >= 0; i-- {
 | 
			
		||||
		parents[i].fillLookup(&ret, true)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.fillLookup(&ret, false)
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) fillLookup(ret *lookup, onlyOptions bool) {
 | 
			
		||||
	c.eachGroup(func(g *Group) {
 | 
			
		||||
		for _, option := range g.options {
 | 
			
		||||
			if option.ShortName != 0 {
 | 
			
		||||
				ret.shortNames[string(option.ShortName)] = option
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(option.LongName) > 0 {
 | 
			
		||||
				ret.longNames[option.LongNameWithNamespace()] = option
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if onlyOptions {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, subcommand := range c.commands {
 | 
			
		||||
		ret.commands[subcommand.Name] = subcommand
 | 
			
		||||
 | 
			
		||||
		for _, a := range subcommand.Aliases {
 | 
			
		||||
			ret.commands[a] = subcommand
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) groupByName(name string) *Group {
 | 
			
		||||
	if grp := c.Group.groupByName(name); grp != nil {
 | 
			
		||||
		return grp
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, subc := range c.commands {
 | 
			
		||||
		prefix := subc.Name + "."
 | 
			
		||||
 | 
			
		||||
		if strings.HasPrefix(name, prefix) {
 | 
			
		||||
			if grp := subc.groupByName(name[len(prefix):]); grp != nil {
 | 
			
		||||
				return grp
 | 
			
		||||
			}
 | 
			
		||||
		} else if name == subc.Name {
 | 
			
		||||
			return subc.Group
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type commandList []*Command
 | 
			
		||||
 | 
			
		||||
func (c commandList) Less(i, j int) bool {
 | 
			
		||||
	return c[i].Name < c[j].Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c commandList) Len() int {
 | 
			
		||||
	return len(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c commandList) Swap(i, j int) {
 | 
			
		||||
	c[i], c[j] = c[j], c[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) sortedVisibleCommands() []*Command {
 | 
			
		||||
	ret := commandList(c.visibleCommands())
 | 
			
		||||
	sort.Sort(ret)
 | 
			
		||||
 | 
			
		||||
	return []*Command(ret)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) visibleCommands() []*Command {
 | 
			
		||||
	ret := make([]*Command, 0, len(c.commands))
 | 
			
		||||
 | 
			
		||||
	for _, cmd := range c.commands {
 | 
			
		||||
		if !cmd.Hidden {
 | 
			
		||||
			ret = append(ret, cmd)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) match(name string) bool {
 | 
			
		||||
	if c.Name == name {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, v := range c.Aliases {
 | 
			
		||||
		if v == name {
 | 
			
		||||
			return true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) hasCliOptions() bool {
 | 
			
		||||
	ret := false
 | 
			
		||||
 | 
			
		||||
	c.eachGroup(func(g *Group) {
 | 
			
		||||
		if g.isBuiltinHelp {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, opt := range g.options {
 | 
			
		||||
			if opt.canCli() {
 | 
			
		||||
				ret = true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *Command) fillParseState(s *parseState) {
 | 
			
		||||
	s.positional = make([]*Arg, len(c.args))
 | 
			
		||||
	copy(s.positional, c.args)
 | 
			
		||||
 | 
			
		||||
	s.lookup = c.makeLookup()
 | 
			
		||||
	s.command = c
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										309
									
								
								vendor/github.com/jessevdk/go-flags/completion.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										309
									
								
								vendor/github.com/jessevdk/go-flags/completion.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,309 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Completion is a type containing information of a completion.
 | 
			
		||||
type Completion struct {
 | 
			
		||||
	// The completed item
 | 
			
		||||
	Item string
 | 
			
		||||
 | 
			
		||||
	// A description of the completed item (optional)
 | 
			
		||||
	Description string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type completions []Completion
 | 
			
		||||
 | 
			
		||||
func (c completions) Len() int {
 | 
			
		||||
	return len(c)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c completions) Less(i, j int) bool {
 | 
			
		||||
	return c[i].Item < c[j].Item
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c completions) Swap(i, j int) {
 | 
			
		||||
	c[i], c[j] = c[j], c[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Completer is an interface which can be implemented by types
 | 
			
		||||
// to provide custom command line argument completion.
 | 
			
		||||
type Completer interface {
 | 
			
		||||
	// Complete receives a prefix representing a (partial) value
 | 
			
		||||
	// for its type and should provide a list of possible valid
 | 
			
		||||
	// completions.
 | 
			
		||||
	Complete(match string) []Completion
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type completion struct {
 | 
			
		||||
	parser *Parser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Filename is a string alias which provides filename completion.
 | 
			
		||||
type Filename string
 | 
			
		||||
 | 
			
		||||
func completionsWithoutDescriptions(items []string) []Completion {
 | 
			
		||||
	ret := make([]Completion, len(items))
 | 
			
		||||
 | 
			
		||||
	for i, v := range items {
 | 
			
		||||
		ret[i].Item = v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Complete returns a list of existing files with the given
 | 
			
		||||
// prefix.
 | 
			
		||||
func (f *Filename) Complete(match string) []Completion {
 | 
			
		||||
	ret, _ := filepath.Glob(match + "*")
 | 
			
		||||
	return completionsWithoutDescriptions(ret)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) skipPositional(s *parseState, n int) {
 | 
			
		||||
	if n >= len(s.positional) {
 | 
			
		||||
		s.positional = nil
 | 
			
		||||
	} else {
 | 
			
		||||
		s.positional = s.positional[n:]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) completeOptionNames(s *parseState, prefix string, match string, short bool) []Completion {
 | 
			
		||||
	if short && len(match) != 0 {
 | 
			
		||||
		return []Completion{
 | 
			
		||||
			Completion{
 | 
			
		||||
				Item: prefix + match,
 | 
			
		||||
			},
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var results []Completion
 | 
			
		||||
	repeats := map[string]bool{}
 | 
			
		||||
 | 
			
		||||
	for name, opt := range s.lookup.longNames {
 | 
			
		||||
		if strings.HasPrefix(name, match) && !opt.Hidden {
 | 
			
		||||
			results = append(results, Completion{
 | 
			
		||||
				Item:        defaultLongOptDelimiter + name,
 | 
			
		||||
				Description: opt.Description,
 | 
			
		||||
			})
 | 
			
		||||
 | 
			
		||||
			if short {
 | 
			
		||||
				repeats[string(opt.ShortName)] = true
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if short {
 | 
			
		||||
		for name, opt := range s.lookup.shortNames {
 | 
			
		||||
			if _, exist := repeats[name]; !exist && strings.HasPrefix(name, match) && !opt.Hidden {
 | 
			
		||||
				results = append(results, Completion{
 | 
			
		||||
					Item:        string(defaultShortOptDelimiter) + name,
 | 
			
		||||
					Description: opt.Description,
 | 
			
		||||
				})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return results
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) completeNamesForLongPrefix(s *parseState, prefix string, match string) []Completion {
 | 
			
		||||
	return c.completeOptionNames(s, prefix, match, false)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) completeNamesForShortPrefix(s *parseState, prefix string, match string) []Completion {
 | 
			
		||||
	return c.completeOptionNames(s, prefix, match, true)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) completeCommands(s *parseState, match string) []Completion {
 | 
			
		||||
	n := make([]Completion, 0, len(s.command.commands))
 | 
			
		||||
 | 
			
		||||
	for _, cmd := range s.command.commands {
 | 
			
		||||
		if cmd.data != c && strings.HasPrefix(cmd.Name, match) {
 | 
			
		||||
			n = append(n, Completion{
 | 
			
		||||
				Item:        cmd.Name,
 | 
			
		||||
				Description: cmd.ShortDescription,
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return n
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) completeValue(value reflect.Value, prefix string, match string) []Completion {
 | 
			
		||||
	if value.Kind() == reflect.Slice {
 | 
			
		||||
		value = reflect.New(value.Type().Elem())
 | 
			
		||||
	}
 | 
			
		||||
	i := value.Interface()
 | 
			
		||||
 | 
			
		||||
	var ret []Completion
 | 
			
		||||
 | 
			
		||||
	if cmp, ok := i.(Completer); ok {
 | 
			
		||||
		ret = cmp.Complete(match)
 | 
			
		||||
	} else if value.CanAddr() {
 | 
			
		||||
		if cmp, ok = value.Addr().Interface().(Completer); ok {
 | 
			
		||||
			ret = cmp.Complete(match)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, v := range ret {
 | 
			
		||||
		ret[i].Item = prefix + v.Item
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) complete(args []string) []Completion {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		args = []string{""}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := &parseState{
 | 
			
		||||
		args: args,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.parser.fillParseState(s)
 | 
			
		||||
 | 
			
		||||
	var opt *Option
 | 
			
		||||
 | 
			
		||||
	for len(s.args) > 1 {
 | 
			
		||||
		arg := s.pop()
 | 
			
		||||
 | 
			
		||||
		if (c.parser.Options&PassDoubleDash) != None && arg == "--" {
 | 
			
		||||
			opt = nil
 | 
			
		||||
			c.skipPositional(s, len(s.args)-1)
 | 
			
		||||
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if argumentIsOption(arg) {
 | 
			
		||||
			prefix, optname, islong := stripOptionPrefix(arg)
 | 
			
		||||
			optname, _, argument := splitOption(prefix, optname, islong)
 | 
			
		||||
 | 
			
		||||
			if argument == nil {
 | 
			
		||||
				var o *Option
 | 
			
		||||
				canarg := true
 | 
			
		||||
 | 
			
		||||
				if islong {
 | 
			
		||||
					o = s.lookup.longNames[optname]
 | 
			
		||||
				} else {
 | 
			
		||||
					for i, r := range optname {
 | 
			
		||||
						sname := string(r)
 | 
			
		||||
						o = s.lookup.shortNames[sname]
 | 
			
		||||
 | 
			
		||||
						if o == nil {
 | 
			
		||||
							break
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						if i == 0 && o.canArgument() && len(optname) != len(sname) {
 | 
			
		||||
							canarg = false
 | 
			
		||||
							break
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if o == nil && (c.parser.Options&PassAfterNonOption) != None {
 | 
			
		||||
					opt = nil
 | 
			
		||||
					c.skipPositional(s, len(s.args)-1)
 | 
			
		||||
 | 
			
		||||
					break
 | 
			
		||||
				} else if o != nil && o.canArgument() && !o.OptionalArgument && canarg {
 | 
			
		||||
					if len(s.args) > 1 {
 | 
			
		||||
						s.pop()
 | 
			
		||||
					} else {
 | 
			
		||||
						opt = o
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			if len(s.positional) > 0 {
 | 
			
		||||
				if !s.positional[0].isRemaining() {
 | 
			
		||||
					// Don't advance beyond a remaining positional arg (because
 | 
			
		||||
					// it consumes all subsequent args).
 | 
			
		||||
					s.positional = s.positional[1:]
 | 
			
		||||
				}
 | 
			
		||||
			} else if cmd, ok := s.lookup.commands[arg]; ok {
 | 
			
		||||
				cmd.fillParseState(s)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			opt = nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	lastarg := s.args[len(s.args)-1]
 | 
			
		||||
	var ret []Completion
 | 
			
		||||
 | 
			
		||||
	if opt != nil {
 | 
			
		||||
		// Completion for the argument of 'opt'
 | 
			
		||||
		ret = c.completeValue(opt.value, "", lastarg)
 | 
			
		||||
	} else if argumentStartsOption(lastarg) {
 | 
			
		||||
		// Complete the option
 | 
			
		||||
		prefix, optname, islong := stripOptionPrefix(lastarg)
 | 
			
		||||
		optname, split, argument := splitOption(prefix, optname, islong)
 | 
			
		||||
 | 
			
		||||
		if argument == nil && !islong {
 | 
			
		||||
			rname, n := utf8.DecodeRuneInString(optname)
 | 
			
		||||
			sname := string(rname)
 | 
			
		||||
 | 
			
		||||
			if opt := s.lookup.shortNames[sname]; opt != nil && opt.canArgument() {
 | 
			
		||||
				ret = c.completeValue(opt.value, prefix+sname, optname[n:])
 | 
			
		||||
			} else {
 | 
			
		||||
				ret = c.completeNamesForShortPrefix(s, prefix, optname)
 | 
			
		||||
			}
 | 
			
		||||
		} else if argument != nil {
 | 
			
		||||
			if islong {
 | 
			
		||||
				opt = s.lookup.longNames[optname]
 | 
			
		||||
			} else {
 | 
			
		||||
				opt = s.lookup.shortNames[optname]
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if opt != nil {
 | 
			
		||||
				ret = c.completeValue(opt.value, prefix+optname+split, *argument)
 | 
			
		||||
			}
 | 
			
		||||
		} else if islong {
 | 
			
		||||
			ret = c.completeNamesForLongPrefix(s, prefix, optname)
 | 
			
		||||
		} else {
 | 
			
		||||
			ret = c.completeNamesForShortPrefix(s, prefix, optname)
 | 
			
		||||
		}
 | 
			
		||||
	} else if len(s.positional) > 0 {
 | 
			
		||||
		// Complete for positional argument
 | 
			
		||||
		ret = c.completeValue(s.positional[0].value, "", lastarg)
 | 
			
		||||
	} else if len(s.command.commands) > 0 {
 | 
			
		||||
		// Complete for command
 | 
			
		||||
		ret = c.completeCommands(s, lastarg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Sort(completions(ret))
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *completion) print(items []Completion, showDescriptions bool) {
 | 
			
		||||
	if showDescriptions && len(items) > 1 {
 | 
			
		||||
		maxl := 0
 | 
			
		||||
 | 
			
		||||
		for _, v := range items {
 | 
			
		||||
			if len(v.Item) > maxl {
 | 
			
		||||
				maxl = len(v.Item)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, v := range items {
 | 
			
		||||
			fmt.Printf("%s", v.Item)
 | 
			
		||||
 | 
			
		||||
			if len(v.Description) > 0 {
 | 
			
		||||
				fmt.Printf("%s  # %s", strings.Repeat(" ", maxl-len(v.Item)), v.Description)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Printf("\n")
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		for _, v := range items {
 | 
			
		||||
			fmt.Println(v.Item)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										348
									
								
								vendor/github.com/jessevdk/go-flags/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								vendor/github.com/jessevdk/go-flags/convert.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,348 @@
 | 
			
		||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Marshaler is the interface implemented by types that can marshal themselves
 | 
			
		||||
// to a string representation of the flag.
 | 
			
		||||
type Marshaler interface {
 | 
			
		||||
	// MarshalFlag marshals a flag value to its string representation.
 | 
			
		||||
	MarshalFlag() (string, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Unmarshaler is the interface implemented by types that can unmarshal a flag
 | 
			
		||||
// argument to themselves. The provided value is directly passed from the
 | 
			
		||||
// command line.
 | 
			
		||||
type Unmarshaler interface {
 | 
			
		||||
	// UnmarshalFlag unmarshals a string value representation to the flag
 | 
			
		||||
	// value (which therefore needs to be a pointer receiver).
 | 
			
		||||
	UnmarshalFlag(value string) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getBase(options multiTag, base int) (int, error) {
 | 
			
		||||
	sbase := options.Get("base")
 | 
			
		||||
 | 
			
		||||
	var err error
 | 
			
		||||
	var ivbase int64
 | 
			
		||||
 | 
			
		||||
	if sbase != "" {
 | 
			
		||||
		ivbase, err = strconv.ParseInt(sbase, 10, 32)
 | 
			
		||||
		base = int(ivbase)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return base, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convertMarshal(val reflect.Value) (bool, string, error) {
 | 
			
		||||
	// Check first for the Marshaler interface
 | 
			
		||||
	if val.Type().NumMethod() > 0 && val.CanInterface() {
 | 
			
		||||
		if marshaler, ok := val.Interface().(Marshaler); ok {
 | 
			
		||||
			ret, err := marshaler.MarshalFlag()
 | 
			
		||||
			return true, ret, err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false, "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convertToString(val reflect.Value, options multiTag) (string, error) {
 | 
			
		||||
	if ok, ret, err := convertMarshal(val); ok {
 | 
			
		||||
		return ret, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tp := val.Type()
 | 
			
		||||
 | 
			
		||||
	// Support for time.Duration
 | 
			
		||||
	if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() {
 | 
			
		||||
		stringer := val.Interface().(fmt.Stringer)
 | 
			
		||||
		return stringer.String(), nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch tp.Kind() {
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		return val.String(), nil
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		if val.Bool() {
 | 
			
		||||
			return "true", nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return "false", nil
 | 
			
		||||
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 | 
			
		||||
		base, err := getBase(options, 10)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return strconv.FormatInt(val.Int(), base), nil
 | 
			
		||||
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 | 
			
		||||
		base, err := getBase(options, 10)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return strconv.FormatUint(val.Uint(), base), nil
 | 
			
		||||
	case reflect.Float32, reflect.Float64:
 | 
			
		||||
		return strconv.FormatFloat(val.Float(), 'g', -1, tp.Bits()), nil
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		if val.Len() == 0 {
 | 
			
		||||
			return "", nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret := "["
 | 
			
		||||
 | 
			
		||||
		for i := 0; i < val.Len(); i++ {
 | 
			
		||||
			if i != 0 {
 | 
			
		||||
				ret += ", "
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			item, err := convertToString(val.Index(i), options)
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ret += item
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return ret + "]", nil
 | 
			
		||||
	case reflect.Map:
 | 
			
		||||
		ret := "{"
 | 
			
		||||
 | 
			
		||||
		for i, key := range val.MapKeys() {
 | 
			
		||||
			if i != 0 {
 | 
			
		||||
				ret += ", "
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			keyitem, err := convertToString(key, options)
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			item, err := convertToString(val.MapIndex(key), options)
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return "", err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ret += keyitem + ":" + item
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return ret + "}", nil
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		return convertToString(reflect.Indirect(val), options)
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		if !val.IsNil() {
 | 
			
		||||
			return convertToString(val.Elem(), options)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convertUnmarshal(val string, retval reflect.Value) (bool, error) {
 | 
			
		||||
	if retval.Type().NumMethod() > 0 && retval.CanInterface() {
 | 
			
		||||
		if unmarshaler, ok := retval.Interface().(Unmarshaler); ok {
 | 
			
		||||
			if retval.IsNil() {
 | 
			
		||||
				retval.Set(reflect.New(retval.Type().Elem()))
 | 
			
		||||
 | 
			
		||||
				// Re-assign from the new value
 | 
			
		||||
				unmarshaler = retval.Interface().(Unmarshaler)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return true, unmarshaler.UnmarshalFlag(val)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if retval.Type().Kind() != reflect.Ptr && retval.CanAddr() {
 | 
			
		||||
		return convertUnmarshal(val, retval.Addr())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if retval.Type().Kind() == reflect.Interface && !retval.IsNil() {
 | 
			
		||||
		return convertUnmarshal(val, retval.Elem())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func convert(val string, retval reflect.Value, options multiTag) error {
 | 
			
		||||
	if ok, err := convertUnmarshal(val, retval); ok {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	tp := retval.Type()
 | 
			
		||||
 | 
			
		||||
	// Support for time.Duration
 | 
			
		||||
	if tp == reflect.TypeOf((*time.Duration)(nil)).Elem() {
 | 
			
		||||
		parsed, err := time.ParseDuration(val)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.SetInt(int64(parsed))
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch tp.Kind() {
 | 
			
		||||
	case reflect.String:
 | 
			
		||||
		retval.SetString(val)
 | 
			
		||||
	case reflect.Bool:
 | 
			
		||||
		if val == "" {
 | 
			
		||||
			retval.SetBool(true)
 | 
			
		||||
		} else {
 | 
			
		||||
			b, err := strconv.ParseBool(val)
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			retval.SetBool(b)
 | 
			
		||||
		}
 | 
			
		||||
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
 | 
			
		||||
		base, err := getBase(options, 10)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		parsed, err := strconv.ParseInt(val, base, tp.Bits())
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.SetInt(parsed)
 | 
			
		||||
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
 | 
			
		||||
		base, err := getBase(options, 10)
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		parsed, err := strconv.ParseUint(val, base, tp.Bits())
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.SetUint(parsed)
 | 
			
		||||
	case reflect.Float32, reflect.Float64:
 | 
			
		||||
		parsed, err := strconv.ParseFloat(val, tp.Bits())
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.SetFloat(parsed)
 | 
			
		||||
	case reflect.Slice:
 | 
			
		||||
		elemtp := tp.Elem()
 | 
			
		||||
 | 
			
		||||
		elemvalptr := reflect.New(elemtp)
 | 
			
		||||
		elemval := reflect.Indirect(elemvalptr)
 | 
			
		||||
 | 
			
		||||
		if err := convert(val, elemval, options); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.Set(reflect.Append(retval, elemval))
 | 
			
		||||
	case reflect.Map:
 | 
			
		||||
		parts := strings.SplitN(val, ":", 2)
 | 
			
		||||
 | 
			
		||||
		key := parts[0]
 | 
			
		||||
		var value string
 | 
			
		||||
 | 
			
		||||
		if len(parts) == 2 {
 | 
			
		||||
			value = parts[1]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		keytp := tp.Key()
 | 
			
		||||
		keyval := reflect.New(keytp)
 | 
			
		||||
 | 
			
		||||
		if err := convert(key, keyval, options); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		valuetp := tp.Elem()
 | 
			
		||||
		valueval := reflect.New(valuetp)
 | 
			
		||||
 | 
			
		||||
		if err := convert(value, valueval, options); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if retval.IsNil() {
 | 
			
		||||
			retval.Set(reflect.MakeMap(tp))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval.SetMapIndex(reflect.Indirect(keyval), reflect.Indirect(valueval))
 | 
			
		||||
	case reflect.Ptr:
 | 
			
		||||
		if retval.IsNil() {
 | 
			
		||||
			retval.Set(reflect.New(retval.Type().Elem()))
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return convert(val, reflect.Indirect(retval), options)
 | 
			
		||||
	case reflect.Interface:
 | 
			
		||||
		if !retval.IsNil() {
 | 
			
		||||
			return convert(val, retval.Elem(), options)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isPrint(s string) bool {
 | 
			
		||||
	for _, c := range s {
 | 
			
		||||
		if !strconv.IsPrint(c) {
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func quoteIfNeeded(s string) string {
 | 
			
		||||
	if !isPrint(s) {
 | 
			
		||||
		return strconv.Quote(s)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func quoteIfNeededV(s []string) []string {
 | 
			
		||||
	ret := make([]string, len(s))
 | 
			
		||||
 | 
			
		||||
	for i, v := range s {
 | 
			
		||||
		ret[i] = quoteIfNeeded(v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func quoteV(s []string) []string {
 | 
			
		||||
	ret := make([]string, len(s))
 | 
			
		||||
 | 
			
		||||
	for i, v := range s {
 | 
			
		||||
		ret[i] = strconv.Quote(v)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func unquoteIfPossible(s string) (string, error) {
 | 
			
		||||
	if len(s) == 0 || s[0] != '"' {
 | 
			
		||||
		return s, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return strconv.Unquote(s)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										134
									
								
								vendor/github.com/jessevdk/go-flags/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								vendor/github.com/jessevdk/go-flags/error.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrorType represents the type of error.
 | 
			
		||||
type ErrorType uint
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// ErrUnknown indicates a generic error.
 | 
			
		||||
	ErrUnknown ErrorType = iota
 | 
			
		||||
 | 
			
		||||
	// ErrExpectedArgument indicates that an argument was expected.
 | 
			
		||||
	ErrExpectedArgument
 | 
			
		||||
 | 
			
		||||
	// ErrUnknownFlag indicates an unknown flag.
 | 
			
		||||
	ErrUnknownFlag
 | 
			
		||||
 | 
			
		||||
	// ErrUnknownGroup indicates an unknown group.
 | 
			
		||||
	ErrUnknownGroup
 | 
			
		||||
 | 
			
		||||
	// ErrMarshal indicates a marshalling error while converting values.
 | 
			
		||||
	ErrMarshal
 | 
			
		||||
 | 
			
		||||
	// ErrHelp indicates that the built-in help was shown (the error
 | 
			
		||||
	// contains the help message).
 | 
			
		||||
	ErrHelp
 | 
			
		||||
 | 
			
		||||
	// ErrNoArgumentForBool indicates that an argument was given for a
 | 
			
		||||
	// boolean flag (which don't not take any arguments).
 | 
			
		||||
	ErrNoArgumentForBool
 | 
			
		||||
 | 
			
		||||
	// ErrRequired indicates that a required flag was not provided.
 | 
			
		||||
	ErrRequired
 | 
			
		||||
 | 
			
		||||
	// ErrShortNameTooLong indicates that a short flag name was specified,
 | 
			
		||||
	// longer than one character.
 | 
			
		||||
	ErrShortNameTooLong
 | 
			
		||||
 | 
			
		||||
	// ErrDuplicatedFlag indicates that a short or long flag has been
 | 
			
		||||
	// defined more than once
 | 
			
		||||
	ErrDuplicatedFlag
 | 
			
		||||
 | 
			
		||||
	// ErrTag indicates an error while parsing flag tags.
 | 
			
		||||
	ErrTag
 | 
			
		||||
 | 
			
		||||
	// ErrCommandRequired indicates that a command was required but not
 | 
			
		||||
	// specified
 | 
			
		||||
	ErrCommandRequired
 | 
			
		||||
 | 
			
		||||
	// ErrUnknownCommand indicates that an unknown command was specified.
 | 
			
		||||
	ErrUnknownCommand
 | 
			
		||||
 | 
			
		||||
	// ErrInvalidChoice indicates an invalid option value which only allows
 | 
			
		||||
	// a certain number of choices.
 | 
			
		||||
	ErrInvalidChoice
 | 
			
		||||
 | 
			
		||||
	// ErrInvalidTag indicates an invalid tag or invalid use of an existing tag
 | 
			
		||||
	ErrInvalidTag
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (e ErrorType) String() string {
 | 
			
		||||
	switch e {
 | 
			
		||||
	case ErrUnknown:
 | 
			
		||||
		return "unknown"
 | 
			
		||||
	case ErrExpectedArgument:
 | 
			
		||||
		return "expected argument"
 | 
			
		||||
	case ErrUnknownFlag:
 | 
			
		||||
		return "unknown flag"
 | 
			
		||||
	case ErrUnknownGroup:
 | 
			
		||||
		return "unknown group"
 | 
			
		||||
	case ErrMarshal:
 | 
			
		||||
		return "marshal"
 | 
			
		||||
	case ErrHelp:
 | 
			
		||||
		return "help"
 | 
			
		||||
	case ErrNoArgumentForBool:
 | 
			
		||||
		return "no argument for bool"
 | 
			
		||||
	case ErrRequired:
 | 
			
		||||
		return "required"
 | 
			
		||||
	case ErrShortNameTooLong:
 | 
			
		||||
		return "short name too long"
 | 
			
		||||
	case ErrDuplicatedFlag:
 | 
			
		||||
		return "duplicated flag"
 | 
			
		||||
	case ErrTag:
 | 
			
		||||
		return "tag"
 | 
			
		||||
	case ErrCommandRequired:
 | 
			
		||||
		return "command required"
 | 
			
		||||
	case ErrUnknownCommand:
 | 
			
		||||
		return "unknown command"
 | 
			
		||||
	case ErrInvalidChoice:
 | 
			
		||||
		return "invalid choice"
 | 
			
		||||
	case ErrInvalidTag:
 | 
			
		||||
		return "invalid tag"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "unrecognized error type"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error represents a parser error. The error returned from Parse is of this
 | 
			
		||||
// type. The error contains both a Type and Message.
 | 
			
		||||
type Error struct {
 | 
			
		||||
	// The type of error
 | 
			
		||||
	Type ErrorType
 | 
			
		||||
 | 
			
		||||
	// The error message
 | 
			
		||||
	Message string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error returns the error's message
 | 
			
		||||
func (e *Error) Error() string {
 | 
			
		||||
	return e.Message
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newError(tp ErrorType, message string) *Error {
 | 
			
		||||
	return &Error{
 | 
			
		||||
		Type:    tp,
 | 
			
		||||
		Message: message,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newErrorf(tp ErrorType, format string, args ...interface{}) *Error {
 | 
			
		||||
	return newError(tp, fmt.Sprintf(format, args...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func wrapError(err error) *Error {
 | 
			
		||||
	ret, ok := err.(*Error)
 | 
			
		||||
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return newError(ErrUnknown, err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										258
									
								
								vendor/github.com/jessevdk/go-flags/flags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										258
									
								
								vendor/github.com/jessevdk/go-flags/flags.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,258 @@
 | 
			
		||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
Package flags provides an extensive command line option parser.
 | 
			
		||||
The flags package is similar in functionality to the go built-in flag package
 | 
			
		||||
but provides more options and uses reflection to provide a convenient and
 | 
			
		||||
succinct way of specifying command line options.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Supported features
 | 
			
		||||
 | 
			
		||||
The following features are supported in go-flags:
 | 
			
		||||
 | 
			
		||||
    Options with short names (-v)
 | 
			
		||||
    Options with long names (--verbose)
 | 
			
		||||
    Options with and without arguments (bool v.s. other type)
 | 
			
		||||
    Options with optional arguments and default values
 | 
			
		||||
    Option default values from ENVIRONMENT_VARIABLES, including slice and map values
 | 
			
		||||
    Multiple option groups each containing a set of options
 | 
			
		||||
    Generate and print well-formatted help message
 | 
			
		||||
    Passing remaining command line arguments after -- (optional)
 | 
			
		||||
    Ignoring unknown command line options (optional)
 | 
			
		||||
    Supports -I/usr/include -I=/usr/include -I /usr/include option argument specification
 | 
			
		||||
    Supports multiple short options -aux
 | 
			
		||||
    Supports all primitive go types (string, int{8..64}, uint{8..64}, float)
 | 
			
		||||
    Supports same option multiple times (can store in slice or last option counts)
 | 
			
		||||
    Supports maps
 | 
			
		||||
    Supports function callbacks
 | 
			
		||||
    Supports namespaces for (nested) option groups
 | 
			
		||||
 | 
			
		||||
Additional features specific to Windows:
 | 
			
		||||
    Options with short names (/v)
 | 
			
		||||
    Options with long names (/verbose)
 | 
			
		||||
    Windows-style options with arguments use a colon as the delimiter
 | 
			
		||||
    Modify generated help message with Windows-style / options
 | 
			
		||||
    Windows style options can be disabled at build time using the "forceposix"
 | 
			
		||||
    build tag
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Basic usage
 | 
			
		||||
 | 
			
		||||
The flags package uses structs, reflection and struct field tags
 | 
			
		||||
to allow users to specify command line options. This results in very simple
 | 
			
		||||
and concise specification of your application options. For example:
 | 
			
		||||
 | 
			
		||||
    type Options struct {
 | 
			
		||||
        Verbose []bool `short:"v" long:"verbose" description:"Show verbose debug information"`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
This specifies one option with a short name -v and a long name --verbose.
 | 
			
		||||
When either -v or --verbose is found on the command line, a 'true' value
 | 
			
		||||
will be appended to the Verbose field. e.g. when specifying -vvv, the
 | 
			
		||||
resulting value of Verbose will be {[true, true, true]}.
 | 
			
		||||
 | 
			
		||||
Slice options work exactly the same as primitive type options, except that
 | 
			
		||||
whenever the option is encountered, a value is appended to the slice.
 | 
			
		||||
 | 
			
		||||
Map options from string to primitive type are also supported. On the command
 | 
			
		||||
line, you specify the value for such an option as key:value. For example
 | 
			
		||||
 | 
			
		||||
    type Options struct {
 | 
			
		||||
        AuthorInfo string[string] `short:"a"`
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
Then, the AuthorInfo map can be filled with something like
 | 
			
		||||
-a name:Jesse -a "surname:van den Kieboom".
 | 
			
		||||
 | 
			
		||||
Finally, for full control over the conversion between command line argument
 | 
			
		||||
values and options, user defined types can choose to implement the Marshaler
 | 
			
		||||
and Unmarshaler interfaces.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Available field tags
 | 
			
		||||
 | 
			
		||||
The following is a list of tags for struct fields supported by go-flags:
 | 
			
		||||
 | 
			
		||||
    short:            the short name of the option (single character)
 | 
			
		||||
    long:             the long name of the option
 | 
			
		||||
    required:         if non empty, makes the option required to appear on the command
 | 
			
		||||
                      line. If a required option is not present, the parser will
 | 
			
		||||
                      return ErrRequired (optional)
 | 
			
		||||
    description:      the description of the option (optional)
 | 
			
		||||
    long-description: the long description of the option. Currently only
 | 
			
		||||
                      displayed in generated man pages (optional)
 | 
			
		||||
    no-flag:          if non-empty, this field is ignored as an option (optional)
 | 
			
		||||
 | 
			
		||||
    optional:       if non-empty, makes the argument of the option optional. When an
 | 
			
		||||
                    argument is optional it can only be specified using
 | 
			
		||||
                    --option=argument (optional)
 | 
			
		||||
    optional-value: the value of an optional option when the option occurs
 | 
			
		||||
                    without an argument. This tag can be specified multiple
 | 
			
		||||
                    times in the case of maps or slices (optional)
 | 
			
		||||
    default:        the default value of an option. This tag can be specified
 | 
			
		||||
                    multiple times in the case of slices or maps (optional)
 | 
			
		||||
    default-mask:   when specified, this value will be displayed in the help
 | 
			
		||||
                    instead of the actual default value. This is useful
 | 
			
		||||
                    mostly for hiding otherwise sensitive information from
 | 
			
		||||
                    showing up in the help. If default-mask takes the special
 | 
			
		||||
                    value "-", then no default value will be shown at all
 | 
			
		||||
                    (optional)
 | 
			
		||||
    env:            the default value of the option is overridden from the
 | 
			
		||||
                    specified environment variable, if one has been defined.
 | 
			
		||||
                    (optional)
 | 
			
		||||
    env-delim:      the 'env' default value from environment is split into
 | 
			
		||||
                    multiple values with the given delimiter string, use with
 | 
			
		||||
                    slices and maps (optional)
 | 
			
		||||
    value-name:     the name of the argument value (to be shown in the help)
 | 
			
		||||
                    (optional)
 | 
			
		||||
    choice:         limits the values for an option to a set of values.
 | 
			
		||||
                    This tag can be specified multiple times (optional)
 | 
			
		||||
    hidden:         if non-empty, the option is not visible in the help or man page.
 | 
			
		||||
 | 
			
		||||
    base: a base (radix) used to convert strings to integer values, the
 | 
			
		||||
          default base is 10 (i.e. decimal) (optional)
 | 
			
		||||
 | 
			
		||||
    ini-name:       the explicit ini option name (optional)
 | 
			
		||||
    no-ini:         if non-empty this field is ignored as an ini option
 | 
			
		||||
                    (optional)
 | 
			
		||||
 | 
			
		||||
    group:                when specified on a struct field, makes the struct
 | 
			
		||||
                          field a separate group with the given name (optional)
 | 
			
		||||
    namespace:            when specified on a group struct field, the namespace
 | 
			
		||||
                          gets prepended to every option's long name and
 | 
			
		||||
                          subgroup's namespace of this group, separated by
 | 
			
		||||
                          the parser's namespace delimiter (optional)
 | 
			
		||||
    command:              when specified on a struct field, makes the struct
 | 
			
		||||
                          field a (sub)command with the given name (optional)
 | 
			
		||||
    subcommands-optional: when specified on a command struct field, makes
 | 
			
		||||
                          any subcommands of that command optional (optional)
 | 
			
		||||
    alias:                when specified on a command struct field, adds the
 | 
			
		||||
                          specified name as an alias for the command. Can be
 | 
			
		||||
                          be specified multiple times to add more than one
 | 
			
		||||
                          alias (optional)
 | 
			
		||||
    positional-args:      when specified on a field with a struct type,
 | 
			
		||||
                          uses the fields of that struct to parse remaining
 | 
			
		||||
                          positional command line arguments into (in order
 | 
			
		||||
                          of the fields). If a field has a slice type,
 | 
			
		||||
                          then all remaining arguments will be added to it.
 | 
			
		||||
                          Positional arguments are optional by default,
 | 
			
		||||
                          unless the "required" tag is specified together
 | 
			
		||||
                          with the "positional-args" tag. The "required" tag
 | 
			
		||||
                          can also be set on the individual rest argument
 | 
			
		||||
                          fields, to require only the first N positional
 | 
			
		||||
                          arguments. If the "required" tag is set on the
 | 
			
		||||
                          rest arguments slice, then its value determines
 | 
			
		||||
                          the minimum amount of rest arguments that needs to
 | 
			
		||||
                          be provided (e.g. `required:"2"`) (optional)
 | 
			
		||||
    positional-arg-name:  used on a field in a positional argument struct; name
 | 
			
		||||
                          of the positional argument placeholder to be shown in
 | 
			
		||||
                          the help (optional)
 | 
			
		||||
 | 
			
		||||
Either the `short:` tag or the `long:` must be specified to make the field eligible as an
 | 
			
		||||
option.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Option groups
 | 
			
		||||
 | 
			
		||||
Option groups are a simple way to semantically separate your options. All
 | 
			
		||||
options in a particular group are shown together in the help under the name
 | 
			
		||||
of the group. Namespaces can be used to specify option long names more
 | 
			
		||||
precisely and emphasize the options affiliation to their group.
 | 
			
		||||
 | 
			
		||||
There are currently three ways to specify option groups.
 | 
			
		||||
 | 
			
		||||
    1. Use NewNamedParser specifying the various option groups.
 | 
			
		||||
    2. Use AddGroup to add a group to an existing parser.
 | 
			
		||||
    3. Add a struct field to the top-level options annotated with the
 | 
			
		||||
       group:"group-name" tag.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Commands
 | 
			
		||||
 | 
			
		||||
The flags package also has basic support for commands. Commands are often
 | 
			
		||||
used in monolithic applications that support various commands or actions.
 | 
			
		||||
Take git for example, all of the add, commit, checkout, etc. are called
 | 
			
		||||
commands. Using commands you can easily separate multiple functions of your
 | 
			
		||||
application.
 | 
			
		||||
 | 
			
		||||
There are currently two ways to specify a command.
 | 
			
		||||
 | 
			
		||||
    1. Use AddCommand on an existing parser.
 | 
			
		||||
    2. Add a struct field to your options struct annotated with the
 | 
			
		||||
       command:"command-name" tag.
 | 
			
		||||
 | 
			
		||||
The most common, idiomatic way to implement commands is to define a global
 | 
			
		||||
parser instance and implement each command in a separate file. These
 | 
			
		||||
command files should define a go init function which calls AddCommand on
 | 
			
		||||
the global parser.
 | 
			
		||||
 | 
			
		||||
When parsing ends and there is an active command and that command implements
 | 
			
		||||
the Commander interface, then its Execute method will be run with the
 | 
			
		||||
remaining command line arguments.
 | 
			
		||||
 | 
			
		||||
Command structs can have options which become valid to parse after the
 | 
			
		||||
command has been specified on the command line, in addition to the options
 | 
			
		||||
of all the parent commands. I.e. considering a -v flag on the parser and an
 | 
			
		||||
add command, the following are equivalent:
 | 
			
		||||
 | 
			
		||||
    ./app -v add
 | 
			
		||||
    ./app add -v
 | 
			
		||||
 | 
			
		||||
However, if the -v flag is defined on the add command, then the first of
 | 
			
		||||
the two examples above would fail since the -v flag is not defined before
 | 
			
		||||
the add command.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Completion
 | 
			
		||||
 | 
			
		||||
go-flags has builtin support to provide bash completion of flags, commands
 | 
			
		||||
and argument values. To use completion, the binary which uses go-flags
 | 
			
		||||
can be invoked in a special environment to list completion of the current
 | 
			
		||||
command line argument. It should be noted that this `executes` your application,
 | 
			
		||||
and it is up to the user to make sure there are no negative side effects (for
 | 
			
		||||
example from init functions).
 | 
			
		||||
 | 
			
		||||
Setting the environment variable `GO_FLAGS_COMPLETION=1` enables completion
 | 
			
		||||
by replacing the argument parsing routine with the completion routine which
 | 
			
		||||
outputs completions for the passed arguments. The basic invocation to
 | 
			
		||||
complete a set of arguments is therefore:
 | 
			
		||||
 | 
			
		||||
    GO_FLAGS_COMPLETION=1 ./completion-example arg1 arg2 arg3
 | 
			
		||||
 | 
			
		||||
where `completion-example` is the binary, `arg1` and `arg2` are
 | 
			
		||||
the current arguments, and `arg3` (the last argument) is the argument
 | 
			
		||||
to be completed. If the GO_FLAGS_COMPLETION is set to "verbose", then
 | 
			
		||||
descriptions of possible completion items will also be shown, if there
 | 
			
		||||
are more than 1 completion items.
 | 
			
		||||
 | 
			
		||||
To use this with bash completion, a simple file can be written which
 | 
			
		||||
calls the binary which supports go-flags completion:
 | 
			
		||||
 | 
			
		||||
    _completion_example() {
 | 
			
		||||
        # All arguments except the first one
 | 
			
		||||
        args=("${COMP_WORDS[@]:1:$COMP_CWORD}")
 | 
			
		||||
 | 
			
		||||
        # Only split on newlines
 | 
			
		||||
        local IFS=$'\n'
 | 
			
		||||
 | 
			
		||||
        # Call completion (note that the first element of COMP_WORDS is
 | 
			
		||||
        # the executable itself)
 | 
			
		||||
        COMPREPLY=($(GO_FLAGS_COMPLETION=1 ${COMP_WORDS[0]} "${args[@]}"))
 | 
			
		||||
        return 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    complete -F _completion_example completion-example
 | 
			
		||||
 | 
			
		||||
Completion requires the parser option PassDoubleDash and is therefore enforced if the environment variable GO_FLAGS_COMPLETION is set.
 | 
			
		||||
 | 
			
		||||
Customized completion for argument values is supported by implementing
 | 
			
		||||
the flags.Completer interface for the argument value type. An example
 | 
			
		||||
of a type which does so is the flags.Filename type, an alias of string
 | 
			
		||||
allowing simple filename completion. A slice or array argument value
 | 
			
		||||
whose element type implements flags.Completer will also be completed.
 | 
			
		||||
*/
 | 
			
		||||
package flags
 | 
			
		||||
							
								
								
									
										406
									
								
								vendor/github.com/jessevdk/go-flags/group.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										406
									
								
								vendor/github.com/jessevdk/go-flags/group.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,406 @@
 | 
			
		||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ErrNotPointerToStruct indicates that a provided data container is not
 | 
			
		||||
// a pointer to a struct. Only pointers to structs are valid data containers
 | 
			
		||||
// for options.
 | 
			
		||||
var ErrNotPointerToStruct = errors.New("provided data is not a pointer to struct")
 | 
			
		||||
 | 
			
		||||
// Group represents an option group. Option groups can be used to logically
 | 
			
		||||
// group options together under a description. Groups are only used to provide
 | 
			
		||||
// more structure to options both for the user (as displayed in the help message)
 | 
			
		||||
// and for you, since groups can be nested.
 | 
			
		||||
type Group struct {
 | 
			
		||||
	// A short description of the group. The
 | 
			
		||||
	// short description is primarily used in the built-in generated help
 | 
			
		||||
	// message
 | 
			
		||||
	ShortDescription string
 | 
			
		||||
 | 
			
		||||
	// A long description of the group. The long
 | 
			
		||||
	// description is primarily used to present information on commands
 | 
			
		||||
	// (Command embeds Group) in the built-in generated help and man pages.
 | 
			
		||||
	LongDescription string
 | 
			
		||||
 | 
			
		||||
	// The namespace of the group
 | 
			
		||||
	Namespace string
 | 
			
		||||
 | 
			
		||||
	// If true, the group is not displayed in the help or man page
 | 
			
		||||
	Hidden bool
 | 
			
		||||
 | 
			
		||||
	// The parent of the group or nil if it has no parent
 | 
			
		||||
	parent interface{}
 | 
			
		||||
 | 
			
		||||
	// All the options in the group
 | 
			
		||||
	options []*Option
 | 
			
		||||
 | 
			
		||||
	// All the subgroups
 | 
			
		||||
	groups []*Group
 | 
			
		||||
 | 
			
		||||
	// Whether the group represents the built-in help group
 | 
			
		||||
	isBuiltinHelp bool
 | 
			
		||||
 | 
			
		||||
	data interface{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type scanHandler func(reflect.Value, *reflect.StructField) (bool, error)
 | 
			
		||||
 | 
			
		||||
// AddGroup adds a new group to the command with the given name and data. The
 | 
			
		||||
// data needs to be a pointer to a struct from which the fields indicate which
 | 
			
		||||
// options are in the group.
 | 
			
		||||
func (g *Group) AddGroup(shortDescription string, longDescription string, data interface{}) (*Group, error) {
 | 
			
		||||
	group := newGroup(shortDescription, longDescription, data)
 | 
			
		||||
 | 
			
		||||
	group.parent = g
 | 
			
		||||
 | 
			
		||||
	if err := group.scan(); err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g.groups = append(g.groups, group)
 | 
			
		||||
	return group, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Groups returns the list of groups embedded in this group.
 | 
			
		||||
func (g *Group) Groups() []*Group {
 | 
			
		||||
	return g.groups
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Options returns the list of options in this group.
 | 
			
		||||
func (g *Group) Options() []*Option {
 | 
			
		||||
	return g.options
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Find locates the subgroup with the given short description and returns it.
 | 
			
		||||
// If no such group can be found Find will return nil. Note that the description
 | 
			
		||||
// is matched case insensitively.
 | 
			
		||||
func (g *Group) Find(shortDescription string) *Group {
 | 
			
		||||
	lshortDescription := strings.ToLower(shortDescription)
 | 
			
		||||
 | 
			
		||||
	var ret *Group
 | 
			
		||||
 | 
			
		||||
	g.eachGroup(func(gg *Group) {
 | 
			
		||||
		if gg != g && strings.ToLower(gg.ShortDescription) == lshortDescription {
 | 
			
		||||
			ret = gg
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) findOption(matcher func(*Option) bool) (option *Option) {
 | 
			
		||||
	g.eachGroup(func(g *Group) {
 | 
			
		||||
		for _, opt := range g.options {
 | 
			
		||||
			if option == nil && matcher(opt) {
 | 
			
		||||
				option = opt
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return option
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindOptionByLongName finds an option that is part of the group, or any of its
 | 
			
		||||
// subgroups, by matching its long name (including the option namespace).
 | 
			
		||||
func (g *Group) FindOptionByLongName(longName string) *Option {
 | 
			
		||||
	return g.findOption(func(option *Option) bool {
 | 
			
		||||
		return option.LongNameWithNamespace() == longName
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FindOptionByShortName finds an option that is part of the group, or any of
 | 
			
		||||
// its subgroups, by matching its short name.
 | 
			
		||||
func (g *Group) FindOptionByShortName(shortName rune) *Option {
 | 
			
		||||
	return g.findOption(func(option *Option) bool {
 | 
			
		||||
		return option.ShortName == shortName
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newGroup(shortDescription string, longDescription string, data interface{}) *Group {
 | 
			
		||||
	return &Group{
 | 
			
		||||
		ShortDescription: shortDescription,
 | 
			
		||||
		LongDescription:  longDescription,
 | 
			
		||||
 | 
			
		||||
		data: data,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option {
 | 
			
		||||
	prio := 0
 | 
			
		||||
	var retopt *Option
 | 
			
		||||
 | 
			
		||||
	g.eachGroup(func(g *Group) {
 | 
			
		||||
		for _, opt := range g.options {
 | 
			
		||||
			if namematch != nil && namematch(opt, name) && prio < 4 {
 | 
			
		||||
				retopt = opt
 | 
			
		||||
				prio = 4
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if name == opt.field.Name && prio < 3 {
 | 
			
		||||
				retopt = opt
 | 
			
		||||
				prio = 3
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if name == opt.LongNameWithNamespace() && prio < 2 {
 | 
			
		||||
				retopt = opt
 | 
			
		||||
				prio = 2
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if opt.ShortName != 0 && name == string(opt.ShortName) && prio < 1 {
 | 
			
		||||
				retopt = opt
 | 
			
		||||
				prio = 1
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return retopt
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) eachGroup(f func(*Group)) {
 | 
			
		||||
	f(g)
 | 
			
		||||
 | 
			
		||||
	for _, gg := range g.groups {
 | 
			
		||||
		gg.eachGroup(f)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func isStringFalsy(s string) bool {
 | 
			
		||||
	return s == "" || s == "false" || s == "no" || s == "0"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) scanStruct(realval reflect.Value, sfield *reflect.StructField, handler scanHandler) error {
 | 
			
		||||
	stype := realval.Type()
 | 
			
		||||
 | 
			
		||||
	if sfield != nil {
 | 
			
		||||
		if ok, err := handler(realval, sfield); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		} else if ok {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < stype.NumField(); i++ {
 | 
			
		||||
		field := stype.Field(i)
 | 
			
		||||
 | 
			
		||||
		// PkgName is set only for non-exported fields, which we ignore
 | 
			
		||||
		if field.PkgPath != "" && !field.Anonymous {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		mtag := newMultiTag(string(field.Tag))
 | 
			
		||||
 | 
			
		||||
		if err := mtag.Parse(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Skip fields with the no-flag tag
 | 
			
		||||
		if mtag.Get("no-flag") != "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Dive deep into structs or pointers to structs
 | 
			
		||||
		kind := field.Type.Kind()
 | 
			
		||||
		fld := realval.Field(i)
 | 
			
		||||
 | 
			
		||||
		if kind == reflect.Struct {
 | 
			
		||||
			if err := g.scanStruct(fld, &field, handler); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		} else if kind == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
 | 
			
		||||
			flagCountBefore := len(g.options) + len(g.groups)
 | 
			
		||||
 | 
			
		||||
			if fld.IsNil() {
 | 
			
		||||
				fld = reflect.New(fld.Type().Elem())
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err := g.scanStruct(reflect.Indirect(fld), &field, handler); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(g.options)+len(g.groups) != flagCountBefore {
 | 
			
		||||
				realval.Field(i).Set(fld)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		longname := mtag.Get("long")
 | 
			
		||||
		shortname := mtag.Get("short")
 | 
			
		||||
 | 
			
		||||
		// Need at least either a short or long name
 | 
			
		||||
		if longname == "" && shortname == "" && mtag.Get("ini-name") == "" {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		short := rune(0)
 | 
			
		||||
		rc := utf8.RuneCountInString(shortname)
 | 
			
		||||
 | 
			
		||||
		if rc > 1 {
 | 
			
		||||
			return newErrorf(ErrShortNameTooLong,
 | 
			
		||||
				"short names can only be 1 character long, not `%s'",
 | 
			
		||||
				shortname)
 | 
			
		||||
 | 
			
		||||
		} else if rc == 1 {
 | 
			
		||||
			short, _ = utf8.DecodeRuneInString(shortname)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		description := mtag.Get("description")
 | 
			
		||||
		def := mtag.GetMany("default")
 | 
			
		||||
 | 
			
		||||
		optionalValue := mtag.GetMany("optional-value")
 | 
			
		||||
		valueName := mtag.Get("value-name")
 | 
			
		||||
		defaultMask := mtag.Get("default-mask")
 | 
			
		||||
 | 
			
		||||
		optional := !isStringFalsy(mtag.Get("optional"))
 | 
			
		||||
		required := !isStringFalsy(mtag.Get("required"))
 | 
			
		||||
		choices := mtag.GetMany("choice")
 | 
			
		||||
		hidden := !isStringFalsy(mtag.Get("hidden"))
 | 
			
		||||
 | 
			
		||||
		option := &Option{
 | 
			
		||||
			Description:      description,
 | 
			
		||||
			ShortName:        short,
 | 
			
		||||
			LongName:         longname,
 | 
			
		||||
			Default:          def,
 | 
			
		||||
			EnvDefaultKey:    mtag.Get("env"),
 | 
			
		||||
			EnvDefaultDelim:  mtag.Get("env-delim"),
 | 
			
		||||
			OptionalArgument: optional,
 | 
			
		||||
			OptionalValue:    optionalValue,
 | 
			
		||||
			Required:         required,
 | 
			
		||||
			ValueName:        valueName,
 | 
			
		||||
			DefaultMask:      defaultMask,
 | 
			
		||||
			Choices:          choices,
 | 
			
		||||
			Hidden:           hidden,
 | 
			
		||||
 | 
			
		||||
			group: g,
 | 
			
		||||
 | 
			
		||||
			field: field,
 | 
			
		||||
			value: realval.Field(i),
 | 
			
		||||
			tag:   mtag,
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if option.isBool() && option.Default != nil {
 | 
			
		||||
			return newErrorf(ErrInvalidTag,
 | 
			
		||||
				"boolean flag `%s' may not have default values, they always default to `false' and can only be turned on",
 | 
			
		||||
				option.shortAndLongName())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		g.options = append(g.options, option)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) checkForDuplicateFlags() *Error {
 | 
			
		||||
	shortNames := make(map[rune]*Option)
 | 
			
		||||
	longNames := make(map[string]*Option)
 | 
			
		||||
 | 
			
		||||
	var duplicateError *Error
 | 
			
		||||
 | 
			
		||||
	g.eachGroup(func(g *Group) {
 | 
			
		||||
		for _, option := range g.options {
 | 
			
		||||
			if option.LongName != "" {
 | 
			
		||||
				longName := option.LongNameWithNamespace()
 | 
			
		||||
 | 
			
		||||
				if otherOption, ok := longNames[longName]; ok {
 | 
			
		||||
					duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same long name as option `%s'", option, otherOption)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				longNames[longName] = option
 | 
			
		||||
			}
 | 
			
		||||
			if option.ShortName != 0 {
 | 
			
		||||
				if otherOption, ok := shortNames[option.ShortName]; ok {
 | 
			
		||||
					duplicateError = newErrorf(ErrDuplicatedFlag, "option `%s' uses the same short name as option `%s'", option, otherOption)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				shortNames[option.ShortName] = option
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return duplicateError
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) scanSubGroupHandler(realval reflect.Value, sfield *reflect.StructField) (bool, error) {
 | 
			
		||||
	mtag := newMultiTag(string(sfield.Tag))
 | 
			
		||||
 | 
			
		||||
	if err := mtag.Parse(); err != nil {
 | 
			
		||||
		return true, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	subgroup := mtag.Get("group")
 | 
			
		||||
 | 
			
		||||
	if len(subgroup) != 0 {
 | 
			
		||||
		var ptrval reflect.Value
 | 
			
		||||
 | 
			
		||||
		if realval.Kind() == reflect.Ptr {
 | 
			
		||||
			ptrval = realval
 | 
			
		||||
 | 
			
		||||
			if ptrval.IsNil() {
 | 
			
		||||
				ptrval.Set(reflect.New(ptrval.Type()))
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			ptrval = realval.Addr()
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		description := mtag.Get("description")
 | 
			
		||||
 | 
			
		||||
		group, err := g.AddGroup(subgroup, description, ptrval.Interface())
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return true, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		group.Namespace = mtag.Get("namespace")
 | 
			
		||||
		group.Hidden = mtag.Get("hidden") != ""
 | 
			
		||||
 | 
			
		||||
		return true, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) scanType(handler scanHandler) error {
 | 
			
		||||
	// Get all the public fields in the data struct
 | 
			
		||||
	ptrval := reflect.ValueOf(g.data)
 | 
			
		||||
 | 
			
		||||
	if ptrval.Type().Kind() != reflect.Ptr {
 | 
			
		||||
		panic(ErrNotPointerToStruct)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stype := ptrval.Type().Elem()
 | 
			
		||||
 | 
			
		||||
	if stype.Kind() != reflect.Struct {
 | 
			
		||||
		panic(ErrNotPointerToStruct)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	realval := reflect.Indirect(ptrval)
 | 
			
		||||
 | 
			
		||||
	if err := g.scanStruct(realval, nil, handler); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := g.checkForDuplicateFlags(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) scan() error {
 | 
			
		||||
	return g.scanType(g.scanSubGroupHandler)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (g *Group) groupByName(name string) *Group {
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		return g
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g.Find(name)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										491
									
								
								vendor/github.com/jessevdk/go-flags/help.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										491
									
								
								vendor/github.com/jessevdk/go-flags/help.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,491 @@
 | 
			
		||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type alignmentInfo struct {
 | 
			
		||||
	maxLongLen      int
 | 
			
		||||
	hasShort        bool
 | 
			
		||||
	hasValueName    bool
 | 
			
		||||
	terminalColumns int
 | 
			
		||||
	indent          bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	paddingBeforeOption                 = 2
 | 
			
		||||
	distanceBetweenOptionAndDescription = 2
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (a *alignmentInfo) descriptionStart() int {
 | 
			
		||||
	ret := a.maxLongLen + distanceBetweenOptionAndDescription
 | 
			
		||||
 | 
			
		||||
	if a.hasShort {
 | 
			
		||||
		ret += 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if a.maxLongLen > 0 {
 | 
			
		||||
		ret += 4
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if a.hasValueName {
 | 
			
		||||
		ret += 3
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *alignmentInfo) updateLen(name string, indent bool) {
 | 
			
		||||
	l := utf8.RuneCountInString(name)
 | 
			
		||||
 | 
			
		||||
	if indent {
 | 
			
		||||
		l = l + 4
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if l > a.maxLongLen {
 | 
			
		||||
		a.maxLongLen = l
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) getAlignmentInfo() alignmentInfo {
 | 
			
		||||
	ret := alignmentInfo{
 | 
			
		||||
		maxLongLen:      0,
 | 
			
		||||
		hasShort:        false,
 | 
			
		||||
		hasValueName:    false,
 | 
			
		||||
		terminalColumns: getTerminalColumns(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ret.terminalColumns <= 0 {
 | 
			
		||||
		ret.terminalColumns = 80
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var prevcmd *Command
 | 
			
		||||
 | 
			
		||||
	p.eachActiveGroup(func(c *Command, grp *Group) {
 | 
			
		||||
		if c != prevcmd {
 | 
			
		||||
			for _, arg := range c.args {
 | 
			
		||||
				ret.updateLen(arg.Name, c != p.Command)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, info := range grp.options {
 | 
			
		||||
			if !info.canCli() {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if info.ShortName != 0 {
 | 
			
		||||
				ret.hasShort = true
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(info.ValueName) > 0 {
 | 
			
		||||
				ret.hasValueName = true
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			l := info.LongNameWithNamespace() + info.ValueName
 | 
			
		||||
 | 
			
		||||
			if len(info.Choices) != 0 {
 | 
			
		||||
				l += "[" + strings.Join(info.Choices, "|") + "]"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			ret.updateLen(l, c != p.Command)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func wrapText(s string, l int, prefix string) string {
 | 
			
		||||
	var ret string
 | 
			
		||||
 | 
			
		||||
	if l < 10 {
 | 
			
		||||
		l = 10
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Basic text wrapping of s at spaces to fit in l
 | 
			
		||||
	lines := strings.Split(s, "\n")
 | 
			
		||||
 | 
			
		||||
	for _, line := range lines {
 | 
			
		||||
		var retline string
 | 
			
		||||
 | 
			
		||||
		line = strings.TrimSpace(line)
 | 
			
		||||
 | 
			
		||||
		for len(line) > l {
 | 
			
		||||
			// Try to split on space
 | 
			
		||||
			suffix := ""
 | 
			
		||||
 | 
			
		||||
			pos := strings.LastIndex(line[:l], " ")
 | 
			
		||||
 | 
			
		||||
			if pos < 0 {
 | 
			
		||||
				pos = l - 1
 | 
			
		||||
				suffix = "-\n"
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(retline) != 0 {
 | 
			
		||||
				retline += "\n" + prefix
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			retline += strings.TrimSpace(line[:pos]) + suffix
 | 
			
		||||
			line = strings.TrimSpace(line[pos:])
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(line) > 0 {
 | 
			
		||||
			if len(retline) != 0 {
 | 
			
		||||
				retline += "\n" + prefix
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			retline += line
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(ret) > 0 {
 | 
			
		||||
			ret += "\n"
 | 
			
		||||
 | 
			
		||||
			if len(retline) > 0 {
 | 
			
		||||
				ret += prefix
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret += retline
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) writeHelpOption(writer *bufio.Writer, option *Option, info alignmentInfo) {
 | 
			
		||||
	line := &bytes.Buffer{}
 | 
			
		||||
 | 
			
		||||
	prefix := paddingBeforeOption
 | 
			
		||||
 | 
			
		||||
	if info.indent {
 | 
			
		||||
		prefix += 4
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if option.Hidden {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	line.WriteString(strings.Repeat(" ", prefix))
 | 
			
		||||
 | 
			
		||||
	if option.ShortName != 0 {
 | 
			
		||||
		line.WriteRune(defaultShortOptDelimiter)
 | 
			
		||||
		line.WriteRune(option.ShortName)
 | 
			
		||||
	} else if info.hasShort {
 | 
			
		||||
		line.WriteString("  ")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	descstart := info.descriptionStart() + paddingBeforeOption
 | 
			
		||||
 | 
			
		||||
	if len(option.LongName) > 0 {
 | 
			
		||||
		if option.ShortName != 0 {
 | 
			
		||||
			line.WriteString(", ")
 | 
			
		||||
		} else if info.hasShort {
 | 
			
		||||
			line.WriteString("  ")
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		line.WriteString(defaultLongOptDelimiter)
 | 
			
		||||
		line.WriteString(option.LongNameWithNamespace())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if option.canArgument() {
 | 
			
		||||
		line.WriteRune(defaultNameArgDelimiter)
 | 
			
		||||
 | 
			
		||||
		if len(option.ValueName) > 0 {
 | 
			
		||||
			line.WriteString(option.ValueName)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(option.Choices) > 0 {
 | 
			
		||||
			line.WriteString("[" + strings.Join(option.Choices, "|") + "]")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	written := line.Len()
 | 
			
		||||
	line.WriteTo(writer)
 | 
			
		||||
 | 
			
		||||
	if option.Description != "" {
 | 
			
		||||
		dw := descstart - written
 | 
			
		||||
		writer.WriteString(strings.Repeat(" ", dw))
 | 
			
		||||
 | 
			
		||||
		var def string
 | 
			
		||||
 | 
			
		||||
		if len(option.DefaultMask) != 0 {
 | 
			
		||||
			if option.DefaultMask != "-" {
 | 
			
		||||
				def = option.DefaultMask
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			def = option.defaultLiteral
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var envDef string
 | 
			
		||||
		if option.EnvDefaultKey != "" {
 | 
			
		||||
			var envPrintable string
 | 
			
		||||
			if runtime.GOOS == "windows" {
 | 
			
		||||
				envPrintable = "%" + option.EnvDefaultKey + "%"
 | 
			
		||||
			} else {
 | 
			
		||||
				envPrintable = "$" + option.EnvDefaultKey
 | 
			
		||||
			}
 | 
			
		||||
			envDef = fmt.Sprintf(" [%s]", envPrintable)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var desc string
 | 
			
		||||
 | 
			
		||||
		if def != "" {
 | 
			
		||||
			desc = fmt.Sprintf("%s (default: %v)%s", option.Description, def, envDef)
 | 
			
		||||
		} else {
 | 
			
		||||
			desc = option.Description + envDef
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		writer.WriteString(wrapText(desc,
 | 
			
		||||
			info.terminalColumns-descstart,
 | 
			
		||||
			strings.Repeat(" ", descstart)))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	writer.WriteString("\n")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func maxCommandLength(s []*Command) int {
 | 
			
		||||
	if len(s) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret := len(s[0].Name)
 | 
			
		||||
 | 
			
		||||
	for _, v := range s[1:] {
 | 
			
		||||
		l := len(v.Name)
 | 
			
		||||
 | 
			
		||||
		if l > ret {
 | 
			
		||||
			ret = l
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteHelp writes a help message containing all the possible options and
 | 
			
		||||
// their descriptions to the provided writer. Note that the HelpFlag parser
 | 
			
		||||
// option provides a convenient way to add a -h/--help option group to the
 | 
			
		||||
// command line parser which will automatically show the help messages using
 | 
			
		||||
// this method.
 | 
			
		||||
func (p *Parser) WriteHelp(writer io.Writer) {
 | 
			
		||||
	if writer == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wr := bufio.NewWriter(writer)
 | 
			
		||||
	aligninfo := p.getAlignmentInfo()
 | 
			
		||||
 | 
			
		||||
	cmd := p.Command
 | 
			
		||||
 | 
			
		||||
	for cmd.Active != nil {
 | 
			
		||||
		cmd = cmd.Active
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if p.Name != "" {
 | 
			
		||||
		wr.WriteString("Usage:\n")
 | 
			
		||||
		wr.WriteString(" ")
 | 
			
		||||
 | 
			
		||||
		allcmd := p.Command
 | 
			
		||||
 | 
			
		||||
		for allcmd != nil {
 | 
			
		||||
			var usage string
 | 
			
		||||
 | 
			
		||||
			if allcmd == p.Command {
 | 
			
		||||
				if len(p.Usage) != 0 {
 | 
			
		||||
					usage = p.Usage
 | 
			
		||||
				} else if p.Options&HelpFlag != 0 {
 | 
			
		||||
					usage = "[OPTIONS]"
 | 
			
		||||
				}
 | 
			
		||||
			} else if us, ok := allcmd.data.(Usage); ok {
 | 
			
		||||
				usage = us.Usage()
 | 
			
		||||
			} else if allcmd.hasCliOptions() {
 | 
			
		||||
				usage = fmt.Sprintf("[%s-OPTIONS]", allcmd.Name)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(usage) != 0 {
 | 
			
		||||
				fmt.Fprintf(wr, " %s %s", allcmd.Name, usage)
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprintf(wr, " %s", allcmd.Name)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(allcmd.args) > 0 {
 | 
			
		||||
				fmt.Fprintf(wr, " ")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for i, arg := range allcmd.args {
 | 
			
		||||
				if i != 0 {
 | 
			
		||||
					fmt.Fprintf(wr, " ")
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				name := arg.Name
 | 
			
		||||
 | 
			
		||||
				if arg.isRemaining() {
 | 
			
		||||
					name = name + "..."
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if !allcmd.ArgsRequired {
 | 
			
		||||
					fmt.Fprintf(wr, "[%s]", name)
 | 
			
		||||
				} else {
 | 
			
		||||
					fmt.Fprintf(wr, "%s", name)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if allcmd.Active == nil && len(allcmd.commands) > 0 {
 | 
			
		||||
				var co, cc string
 | 
			
		||||
 | 
			
		||||
				if allcmd.SubcommandsOptional {
 | 
			
		||||
					co, cc = "[", "]"
 | 
			
		||||
				} else {
 | 
			
		||||
					co, cc = "<", ">"
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				visibleCommands := allcmd.visibleCommands()
 | 
			
		||||
 | 
			
		||||
				if len(visibleCommands) > 3 {
 | 
			
		||||
					fmt.Fprintf(wr, " %scommand%s", co, cc)
 | 
			
		||||
				} else {
 | 
			
		||||
					subcommands := allcmd.sortedVisibleCommands()
 | 
			
		||||
					names := make([]string, len(subcommands))
 | 
			
		||||
 | 
			
		||||
					for i, subc := range subcommands {
 | 
			
		||||
						names[i] = subc.Name
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					fmt.Fprintf(wr, " %s%s%s", co, strings.Join(names, " | "), cc)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			allcmd = allcmd.Active
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintln(wr)
 | 
			
		||||
 | 
			
		||||
		if len(cmd.LongDescription) != 0 {
 | 
			
		||||
			fmt.Fprintln(wr)
 | 
			
		||||
 | 
			
		||||
			t := wrapText(cmd.LongDescription,
 | 
			
		||||
				aligninfo.terminalColumns,
 | 
			
		||||
				"")
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintln(wr, t)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c := p.Command
 | 
			
		||||
 | 
			
		||||
	for c != nil {
 | 
			
		||||
		printcmd := c != p.Command
 | 
			
		||||
 | 
			
		||||
		c.eachGroup(func(grp *Group) {
 | 
			
		||||
			first := true
 | 
			
		||||
 | 
			
		||||
			// Skip built-in help group for all commands except the top-level
 | 
			
		||||
			// parser
 | 
			
		||||
			if grp.Hidden || (grp.isBuiltinHelp && c != p.Command) {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for _, info := range grp.options {
 | 
			
		||||
				if !info.canCli() || info.Hidden {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if printcmd {
 | 
			
		||||
					fmt.Fprintf(wr, "\n[%s command options]\n", c.Name)
 | 
			
		||||
					aligninfo.indent = true
 | 
			
		||||
					printcmd = false
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if first && cmd.Group != grp {
 | 
			
		||||
					fmt.Fprintln(wr)
 | 
			
		||||
 | 
			
		||||
					if aligninfo.indent {
 | 
			
		||||
						wr.WriteString("    ")
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					fmt.Fprintf(wr, "%s:\n", grp.ShortDescription)
 | 
			
		||||
					first = false
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				p.writeHelpOption(wr, info, aligninfo)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		var args []*Arg
 | 
			
		||||
		for _, arg := range c.args {
 | 
			
		||||
			if arg.Description != "" {
 | 
			
		||||
				args = append(args, arg)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(args) > 0 {
 | 
			
		||||
			if c == p.Command {
 | 
			
		||||
				fmt.Fprintf(wr, "\nArguments:\n")
 | 
			
		||||
			} else {
 | 
			
		||||
				fmt.Fprintf(wr, "\n[%s command arguments]\n", c.Name)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			descStart := aligninfo.descriptionStart() + paddingBeforeOption
 | 
			
		||||
 | 
			
		||||
			for _, arg := range args {
 | 
			
		||||
				argPrefix := strings.Repeat(" ", paddingBeforeOption)
 | 
			
		||||
				argPrefix += arg.Name
 | 
			
		||||
 | 
			
		||||
				if len(arg.Description) > 0 {
 | 
			
		||||
					argPrefix += ":"
 | 
			
		||||
					wr.WriteString(argPrefix)
 | 
			
		||||
 | 
			
		||||
					// Space between "arg:" and the description start
 | 
			
		||||
					descPadding := strings.Repeat(" ", descStart-len(argPrefix))
 | 
			
		||||
					// How much space the description gets before wrapping
 | 
			
		||||
					descWidth := aligninfo.terminalColumns - 1 - descStart
 | 
			
		||||
					// Whitespace to which we can indent new description lines
 | 
			
		||||
					descPrefix := strings.Repeat(" ", descStart)
 | 
			
		||||
 | 
			
		||||
					wr.WriteString(descPadding)
 | 
			
		||||
					wr.WriteString(wrapText(arg.Description, descWidth, descPrefix))
 | 
			
		||||
				} else {
 | 
			
		||||
					wr.WriteString(argPrefix)
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				fmt.Fprintln(wr)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c = c.Active
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scommands := cmd.sortedVisibleCommands()
 | 
			
		||||
 | 
			
		||||
	if len(scommands) > 0 {
 | 
			
		||||
		maxnamelen := maxCommandLength(scommands)
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintln(wr)
 | 
			
		||||
		fmt.Fprintln(wr, "Available commands:")
 | 
			
		||||
 | 
			
		||||
		for _, c := range scommands {
 | 
			
		||||
			fmt.Fprintf(wr, "  %s", c.Name)
 | 
			
		||||
 | 
			
		||||
			if len(c.ShortDescription) > 0 {
 | 
			
		||||
				pad := strings.Repeat(" ", maxnamelen-len(c.Name))
 | 
			
		||||
				fmt.Fprintf(wr, "%s  %s", pad, c.ShortDescription)
 | 
			
		||||
 | 
			
		||||
				if len(c.Aliases) > 0 {
 | 
			
		||||
					fmt.Fprintf(wr, " (aliases: %s)", strings.Join(c.Aliases, ", "))
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintln(wr)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	wr.Flush()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										597
									
								
								vendor/github.com/jessevdk/go-flags/ini.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										597
									
								
								vendor/github.com/jessevdk/go-flags/ini.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,597 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"os"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IniError contains location information on where an error occurred.
 | 
			
		||||
type IniError struct {
 | 
			
		||||
	// The error message.
 | 
			
		||||
	Message string
 | 
			
		||||
 | 
			
		||||
	// The filename of the file in which the error occurred.
 | 
			
		||||
	File string
 | 
			
		||||
 | 
			
		||||
	// The line number at which the error occurred.
 | 
			
		||||
	LineNumber uint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Error provides a "file:line: message" formatted message of the ini error.
 | 
			
		||||
func (x *IniError) Error() string {
 | 
			
		||||
	return fmt.Sprintf(
 | 
			
		||||
		"%s:%d: %s",
 | 
			
		||||
		x.File,
 | 
			
		||||
		x.LineNumber,
 | 
			
		||||
		x.Message,
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IniOptions for writing
 | 
			
		||||
type IniOptions uint
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// IniNone indicates no options.
 | 
			
		||||
	IniNone IniOptions = 0
 | 
			
		||||
 | 
			
		||||
	// IniIncludeDefaults indicates that default values should be written.
 | 
			
		||||
	IniIncludeDefaults = 1 << iota
 | 
			
		||||
 | 
			
		||||
	// IniCommentDefaults indicates that if IniIncludeDefaults is used
 | 
			
		||||
	// options with default values are written but commented out.
 | 
			
		||||
	IniCommentDefaults
 | 
			
		||||
 | 
			
		||||
	// IniIncludeComments indicates that comments containing the description
 | 
			
		||||
	// of an option should be written.
 | 
			
		||||
	IniIncludeComments
 | 
			
		||||
 | 
			
		||||
	// IniDefault provides a default set of options.
 | 
			
		||||
	IniDefault = IniIncludeComments
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// IniParser is a utility to read and write flags options from and to ini
 | 
			
		||||
// formatted strings.
 | 
			
		||||
type IniParser struct {
 | 
			
		||||
	ParseAsDefaults bool // override default flags
 | 
			
		||||
 | 
			
		||||
	parser *Parser
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type iniValue struct {
 | 
			
		||||
	Name       string
 | 
			
		||||
	Value      string
 | 
			
		||||
	Quoted     bool
 | 
			
		||||
	LineNumber uint
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type iniSection []iniValue
 | 
			
		||||
 | 
			
		||||
type ini struct {
 | 
			
		||||
	File     string
 | 
			
		||||
	Sections map[string]iniSection
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewIniParser creates a new ini parser for a given Parser.
 | 
			
		||||
func NewIniParser(p *Parser) *IniParser {
 | 
			
		||||
	return &IniParser{
 | 
			
		||||
		parser: p,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IniParse is a convenience function to parse command line options with default
 | 
			
		||||
// settings from an ini formatted file. The provided data is a pointer to a struct
 | 
			
		||||
// representing the default option group (named "Application Options"). For
 | 
			
		||||
// more control, use flags.NewParser.
 | 
			
		||||
func IniParse(filename string, data interface{}) error {
 | 
			
		||||
	p := NewParser(data, Default)
 | 
			
		||||
 | 
			
		||||
	return NewIniParser(p).ParseFile(filename)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseFile parses flags from an ini formatted file. See Parse for more
 | 
			
		||||
// information on the ini file format. The returned errors can be of the type
 | 
			
		||||
// flags.Error or flags.IniError.
 | 
			
		||||
func (i *IniParser) ParseFile(filename string) error {
 | 
			
		||||
	ini, err := readIniFromFile(filename)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return i.parse(ini)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse parses flags from an ini format. You can use ParseFile as a
 | 
			
		||||
// convenience function to parse from a filename instead of a general
 | 
			
		||||
// io.Reader.
 | 
			
		||||
//
 | 
			
		||||
// The format of the ini file is as follows:
 | 
			
		||||
//
 | 
			
		||||
//     [Option group name]
 | 
			
		||||
//     option = value
 | 
			
		||||
//
 | 
			
		||||
// Each section in the ini file represents an option group or command in the
 | 
			
		||||
// flags parser. The default flags parser option group (i.e. when using
 | 
			
		||||
// flags.Parse) is named 'Application Options'. The ini option name is matched
 | 
			
		||||
// in the following order:
 | 
			
		||||
//
 | 
			
		||||
//     1. Compared to the ini-name tag on the option struct field (if present)
 | 
			
		||||
//     2. Compared to the struct field name
 | 
			
		||||
//     3. Compared to the option long name (if present)
 | 
			
		||||
//     4. Compared to the option short name (if present)
 | 
			
		||||
//
 | 
			
		||||
// Sections for nested groups and commands can be addressed using a dot `.'
 | 
			
		||||
// namespacing notation (i.e [subcommand.Options]). Group section names are
 | 
			
		||||
// matched case insensitive.
 | 
			
		||||
//
 | 
			
		||||
// The returned errors can be of the type flags.Error or flags.IniError.
 | 
			
		||||
func (i *IniParser) Parse(reader io.Reader) error {
 | 
			
		||||
	ini, err := readIni(reader, "")
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return i.parse(ini)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteFile writes the flags as ini format into a file. See Write
 | 
			
		||||
// for more information. The returned error occurs when the specified file
 | 
			
		||||
// could not be opened for writing.
 | 
			
		||||
func (i *IniParser) WriteFile(filename string, options IniOptions) error {
 | 
			
		||||
	return writeIniToFile(i, filename, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Write writes the current values of all the flags to an ini format.
 | 
			
		||||
// See Parse for more information on the ini file format. You typically
 | 
			
		||||
// call this only after settings have been parsed since the default values of each
 | 
			
		||||
// option are stored just before parsing the flags (this is only relevant when
 | 
			
		||||
// IniIncludeDefaults is _not_ set in options).
 | 
			
		||||
func (i *IniParser) Write(writer io.Writer, options IniOptions) {
 | 
			
		||||
	writeIni(i, writer, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readFullLine(reader *bufio.Reader) (string, error) {
 | 
			
		||||
	var line []byte
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		l, more, err := reader.ReadLine()
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return "", err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if line == nil && !more {
 | 
			
		||||
			return string(l), nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		line = append(line, l...)
 | 
			
		||||
 | 
			
		||||
		if !more {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return string(line), nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func optionIniName(option *Option) string {
 | 
			
		||||
	name := option.tag.Get("_read-ini-name")
 | 
			
		||||
 | 
			
		||||
	if len(name) != 0 {
 | 
			
		||||
		return name
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	name = option.tag.Get("ini-name")
 | 
			
		||||
 | 
			
		||||
	if len(name) != 0 {
 | 
			
		||||
		return name
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return option.field.Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeGroupIni(cmd *Command, group *Group, namespace string, writer io.Writer, options IniOptions) {
 | 
			
		||||
	var sname string
 | 
			
		||||
 | 
			
		||||
	if len(namespace) != 0 {
 | 
			
		||||
		sname = namespace
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if cmd.Group != group && len(group.ShortDescription) != 0 {
 | 
			
		||||
		if len(sname) != 0 {
 | 
			
		||||
			sname += "."
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sname += group.ShortDescription
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sectionwritten := false
 | 
			
		||||
	comments := (options & IniIncludeComments) != IniNone
 | 
			
		||||
 | 
			
		||||
	for _, option := range group.options {
 | 
			
		||||
		if option.isFunc() || option.Hidden {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(option.tag.Get("no-ini")) != 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		val := option.value
 | 
			
		||||
 | 
			
		||||
		if (options&IniIncludeDefaults) == IniNone && option.valueIsDefault() {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !sectionwritten {
 | 
			
		||||
			fmt.Fprintf(writer, "[%s]\n", sname)
 | 
			
		||||
			sectionwritten = true
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if comments && len(option.Description) != 0 {
 | 
			
		||||
			fmt.Fprintf(writer, "; %s\n", option.Description)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		oname := optionIniName(option)
 | 
			
		||||
 | 
			
		||||
		commentOption := (options&(IniIncludeDefaults|IniCommentDefaults)) == IniIncludeDefaults|IniCommentDefaults && option.valueIsDefault()
 | 
			
		||||
 | 
			
		||||
		kind := val.Type().Kind()
 | 
			
		||||
		switch kind {
 | 
			
		||||
		case reflect.Slice:
 | 
			
		||||
			kind = val.Type().Elem().Kind()
 | 
			
		||||
 | 
			
		||||
			if val.Len() == 0 {
 | 
			
		||||
				writeOption(writer, oname, kind, "", "", true, option.iniQuote)
 | 
			
		||||
			} else {
 | 
			
		||||
				for idx := 0; idx < val.Len(); idx++ {
 | 
			
		||||
					v, _ := convertToString(val.Index(idx), option.tag)
 | 
			
		||||
 | 
			
		||||
					writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		case reflect.Map:
 | 
			
		||||
			kind = val.Type().Elem().Kind()
 | 
			
		||||
 | 
			
		||||
			if val.Len() == 0 {
 | 
			
		||||
				writeOption(writer, oname, kind, "", "", true, option.iniQuote)
 | 
			
		||||
			} else {
 | 
			
		||||
				mkeys := val.MapKeys()
 | 
			
		||||
				keys := make([]string, len(val.MapKeys()))
 | 
			
		||||
				kkmap := make(map[string]reflect.Value)
 | 
			
		||||
 | 
			
		||||
				for i, k := range mkeys {
 | 
			
		||||
					keys[i], _ = convertToString(k, option.tag)
 | 
			
		||||
					kkmap[keys[i]] = k
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				sort.Strings(keys)
 | 
			
		||||
 | 
			
		||||
				for _, k := range keys {
 | 
			
		||||
					v, _ := convertToString(val.MapIndex(kkmap[k]), option.tag)
 | 
			
		||||
 | 
			
		||||
					writeOption(writer, oname, kind, k, v, commentOption, option.iniQuote)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		default:
 | 
			
		||||
			v, _ := convertToString(val, option.tag)
 | 
			
		||||
 | 
			
		||||
			writeOption(writer, oname, kind, "", v, commentOption, option.iniQuote)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if comments {
 | 
			
		||||
			fmt.Fprintln(writer)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if sectionwritten && !comments {
 | 
			
		||||
		fmt.Fprintln(writer)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeOption(writer io.Writer, optionName string, optionType reflect.Kind, optionKey string, optionValue string, commentOption bool, forceQuote bool) {
 | 
			
		||||
	if forceQuote || (optionType == reflect.String && !isPrint(optionValue)) {
 | 
			
		||||
		optionValue = strconv.Quote(optionValue)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	comment := ""
 | 
			
		||||
	if commentOption {
 | 
			
		||||
		comment = "; "
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(writer, "%s%s =", comment, optionName)
 | 
			
		||||
 | 
			
		||||
	if optionKey != "" {
 | 
			
		||||
		fmt.Fprintf(writer, " %s:%s", optionKey, optionValue)
 | 
			
		||||
	} else if optionValue != "" {
 | 
			
		||||
		fmt.Fprintf(writer, " %s", optionValue)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintln(writer)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeCommandIni(command *Command, namespace string, writer io.Writer, options IniOptions) {
 | 
			
		||||
	command.eachGroup(func(group *Group) {
 | 
			
		||||
		if !group.Hidden {
 | 
			
		||||
			writeGroupIni(command, group, namespace, writer, options)
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	for _, c := range command.commands {
 | 
			
		||||
		var nns string
 | 
			
		||||
 | 
			
		||||
		if c.Hidden {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(namespace) != 0 {
 | 
			
		||||
			nns = c.Name + "." + nns
 | 
			
		||||
		} else {
 | 
			
		||||
			nns = c.Name
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		writeCommandIni(c, nns, writer, options)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeIni(parser *IniParser, writer io.Writer, options IniOptions) {
 | 
			
		||||
	writeCommandIni(parser.parser.Command, "", writer, options)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeIniToFile(parser *IniParser, filename string, options IniOptions) error {
 | 
			
		||||
	file, err := os.Create(filename)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	writeIni(parser, file, options)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readIniFromFile(filename string) (*ini, error) {
 | 
			
		||||
	file, err := os.Open(filename)
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	defer file.Close()
 | 
			
		||||
 | 
			
		||||
	return readIni(file, filename)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func readIni(contents io.Reader, filename string) (*ini, error) {
 | 
			
		||||
	ret := &ini{
 | 
			
		||||
		File:     filename,
 | 
			
		||||
		Sections: make(map[string]iniSection),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reader := bufio.NewReader(contents)
 | 
			
		||||
 | 
			
		||||
	// Empty global section
 | 
			
		||||
	section := make(iniSection, 0, 10)
 | 
			
		||||
	sectionname := ""
 | 
			
		||||
 | 
			
		||||
	ret.Sections[sectionname] = section
 | 
			
		||||
 | 
			
		||||
	var lineno uint
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		line, err := readFullLine(reader)
 | 
			
		||||
 | 
			
		||||
		if err == io.EOF {
 | 
			
		||||
			break
 | 
			
		||||
		} else if err != nil {
 | 
			
		||||
			return nil, err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		lineno++
 | 
			
		||||
		line = strings.TrimSpace(line)
 | 
			
		||||
 | 
			
		||||
		// Skip empty lines and lines starting with ; (comments)
 | 
			
		||||
		if len(line) == 0 || line[0] == ';' || line[0] == '#' {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if line[0] == '[' {
 | 
			
		||||
			if line[0] != '[' || line[len(line)-1] != ']' {
 | 
			
		||||
				return nil, &IniError{
 | 
			
		||||
					Message:    "malformed section header",
 | 
			
		||||
					File:       filename,
 | 
			
		||||
					LineNumber: lineno,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			name := strings.TrimSpace(line[1 : len(line)-1])
 | 
			
		||||
 | 
			
		||||
			if len(name) == 0 {
 | 
			
		||||
				return nil, &IniError{
 | 
			
		||||
					Message:    "empty section name",
 | 
			
		||||
					File:       filename,
 | 
			
		||||
					LineNumber: lineno,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			sectionname = name
 | 
			
		||||
			section = ret.Sections[name]
 | 
			
		||||
 | 
			
		||||
			if section == nil {
 | 
			
		||||
				section = make(iniSection, 0, 10)
 | 
			
		||||
				ret.Sections[name] = section
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Parse option here
 | 
			
		||||
		keyval := strings.SplitN(line, "=", 2)
 | 
			
		||||
 | 
			
		||||
		if len(keyval) != 2 {
 | 
			
		||||
			return nil, &IniError{
 | 
			
		||||
				Message:    fmt.Sprintf("malformed key=value (%s)", line),
 | 
			
		||||
				File:       filename,
 | 
			
		||||
				LineNumber: lineno,
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		name := strings.TrimSpace(keyval[0])
 | 
			
		||||
		value := strings.TrimSpace(keyval[1])
 | 
			
		||||
		quoted := false
 | 
			
		||||
 | 
			
		||||
		if len(value) != 0 && value[0] == '"' {
 | 
			
		||||
			if v, err := strconv.Unquote(value); err == nil {
 | 
			
		||||
				value = v
 | 
			
		||||
 | 
			
		||||
				quoted = true
 | 
			
		||||
			} else {
 | 
			
		||||
				return nil, &IniError{
 | 
			
		||||
					Message:    err.Error(),
 | 
			
		||||
					File:       filename,
 | 
			
		||||
					LineNumber: lineno,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		section = append(section, iniValue{
 | 
			
		||||
			Name:       name,
 | 
			
		||||
			Value:      value,
 | 
			
		||||
			Quoted:     quoted,
 | 
			
		||||
			LineNumber: lineno,
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		ret.Sections[sectionname] = section
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (i *IniParser) matchingGroups(name string) []*Group {
 | 
			
		||||
	if len(name) == 0 {
 | 
			
		||||
		var ret []*Group
 | 
			
		||||
 | 
			
		||||
		i.parser.eachGroup(func(g *Group) {
 | 
			
		||||
			ret = append(ret, g)
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		return ret
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	g := i.parser.groupByName(name)
 | 
			
		||||
 | 
			
		||||
	if g != nil {
 | 
			
		||||
		return []*Group{g}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (i *IniParser) parse(ini *ini) error {
 | 
			
		||||
	p := i.parser
 | 
			
		||||
 | 
			
		||||
	var quotesLookup = make(map[*Option]bool)
 | 
			
		||||
 | 
			
		||||
	for name, section := range ini.Sections {
 | 
			
		||||
		groups := i.matchingGroups(name)
 | 
			
		||||
 | 
			
		||||
		if len(groups) == 0 {
 | 
			
		||||
			return newErrorf(ErrUnknownGroup, "could not find option group `%s'", name)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, inival := range section {
 | 
			
		||||
			var opt *Option
 | 
			
		||||
 | 
			
		||||
			for _, group := range groups {
 | 
			
		||||
				opt = group.optionByName(inival.Name, func(o *Option, n string) bool {
 | 
			
		||||
					return strings.ToLower(o.tag.Get("ini-name")) == strings.ToLower(n)
 | 
			
		||||
				})
 | 
			
		||||
 | 
			
		||||
				if opt != nil && len(opt.tag.Get("no-ini")) != 0 {
 | 
			
		||||
					opt = nil
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if opt != nil {
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if opt == nil {
 | 
			
		||||
				if (p.Options & IgnoreUnknown) == None {
 | 
			
		||||
					return &IniError{
 | 
			
		||||
						Message:    fmt.Sprintf("unknown option: %s", inival.Name),
 | 
			
		||||
						File:       ini.File,
 | 
			
		||||
						LineNumber: inival.LineNumber,
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// ini value is ignored if override is set and
 | 
			
		||||
			// value was previously set from non default
 | 
			
		||||
			if i.ParseAsDefaults && !opt.isSetDefault {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			pval := &inival.Value
 | 
			
		||||
 | 
			
		||||
			if !opt.canArgument() && len(inival.Value) == 0 {
 | 
			
		||||
				pval = nil
 | 
			
		||||
			} else {
 | 
			
		||||
				if opt.value.Type().Kind() == reflect.Map {
 | 
			
		||||
					parts := strings.SplitN(inival.Value, ":", 2)
 | 
			
		||||
 | 
			
		||||
					// only handle unquoting
 | 
			
		||||
					if len(parts) == 2 && parts[1][0] == '"' {
 | 
			
		||||
						if v, err := strconv.Unquote(parts[1]); err == nil {
 | 
			
		||||
							parts[1] = v
 | 
			
		||||
 | 
			
		||||
							inival.Quoted = true
 | 
			
		||||
						} else {
 | 
			
		||||
							return &IniError{
 | 
			
		||||
								Message:    err.Error(),
 | 
			
		||||
								File:       ini.File,
 | 
			
		||||
								LineNumber: inival.LineNumber,
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						s := parts[0] + ":" + parts[1]
 | 
			
		||||
 | 
			
		||||
						pval = &s
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if err := opt.set(pval); err != nil {
 | 
			
		||||
				return &IniError{
 | 
			
		||||
					Message:    err.Error(),
 | 
			
		||||
					File:       ini.File,
 | 
			
		||||
					LineNumber: inival.LineNumber,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// either all INI values are quoted or only values who need quoting
 | 
			
		||||
			if _, ok := quotesLookup[opt]; !inival.Quoted || !ok {
 | 
			
		||||
				quotesLookup[opt] = inival.Quoted
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			opt.tag.Set("_read-ini-name", inival.Name)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for opt, quoted := range quotesLookup {
 | 
			
		||||
		opt.iniQuote = quoted
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										205
									
								
								vendor/github.com/jessevdk/go-flags/man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								vendor/github.com/jessevdk/go-flags/man.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,205 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func manQuote(s string) string {
 | 
			
		||||
	return strings.Replace(s, "\\", "\\\\", -1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func formatForMan(wr io.Writer, s string) {
 | 
			
		||||
	for {
 | 
			
		||||
		idx := strings.IndexRune(s, '`')
 | 
			
		||||
 | 
			
		||||
		if idx < 0 {
 | 
			
		||||
			fmt.Fprintf(wr, "%s", manQuote(s))
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(wr, "%s", manQuote(s[:idx]))
 | 
			
		||||
 | 
			
		||||
		s = s[idx+1:]
 | 
			
		||||
		idx = strings.IndexRune(s, '\'')
 | 
			
		||||
 | 
			
		||||
		if idx < 0 {
 | 
			
		||||
			fmt.Fprintf(wr, "%s", manQuote(s))
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		fmt.Fprintf(wr, "\\fB%s\\fP", manQuote(s[:idx]))
 | 
			
		||||
		s = s[idx+1:]
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeManPageOptions(wr io.Writer, grp *Group) {
 | 
			
		||||
	grp.eachGroup(func(group *Group) {
 | 
			
		||||
		if group.Hidden || len(group.options) == 0 {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the parent (grp) has any subgroups, display their descriptions as
 | 
			
		||||
		// subsection headers similar to the output of --help.
 | 
			
		||||
		if group.ShortDescription != "" && len(grp.groups) > 0 {
 | 
			
		||||
			fmt.Fprintf(wr, ".SS %s\n", group.ShortDescription)
 | 
			
		||||
 | 
			
		||||
			if group.LongDescription != "" {
 | 
			
		||||
				formatForMan(wr, group.LongDescription)
 | 
			
		||||
				fmt.Fprintln(wr, "")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for _, opt := range group.options {
 | 
			
		||||
			if !opt.canCli() || opt.Hidden {
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintln(wr, ".TP")
 | 
			
		||||
			fmt.Fprintf(wr, "\\fB")
 | 
			
		||||
 | 
			
		||||
			if opt.ShortName != 0 {
 | 
			
		||||
				fmt.Fprintf(wr, "\\fB\\-%c\\fR", opt.ShortName)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(opt.LongName) != 0 {
 | 
			
		||||
				if opt.ShortName != 0 {
 | 
			
		||||
					fmt.Fprintf(wr, ", ")
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				fmt.Fprintf(wr, "\\fB\\-\\-%s\\fR", manQuote(opt.LongNameWithNamespace()))
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(opt.ValueName) != 0 || opt.OptionalArgument {
 | 
			
		||||
				if opt.OptionalArgument {
 | 
			
		||||
					fmt.Fprintf(wr, " [\\fI%s=%s\\fR]", manQuote(opt.ValueName), manQuote(strings.Join(quoteV(opt.OptionalValue), ", ")))
 | 
			
		||||
				} else {
 | 
			
		||||
					fmt.Fprintf(wr, " \\fI%s\\fR", manQuote(opt.ValueName))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(opt.Default) != 0 {
 | 
			
		||||
				fmt.Fprintf(wr, " <default: \\fI%s\\fR>", manQuote(strings.Join(quoteV(opt.Default), ", ")))
 | 
			
		||||
			} else if len(opt.EnvDefaultKey) != 0 {
 | 
			
		||||
				if runtime.GOOS == "windows" {
 | 
			
		||||
					fmt.Fprintf(wr, " <default: \\fI%%%s%%\\fR>", manQuote(opt.EnvDefaultKey))
 | 
			
		||||
				} else {
 | 
			
		||||
					fmt.Fprintf(wr, " <default: \\fI$%s\\fR>", manQuote(opt.EnvDefaultKey))
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if opt.Required {
 | 
			
		||||
				fmt.Fprintf(wr, " (\\fIrequired\\fR)")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			fmt.Fprintln(wr, "\\fP")
 | 
			
		||||
 | 
			
		||||
			if len(opt.Description) != 0 {
 | 
			
		||||
				formatForMan(wr, opt.Description)
 | 
			
		||||
				fmt.Fprintln(wr, "")
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeManPageSubcommands(wr io.Writer, name string, root *Command) {
 | 
			
		||||
	commands := root.sortedVisibleCommands()
 | 
			
		||||
 | 
			
		||||
	for _, c := range commands {
 | 
			
		||||
		var nn string
 | 
			
		||||
 | 
			
		||||
		if c.Hidden {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if len(name) != 0 {
 | 
			
		||||
			nn = name + " " + c.Name
 | 
			
		||||
		} else {
 | 
			
		||||
			nn = c.Name
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		writeManPageCommand(wr, nn, root, c)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func writeManPageCommand(wr io.Writer, name string, root *Command, command *Command) {
 | 
			
		||||
	fmt.Fprintf(wr, ".SS %s\n", name)
 | 
			
		||||
	fmt.Fprintln(wr, command.ShortDescription)
 | 
			
		||||
 | 
			
		||||
	if len(command.LongDescription) > 0 {
 | 
			
		||||
		fmt.Fprintln(wr, "")
 | 
			
		||||
 | 
			
		||||
		cmdstart := fmt.Sprintf("The %s command", manQuote(command.Name))
 | 
			
		||||
 | 
			
		||||
		if strings.HasPrefix(command.LongDescription, cmdstart) {
 | 
			
		||||
			fmt.Fprintf(wr, "The \\fI%s\\fP command", manQuote(command.Name))
 | 
			
		||||
 | 
			
		||||
			formatForMan(wr, command.LongDescription[len(cmdstart):])
 | 
			
		||||
			fmt.Fprintln(wr, "")
 | 
			
		||||
		} else {
 | 
			
		||||
			formatForMan(wr, command.LongDescription)
 | 
			
		||||
			fmt.Fprintln(wr, "")
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var usage string
 | 
			
		||||
	if us, ok := command.data.(Usage); ok {
 | 
			
		||||
		usage = us.Usage()
 | 
			
		||||
	} else if command.hasCliOptions() {
 | 
			
		||||
		usage = fmt.Sprintf("[%s-OPTIONS]", command.Name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var pre string
 | 
			
		||||
	if root.hasCliOptions() {
 | 
			
		||||
		pre = fmt.Sprintf("%s [OPTIONS] %s", root.Name, command.Name)
 | 
			
		||||
	} else {
 | 
			
		||||
		pre = fmt.Sprintf("%s %s", root.Name, command.Name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(usage) > 0 {
 | 
			
		||||
		fmt.Fprintf(wr, "\n\\fBUsage\\fP: %s %s\n.TP\n", manQuote(pre), manQuote(usage))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(command.Aliases) > 0 {
 | 
			
		||||
		fmt.Fprintf(wr, "\n\\fBAliases\\fP: %s\n\n", manQuote(strings.Join(command.Aliases, ", ")))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	writeManPageOptions(wr, command.Group)
 | 
			
		||||
	writeManPageSubcommands(wr, name, command)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// WriteManPage writes a basic man page in groff format to the specified
 | 
			
		||||
// writer.
 | 
			
		||||
func (p *Parser) WriteManPage(wr io.Writer) {
 | 
			
		||||
	t := time.Now()
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(wr, ".TH %s 1 \"%s\"\n", manQuote(p.Name), t.Format("2 January 2006"))
 | 
			
		||||
	fmt.Fprintln(wr, ".SH NAME")
 | 
			
		||||
	fmt.Fprintf(wr, "%s \\- %s\n", manQuote(p.Name), manQuote(p.ShortDescription))
 | 
			
		||||
	fmt.Fprintln(wr, ".SH SYNOPSIS")
 | 
			
		||||
 | 
			
		||||
	usage := p.Usage
 | 
			
		||||
 | 
			
		||||
	if len(usage) == 0 {
 | 
			
		||||
		usage = "[OPTIONS]"
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintf(wr, "\\fB%s\\fP %s\n", manQuote(p.Name), manQuote(usage))
 | 
			
		||||
	fmt.Fprintln(wr, ".SH DESCRIPTION")
 | 
			
		||||
 | 
			
		||||
	formatForMan(wr, p.LongDescription)
 | 
			
		||||
	fmt.Fprintln(wr, "")
 | 
			
		||||
 | 
			
		||||
	fmt.Fprintln(wr, ".SH OPTIONS")
 | 
			
		||||
 | 
			
		||||
	writeManPageOptions(wr, p.Command.Group)
 | 
			
		||||
 | 
			
		||||
	if len(p.visibleCommands()) > 0 {
 | 
			
		||||
		fmt.Fprintln(wr, ".SH COMMANDS")
 | 
			
		||||
 | 
			
		||||
		writeManPageSubcommands(wr, "", p.Command)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										140
									
								
								vendor/github.com/jessevdk/go-flags/multitag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								vendor/github.com/jessevdk/go-flags/multitag.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type multiTag struct {
 | 
			
		||||
	value string
 | 
			
		||||
	cache map[string][]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMultiTag(v string) multiTag {
 | 
			
		||||
	return multiTag{
 | 
			
		||||
		value: v,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) scan() (map[string][]string, error) {
 | 
			
		||||
	v := x.value
 | 
			
		||||
 | 
			
		||||
	ret := make(map[string][]string)
 | 
			
		||||
 | 
			
		||||
	// This is mostly copied from reflect.StructTag.Get
 | 
			
		||||
	for v != "" {
 | 
			
		||||
		i := 0
 | 
			
		||||
 | 
			
		||||
		// Skip whitespace
 | 
			
		||||
		for i < len(v) && v[i] == ' ' {
 | 
			
		||||
			i++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		v = v[i:]
 | 
			
		||||
 | 
			
		||||
		if v == "" {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Scan to colon to find key
 | 
			
		||||
		i = 0
 | 
			
		||||
 | 
			
		||||
		for i < len(v) && v[i] != ' ' && v[i] != ':' && v[i] != '"' {
 | 
			
		||||
			i++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i >= len(v) {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "expected `:' after key name, but got end of tag (in `%v`)", x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if v[i] != ':' {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "expected `:' after key name, but got `%v' (in `%v`)", v[i], x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i+1 >= len(v) {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "expected `\"' to start tag value at end of tag (in `%v`)", x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if v[i+1] != '"' {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "expected `\"' to start tag value, but got `%v' (in `%v`)", v[i+1], x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		name := v[:i]
 | 
			
		||||
		v = v[i+1:]
 | 
			
		||||
 | 
			
		||||
		// Scan quoted string to find value
 | 
			
		||||
		i = 1
 | 
			
		||||
 | 
			
		||||
		for i < len(v) && v[i] != '"' {
 | 
			
		||||
			if v[i] == '\n' {
 | 
			
		||||
				return nil, newErrorf(ErrTag, "unexpected newline in tag value `%v' (in `%v`)", name, x.value)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if v[i] == '\\' {
 | 
			
		||||
				i++
 | 
			
		||||
			}
 | 
			
		||||
			i++
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if i >= len(v) {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "expected end of tag value `\"' at end of tag (in `%v`)", x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		val, err := strconv.Unquote(v[:i+1])
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return nil, newErrorf(ErrTag, "Malformed value of tag `%v:%v` => %v (in `%v`)", name, v[:i+1], err, x.value)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		v = v[i+1:]
 | 
			
		||||
 | 
			
		||||
		ret[name] = append(ret[name], val)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) Parse() error {
 | 
			
		||||
	vals, err := x.scan()
 | 
			
		||||
	x.cache = vals
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) cached() map[string][]string {
 | 
			
		||||
	if x.cache == nil {
 | 
			
		||||
		cache, _ := x.scan()
 | 
			
		||||
 | 
			
		||||
		if cache == nil {
 | 
			
		||||
			cache = make(map[string][]string)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		x.cache = cache
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return x.cache
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) Get(key string) string {
 | 
			
		||||
	c := x.cached()
 | 
			
		||||
 | 
			
		||||
	if v, ok := c[key]; ok {
 | 
			
		||||
		return v[len(v)-1]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) GetMany(key string) []string {
 | 
			
		||||
	c := x.cached()
 | 
			
		||||
	return c[key]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) Set(key string, value string) {
 | 
			
		||||
	c := x.cached()
 | 
			
		||||
	c[key] = []string{value}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *multiTag) SetMany(key string, value []string) {
 | 
			
		||||
	c := x.cached()
 | 
			
		||||
	c[key] = value
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										459
									
								
								vendor/github.com/jessevdk/go-flags/option.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										459
									
								
								vendor/github.com/jessevdk/go-flags/option.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,459 @@
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Option flag information. Contains a description of the option, short and
 | 
			
		||||
// long name as well as a default value and whether an argument for this
 | 
			
		||||
// flag is optional.
 | 
			
		||||
type Option struct {
 | 
			
		||||
	// The description of the option flag. This description is shown
 | 
			
		||||
	// automatically in the built-in help.
 | 
			
		||||
	Description string
 | 
			
		||||
 | 
			
		||||
	// The short name of the option (a single character). If not 0, the
 | 
			
		||||
	// option flag can be 'activated' using -<ShortName>. Either ShortName
 | 
			
		||||
	// or LongName needs to be non-empty.
 | 
			
		||||
	ShortName rune
 | 
			
		||||
 | 
			
		||||
	// The long name of the option. If not "", the option flag can be
 | 
			
		||||
	// activated using --<LongName>. Either ShortName or LongName needs
 | 
			
		||||
	// to be non-empty.
 | 
			
		||||
	LongName string
 | 
			
		||||
 | 
			
		||||
	// The default value of the option.
 | 
			
		||||
	Default []string
 | 
			
		||||
 | 
			
		||||
	// The optional environment default value key name.
 | 
			
		||||
	EnvDefaultKey string
 | 
			
		||||
 | 
			
		||||
	// The optional delimiter string for EnvDefaultKey values.
 | 
			
		||||
	EnvDefaultDelim string
 | 
			
		||||
 | 
			
		||||
	// If true, specifies that the argument to an option flag is optional.
 | 
			
		||||
	// When no argument to the flag is specified on the command line, the
 | 
			
		||||
	// value of OptionalValue will be set in the field this option represents.
 | 
			
		||||
	// This is only valid for non-boolean options.
 | 
			
		||||
	OptionalArgument bool
 | 
			
		||||
 | 
			
		||||
	// The optional value of the option. The optional value is used when
 | 
			
		||||
	// the option flag is marked as having an OptionalArgument. This means
 | 
			
		||||
	// that when the flag is specified, but no option argument is given,
 | 
			
		||||
	// the value of the field this option represents will be set to
 | 
			
		||||
	// OptionalValue. This is only valid for non-boolean options.
 | 
			
		||||
	OptionalValue []string
 | 
			
		||||
 | 
			
		||||
	// If true, the option _must_ be specified on the command line. If the
 | 
			
		||||
	// option is not specified, the parser will generate an ErrRequired type
 | 
			
		||||
	// error.
 | 
			
		||||
	Required bool
 | 
			
		||||
 | 
			
		||||
	// A name for the value of an option shown in the Help as --flag [ValueName]
 | 
			
		||||
	ValueName string
 | 
			
		||||
 | 
			
		||||
	// A mask value to show in the help instead of the default value. This
 | 
			
		||||
	// is useful for hiding sensitive information in the help, such as
 | 
			
		||||
	// passwords.
 | 
			
		||||
	DefaultMask string
 | 
			
		||||
 | 
			
		||||
	// If non empty, only a certain set of values is allowed for an option.
 | 
			
		||||
	Choices []string
 | 
			
		||||
 | 
			
		||||
	// If true, the option is not displayed in the help or man page
 | 
			
		||||
	Hidden bool
 | 
			
		||||
 | 
			
		||||
	// The group which the option belongs to
 | 
			
		||||
	group *Group
 | 
			
		||||
 | 
			
		||||
	// The struct field which the option represents.
 | 
			
		||||
	field reflect.StructField
 | 
			
		||||
 | 
			
		||||
	// The struct field value which the option represents.
 | 
			
		||||
	value reflect.Value
 | 
			
		||||
 | 
			
		||||
	// Determines if the option will be always quoted in the INI output
 | 
			
		||||
	iniQuote bool
 | 
			
		||||
 | 
			
		||||
	tag            multiTag
 | 
			
		||||
	isSet          bool
 | 
			
		||||
	isSetDefault   bool
 | 
			
		||||
	preventDefault bool
 | 
			
		||||
 | 
			
		||||
	defaultLiteral string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// LongNameWithNamespace returns the option's long name with the group namespaces
 | 
			
		||||
// prepended by walking up the option's group tree. Namespaces and the long name
 | 
			
		||||
// itself are separated by the parser's namespace delimiter. If the long name is
 | 
			
		||||
// empty an empty string is returned.
 | 
			
		||||
func (option *Option) LongNameWithNamespace() string {
 | 
			
		||||
	if len(option.LongName) == 0 {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fetch the namespace delimiter from the parser which is always at the
 | 
			
		||||
	// end of the group hierarchy
 | 
			
		||||
	namespaceDelimiter := ""
 | 
			
		||||
	g := option.group
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		if p, ok := g.parent.(*Parser); ok {
 | 
			
		||||
			namespaceDelimiter = p.NamespaceDelimiter
 | 
			
		||||
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch i := g.parent.(type) {
 | 
			
		||||
		case *Command:
 | 
			
		||||
			g = i.Group
 | 
			
		||||
		case *Group:
 | 
			
		||||
			g = i
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// concatenate long name with namespace
 | 
			
		||||
	longName := option.LongName
 | 
			
		||||
	g = option.group
 | 
			
		||||
 | 
			
		||||
	for g != nil {
 | 
			
		||||
		if g.Namespace != "" {
 | 
			
		||||
			longName = g.Namespace + namespaceDelimiter + longName
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		switch i := g.parent.(type) {
 | 
			
		||||
		case *Command:
 | 
			
		||||
			g = i.Group
 | 
			
		||||
		case *Group:
 | 
			
		||||
			g = i
 | 
			
		||||
		case *Parser:
 | 
			
		||||
			g = nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return longName
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String converts an option to a human friendly readable string describing the
 | 
			
		||||
// option.
 | 
			
		||||
func (option *Option) String() string {
 | 
			
		||||
	var s string
 | 
			
		||||
	var short string
 | 
			
		||||
 | 
			
		||||
	if option.ShortName != 0 {
 | 
			
		||||
		data := make([]byte, utf8.RuneLen(option.ShortName))
 | 
			
		||||
		utf8.EncodeRune(data, option.ShortName)
 | 
			
		||||
		short = string(data)
 | 
			
		||||
 | 
			
		||||
		if len(option.LongName) != 0 {
 | 
			
		||||
			s = fmt.Sprintf("%s%s, %s%s",
 | 
			
		||||
				string(defaultShortOptDelimiter), short,
 | 
			
		||||
				defaultLongOptDelimiter, option.LongNameWithNamespace())
 | 
			
		||||
		} else {
 | 
			
		||||
			s = fmt.Sprintf("%s%s", string(defaultShortOptDelimiter), short)
 | 
			
		||||
		}
 | 
			
		||||
	} else if len(option.LongName) != 0 {
 | 
			
		||||
		s = fmt.Sprintf("%s%s", defaultLongOptDelimiter, option.LongNameWithNamespace())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Value returns the option value as an interface{}.
 | 
			
		||||
func (option *Option) Value() interface{} {
 | 
			
		||||
	return option.value.Interface()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Field returns the reflect struct field of the option.
 | 
			
		||||
func (option *Option) Field() reflect.StructField {
 | 
			
		||||
	return option.field
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSet returns true if option has been set
 | 
			
		||||
func (option *Option) IsSet() bool {
 | 
			
		||||
	return option.isSet
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsSetDefault returns true if option has been set via the default option tag
 | 
			
		||||
func (option *Option) IsSetDefault() bool {
 | 
			
		||||
	return option.isSetDefault
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Set the value of an option to the specified value. An error will be returned
 | 
			
		||||
// if the specified value could not be converted to the corresponding option
 | 
			
		||||
// value type.
 | 
			
		||||
func (option *Option) set(value *string) error {
 | 
			
		||||
	kind := option.value.Type().Kind()
 | 
			
		||||
 | 
			
		||||
	if (kind == reflect.Map || kind == reflect.Slice) && !option.isSet {
 | 
			
		||||
		option.empty()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	option.isSet = true
 | 
			
		||||
	option.preventDefault = true
 | 
			
		||||
 | 
			
		||||
	if len(option.Choices) != 0 {
 | 
			
		||||
		found := false
 | 
			
		||||
 | 
			
		||||
		for _, choice := range option.Choices {
 | 
			
		||||
			if choice == *value {
 | 
			
		||||
				found = true
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !found {
 | 
			
		||||
			allowed := strings.Join(option.Choices[0:len(option.Choices)-1], ", ")
 | 
			
		||||
 | 
			
		||||
			if len(option.Choices) > 1 {
 | 
			
		||||
				allowed += " or " + option.Choices[len(option.Choices)-1]
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return newErrorf(ErrInvalidChoice,
 | 
			
		||||
				"Invalid value `%s' for option `%s'. Allowed values are: %s",
 | 
			
		||||
				*value, option, allowed)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if option.isFunc() {
 | 
			
		||||
		return option.call(value)
 | 
			
		||||
	} else if value != nil {
 | 
			
		||||
		return convert(*value, option.value, option.tag)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return convert("", option.value, option.tag)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) canCli() bool {
 | 
			
		||||
	return option.ShortName != 0 || len(option.LongName) != 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) canArgument() bool {
 | 
			
		||||
	if u := option.isUnmarshaler(); u != nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return !option.isBool()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) emptyValue() reflect.Value {
 | 
			
		||||
	tp := option.value.Type()
 | 
			
		||||
 | 
			
		||||
	if tp.Kind() == reflect.Map {
 | 
			
		||||
		return reflect.MakeMap(tp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return reflect.Zero(tp)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) empty() {
 | 
			
		||||
	if !option.isFunc() {
 | 
			
		||||
		option.value.Set(option.emptyValue())
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) clearDefault() {
 | 
			
		||||
	usedDefault := option.Default
 | 
			
		||||
 | 
			
		||||
	if envKey := option.EnvDefaultKey; envKey != "" {
 | 
			
		||||
		if value, ok := os.LookupEnv(envKey); ok {
 | 
			
		||||
			if option.EnvDefaultDelim != "" {
 | 
			
		||||
				usedDefault = strings.Split(value,
 | 
			
		||||
					option.EnvDefaultDelim)
 | 
			
		||||
			} else {
 | 
			
		||||
				usedDefault = []string{value}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	option.isSetDefault = true
 | 
			
		||||
 | 
			
		||||
	if len(usedDefault) > 0 {
 | 
			
		||||
		option.empty()
 | 
			
		||||
 | 
			
		||||
		for _, d := range usedDefault {
 | 
			
		||||
			option.set(&d)
 | 
			
		||||
			option.isSetDefault = true
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		tp := option.value.Type()
 | 
			
		||||
 | 
			
		||||
		switch tp.Kind() {
 | 
			
		||||
		case reflect.Map:
 | 
			
		||||
			if option.value.IsNil() {
 | 
			
		||||
				option.empty()
 | 
			
		||||
			}
 | 
			
		||||
		case reflect.Slice:
 | 
			
		||||
			if option.value.IsNil() {
 | 
			
		||||
				option.empty()
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) valueIsDefault() bool {
 | 
			
		||||
	// Check if the value of the option corresponds to its
 | 
			
		||||
	// default value
 | 
			
		||||
	emptyval := option.emptyValue()
 | 
			
		||||
 | 
			
		||||
	checkvalptr := reflect.New(emptyval.Type())
 | 
			
		||||
	checkval := reflect.Indirect(checkvalptr)
 | 
			
		||||
 | 
			
		||||
	checkval.Set(emptyval)
 | 
			
		||||
 | 
			
		||||
	if len(option.Default) != 0 {
 | 
			
		||||
		for _, v := range option.Default {
 | 
			
		||||
			convert(v, checkval, option.tag)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return reflect.DeepEqual(option.value.Interface(), checkval.Interface())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) isUnmarshaler() Unmarshaler {
 | 
			
		||||
	v := option.value
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		if !v.CanInterface() {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		i := v.Interface()
 | 
			
		||||
 | 
			
		||||
		if u, ok := i.(Unmarshaler); ok {
 | 
			
		||||
			return u
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !v.CanAddr() {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		v = v.Addr()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) isBool() bool {
 | 
			
		||||
	tp := option.value.Type()
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		switch tp.Kind() {
 | 
			
		||||
		case reflect.Slice, reflect.Ptr:
 | 
			
		||||
			tp = tp.Elem()
 | 
			
		||||
		case reflect.Bool:
 | 
			
		||||
			return true
 | 
			
		||||
		case reflect.Func:
 | 
			
		||||
			return tp.NumIn() == 0
 | 
			
		||||
		default:
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) isSignedNumber() bool {
 | 
			
		||||
	tp := option.value.Type()
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		switch tp.Kind() {
 | 
			
		||||
		case reflect.Slice, reflect.Ptr:
 | 
			
		||||
			tp = tp.Elem()
 | 
			
		||||
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float32, reflect.Float64:
 | 
			
		||||
			return true
 | 
			
		||||
		default:
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) isFunc() bool {
 | 
			
		||||
	return option.value.Type().Kind() == reflect.Func
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) call(value *string) error {
 | 
			
		||||
	var retval []reflect.Value
 | 
			
		||||
 | 
			
		||||
	if value == nil {
 | 
			
		||||
		retval = option.value.Call(nil)
 | 
			
		||||
	} else {
 | 
			
		||||
		tp := option.value.Type().In(0)
 | 
			
		||||
 | 
			
		||||
		val := reflect.New(tp)
 | 
			
		||||
		val = reflect.Indirect(val)
 | 
			
		||||
 | 
			
		||||
		if err := convert(*value, val, option.tag); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		retval = option.value.Call([]reflect.Value{val})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(retval) == 1 && retval[0].Type() == reflect.TypeOf((*error)(nil)).Elem() {
 | 
			
		||||
		if retval[0].Interface() == nil {
 | 
			
		||||
			return nil
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return retval[0].Interface().(error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) updateDefaultLiteral() {
 | 
			
		||||
	defs := option.Default
 | 
			
		||||
	def := ""
 | 
			
		||||
 | 
			
		||||
	if len(defs) == 0 && option.canArgument() {
 | 
			
		||||
		var showdef bool
 | 
			
		||||
 | 
			
		||||
		switch option.field.Type.Kind() {
 | 
			
		||||
		case reflect.Func, reflect.Ptr:
 | 
			
		||||
			showdef = !option.value.IsNil()
 | 
			
		||||
		case reflect.Slice, reflect.String, reflect.Array:
 | 
			
		||||
			showdef = option.value.Len() > 0
 | 
			
		||||
		case reflect.Map:
 | 
			
		||||
			showdef = !option.value.IsNil() && option.value.Len() > 0
 | 
			
		||||
		default:
 | 
			
		||||
			zeroval := reflect.Zero(option.field.Type)
 | 
			
		||||
			showdef = !reflect.DeepEqual(zeroval.Interface(), option.value.Interface())
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if showdef {
 | 
			
		||||
			def, _ = convertToString(option.value, option.tag)
 | 
			
		||||
		}
 | 
			
		||||
	} else if len(defs) != 0 {
 | 
			
		||||
		l := len(defs) - 1
 | 
			
		||||
 | 
			
		||||
		for i := 0; i < l; i++ {
 | 
			
		||||
			def += quoteIfNeeded(defs[i]) + ", "
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		def += quoteIfNeeded(defs[l])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	option.defaultLiteral = def
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (option *Option) shortAndLongName() string {
 | 
			
		||||
	ret := &bytes.Buffer{}
 | 
			
		||||
 | 
			
		||||
	if option.ShortName != 0 {
 | 
			
		||||
		ret.WriteRune(defaultShortOptDelimiter)
 | 
			
		||||
		ret.WriteRune(option.ShortName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(option.LongName) != 0 {
 | 
			
		||||
		if option.ShortName != 0 {
 | 
			
		||||
			ret.WriteRune('/')
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret.WriteString(option.LongName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return ret.String()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										67
									
								
								vendor/github.com/jessevdk/go-flags/optstyle_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								vendor/github.com/jessevdk/go-flags/optstyle_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
			
		||||
// +build !windows forceposix
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	defaultShortOptDelimiter = '-'
 | 
			
		||||
	defaultLongOptDelimiter  = "--"
 | 
			
		||||
	defaultNameArgDelimiter  = '='
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func argumentStartsOption(arg string) bool {
 | 
			
		||||
	return len(arg) > 0 && arg[0] == '-'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func argumentIsOption(arg string) bool {
 | 
			
		||||
	if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stripOptionPrefix returns the option without the prefix and whether or
 | 
			
		||||
// not the option is a long option or not.
 | 
			
		||||
func stripOptionPrefix(optname string) (prefix string, name string, islong bool) {
 | 
			
		||||
	if strings.HasPrefix(optname, "--") {
 | 
			
		||||
		return "--", optname[2:], true
 | 
			
		||||
	} else if strings.HasPrefix(optname, "-") {
 | 
			
		||||
		return "-", optname[1:], false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return "", optname, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitOption attempts to split the passed option into a name and an argument.
 | 
			
		||||
// When there is no argument specified, nil will be returned for it.
 | 
			
		||||
func splitOption(prefix string, option string, islong bool) (string, string, *string) {
 | 
			
		||||
	pos := strings.Index(option, "=")
 | 
			
		||||
 | 
			
		||||
	if (islong && pos >= 0) || (!islong && pos == 1) {
 | 
			
		||||
		rest := option[pos+1:]
 | 
			
		||||
		return option[:pos], "=", &rest
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return option, "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// addHelpGroup adds a new group that contains default help parameters.
 | 
			
		||||
func (c *Command) addHelpGroup(showHelp func() error) *Group {
 | 
			
		||||
	var help struct {
 | 
			
		||||
		ShowHelp func() error `short:"h" long:"help" description:"Show this help message"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	help.ShowHelp = showHelp
 | 
			
		||||
	ret, _ := c.AddGroup("Help Options", "", &help)
 | 
			
		||||
	ret.isBuiltinHelp = true
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										108
									
								
								vendor/github.com/jessevdk/go-flags/optstyle_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								vendor/github.com/jessevdk/go-flags/optstyle_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
// +build !forceposix
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Windows uses a front slash for both short and long options.  Also it uses
 | 
			
		||||
// a colon for name/argument delimter.
 | 
			
		||||
const (
 | 
			
		||||
	defaultShortOptDelimiter = '/'
 | 
			
		||||
	defaultLongOptDelimiter  = "/"
 | 
			
		||||
	defaultNameArgDelimiter  = ':'
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func argumentStartsOption(arg string) bool {
 | 
			
		||||
	return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func argumentIsOption(arg string) bool {
 | 
			
		||||
	// Windows-style options allow front slash for the option
 | 
			
		||||
	// delimiter.
 | 
			
		||||
	if len(arg) > 1 && arg[0] == '/' {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// stripOptionPrefix returns the option without the prefix and whether or
 | 
			
		||||
// not the option is a long option or not.
 | 
			
		||||
func stripOptionPrefix(optname string) (prefix string, name string, islong bool) {
 | 
			
		||||
	// Determine if the argument is a long option or not.  Windows
 | 
			
		||||
	// typically supports both long and short options with a single
 | 
			
		||||
	// front slash as the option delimiter, so handle this situation
 | 
			
		||||
	// nicely.
 | 
			
		||||
	possplit := 0
 | 
			
		||||
 | 
			
		||||
	if strings.HasPrefix(optname, "--") {
 | 
			
		||||
		possplit = 2
 | 
			
		||||
		islong = true
 | 
			
		||||
	} else if strings.HasPrefix(optname, "-") {
 | 
			
		||||
		possplit = 1
 | 
			
		||||
		islong = false
 | 
			
		||||
	} else if strings.HasPrefix(optname, "/") {
 | 
			
		||||
		possplit = 1
 | 
			
		||||
		islong = len(optname) > 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return optname[:possplit], optname[possplit:], islong
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// splitOption attempts to split the passed option into a name and an argument.
 | 
			
		||||
// When there is no argument specified, nil will be returned for it.
 | 
			
		||||
func splitOption(prefix string, option string, islong bool) (string, string, *string) {
 | 
			
		||||
	if len(option) == 0 {
 | 
			
		||||
		return option, "", nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Windows typically uses a colon for the option name and argument
 | 
			
		||||
	// delimiter while POSIX typically uses an equals.  Support both styles,
 | 
			
		||||
	// but don't allow the two to be mixed.  That is to say /foo:bar and
 | 
			
		||||
	// --foo=bar are acceptable, but /foo=bar and --foo:bar are not.
 | 
			
		||||
	var pos int
 | 
			
		||||
	var sp string
 | 
			
		||||
 | 
			
		||||
	if prefix == "/" {
 | 
			
		||||
		sp = ":"
 | 
			
		||||
		pos = strings.Index(option, sp)
 | 
			
		||||
	} else if len(prefix) > 0 {
 | 
			
		||||
		sp = "="
 | 
			
		||||
		pos = strings.Index(option, sp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (islong && pos >= 0) || (!islong && pos == 1) {
 | 
			
		||||
		rest := option[pos+1:]
 | 
			
		||||
		return option[:pos], sp, &rest
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return option, "", nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// addHelpGroup adds a new group that contains default help parameters.
 | 
			
		||||
func (c *Command) addHelpGroup(showHelp func() error) *Group {
 | 
			
		||||
	// Windows CLI applications typically use /? for help, so make both
 | 
			
		||||
	// that available as well as the POSIX style h and help.
 | 
			
		||||
	var help struct {
 | 
			
		||||
		ShowHelpWindows func() error `short:"?" description:"Show this help message"`
 | 
			
		||||
		ShowHelpPosix   func() error `short:"h" long:"help" description:"Show this help message"`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	help.ShowHelpWindows = showHelp
 | 
			
		||||
	help.ShowHelpPosix = showHelp
 | 
			
		||||
 | 
			
		||||
	ret, _ := c.AddGroup("Help Options", "", &help)
 | 
			
		||||
	ret.isBuiltinHelp = true
 | 
			
		||||
 | 
			
		||||
	return ret
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										700
									
								
								vendor/github.com/jessevdk/go-flags/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										700
									
								
								vendor/github.com/jessevdk/go-flags/parser.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,700 @@
 | 
			
		||||
// Copyright 2012 Jesse van den Kieboom. All rights reserved.
 | 
			
		||||
// Use of this source code is governed by a BSD-style
 | 
			
		||||
// license that can be found in the LICENSE file.
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"unicode/utf8"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// A Parser provides command line option parsing. It can contain several
 | 
			
		||||
// option groups each with their own set of options.
 | 
			
		||||
type Parser struct {
 | 
			
		||||
	// Embedded, see Command for more information
 | 
			
		||||
	*Command
 | 
			
		||||
 | 
			
		||||
	// A usage string to be displayed in the help message.
 | 
			
		||||
	Usage string
 | 
			
		||||
 | 
			
		||||
	// Option flags changing the behavior of the parser.
 | 
			
		||||
	Options Options
 | 
			
		||||
 | 
			
		||||
	// NamespaceDelimiter separates group namespaces and option long names
 | 
			
		||||
	NamespaceDelimiter string
 | 
			
		||||
 | 
			
		||||
	// UnknownOptionsHandler is a function which gets called when the parser
 | 
			
		||||
	// encounters an unknown option. The function receives the unknown option
 | 
			
		||||
	// name, a SplitArgument which specifies its value if set with an argument
 | 
			
		||||
	// separator, and the remaining command line arguments.
 | 
			
		||||
	// It should return a new list of remaining arguments to continue parsing,
 | 
			
		||||
	// or an error to indicate a parse failure.
 | 
			
		||||
	UnknownOptionHandler func(option string, arg SplitArgument, args []string) ([]string, error)
 | 
			
		||||
 | 
			
		||||
	// CompletionHandler is a function gets called to handle the completion of
 | 
			
		||||
	// items. By default, the items are printed and the application is exited.
 | 
			
		||||
	// You can override this default behavior by specifying a custom CompletionHandler.
 | 
			
		||||
	CompletionHandler func(items []Completion)
 | 
			
		||||
 | 
			
		||||
	// CommandHandler is a function that gets called to handle execution of a
 | 
			
		||||
	// command. By default, the command will simply be executed. This can be
 | 
			
		||||
	// overridden to perform certain actions (such as applying global flags)
 | 
			
		||||
	// just before the command is executed. Note that if you override the
 | 
			
		||||
	// handler it is your responsibility to call the command.Execute function.
 | 
			
		||||
	//
 | 
			
		||||
	// The command passed into CommandHandler may be nil in case there is no
 | 
			
		||||
	// command to be executed when parsing has finished.
 | 
			
		||||
	CommandHandler func(command Commander, args []string) error
 | 
			
		||||
 | 
			
		||||
	internalError error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SplitArgument represents the argument value of an option that was passed using
 | 
			
		||||
// an argument separator.
 | 
			
		||||
type SplitArgument interface {
 | 
			
		||||
	// String returns the option's value as a string, and a boolean indicating
 | 
			
		||||
	// if the option was present.
 | 
			
		||||
	Value() (string, bool)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type strArgument struct {
 | 
			
		||||
	value *string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s strArgument) Value() (string, bool) {
 | 
			
		||||
	if s.value == nil {
 | 
			
		||||
		return "", false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return *s.value, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Options provides parser options that change the behavior of the option
 | 
			
		||||
// parser.
 | 
			
		||||
type Options uint
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// None indicates no options.
 | 
			
		||||
	None Options = 0
 | 
			
		||||
 | 
			
		||||
	// HelpFlag adds a default Help Options group to the parser containing
 | 
			
		||||
	// -h and --help options. When either -h or --help is specified on the
 | 
			
		||||
	// command line, the parser will return the special error of type
 | 
			
		||||
	// ErrHelp. When PrintErrors is also specified, then the help message
 | 
			
		||||
	// will also be automatically printed to os.Stdout.
 | 
			
		||||
	HelpFlag = 1 << iota
 | 
			
		||||
 | 
			
		||||
	// PassDoubleDash passes all arguments after a double dash, --, as
 | 
			
		||||
	// remaining command line arguments (i.e. they will not be parsed for
 | 
			
		||||
	// flags).
 | 
			
		||||
	PassDoubleDash
 | 
			
		||||
 | 
			
		||||
	// IgnoreUnknown ignores any unknown options and passes them as
 | 
			
		||||
	// remaining command line arguments instead of generating an error.
 | 
			
		||||
	IgnoreUnknown
 | 
			
		||||
 | 
			
		||||
	// PrintErrors prints any errors which occurred during parsing to
 | 
			
		||||
	// os.Stderr. In the special case of ErrHelp, the message will be printed
 | 
			
		||||
	// to os.Stdout.
 | 
			
		||||
	PrintErrors
 | 
			
		||||
 | 
			
		||||
	// PassAfterNonOption passes all arguments after the first non option
 | 
			
		||||
	// as remaining command line arguments. This is equivalent to strict
 | 
			
		||||
	// POSIX processing.
 | 
			
		||||
	PassAfterNonOption
 | 
			
		||||
 | 
			
		||||
	// Default is a convenient default set of options which should cover
 | 
			
		||||
	// most of the uses of the flags package.
 | 
			
		||||
	Default = HelpFlag | PrintErrors | PassDoubleDash
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type parseState struct {
 | 
			
		||||
	arg        string
 | 
			
		||||
	args       []string
 | 
			
		||||
	retargs    []string
 | 
			
		||||
	positional []*Arg
 | 
			
		||||
	err        error
 | 
			
		||||
 | 
			
		||||
	command *Command
 | 
			
		||||
	lookup  lookup
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse is a convenience function to parse command line options with default
 | 
			
		||||
// settings. The provided data is a pointer to a struct representing the
 | 
			
		||||
// default option group (named "Application Options"). For more control, use
 | 
			
		||||
// flags.NewParser.
 | 
			
		||||
func Parse(data interface{}) ([]string, error) {
 | 
			
		||||
	return NewParser(data, Default).Parse()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseArgs is a convenience function to parse command line options with default
 | 
			
		||||
// settings. The provided data is a pointer to a struct representing the
 | 
			
		||||
// default option group (named "Application Options"). The args argument is
 | 
			
		||||
// the list of command line arguments to parse. If you just want to parse the
 | 
			
		||||
// default program command line arguments (i.e. os.Args), then use flags.Parse
 | 
			
		||||
// instead. For more control, use flags.NewParser.
 | 
			
		||||
func ParseArgs(data interface{}, args []string) ([]string, error) {
 | 
			
		||||
	return NewParser(data, Default).ParseArgs(args)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewParser creates a new parser. It uses os.Args[0] as the application
 | 
			
		||||
// name and then calls Parser.NewNamedParser (see Parser.NewNamedParser for
 | 
			
		||||
// more details). The provided data is a pointer to a struct representing the
 | 
			
		||||
// default option group (named "Application Options"), or nil if the default
 | 
			
		||||
// group should not be added. The options parameter specifies a set of options
 | 
			
		||||
// for the parser.
 | 
			
		||||
func NewParser(data interface{}, options Options) *Parser {
 | 
			
		||||
	p := NewNamedParser(path.Base(os.Args[0]), options)
 | 
			
		||||
 | 
			
		||||
	if data != nil {
 | 
			
		||||
		g, err := p.AddGroup("Application Options", "", data)
 | 
			
		||||
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			g.parent = p
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		p.internalError = err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewNamedParser creates a new parser. The appname is used to display the
 | 
			
		||||
// executable name in the built-in help message. Option groups and commands can
 | 
			
		||||
// be added to this parser by using AddGroup and AddCommand.
 | 
			
		||||
func NewNamedParser(appname string, options Options) *Parser {
 | 
			
		||||
	p := &Parser{
 | 
			
		||||
		Command:            newCommand(appname, "", "", nil),
 | 
			
		||||
		Options:            options,
 | 
			
		||||
		NamespaceDelimiter: ".",
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.Command.parent = p
 | 
			
		||||
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Parse parses the command line arguments from os.Args using Parser.ParseArgs.
 | 
			
		||||
// For more detailed information see ParseArgs.
 | 
			
		||||
func (p *Parser) Parse() ([]string, error) {
 | 
			
		||||
	return p.ParseArgs(os.Args[1:])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ParseArgs parses the command line arguments according to the option groups that
 | 
			
		||||
// were added to the parser. On successful parsing of the arguments, the
 | 
			
		||||
// remaining, non-option, arguments (if any) are returned. The returned error
 | 
			
		||||
// indicates a parsing error and can be used with PrintError to display
 | 
			
		||||
// contextual information on where the error occurred exactly.
 | 
			
		||||
//
 | 
			
		||||
// When the common help group has been added (AddHelp) and either -h or --help
 | 
			
		||||
// was specified in the command line arguments, a help message will be
 | 
			
		||||
// automatically printed if the PrintErrors option is enabled.
 | 
			
		||||
// Furthermore, the special error type ErrHelp is returned.
 | 
			
		||||
// It is up to the caller to exit the program if so desired.
 | 
			
		||||
func (p *Parser) ParseArgs(args []string) ([]string, error) {
 | 
			
		||||
	if p.internalError != nil {
 | 
			
		||||
		return nil, p.internalError
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.eachOption(func(c *Command, g *Group, option *Option) {
 | 
			
		||||
		option.isSet = false
 | 
			
		||||
		option.isSetDefault = false
 | 
			
		||||
		option.updateDefaultLiteral()
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// Add built-in help group to all commands if necessary
 | 
			
		||||
	if (p.Options & HelpFlag) != None {
 | 
			
		||||
		p.addHelpGroups(p.showBuiltinHelp)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	compval := os.Getenv("GO_FLAGS_COMPLETION")
 | 
			
		||||
 | 
			
		||||
	if len(compval) != 0 {
 | 
			
		||||
		comp := &completion{parser: p}
 | 
			
		||||
		items := comp.complete(args)
 | 
			
		||||
 | 
			
		||||
		if p.CompletionHandler != nil {
 | 
			
		||||
			p.CompletionHandler(items)
 | 
			
		||||
		} else {
 | 
			
		||||
			comp.print(items, compval == "verbose")
 | 
			
		||||
			os.Exit(0)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s := &parseState{
 | 
			
		||||
		args:    args,
 | 
			
		||||
		retargs: make([]string, 0, len(args)),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.fillParseState(s)
 | 
			
		||||
 | 
			
		||||
	for !s.eof() {
 | 
			
		||||
		arg := s.pop()
 | 
			
		||||
 | 
			
		||||
		// When PassDoubleDash is set and we encounter a --, then
 | 
			
		||||
		// simply append all the rest as arguments and break out
 | 
			
		||||
		if (p.Options&PassDoubleDash) != None && arg == "--" {
 | 
			
		||||
			s.addArgs(s.args...)
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !argumentIsOption(arg) {
 | 
			
		||||
			// Note: this also sets s.err, so we can just check for
 | 
			
		||||
			// nil here and use s.err later
 | 
			
		||||
			if p.parseNonOption(s) != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		var err error
 | 
			
		||||
 | 
			
		||||
		prefix, optname, islong := stripOptionPrefix(arg)
 | 
			
		||||
		optname, _, argument := splitOption(prefix, optname, islong)
 | 
			
		||||
 | 
			
		||||
		if islong {
 | 
			
		||||
			err = p.parseLong(s, optname, argument)
 | 
			
		||||
		} else {
 | 
			
		||||
			err = p.parseShort(s, optname, argument)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			ignoreUnknown := (p.Options & IgnoreUnknown) != None
 | 
			
		||||
			parseErr := wrapError(err)
 | 
			
		||||
 | 
			
		||||
			if parseErr.Type != ErrUnknownFlag || (!ignoreUnknown && p.UnknownOptionHandler == nil) {
 | 
			
		||||
				s.err = parseErr
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if ignoreUnknown {
 | 
			
		||||
				s.addArgs(arg)
 | 
			
		||||
			} else if p.UnknownOptionHandler != nil {
 | 
			
		||||
				modifiedArgs, err := p.UnknownOptionHandler(optname, strArgument{argument}, s.args)
 | 
			
		||||
 | 
			
		||||
				if err != nil {
 | 
			
		||||
					s.err = err
 | 
			
		||||
					break
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				s.args = modifiedArgs
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.err == nil {
 | 
			
		||||
		p.eachOption(func(c *Command, g *Group, option *Option) {
 | 
			
		||||
			if option.preventDefault {
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			option.clearDefault()
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		s.checkRequired(p)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var reterr error
 | 
			
		||||
 | 
			
		||||
	if s.err != nil {
 | 
			
		||||
		reterr = s.err
 | 
			
		||||
	} else if len(s.command.commands) != 0 && !s.command.SubcommandsOptional {
 | 
			
		||||
		reterr = s.estimateCommand()
 | 
			
		||||
	} else if cmd, ok := s.command.data.(Commander); ok {
 | 
			
		||||
		if p.CommandHandler != nil {
 | 
			
		||||
			reterr = p.CommandHandler(cmd, s.retargs)
 | 
			
		||||
		} else {
 | 
			
		||||
			reterr = cmd.Execute(s.retargs)
 | 
			
		||||
		}
 | 
			
		||||
	} else if p.CommandHandler != nil {
 | 
			
		||||
		reterr = p.CommandHandler(nil, s.retargs)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if reterr != nil {
 | 
			
		||||
		var retargs []string
 | 
			
		||||
 | 
			
		||||
		if ourErr, ok := reterr.(*Error); !ok || ourErr.Type != ErrHelp {
 | 
			
		||||
			retargs = append([]string{s.arg}, s.args...)
 | 
			
		||||
		} else {
 | 
			
		||||
			retargs = s.args
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return retargs, p.printError(reterr)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return s.retargs, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) eof() bool {
 | 
			
		||||
	return len(p.args) == 0
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) pop() string {
 | 
			
		||||
	if p.eof() {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.arg = p.args[0]
 | 
			
		||||
	p.args = p.args[1:]
 | 
			
		||||
 | 
			
		||||
	return p.arg
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) peek() string {
 | 
			
		||||
	if p.eof() {
 | 
			
		||||
		return ""
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p.args[0]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) checkRequired(parser *Parser) error {
 | 
			
		||||
	c := parser.Command
 | 
			
		||||
 | 
			
		||||
	var required []*Option
 | 
			
		||||
 | 
			
		||||
	for c != nil {
 | 
			
		||||
		c.eachGroup(func(g *Group) {
 | 
			
		||||
			for _, option := range g.options {
 | 
			
		||||
				if !option.isSet && option.Required {
 | 
			
		||||
					required = append(required, option)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
 | 
			
		||||
		c = c.Active
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(required) == 0 {
 | 
			
		||||
		if len(p.positional) > 0 {
 | 
			
		||||
			var reqnames []string
 | 
			
		||||
 | 
			
		||||
			for _, arg := range p.positional {
 | 
			
		||||
				argRequired := (!arg.isRemaining() && p.command.ArgsRequired) || arg.Required != -1 || arg.RequiredMaximum != -1
 | 
			
		||||
 | 
			
		||||
				if !argRequired {
 | 
			
		||||
					continue
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if arg.isRemaining() {
 | 
			
		||||
					if arg.value.Len() < arg.Required {
 | 
			
		||||
						var arguments string
 | 
			
		||||
 | 
			
		||||
						if arg.Required > 1 {
 | 
			
		||||
							arguments = "arguments, but got only " + fmt.Sprintf("%d", arg.value.Len())
 | 
			
		||||
						} else {
 | 
			
		||||
							arguments = "argument"
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						reqnames = append(reqnames, "`"+arg.Name+" (at least "+fmt.Sprintf("%d", arg.Required)+" "+arguments+")`")
 | 
			
		||||
					} else if arg.RequiredMaximum != -1 && arg.value.Len() > arg.RequiredMaximum {
 | 
			
		||||
						if arg.RequiredMaximum == 0 {
 | 
			
		||||
							reqnames = append(reqnames, "`"+arg.Name+" (zero arguments)`")
 | 
			
		||||
						} else {
 | 
			
		||||
							var arguments string
 | 
			
		||||
 | 
			
		||||
							if arg.RequiredMaximum > 1 {
 | 
			
		||||
								arguments = "arguments, but got " + fmt.Sprintf("%d", arg.value.Len())
 | 
			
		||||
							} else {
 | 
			
		||||
								arguments = "argument"
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							reqnames = append(reqnames, "`"+arg.Name+" (at most "+fmt.Sprintf("%d", arg.RequiredMaximum)+" "+arguments+")`")
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				} else {
 | 
			
		||||
					reqnames = append(reqnames, "`"+arg.Name+"`")
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(reqnames) == 0 {
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			var msg string
 | 
			
		||||
 | 
			
		||||
			if len(reqnames) == 1 {
 | 
			
		||||
				msg = fmt.Sprintf("the required argument %s was not provided", reqnames[0])
 | 
			
		||||
			} else {
 | 
			
		||||
				msg = fmt.Sprintf("the required arguments %s and %s were not provided",
 | 
			
		||||
					strings.Join(reqnames[:len(reqnames)-1], ", "), reqnames[len(reqnames)-1])
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			p.err = newError(ErrRequired, msg)
 | 
			
		||||
			return p.err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	names := make([]string, 0, len(required))
 | 
			
		||||
 | 
			
		||||
	for _, k := range required {
 | 
			
		||||
		names = append(names, "`"+k.String()+"'")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	sort.Strings(names)
 | 
			
		||||
 | 
			
		||||
	var msg string
 | 
			
		||||
 | 
			
		||||
	if len(names) == 1 {
 | 
			
		||||
		msg = fmt.Sprintf("the required flag %s was not specified", names[0])
 | 
			
		||||
	} else {
 | 
			
		||||
		msg = fmt.Sprintf("the required flags %s and %s were not specified",
 | 
			
		||||
			strings.Join(names[:len(names)-1], ", "), names[len(names)-1])
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.err = newError(ErrRequired, msg)
 | 
			
		||||
	return p.err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) estimateCommand() error {
 | 
			
		||||
	commands := p.command.sortedVisibleCommands()
 | 
			
		||||
	cmdnames := make([]string, len(commands))
 | 
			
		||||
 | 
			
		||||
	for i, v := range commands {
 | 
			
		||||
		cmdnames[i] = v.Name
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var msg string
 | 
			
		||||
	var errtype ErrorType
 | 
			
		||||
 | 
			
		||||
	if len(p.retargs) != 0 {
 | 
			
		||||
		c, l := closestChoice(p.retargs[0], cmdnames)
 | 
			
		||||
		msg = fmt.Sprintf("Unknown command `%s'", p.retargs[0])
 | 
			
		||||
		errtype = ErrUnknownCommand
 | 
			
		||||
 | 
			
		||||
		if float32(l)/float32(len(c)) < 0.5 {
 | 
			
		||||
			msg = fmt.Sprintf("%s, did you mean `%s'?", msg, c)
 | 
			
		||||
		} else if len(cmdnames) == 1 {
 | 
			
		||||
			msg = fmt.Sprintf("%s. You should use the %s command",
 | 
			
		||||
				msg,
 | 
			
		||||
				cmdnames[0])
 | 
			
		||||
		} else if len(cmdnames) > 1 {
 | 
			
		||||
			msg = fmt.Sprintf("%s. Please specify one command of: %s or %s",
 | 
			
		||||
				msg,
 | 
			
		||||
				strings.Join(cmdnames[:len(cmdnames)-1], ", "),
 | 
			
		||||
				cmdnames[len(cmdnames)-1])
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		errtype = ErrCommandRequired
 | 
			
		||||
 | 
			
		||||
		if len(cmdnames) == 1 {
 | 
			
		||||
			msg = fmt.Sprintf("Please specify the %s command", cmdnames[0])
 | 
			
		||||
		} else if len(cmdnames) > 1 {
 | 
			
		||||
			msg = fmt.Sprintf("Please specify one command of: %s or %s",
 | 
			
		||||
				strings.Join(cmdnames[:len(cmdnames)-1], ", "),
 | 
			
		||||
				cmdnames[len(cmdnames)-1])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newError(errtype, msg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) parseOption(s *parseState, name string, option *Option, canarg bool, argument *string) (err error) {
 | 
			
		||||
	if !option.canArgument() {
 | 
			
		||||
		if argument != nil {
 | 
			
		||||
			return newErrorf(ErrNoArgumentForBool, "bool flag `%s' cannot have an argument", option)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		err = option.set(nil)
 | 
			
		||||
	} else if argument != nil || (canarg && !s.eof()) {
 | 
			
		||||
		var arg string
 | 
			
		||||
 | 
			
		||||
		if argument != nil {
 | 
			
		||||
			arg = *argument
 | 
			
		||||
		} else {
 | 
			
		||||
			arg = s.pop()
 | 
			
		||||
 | 
			
		||||
			if argumentIsOption(arg) && !(option.isSignedNumber() && len(arg) > 1 && arg[0] == '-' && arg[1] >= '0' && arg[1] <= '9') {
 | 
			
		||||
				return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got option `%s'", option, arg)
 | 
			
		||||
			} else if p.Options&PassDoubleDash != 0 && arg == "--" {
 | 
			
		||||
				return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got double dash `--'", option)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if option.tag.Get("unquote") != "false" {
 | 
			
		||||
			arg, err = unquoteIfPossible(arg)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err == nil {
 | 
			
		||||
			err = option.set(&arg)
 | 
			
		||||
		}
 | 
			
		||||
	} else if option.OptionalArgument {
 | 
			
		||||
		option.empty()
 | 
			
		||||
 | 
			
		||||
		for _, v := range option.OptionalValue {
 | 
			
		||||
			err = option.set(&v)
 | 
			
		||||
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				break
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		err = newErrorf(ErrExpectedArgument, "expected argument for flag `%s'", option)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if _, ok := err.(*Error); !ok {
 | 
			
		||||
			err = newErrorf(ErrMarshal, "invalid argument for flag `%s' (expected %s): %s",
 | 
			
		||||
				option,
 | 
			
		||||
				option.value.Type(),
 | 
			
		||||
				err.Error())
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) parseLong(s *parseState, name string, argument *string) error {
 | 
			
		||||
	if option := s.lookup.longNames[name]; option != nil {
 | 
			
		||||
		// Only long options that are required can consume an argument
 | 
			
		||||
		// from the argument list
 | 
			
		||||
		canarg := !option.OptionalArgument
 | 
			
		||||
 | 
			
		||||
		return p.parseOption(s, name, option, canarg, argument)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newErrorf(ErrUnknownFlag, "unknown flag `%s'", name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) splitShortConcatArg(s *parseState, optname string) (string, *string) {
 | 
			
		||||
	c, n := utf8.DecodeRuneInString(optname)
 | 
			
		||||
 | 
			
		||||
	if n == len(optname) {
 | 
			
		||||
		return optname, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	first := string(c)
 | 
			
		||||
 | 
			
		||||
	if option := s.lookup.shortNames[first]; option != nil && option.canArgument() {
 | 
			
		||||
		arg := optname[n:]
 | 
			
		||||
		return first, &arg
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return optname, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) parseShort(s *parseState, optname string, argument *string) error {
 | 
			
		||||
	if argument == nil {
 | 
			
		||||
		optname, argument = p.splitShortConcatArg(s, optname)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i, c := range optname {
 | 
			
		||||
		shortname := string(c)
 | 
			
		||||
 | 
			
		||||
		if option := s.lookup.shortNames[shortname]; option != nil {
 | 
			
		||||
			// Only the last short argument can consume an argument from
 | 
			
		||||
			// the arguments list, and only if it's non optional
 | 
			
		||||
			canarg := (i+utf8.RuneLen(c) == len(optname)) && !option.OptionalArgument
 | 
			
		||||
 | 
			
		||||
			if err := p.parseOption(s, shortname, option, canarg, argument); err != nil {
 | 
			
		||||
				return err
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			return newErrorf(ErrUnknownFlag, "unknown flag `%s'", shortname)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Only the first option can have a concatted argument, so just
 | 
			
		||||
		// clear argument here
 | 
			
		||||
		argument = nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *parseState) addArgs(args ...string) error {
 | 
			
		||||
	for len(p.positional) > 0 && len(args) > 0 {
 | 
			
		||||
		arg := p.positional[0]
 | 
			
		||||
 | 
			
		||||
		if err := convert(args[0], arg.value, arg.tag); err != nil {
 | 
			
		||||
			p.err = err
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if !arg.isRemaining() {
 | 
			
		||||
			p.positional = p.positional[1:]
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		args = args[1:]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.retargs = append(p.retargs, args...)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) parseNonOption(s *parseState) error {
 | 
			
		||||
	if len(s.positional) > 0 {
 | 
			
		||||
		return s.addArgs(s.arg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(s.command.commands) > 0 && len(s.retargs) == 0 {
 | 
			
		||||
		if cmd := s.lookup.commands[s.arg]; cmd != nil {
 | 
			
		||||
			s.command.Active = cmd
 | 
			
		||||
			cmd.fillParseState(s)
 | 
			
		||||
 | 
			
		||||
			return nil
 | 
			
		||||
		} else if !s.command.SubcommandsOptional {
 | 
			
		||||
			s.addArgs(s.arg)
 | 
			
		||||
			return newErrorf(ErrUnknownCommand, "Unknown command `%s'", s.arg)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (p.Options & PassAfterNonOption) != None {
 | 
			
		||||
		// If PassAfterNonOption is set then all remaining arguments
 | 
			
		||||
		// are considered positional
 | 
			
		||||
		if err := s.addArgs(s.arg); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if err := s.addArgs(s.args...); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		s.args = []string{}
 | 
			
		||||
	} else {
 | 
			
		||||
		return s.addArgs(s.arg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) showBuiltinHelp() error {
 | 
			
		||||
	var b bytes.Buffer
 | 
			
		||||
 | 
			
		||||
	p.WriteHelp(&b)
 | 
			
		||||
	return newError(ErrHelp, b.String())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) printError(err error) error {
 | 
			
		||||
	if err != nil && (p.Options&PrintErrors) != None {
 | 
			
		||||
		flagsErr, ok := err.(*Error)
 | 
			
		||||
 | 
			
		||||
		if ok && flagsErr.Type == ErrHelp {
 | 
			
		||||
			fmt.Fprintln(os.Stdout, err)
 | 
			
		||||
		} else {
 | 
			
		||||
			fmt.Fprintln(os.Stderr, err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (p *Parser) clearIsSet() {
 | 
			
		||||
	p.eachCommand(func(c *Command) {
 | 
			
		||||
		c.eachGroup(func(g *Group) {
 | 
			
		||||
			for _, option := range g.options {
 | 
			
		||||
				option.isSet = false
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}, true)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								vendor/github.com/jessevdk/go-flags/termsize.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								vendor/github.com/jessevdk/go-flags/termsize.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
// +build !windows,!plan9,!solaris,!appengine
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"syscall"
 | 
			
		||||
	"unsafe"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type winsize struct {
 | 
			
		||||
	row, col       uint16
 | 
			
		||||
	xpixel, ypixel uint16
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getTerminalColumns() int {
 | 
			
		||||
	ws := winsize{}
 | 
			
		||||
 | 
			
		||||
	if tIOCGWINSZ != 0 {
 | 
			
		||||
		syscall.Syscall(syscall.SYS_IOCTL,
 | 
			
		||||
			uintptr(0),
 | 
			
		||||
			uintptr(tIOCGWINSZ),
 | 
			
		||||
			uintptr(unsafe.Pointer(&ws)))
 | 
			
		||||
 | 
			
		||||
		return int(ws.col)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 80
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/termsize_nosysioctl.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// +build windows plan9 solaris appengine
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
func getTerminalColumns() int {
 | 
			
		||||
	return 80
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_bsdish.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_bsdish.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// +build darwin freebsd netbsd openbsd
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	tIOCGWINSZ = 0x40087468
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_linux.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// +build linux
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	tIOCGWINSZ = 0x5413
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/jessevdk/go-flags/tiocgwinsz_other.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
// +build !darwin,!freebsd,!netbsd,!openbsd,!linux
 | 
			
		||||
 | 
			
		||||
package flags
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	tIOCGWINSZ = 0
 | 
			
		||||
)
 | 
			
		||||
		Reference in New Issue
	
	Block a user