Merge branch 'main' into issue_1500
This commit is contained in:
commit
fb23ff4aa2
2
.github/workflows/cli.yml
vendored
2
.github/workflows/cli.yml
vendored
@ -40,6 +40,8 @@ jobs:
|
|||||||
GFLAGS: -tags urfave_cli_no_docs
|
GFLAGS: -tags urfave_cli_no_docs
|
||||||
- run: make check-binary-size
|
- run: make check-binary-size
|
||||||
- run: make yamlfmt
|
- run: make yamlfmt
|
||||||
|
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
||||||
|
run: make generate
|
||||||
- run: make diffcheck
|
- run: make diffcheck
|
||||||
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
- if: matrix.go == '1.19.x' && matrix.os == 'ubuntu-latest'
|
||||||
run: make v2diff
|
run: make v2diff
|
||||||
|
@ -177,7 +177,7 @@ func ExampleApp_Run_commandHelp() {
|
|||||||
// greet describeit - use it to see a description
|
// greet describeit - use it to see a description
|
||||||
//
|
//
|
||||||
// USAGE:
|
// USAGE:
|
||||||
// greet describeit [command options] [arguments...]
|
// greet describeit [arguments...]
|
||||||
//
|
//
|
||||||
// DESCRIPTION:
|
// DESCRIPTION:
|
||||||
// This is how we describe describeit the function
|
// This is how we describe describeit the function
|
||||||
|
11
command.go
11
command.go
@ -295,6 +295,17 @@ func (c *Command) startApp(ctx *Context) error {
|
|||||||
return app.RunAsSubcommand(ctx)
|
return app.RunAsSubcommand(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VisibleCommands returns a slice of the Commands with Hidden=false
|
||||||
|
func (c *Command) VisibleCommands() []*Command {
|
||||||
|
var ret []*Command
|
||||||
|
for _, command := range c.Subcommands {
|
||||||
|
if !command.Hidden {
|
||||||
|
ret = append(ret, command)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory {
|
||||||
if c.flagCategories == nil {
|
if c.flagCategories == nil {
|
||||||
|
@ -422,3 +422,30 @@ func TestCommand_CanAddVFlagOnCommands(t *testing.T) {
|
|||||||
err := app.Run([]string{"foo", "bar"})
|
err := app.Run([]string{"foo", "bar"})
|
||||||
expect(t, err, nil)
|
expect(t, err, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCommand_VisibleSubcCommands(t *testing.T) {
|
||||||
|
|
||||||
|
subc1 := &Command{
|
||||||
|
Name: "subc1",
|
||||||
|
Usage: "subc1 command1",
|
||||||
|
}
|
||||||
|
subc3 := &Command{
|
||||||
|
Name: "subc3",
|
||||||
|
Usage: "subc3 command2",
|
||||||
|
}
|
||||||
|
c := &Command{
|
||||||
|
Name: "bar",
|
||||||
|
Usage: "this is for testing",
|
||||||
|
Subcommands: []*Command{
|
||||||
|
subc1,
|
||||||
|
{
|
||||||
|
Name: "subc2",
|
||||||
|
Usage: "subc2 command2",
|
||||||
|
Hidden: true,
|
||||||
|
},
|
||||||
|
subc3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(t, c.VisibleCommands(), []*Command{subc1, subc3})
|
||||||
|
}
|
||||||
|
29
flag.go
29
flag.go
@ -129,6 +129,14 @@ type DocGenerationFlag interface {
|
|||||||
GetEnvVars() []string
|
GetEnvVars() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||||
|
type DocGenerationSliceFlag interface {
|
||||||
|
DocGenerationFlag
|
||||||
|
|
||||||
|
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||||
|
IsSliceFlag() bool
|
||||||
|
}
|
||||||
|
|
||||||
// VisibleFlag is an interface that allows to check if a flag is visible
|
// VisibleFlag is an interface that allows to check if a flag is visible
|
||||||
type VisibleFlag interface {
|
type VisibleFlag interface {
|
||||||
Flag
|
Flag
|
||||||
@ -325,24 +333,13 @@ func stringifyFlag(f Flag) string {
|
|||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
usageWithDefault := strings.TrimSpace(usage + defaultValueString)
|
||||||
|
|
||||||
return withEnvHint(df.GetEnvVars(),
|
pn := prefixedNames(df.Names(), placeholder)
|
||||||
fmt.Sprintf("%s\t%s", prefixedNames(df.Names(), placeholder), usageWithDefault))
|
sliceFlag, ok := f.(DocGenerationSliceFlag)
|
||||||
}
|
if ok && sliceFlag.IsSliceFlag() {
|
||||||
|
pn = pn + " [ " + pn + " ]"
|
||||||
func stringifySliceFlag(usage string, names, defaultVals []string) string {
|
|
||||||
placeholder, usage := unquoteUsage(usage)
|
|
||||||
if placeholder == "" {
|
|
||||||
placeholder = defaultPlaceholder
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultVal := ""
|
return withEnvHint(df.GetEnvVars(), fmt.Sprintf("%s\t%s", pn, usageWithDefault))
|
||||||
if len(defaultVals) > 0 {
|
|
||||||
defaultVal = fmt.Sprintf(formatDefault("%s"), strings.Join(defaultVals, ", "))
|
|
||||||
}
|
|
||||||
|
|
||||||
usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal))
|
|
||||||
pn := prefixedNames(names, placeholder)
|
|
||||||
return fmt.Sprintf("%s [ %s ]\t%s", pn, pn, usageWithDefault)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasFlag(flags []Flag, fl Flag) bool {
|
func hasFlag(flags []Flag, fl Flag) bool {
|
||||||
|
@ -83,7 +83,7 @@ func (f *Float64Slice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *Float64SliceFlag) String() string {
|
func (f *Float64SliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true if the flag takes a value, otherwise false
|
// TakesValue returns true if the flag takes a value, otherwise false
|
||||||
@ -104,10 +104,13 @@ func (f *Float64SliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *Float64SliceFlag) GetValue() string {
|
func (f *Float64SliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, i := range f.Value.Value() {
|
||||||
|
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -123,6 +126,11 @@ func (f *Float64SliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *Float64SliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -169,18 +177,6 @@ func (f *Float64SliceFlag) Get(ctx *Context) []float64 {
|
|||||||
return ctx.Float64Slice(f.Name)
|
return ctx.Float64Slice(f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Float64SliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, i := range f.Value.Value() {
|
|
||||||
defaultVals = append(defaultVals, strings.TrimRight(strings.TrimRight(fmt.Sprintf("%f", i), "0"), "."))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunAction executes flag action if set
|
// RunAction executes flag action if set
|
||||||
func (f *Float64SliceFlag) RunAction(c *Context) error {
|
func (f *Float64SliceFlag) RunAction(c *Context) error {
|
||||||
if f.Action != nil {
|
if f.Action != nil {
|
||||||
|
@ -62,6 +62,10 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range f.Names() {
|
for _, name := range f.Names() {
|
||||||
|
if f.Destination != nil {
|
||||||
|
set.Var(f.Destination, name, f.Usage)
|
||||||
|
continue
|
||||||
|
}
|
||||||
set.Var(f.Value, name, f.Usage)
|
set.Var(f.Value, name, f.Usage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ func (i *Int64Slice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *Int64SliceFlag) String() string {
|
func (f *Int64SliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
// TakesValue returns true of the flag takes a value, otherwise false
|
||||||
@ -105,10 +105,13 @@ func (f *Int64SliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *Int64SliceFlag) GetValue() string {
|
func (f *Int64SliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, i := range f.Value.Value() {
|
||||||
|
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -124,6 +127,11 @@ func (f *Int64SliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *Int64SliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -168,17 +176,6 @@ func (f *Int64SliceFlag) Get(ctx *Context) []int64 {
|
|||||||
return ctx.Int64Slice(f.Name)
|
return ctx.Int64Slice(f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Int64SliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, i := range f.Value.Value() {
|
|
||||||
defaultVals = append(defaultVals, strconv.FormatInt(i, 10))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunAction executes flag action if set
|
// RunAction executes flag action if set
|
||||||
func (f *Int64SliceFlag) RunAction(c *Context) error {
|
func (f *Int64SliceFlag) RunAction(c *Context) error {
|
||||||
if f.Action != nil {
|
if f.Action != nil {
|
||||||
|
@ -95,7 +95,7 @@ func (i *IntSlice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *IntSliceFlag) String() string {
|
func (f *IntSliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
// TakesValue returns true of the flag takes a value, otherwise false
|
||||||
@ -116,10 +116,13 @@ func (f *IntSliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *IntSliceFlag) GetValue() string {
|
func (f *IntSliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, i := range f.Value.Value() {
|
||||||
|
defaultVals = append(defaultVals, strconv.Itoa(i))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -135,6 +138,11 @@ func (f *IntSliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *IntSliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *IntSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -188,17 +196,6 @@ func (f *IntSliceFlag) RunAction(c *Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *IntSliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, i := range f.Value.Value() {
|
|
||||||
defaultVals = append(defaultVals, strconv.Itoa(i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSlice looks up the value of a local IntSliceFlag, returns
|
// IntSlice looks up the value of a local IntSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (cCtx *Context) IntSlice(name string) []int {
|
func (cCtx *Context) IntSlice(name string) []int {
|
||||||
|
@ -74,7 +74,7 @@ func (s *StringSlice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *StringSliceFlag) String() string {
|
func (f *StringSliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
// TakesValue returns true of the flag takes a value, otherwise false
|
||||||
@ -95,10 +95,15 @@ func (f *StringSliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *StringSliceFlag) GetValue() string {
|
func (f *StringSliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, s := range f.Value.Value() {
|
||||||
|
if len(s) > 0 {
|
||||||
|
defaultVals = append(defaultVals, strconv.Quote(s))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -114,6 +119,11 @@ func (f *StringSliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *StringSliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *StringSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -158,19 +168,6 @@ func (f *StringSliceFlag) Get(ctx *Context) []string {
|
|||||||
return ctx.StringSlice(f.Name)
|
return ctx.StringSlice(f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *StringSliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, s := range f.Value.Value() {
|
|
||||||
if len(s) > 0 {
|
|
||||||
defaultVals = append(defaultVals, strconv.Quote(s))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// RunAction executes flag action if set
|
// RunAction executes flag action if set
|
||||||
func (f *StringSliceFlag) RunAction(c *Context) error {
|
func (f *StringSliceFlag) RunAction(c *Context) error {
|
||||||
if f.Action != nil {
|
if f.Action != nil {
|
||||||
|
67
flag_test.go
67
flag_test.go
@ -307,12 +307,12 @@ func TestFlagStringifying(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "float64-slice-flag",
|
name: "float64-slice-flag",
|
||||||
fl: &Float64SliceFlag{Name: "pizzas"},
|
fl: &Float64SliceFlag{Name: "pizzas"},
|
||||||
expected: "--pizzas value\t",
|
expected: "--pizzas value [ --pizzas value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "float64-slice-flag-with-default-text",
|
name: "float64-slice-flag-with-default-text",
|
||||||
fl: &Float64SliceFlag{Name: "pepperonis", DefaultText: "shaved"},
|
fl: &Float64SliceFlag{Name: "pepperonis", DefaultText: "shaved"},
|
||||||
expected: "--pepperonis value\t(default: shaved)",
|
expected: "--pepperonis value [ --pepperonis value ]\t(default: shaved)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "generic-flag",
|
name: "generic-flag",
|
||||||
@ -337,7 +337,7 @@ func TestFlagStringifying(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "int-slice-flag",
|
name: "int-slice-flag",
|
||||||
fl: &IntSliceFlag{Name: "pencils"},
|
fl: &IntSliceFlag{Name: "pencils"},
|
||||||
expected: "--pencils value\t",
|
expected: "--pencils value [ --pencils value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "int-slice-flag-with-default-text",
|
name: "int-slice-flag-with-default-text",
|
||||||
@ -347,7 +347,7 @@ func TestFlagStringifying(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "uint-slice-flag",
|
name: "uint-slice-flag",
|
||||||
fl: &UintSliceFlag{Name: "pencils"},
|
fl: &UintSliceFlag{Name: "pencils"},
|
||||||
expected: "--pencils value\t",
|
expected: "--pencils value [ --pencils value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uint-slice-flag-with-default-text",
|
name: "uint-slice-flag-with-default-text",
|
||||||
@ -367,22 +367,22 @@ func TestFlagStringifying(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "int64-slice-flag",
|
name: "int64-slice-flag",
|
||||||
fl: &Int64SliceFlag{Name: "drawers"},
|
fl: &Int64SliceFlag{Name: "drawers"},
|
||||||
expected: "--drawers value\t",
|
expected: "--drawers value [ --drawers value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "int64-slice-flag-with-default-text",
|
name: "int64-slice-flag-with-default-text",
|
||||||
fl: &Int64SliceFlag{Name: "handles", DefaultText: "-2"},
|
fl: &Int64SliceFlag{Name: "handles", DefaultText: "-2"},
|
||||||
expected: "--handles value\t(default: -2)",
|
expected: "--handles value [ --handles value ]\t(default: -2)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uint64-slice-flag",
|
name: "uint64-slice-flag",
|
||||||
fl: &Uint64SliceFlag{Name: "drawers"},
|
fl: &Uint64SliceFlag{Name: "drawers"},
|
||||||
expected: "--drawers value\t",
|
expected: "--drawers value [ --drawers value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uint64-slice-flag-with-default-text",
|
name: "uint64-slice-flag-with-default-text",
|
||||||
fl: &Uint64SliceFlag{Name: "handles", DefaultText: "-2"},
|
fl: &Uint64SliceFlag{Name: "handles", DefaultText: "-2"},
|
||||||
expected: "--handles value\t(default: -2)",
|
expected: "--handles value [ --handles value ]\t(default: -2)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "path-flag",
|
name: "path-flag",
|
||||||
@ -407,12 +407,12 @@ func TestFlagStringifying(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "string-slice-flag",
|
name: "string-slice-flag",
|
||||||
fl: &StringSliceFlag{Name: "meow-sounds"},
|
fl: &StringSliceFlag{Name: "meow-sounds"},
|
||||||
expected: "--meow-sounds value\t",
|
expected: "--meow-sounds value [ --meow-sounds value ]\t",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "string-slice-flag-with-default-text",
|
name: "string-slice-flag-with-default-text",
|
||||||
fl: &StringSliceFlag{Name: "moo-sounds", DefaultText: "awoo"},
|
fl: &StringSliceFlag{Name: "moo-sounds", DefaultText: "awoo"},
|
||||||
expected: "--moo-sounds value\t(default: awoo)",
|
expected: "--moo-sounds value [ --moo-sounds value ]\t(default: awoo)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "timestamp-flag",
|
name: "timestamp-flag",
|
||||||
@ -2724,6 +2724,53 @@ func TestParseGeneric(t *testing.T) {
|
|||||||
}).Run([]string{"run", "-s", "10,20"})
|
}).Run([]string{"run", "-s", "10,20"})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type genericType struct {
|
||||||
|
s []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *genericType) Set(value string) error {
|
||||||
|
g.s = strings.Split(value, "-")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *genericType) String() string {
|
||||||
|
return strings.Join(g.s, "-")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseDestinationGeneric(t *testing.T) {
|
||||||
|
expectedString := "abc1-123d"
|
||||||
|
expectedGeneric := &genericType{[]string{"abc1", "123d"}}
|
||||||
|
dest := &genericType{}
|
||||||
|
|
||||||
|
_ = (&App{
|
||||||
|
Flags: []Flag{
|
||||||
|
&GenericFlag{
|
||||||
|
Name: "dest",
|
||||||
|
Destination: dest,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(ctx *Context) error {
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(dest, expectedGeneric) {
|
||||||
|
t.Errorf(
|
||||||
|
"expected destination generic: %+v, actual: %+v",
|
||||||
|
expectedGeneric,
|
||||||
|
dest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if dest.String() != expectedString {
|
||||||
|
t.Errorf(
|
||||||
|
"expected destination string: %s, actual: %s",
|
||||||
|
expectedString,
|
||||||
|
dest.String(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}).Run([]string{"run", "--dest", expectedString})
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseGenericFromEnv(t *testing.T) {
|
func TestParseGenericFromEnv(t *testing.T) {
|
||||||
defer resetEnv(os.Environ())
|
defer resetEnv(os.Environ())
|
||||||
os.Clearenv()
|
os.Clearenv()
|
||||||
|
@ -88,7 +88,7 @@ func (i *Uint64Slice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *Uint64SliceFlag) String() string {
|
func (f *Uint64SliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
// TakesValue returns true of the flag takes a value, otherwise false
|
||||||
@ -109,10 +109,13 @@ func (f *Uint64SliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *Uint64SliceFlag) GetValue() string {
|
func (f *Uint64SliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, i := range f.Value.Value() {
|
||||||
|
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -128,6 +131,11 @@ func (f *Uint64SliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *Uint64SliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -172,17 +180,6 @@ func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
|
|||||||
return ctx.Uint64Slice(f.Name)
|
return ctx.Uint64Slice(f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Uint64SliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, i := range f.Value.Value() {
|
|
||||||
defaultVals = append(defaultVals, strconv.FormatUint(i, 10))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
// Uint64Slice looks up the value of a local Uint64SliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (cCtx *Context) Uint64Slice(name string) []uint64 {
|
func (cCtx *Context) Uint64Slice(name string) []uint64 {
|
||||||
|
@ -99,7 +99,7 @@ func (i *UintSlice) Get() interface{} {
|
|||||||
// String returns a readable representation of this value
|
// String returns a readable representation of this value
|
||||||
// (for usage defaults)
|
// (for usage defaults)
|
||||||
func (f *UintSliceFlag) String() string {
|
func (f *UintSliceFlag) String() string {
|
||||||
return withEnvHint(f.GetEnvVars(), f.stringify())
|
return FlagStringer(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TakesValue returns true of the flag takes a value, otherwise false
|
// TakesValue returns true of the flag takes a value, otherwise false
|
||||||
@ -120,10 +120,13 @@ func (f *UintSliceFlag) GetCategory() string {
|
|||||||
// GetValue returns the flags value as string representation and an empty
|
// GetValue returns the flags value as string representation and an empty
|
||||||
// string if the flag takes no value at all.
|
// string if the flag takes no value at all.
|
||||||
func (f *UintSliceFlag) GetValue() string {
|
func (f *UintSliceFlag) GetValue() string {
|
||||||
if f.Value != nil {
|
var defaultVals []string
|
||||||
return f.Value.String()
|
if f.Value != nil && len(f.Value.Value()) > 0 {
|
||||||
|
for _, i := range f.Value.Value() {
|
||||||
|
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
|
||||||
}
|
}
|
||||||
return ""
|
}
|
||||||
|
return strings.Join(defaultVals, ", ")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultText returns the default text for this flag
|
// GetDefaultText returns the default text for this flag
|
||||||
@ -139,6 +142,11 @@ func (f *UintSliceFlag) GetEnvVars() []string {
|
|||||||
return f.EnvVars
|
return f.EnvVars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
func (f *UintSliceFlag) IsSliceFlag() bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Apply populates the flag given the flag set and environment
|
// Apply populates the flag given the flag set and environment
|
||||||
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
|
func (f *UintSliceFlag) Apply(set *flag.FlagSet) error {
|
||||||
// apply any default
|
// apply any default
|
||||||
@ -183,17 +191,6 @@ func (f *UintSliceFlag) Get(ctx *Context) []uint {
|
|||||||
return ctx.UintSlice(f.Name)
|
return ctx.UintSlice(f.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *UintSliceFlag) stringify() string {
|
|
||||||
var defaultVals []string
|
|
||||||
if f.Value != nil && len(f.Value.Value()) > 0 {
|
|
||||||
for _, i := range f.Value.Value() {
|
|
||||||
defaultVals = append(defaultVals, strconv.FormatUint(uint64(i), 10))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringifySliceFlag(f.Usage, f.Names(), defaultVals)
|
|
||||||
}
|
|
||||||
|
|
||||||
// UintSlice looks up the value of a local UintSliceFlag, returns
|
// UintSlice looks up the value of a local UintSliceFlag, returns
|
||||||
// nil if not found
|
// nil if not found
|
||||||
func (cCtx *Context) UintSlice(name string) []uint {
|
func (cCtx *Context) UintSlice(name string) []uint {
|
||||||
|
@ -32,7 +32,7 @@ var (
|
|||||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||||
)
|
)
|
||||||
var AppHelpTemplate = `NAME:
|
var AppHelpTemplate = `NAME:
|
||||||
{{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||||
@ -41,52 +41,39 @@ VERSION:
|
|||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if len .Authors}}
|
{{template "descriptionTemplate" .}}{{end}}
|
||||||
|
{{- if len .Authors}}
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
|
||||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
|
GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}
|
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}}
|
||||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
|
||||||
{{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}}
|
|
||||||
|
|
||||||
COPYRIGHT:
|
COPYRIGHT:
|
||||||
{{wrap .Copyright 3}}{{end}}
|
{{template "copyrightTemplate" .}}{{end}}
|
||||||
`
|
`
|
||||||
AppHelpTemplate is the text template for the Default help topic. cli.go
|
AppHelpTemplate is the text template for the Default help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
setting this variable.
|
setting this variable.
|
||||||
|
|
||||||
var CommandHelpTemplate = `NAME:
|
var CommandHelpTemplate = `NAME:
|
||||||
{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
{{template "usageTemplate" .}}{{if .Category}}
|
||||||
|
|
||||||
CATEGORY:
|
CATEGORY:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
|
||||||
`
|
|
||||||
CommandHelpTemplate is the text template for the command help topic. cli.go
|
CommandHelpTemplate is the text template for the command help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
setting this variable.
|
setting this variable.
|
||||||
@ -145,22 +132,19 @@ var OsExiter = os.Exit
|
|||||||
os.Exit.
|
os.Exit.
|
||||||
|
|
||||||
var SubcommandHelpTemplate = `NAME:
|
var SubcommandHelpTemplate = `NAME:
|
||||||
{{.HelpName}} - {{.Usage}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
|
||||||
`
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
cli.go uses text/template to render templates. You can render custom help
|
cli.go uses text/template to render templates. You can render custom help
|
||||||
text by setting this variable.
|
text by setting this variable.
|
||||||
@ -585,6 +569,9 @@ func (c *Command) Run(ctx *Context) (err error)
|
|||||||
Run invokes the command given the context, parses ctx.Args() to generate
|
Run invokes the command given the context, parses ctx.Args() to generate
|
||||||
command-specific flags
|
command-specific flags
|
||||||
|
|
||||||
|
func (c *Command) VisibleCommands() []*Command
|
||||||
|
VisibleCommands returns a slice of the Commands with Hidden=false
|
||||||
|
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
||||||
VisibleFlagCategories returns a slice containing all the visible flag
|
VisibleFlagCategories returns a slice containing all the visible flag
|
||||||
categories with the flags they contain
|
categories with the flags they contain
|
||||||
@ -753,6 +740,14 @@ type DocGenerationFlag interface {
|
|||||||
DocGenerationFlag is an interface that allows documentation generation for
|
DocGenerationFlag is an interface that allows documentation generation for
|
||||||
the flag
|
the flag
|
||||||
|
|
||||||
|
type DocGenerationSliceFlag interface {
|
||||||
|
DocGenerationFlag
|
||||||
|
|
||||||
|
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||||
|
IsSliceFlag() bool
|
||||||
|
}
|
||||||
|
DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||||
|
|
||||||
type DurationFlag struct {
|
type DurationFlag struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@ -1071,6 +1066,9 @@ func (f *Float64SliceFlag) IsRequired() bool
|
|||||||
func (f *Float64SliceFlag) IsSet() bool
|
func (f *Float64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Float64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Float64SliceFlag) IsVisible() bool
|
func (f *Float64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1306,6 +1304,9 @@ func (f *Int64SliceFlag) IsRequired() bool
|
|||||||
func (f *Int64SliceFlag) IsSet() bool
|
func (f *Int64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Int64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Int64SliceFlag) IsVisible() bool
|
func (f *Int64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1471,6 +1472,9 @@ func (f *IntSliceFlag) IsRequired() bool
|
|||||||
func (f *IntSliceFlag) IsSet() bool
|
func (f *IntSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *IntSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *IntSliceFlag) IsVisible() bool
|
func (f *IntSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1810,6 +1814,9 @@ func (f *StringSliceFlag) IsRequired() bool
|
|||||||
func (f *StringSliceFlag) IsSet() bool
|
func (f *StringSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *StringSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *StringSliceFlag) IsVisible() bool
|
func (f *StringSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -2071,6 +2078,9 @@ func (f *Uint64SliceFlag) IsRequired() bool
|
|||||||
func (f *Uint64SliceFlag) IsSet() bool
|
func (f *Uint64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Uint64SliceFlag) IsVisible() bool
|
func (f *Uint64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -2227,6 +2237,9 @@ func (f *UintSliceFlag) IsRequired() bool
|
|||||||
func (f *UintSliceFlag) IsSet() bool
|
func (f *UintSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *UintSliceFlag) IsVisible() bool
|
func (f *UintSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
|
17
help.go
17
help.go
@ -242,7 +242,11 @@ func ShowCommandHelp(ctx *Context, command string) error {
|
|||||||
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
c.Subcommands = append(c.Subcommands, helpCommandDontUse)
|
||||||
}
|
}
|
||||||
if !ctx.App.HideHelp && HelpFlag != nil {
|
if !ctx.App.HideHelp && HelpFlag != nil {
|
||||||
c.appendFlag(HelpFlag)
|
if c.flagCategories == nil {
|
||||||
|
c.flagCategories = newFlagCategoriesFromFlags([]Flag{HelpFlag})
|
||||||
|
} else {
|
||||||
|
c.flagCategories.AddFlag("", HelpFlag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
templ := c.CustomHelpTemplate
|
templ := c.CustomHelpTemplate
|
||||||
if templ == "" {
|
if templ == "" {
|
||||||
@ -358,6 +362,17 @@ func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs
|
|||||||
|
|
||||||
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0)
|
||||||
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
t := template.Must(template.New("help").Funcs(funcMap).Parse(templ))
|
||||||
|
t.New("helpNameTemplate").Parse(helpNameTemplate)
|
||||||
|
t.New("usageTemplate").Parse(usageTemplate)
|
||||||
|
t.New("descriptionTemplate").Parse(descriptionTemplate)
|
||||||
|
t.New("visibleCommandTemplate").Parse(visibleCommandTemplate)
|
||||||
|
t.New("copyrightTemplate").Parse(copyrightTemplate)
|
||||||
|
t.New("versionTemplate").Parse(versionTemplate)
|
||||||
|
t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate)
|
||||||
|
t.New("visibleFlagTemplate").Parse(visibleFlagTemplate)
|
||||||
|
t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1))
|
||||||
|
t.New("authorsTemplate").Parse(authorsTemplate)
|
||||||
|
t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate)
|
||||||
|
|
||||||
err := t.Execute(w, data)
|
err := t.Execute(w, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
76
help_test.go
76
help_test.go
@ -1443,3 +1443,79 @@ OPTIONS:
|
|||||||
output.String(), expected)
|
output.String(), expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestWrappedHelpSubcommand(t *testing.T) {
|
||||||
|
|
||||||
|
// Reset HelpPrinter after this test.
|
||||||
|
defer func(old helpPrinter) {
|
||||||
|
HelpPrinter = old
|
||||||
|
}(HelpPrinter)
|
||||||
|
|
||||||
|
output := new(bytes.Buffer)
|
||||||
|
app := &App{
|
||||||
|
Name: "cli.test",
|
||||||
|
Writer: output,
|
||||||
|
Commands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "bar",
|
||||||
|
Aliases: []string{"a"},
|
||||||
|
Usage: "add a task to the list",
|
||||||
|
UsageText: "this is an even longer way of describing adding a task to the list",
|
||||||
|
Description: "and a description long enough to wrap in this test case",
|
||||||
|
Action: func(c *Context) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Subcommands: []*Command{
|
||||||
|
{
|
||||||
|
Name: "grok",
|
||||||
|
Usage: "remove an existing template",
|
||||||
|
UsageText: "longer usage text goes here, la la la, hopefully this is long enough to wrap even more",
|
||||||
|
Action: func(c *Context) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
Flags: []Flag{
|
||||||
|
&StringFlag{
|
||||||
|
Name: "test-f",
|
||||||
|
Usage: "my test usage",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpPrinter = func(w io.Writer, templ string, data interface{}) {
|
||||||
|
funcMap := map[string]interface{}{
|
||||||
|
"wrapAt": func() int {
|
||||||
|
return 30
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
HelpPrinterCustom(w, templ, data, funcMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = app.Run([]string{"foo", "bar", "help", "grok"})
|
||||||
|
|
||||||
|
expected := `NAME:
|
||||||
|
cli.test bar grok - remove
|
||||||
|
an
|
||||||
|
existing
|
||||||
|
template
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
longer usage text goes
|
||||||
|
here, la la la, hopefully
|
||||||
|
this is long enough to wrap
|
||||||
|
even more
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--help, -h show help (default: false)
|
||||||
|
--test-f value my test usage
|
||||||
|
`
|
||||||
|
|
||||||
|
if output.String() != expected {
|
||||||
|
t.Errorf("Unexpected wrapping, got:\n%s\nexpected: %s",
|
||||||
|
output.String(), expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
82
template.go
82
template.go
@ -1,10 +1,38 @@
|
|||||||
package cli
|
package cli
|
||||||
|
|
||||||
|
var helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}`
|
||||||
|
var usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}`
|
||||||
|
var descriptionTemplate = `{{wrap .Description 3}}`
|
||||||
|
var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
||||||
|
{{range $index, $author := .Authors}}{{if $index}}
|
||||||
|
{{end}}{{$author}}{{end}}`
|
||||||
|
var visibleCommandTemplate = `{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
||||||
|
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}`
|
||||||
|
var visibleCommandCategoryTemplate = `{{range .VisibleCategories}}{{if .Name}}
|
||||||
|
{{.Name}}:{{range .VisibleCommands}}
|
||||||
|
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{template "visibleCommandTemplate" .}}{{end}}{{end}}`
|
||||||
|
var visibleFlagCategoryTemplate = `{{range .VisibleFlagCategories}}
|
||||||
|
{{if .Name}}{{.Name}}
|
||||||
|
|
||||||
|
{{end}}{{$flglen := len .Flags}}{{range $i, $e := .Flags}}{{if eq (subtract $flglen $i) 1}}{{$e}}
|
||||||
|
{{else}}{{$e}}
|
||||||
|
{{end}}{{end}}{{end}}`
|
||||||
|
|
||||||
|
var visibleFlagTemplate = `{{range $index, $option := .VisibleFlags}}{{if $index}}{{end}}
|
||||||
|
{{wrap $option.String 6}}{{end}}`
|
||||||
|
|
||||||
|
var versionTemplate = `{{if .Version}}{{if not .HideVersion}}
|
||||||
|
|
||||||
|
VERSION:
|
||||||
|
{{.Version}}{{end}}{{end}}`
|
||||||
|
|
||||||
|
var copyrightTemplate = `{{wrap .Copyright 3}}`
|
||||||
|
|
||||||
// AppHelpTemplate is the text template for the Default help topic.
|
// AppHelpTemplate is the text template for the Default help topic.
|
||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
var AppHelpTemplate = `NAME:
|
var AppHelpTemplate = `NAME:
|
||||||
{{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||||
@ -13,73 +41,57 @@ VERSION:
|
|||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if len .Authors}}
|
{{template "descriptionTemplate" .}}{{end}}
|
||||||
|
{{- if len .Authors}}
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
|
||||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
|
GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}
|
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}}
|
||||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
|
||||||
{{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}}
|
|
||||||
|
|
||||||
COPYRIGHT:
|
COPYRIGHT:
|
||||||
{{wrap .Copyright 3}}{{end}}
|
{{template "copyrightTemplate" .}}{{end}}
|
||||||
`
|
`
|
||||||
|
|
||||||
// CommandHelpTemplate is the text template for the command help topic.
|
// CommandHelpTemplate is the text template for the command help topic.
|
||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
var CommandHelpTemplate = `NAME:
|
var CommandHelpTemplate = `NAME:
|
||||||
{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
{{template "usageTemplate" .}}{{if .Category}}
|
||||||
|
|
||||||
CATEGORY:
|
CATEGORY:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
|
||||||
`
|
|
||||||
|
|
||||||
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
// SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
// cli.go uses text/template to render templates. You can
|
// cli.go uses text/template to render templates. You can
|
||||||
// render custom help text by setting this variable.
|
// render custom help text by setting this variable.
|
||||||
var SubcommandHelpTemplate = `NAME:
|
var SubcommandHelpTemplate = `NAME:
|
||||||
{{.HelpName}} - {{.Usage}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
|
||||||
`
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
|
|
||||||
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
var MarkdownDocTemplate = `{{if gt .SectionNum 0}}% {{ .App.Name }} {{ .SectionNum }}
|
||||||
|
|
||||||
|
83
testdata/godoc-v2.x.txt
vendored
83
testdata/godoc-v2.x.txt
vendored
@ -32,7 +32,7 @@ var (
|
|||||||
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
SuggestDidYouMeanTemplate string = suggestDidYouMeanTemplate
|
||||||
)
|
)
|
||||||
var AppHelpTemplate = `NAME:
|
var AppHelpTemplate = `NAME:
|
||||||
{{$v := offset .Name 6}}{{wrap .Name 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
|
||||||
@ -41,52 +41,39 @@ VERSION:
|
|||||||
{{.Version}}{{end}}{{end}}{{if .Description}}
|
{{.Version}}{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if len .Authors}}
|
{{template "descriptionTemplate" .}}{{end}}
|
||||||
|
{{- if len .Authors}}
|
||||||
|
|
||||||
AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
|
AUTHOR{{template "authorsTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
{{range $index, $author := .Authors}}{{if $index}}
|
|
||||||
{{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}}
|
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlagCategories}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:{{range .VisibleFlagCategories}}
|
GLOBAL OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}
|
|
||||||
{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
GLOBAL OPTIONS:
|
GLOBAL OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}{{if .Copyright}}
|
||||||
{{range $index, $option := .VisibleFlags}}{{if $index}}
|
|
||||||
{{end}}{{wrap $option.String 6}}{{end}}{{end}}{{end}}{{if .Copyright}}
|
|
||||||
|
|
||||||
COPYRIGHT:
|
COPYRIGHT:
|
||||||
{{wrap .Copyright 3}}{{end}}
|
{{template "copyrightTemplate" .}}{{end}}
|
||||||
`
|
`
|
||||||
AppHelpTemplate is the text template for the Default help topic. cli.go
|
AppHelpTemplate is the text template for the Default help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
setting this variable.
|
setting this variable.
|
||||||
|
|
||||||
var CommandHelpTemplate = `NAME:
|
var CommandHelpTemplate = `NAME:
|
||||||
{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}}
|
{{template "usageTemplate" .}}{{if .Category}}
|
||||||
|
|
||||||
CATEGORY:
|
CATEGORY:
|
||||||
{{.Category}}{{end}}{{if .Description}}
|
{{.Category}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}{{if .VisibleFlagCategories}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
|
|
||||||
OPTIONS:{{range .VisibleFlagCategories}}
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{if .Name}}{{.Name}}
|
|
||||||
{{end}}{{range .Flags}}{{.}}{{end}}{{end}}{{else}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}{{end}}
|
|
||||||
`
|
|
||||||
CommandHelpTemplate is the text template for the command help topic. cli.go
|
CommandHelpTemplate is the text template for the command help topic. cli.go
|
||||||
uses text/template to render templates. You can render custom help text by
|
uses text/template to render templates. You can render custom help text by
|
||||||
setting this variable.
|
setting this variable.
|
||||||
@ -145,22 +132,19 @@ var OsExiter = os.Exit
|
|||||||
os.Exit.
|
os.Exit.
|
||||||
|
|
||||||
var SubcommandHelpTemplate = `NAME:
|
var SubcommandHelpTemplate = `NAME:
|
||||||
{{.HelpName}} - {{.Usage}}
|
{{template "helpNameTemplate" .}}
|
||||||
|
|
||||||
USAGE:
|
USAGE:
|
||||||
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}}
|
||||||
|
|
||||||
DESCRIPTION:
|
DESCRIPTION:
|
||||||
{{wrap .Description 3}}{{end}}
|
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
|
||||||
|
|
||||||
COMMANDS:{{range .VisibleCategories}}{{if .Name}}
|
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
|
||||||
{{.Name}}:{{range .VisibleCommands}}
|
|
||||||
{{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{ $cv := offsetCommands .VisibleCommands 5}}{{range .VisibleCommands}}
|
|
||||||
{{$s := join .Names ", "}}{{$s}}{{ $sp := subtract $cv (offset $s 3) }}{{ indent $sp ""}}{{wrap .Usage $cv}}{{end}}{{end}}{{end}}{{if .VisibleFlags}}
|
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
|
||||||
{{range .VisibleFlags}}{{.}}{{end}}{{end}}
|
|
||||||
`
|
OPTIONS:{{template "visibleFlagTemplate" .}}{{end}}`
|
||||||
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
SubcommandHelpTemplate is the text template for the subcommand help topic.
|
||||||
cli.go uses text/template to render templates. You can render custom help
|
cli.go uses text/template to render templates. You can render custom help
|
||||||
text by setting this variable.
|
text by setting this variable.
|
||||||
@ -585,6 +569,9 @@ func (c *Command) Run(ctx *Context) (err error)
|
|||||||
Run invokes the command given the context, parses ctx.Args() to generate
|
Run invokes the command given the context, parses ctx.Args() to generate
|
||||||
command-specific flags
|
command-specific flags
|
||||||
|
|
||||||
|
func (c *Command) VisibleCommands() []*Command
|
||||||
|
VisibleCommands returns a slice of the Commands with Hidden=false
|
||||||
|
|
||||||
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
func (c *Command) VisibleFlagCategories() []VisibleFlagCategory
|
||||||
VisibleFlagCategories returns a slice containing all the visible flag
|
VisibleFlagCategories returns a slice containing all the visible flag
|
||||||
categories with the flags they contain
|
categories with the flags they contain
|
||||||
@ -753,6 +740,14 @@ type DocGenerationFlag interface {
|
|||||||
DocGenerationFlag is an interface that allows documentation generation for
|
DocGenerationFlag is an interface that allows documentation generation for
|
||||||
the flag
|
the flag
|
||||||
|
|
||||||
|
type DocGenerationSliceFlag interface {
|
||||||
|
DocGenerationFlag
|
||||||
|
|
||||||
|
// IsSliceFlag returns true for flags that can be given multiple times.
|
||||||
|
IsSliceFlag() bool
|
||||||
|
}
|
||||||
|
DocGenerationSliceFlag extends DocGenerationFlag for slice-based flags.
|
||||||
|
|
||||||
type DurationFlag struct {
|
type DurationFlag struct {
|
||||||
Name string
|
Name string
|
||||||
|
|
||||||
@ -1071,6 +1066,9 @@ func (f *Float64SliceFlag) IsRequired() bool
|
|||||||
func (f *Float64SliceFlag) IsSet() bool
|
func (f *Float64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Float64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Float64SliceFlag) IsVisible() bool
|
func (f *Float64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1306,6 +1304,9 @@ func (f *Int64SliceFlag) IsRequired() bool
|
|||||||
func (f *Int64SliceFlag) IsSet() bool
|
func (f *Int64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Int64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Int64SliceFlag) IsVisible() bool
|
func (f *Int64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1471,6 +1472,9 @@ func (f *IntSliceFlag) IsRequired() bool
|
|||||||
func (f *IntSliceFlag) IsSet() bool
|
func (f *IntSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *IntSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *IntSliceFlag) IsVisible() bool
|
func (f *IntSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -1810,6 +1814,9 @@ func (f *StringSliceFlag) IsRequired() bool
|
|||||||
func (f *StringSliceFlag) IsSet() bool
|
func (f *StringSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *StringSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *StringSliceFlag) IsVisible() bool
|
func (f *StringSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -2071,6 +2078,9 @@ func (f *Uint64SliceFlag) IsRequired() bool
|
|||||||
func (f *Uint64SliceFlag) IsSet() bool
|
func (f *Uint64SliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *Uint64SliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *Uint64SliceFlag) IsVisible() bool
|
func (f *Uint64SliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
@ -2227,6 +2237,9 @@ func (f *UintSliceFlag) IsRequired() bool
|
|||||||
func (f *UintSliceFlag) IsSet() bool
|
func (f *UintSliceFlag) IsSet() bool
|
||||||
IsSet returns whether or not the flag has been set through env or file
|
IsSet returns whether or not the flag has been set through env or file
|
||||||
|
|
||||||
|
func (f *UintSliceFlag) IsSliceFlag() bool
|
||||||
|
IsSliceFlag implements DocGenerationSliceFlag.
|
||||||
|
|
||||||
func (f *UintSliceFlag) IsVisible() bool
|
func (f *UintSliceFlag) IsVisible() bool
|
||||||
IsVisible returns true if the flag is not hidden, otherwise false
|
IsVisible returns true if the flag is not hidden, otherwise false
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user