update all vendored

This commit is contained in:
Louis Abel 2023-12-28 14:56:35 -07:00
parent cb5c7ea3f4
commit 1fe2f9d2a3
Signed by: label
GPG Key ID: 3331F061D1D9990E
34 changed files with 351 additions and 178 deletions

8
go.mod
View File

@ -1,11 +1,11 @@
module github.com/rocky-linux/rpaste module github.com/rocky-linux/rpaste
go 1.18 go 1.20
require github.com/urfave/cli/v2 v2.25.1 require github.com/urfave/cli/v2 v2.27.0
require ( require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e // indirect
) )

6
go.sum
View File

@ -1,10 +1,16 @@
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw= github.com/urfave/cli/v2 v2.23.5 h1:xbrU7tAYviSpqeR3X4nEFWUdB/uDZ6DE+HxmRU7Xtyw=
github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.23.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw= github.com/urfave/cli/v2 v2.25.1 h1:zw8dSP7ghX0Gmm8vugrs6q9Ku0wzweqPyshy+syu9Gw=
github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/cli/v2 v2.25.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc=
github.com/urfave/cli/v2 v2.27.0 h1:uNs1K8JwTFL84X68j5Fjny6hfANh9nTlJ6dRtZAFAHY=
github.com/urfave/cli/v2 v2.27.0/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI=
github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=

View File

@ -17,7 +17,7 @@ import (
// Sane defaults and basic info // Sane defaults and basic info
var ( var (
AppName = "rpaste" AppName = "rpaste"
Version = "0.3.1" Version = "0.3.2"
DefaultConf = "/etc/rpaste/rpaste.conf" DefaultConf = "/etc/rpaste/rpaste.conf"
DefaultLexer = "text" DefaultLexer = "text"
DefaultLifeTime = "1day" DefaultLifeTime = "1day"

View File

@ -9,6 +9,8 @@ func Render(doc []byte) []byte {
renderer := NewRoffRenderer() renderer := NewRoffRenderer()
return blackfriday.Run(doc, return blackfriday.Run(doc,
[]blackfriday.Option{blackfriday.WithRenderer(renderer), []blackfriday.Option{
blackfriday.WithExtensions(renderer.GetExtensions())}...) blackfriday.WithRenderer(renderer),
blackfriday.WithExtensions(renderer.GetExtensions()),
}...)
} }

View File

@ -1,6 +1,7 @@
package md2man package md2man
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"os" "os"
@ -34,10 +35,10 @@ const (
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n" hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
linkTag = "\n\\[la]" linkTag = "\n\\[la]"
linkCloseTag = "\\[ra]" linkCloseTag = "\\[ra]"
codespanTag = "\\fB\\fC" codespanTag = "\\fB"
codespanCloseTag = "\\fR" codespanCloseTag = "\\fR"
codeTag = "\n.PP\n.RS\n\n.nf\n" codeTag = "\n.EX\n"
codeCloseTag = "\n.fi\n.RE\n" codeCloseTag = "\n.EE\n"
quoteTag = "\n.PP\n.RS\n" quoteTag = "\n.PP\n.RS\n"
quoteCloseTag = "\n.RE\n" quoteCloseTag = "\n.RE\n"
listTag = "\n.RS\n" listTag = "\n.RS\n"
@ -86,8 +87,7 @@ func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
// RenderNode is called for each node in a markdown document; based on the node // RenderNode is called for each node in a markdown document; based on the node
// type the equivalent roff output is sent to the writer // type the equivalent roff output is sent to the writer
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
walkAction := blackfriday.GoToNext
var walkAction = blackfriday.GoToNext
switch node.Type { switch node.Type {
case blackfriday.Text: case blackfriday.Text:
@ -109,9 +109,16 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
out(w, strongCloseTag) out(w, strongCloseTag)
} }
case blackfriday.Link: case blackfriday.Link:
if !entering { // Don't render the link text for automatic links, because this
out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) // will only duplicate the URL in the roff output.
// See https://daringfireball.net/projects/markdown/syntax#autolink
if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) {
out(w, string(node.FirstChild.Literal))
} }
// Hyphens in a link must be escaped to avoid word-wrap in the rendered man page.
escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-")
out(w, linkTag+escapedLink+linkCloseTag)
walkAction = blackfriday.SkipChildren
case blackfriday.Image: case blackfriday.Image:
// ignore images // ignore images
walkAction = blackfriday.SkipChildren walkAction = blackfriday.SkipChildren
@ -160,6 +167,11 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
r.handleTableCell(w, node, entering) r.handleTableCell(w, node, entering)
case blackfriday.HTMLSpan: case blackfriday.HTMLSpan:
// ignore other HTML tags // ignore other HTML tags
case blackfriday.HTMLBlock:
if bytes.HasPrefix(node.Literal, []byte("<!--")) {
break // ignore comments, no warning
}
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
default: default:
fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String()) fmt.Fprintln(os.Stderr, "WARNING: go-md2man does not handle node type "+node.Type.String())
} }
@ -254,7 +266,7 @@ func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, ente
start = "\t" start = "\t"
} }
if node.IsHeader { if node.IsHeader {
start += codespanTag start += strongTag
} else if nodeLiteralSize(node) > 30 { } else if nodeLiteralSize(node) > 30 {
start += tableCellStart start += tableCellStart
} }
@ -262,7 +274,7 @@ func (r *roffRenderer) handleTableCell(w io.Writer, node *blackfriday.Node, ente
} else { } else {
var end string var end string
if node.IsHeader { if node.IsHeader {
end = codespanCloseTag end = strongCloseTag
} else if nodeLiteralSize(node) > 30 { } else if nodeLiteralSize(node) > 30 {
end = tableCellEnd end = tableCellEnd
} }

View File

@ -4,6 +4,7 @@
.*envrc .*envrc
.envrc .envrc
.idea .idea
# goimports is installed here if not available
/.local/ /.local/
/site/ /site/
coverage.txt coverage.txt

4
vendor/github.com/urfave/cli/v2/.golangci.yaml generated vendored Normal file
View File

@ -0,0 +1,4 @@
# https://golangci-lint.run/usage/configuration/
linters:
enable:
- misspell

View File

@ -39,6 +39,8 @@ type App struct {
Usage string Usage string
// Text to override the USAGE section of help // Text to override the USAGE section of help
UsageText string UsageText string
// Whether this command supports arguments
Args bool
// Description of the program argument format. // Description of the program argument format.
ArgsUsage string ArgsUsage string
// Version of the program // Version of the program
@ -329,14 +331,24 @@ func (a *App) RunContext(ctx context.Context, arguments []string) (err error) {
a.rootCommand = a.newRootCommand() a.rootCommand = a.newRootCommand()
cCtx.Command = a.rootCommand cCtx.Command = a.rootCommand
if err := checkDuplicatedCmds(a.rootCommand); err != nil {
return err
}
return a.rootCommand.Run(cCtx, arguments...) return a.rootCommand.Run(cCtx, arguments...)
} }
// This is a stub function to keep public API unchanged from old code // RunAsSubcommand is for legacy/compatibility purposes only. New code should only
// // use App.RunContext. This function is slated to be removed in v3.
// Deprecated: use App.Run or App.RunContext
func (a *App) RunAsSubcommand(ctx *Context) (err error) { func (a *App) RunAsSubcommand(ctx *Context) (err error) {
return a.RunContext(ctx.Context, ctx.Args().Slice()) a.Setup()
cCtx := NewContext(a, nil, ctx)
cCtx.shellComplete = ctx.shellComplete
a.rootCommand = a.newRootCommand()
cCtx.Command = a.rootCommand
return a.rootCommand.Run(cCtx, ctx.Args().Slice()...)
} }
func (a *App) suggestFlagFromError(err error, command string) (string, error) { func (a *App) suggestFlagFromError(err error, command string) (string, error) {
@ -448,30 +460,6 @@ func (a *App) handleExitCoder(cCtx *Context, err error) {
} }
} }
func (a *App) commandNames() []string {
var cmdNames []string
for _, cmd := range a.Commands {
cmdNames = append(cmdNames, cmd.Names()...)
}
return cmdNames
}
func (a *App) validCommandName(checkCmdName string) bool {
valid := false
allCommandNames := a.commandNames()
for _, cmdName := range allCommandNames {
if checkCmdName == cmdName {
valid = true
break
}
}
return valid
}
func (a *App) argsWithDefaultCommand(oldArgs Args) Args { func (a *App) argsWithDefaultCommand(oldArgs Args) Args {
if a.DefaultCommand != "" { if a.DefaultCommand != "" {
rawArgs := append([]string{a.DefaultCommand}, oldArgs.Slice()...) rawArgs := append([]string{a.DefaultCommand}, oldArgs.Slice()...)

View File

@ -111,7 +111,7 @@ func newFlagCategoriesFromFlags(fs []Flag) FlagCategories {
} }
} }
if categorized == true { if categorized {
for _, fl := range fs { for _, fl := range fs {
if cf, ok := fl.(CategorizableFlag); ok { if cf, ok := fl.(CategorizableFlag); ok {
if cf.GetCategory() == "" { if cf.GetCategory() == "" {

View File

@ -20,6 +20,8 @@ type Command struct {
UsageText string UsageText string
// A longer explanation of how the command works // A longer explanation of how the command works
Description string Description string
// Whether this command supports arguments
Args bool
// A short description of the arguments of this command // A short description of the arguments of this command
ArgsUsage string ArgsUsage string
// The category the command is part of // The category the command is part of
@ -149,6 +151,9 @@ func (c *Command) Run(cCtx *Context, arguments ...string) (err error) {
if !c.isRoot { if !c.isRoot {
c.setup(cCtx) c.setup(cCtx)
if err := checkDuplicatedCmds(c); err != nil {
return err
}
} }
a := args(arguments) a := args(arguments)
@ -404,3 +409,16 @@ func hasCommand(commands []*Command, command *Command) bool {
return false return false
} }
func checkDuplicatedCmds(parent *Command) error {
seen := make(map[string]struct{})
for _, c := range parent.Subcommands {
for _, name := range c.Names() {
if _, exists := seen[name]; exists {
return fmt.Errorf("parent command [%s] has duplicated subcommand name or alias: %s", parent.Name, name)
}
seen[name] = struct{}{}
}
}
return nil
}

View File

@ -56,6 +56,7 @@ func (cCtx *Context) Set(name, value string) error {
// IsSet determines if the flag was actually set // IsSet determines if the flag was actually set
func (cCtx *Context) IsSet(name string) bool { func (cCtx *Context) IsSet(name string) bool {
if fs := cCtx.lookupFlagSet(name); fs != nil { if fs := cCtx.lookupFlagSet(name); fs != nil {
isSet := false isSet := false
fs.Visit(func(f *flag.Flag) { fs.Visit(func(f *flag.Flag) {
@ -72,7 +73,23 @@ func (cCtx *Context) IsSet(name string) bool {
return false return false
} }
return f.IsSet() if f.IsSet() {
return true
}
// now redo flagset search on aliases
aliases := f.Names()
fs.Visit(func(f *flag.Flag) {
for _, alias := range aliases {
if f.Name == alias {
isSet = true
}
}
})
if isSet {
return true
}
} }
return false return false
@ -127,7 +144,7 @@ func (cCtx *Context) Lineage() []*Context {
return lineage return lineage
} }
// Count returns the num of occurences of this flag // Count returns the num of occurrences of this flag
func (cCtx *Context) Count(name string) int { func (cCtx *Context) Count(name string) int {
if fs := cCtx.lookupFlagSet(name); fs != nil { if fs := cCtx.lookupFlagSet(name); fs != nil {
if cf, ok := fs.Lookup(name).Value.(Countable); ok { if cf, ok := fs.Lookup(name).Value.(Countable); ok {
@ -204,9 +221,10 @@ func (cCtx *Context) checkRequiredFlags(flags []Flag) requiredFlagsErr {
var flagPresent bool var flagPresent bool
var flagName string var flagName string
for _, key := range f.Names() { flagNames := f.Names()
flagName = key flagName = flagNames[0]
for _, key := range flagNames {
if cCtx.IsSet(strings.TrimSpace(key)) { if cCtx.IsSet(strings.TrimSpace(key)) {
flagPresent = true flagPresent = true
} }

View File

@ -153,9 +153,14 @@ func prepareFlags(
// flagDetails returns a string containing the flags metadata // flagDetails returns a string containing the flags metadata
func flagDetails(flag DocGenerationFlag) string { func flagDetails(flag DocGenerationFlag) string {
description := flag.GetUsage() description := flag.GetUsage()
value := flag.GetValue() if flag.TakesValue() {
if value != "" { defaultText := flag.GetDefaultText()
description += " (default: " + value + ")" if defaultText == "" {
defaultText = flag.GetValue()
}
if defaultText != "" {
description += " (default: " + defaultText + ")"
}
} }
return ": " + description return ": " + description
} }

View File

@ -52,7 +52,7 @@ func (b *boolValue) String() string {
func (b *boolValue) IsBoolFlag() bool { return true } func (b *boolValue) IsBoolFlag() bool { return true }
func (b *boolValue) Count() int { func (b *boolValue) Count() int {
if b.count != nil { if b.count != nil && *b.count > 0 {
return *b.count return *b.count
} }
return 0 return 0
@ -84,7 +84,10 @@ func (f *BoolFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return fmt.Sprintf("%v", f.defaultValue) return fmt.Sprintf("%v", f.defaultValue)
}
return fmt.Sprintf("%v", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -105,6 +108,7 @@ func (f *BoolFlag) RunAction(c *Context) error {
func (f *BoolFlag) Apply(set *flag.FlagSet) error { func (f *BoolFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {
@ -130,6 +134,11 @@ func (f *BoolFlag) Apply(set *flag.FlagSet) error {
if count == nil { if count == nil {
count = new(int) count = new(int)
} }
// since count will be incremented for each alias as well
// subtract number of aliases from overall count
*count -= len(f.Aliases)
if dest == nil { if dest == nil {
dest = new(bool) dest = new(bool)
} }

View File

@ -32,7 +32,10 @@ func (f *DurationFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return f.defaultValue.String() return f.defaultValue.String()
}
return f.Value.String()
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -44,6 +47,7 @@ func (f *DurationFlag) GetEnvVars() []string {
func (f *DurationFlag) Apply(set *flag.FlagSet) error { func (f *DurationFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {

View File

@ -32,7 +32,10 @@ func (f *Float64Flag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
return f.GetValue() if f.defaultValueSet {
return fmt.Sprintf("%v", f.defaultValue)
}
return fmt.Sprintf("%v", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -42,6 +45,9 @@ func (f *Float64Flag) GetEnvVars() []string {
// Apply populates the flag given the flag set and environment // Apply populates the flag given the flag set and environment
func (f *Float64Flag) Apply(set *flag.FlagSet) error { func (f *Float64Flag) Apply(set *flag.FlagSet) error {
f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {
valFloat, err := strconv.ParseFloat(val, 64) valFloat, err := strconv.ParseFloat(val, 64)

View File

@ -53,9 +53,15 @@ func (f *GenericFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValue != nil { val := f.Value
return f.defaultValue.String() if f.defaultValueSet {
val = f.defaultValue
} }
if val != nil {
return val.String()
}
return "" return ""
} }
@ -70,6 +76,7 @@ func (f *GenericFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
if f.Value != nil { if f.Value != nil {
f.defaultValue = &stringGeneric{value: f.Value.String()} f.defaultValue = &stringGeneric{value: f.Value.String()}
f.defaultValueSet = true
} }
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
@ -117,13 +124,8 @@ func (cCtx *Context) Generic(name string) interface{} {
} }
func lookupGeneric(name string, set *flag.FlagSet) interface{} { func lookupGeneric(name string, set *flag.FlagSet) interface{} {
f := set.Lookup(name) if f := set.Lookup(name); f != nil {
if f != nil { return f.Value
parsed, err := f.Value, error(nil)
if err != nil {
return nil
}
return parsed
} }
return nil return nil
} }

View File

@ -32,7 +32,10 @@ func (f *IntFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return fmt.Sprintf("%d", f.defaultValue) return fmt.Sprintf("%d", f.defaultValue)
}
return fmt.Sprintf("%d", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -44,6 +47,7 @@ func (f *IntFlag) GetEnvVars() []string {
func (f *IntFlag) Apply(set *flag.FlagSet) error { func (f *IntFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {

View File

@ -32,7 +32,10 @@ func (f *Int64Flag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return fmt.Sprintf("%d", f.defaultValue) return fmt.Sprintf("%d", f.defaultValue)
}
return fmt.Sprintf("%d", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -44,6 +47,7 @@ func (f *Int64Flag) GetEnvVars() []string {
func (f *Int64Flag) Apply(set *flag.FlagSet) error { func (f *Int64Flag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {

View File

@ -33,10 +33,14 @@ func (f *PathFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValue == "" { val := f.Value
return f.defaultValue if f.defaultValueSet {
val = f.defaultValue
} }
return fmt.Sprintf("%q", f.defaultValue) if val == "" {
return val
}
return fmt.Sprintf("%q", val)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -48,6 +52,7 @@ func (f *PathFlag) GetEnvVars() []string {
func (f *PathFlag) Apply(set *flag.FlagSet) error { func (f *PathFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val f.Value = val
@ -90,13 +95,8 @@ func (cCtx *Context) Path(name string) string {
} }
func lookupPath(name string, set *flag.FlagSet) string { func lookupPath(name string, set *flag.FlagSet) string {
f := set.Lookup(name) if f := set.Lookup(name); f != nil {
if f != nil { return f.Value.String()
parsed, err := f.Value.String(), error(nil)
if err != nil {
return ""
}
return parsed
} }
return "" return ""
} }

View File

@ -31,10 +31,15 @@ func (f *StringFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValue == "" { val := f.Value
return f.defaultValue if f.defaultValueSet {
val = f.defaultValue
} }
return fmt.Sprintf("%q", f.defaultValue)
if val == "" {
return val
}
return fmt.Sprintf("%q", val)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag
@ -46,6 +51,7 @@ func (f *StringFlag) GetEnvVars() []string {
func (f *StringFlag) Apply(set *flag.FlagSet) error { func (f *StringFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, _, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
f.Value = val f.Value = val
@ -87,10 +93,8 @@ func (cCtx *Context) String(name string) string {
} }
func lookupString(name string, set *flag.FlagSet) string { func lookupString(name string, set *flag.FlagSet) string {
f := set.Lookup(name) if f := set.Lookup(name); f != nil {
if f != nil { return f.Value.String()
parsed := f.Value.String()
return parsed
} }
return "" return ""
} }

View File

@ -120,8 +120,13 @@ func (f *TimestampFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValue != nil && f.defaultValue.timestamp != nil { val := f.Value
return f.defaultValue.timestamp.String() if f.defaultValueSet {
val = f.defaultValue
}
if val != nil && val.timestamp != nil {
return val.timestamp.String()
} }
return "" return ""
@ -144,11 +149,7 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
f.Value.SetLocation(f.Timezone) f.Value.SetLocation(f.Timezone)
f.defaultValue = f.Value.clone() f.defaultValue = f.Value.clone()
f.defaultValueSet = true
if f.Destination != nil {
f.Destination.SetLayout(f.Layout)
f.Destination.SetLocation(f.Timezone)
}
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if err := f.Value.Set(val); err != nil { if err := f.Value.Set(val); err != nil {
@ -157,6 +158,10 @@ func (f *TimestampFlag) Apply(set *flag.FlagSet) error {
f.HasBeenSet = true f.HasBeenSet = true
} }
if f.Destination != nil {
*f.Destination = *f.Value
}
for _, name := range f.Names() { for _, name := range f.Names() {
if f.Destination != nil { if f.Destination != nil {
set.Var(f.Destination, name, f.Usage) set.Var(f.Destination, name, f.Usage)

View File

@ -25,6 +25,7 @@ func (f *UintFlag) GetCategory() string {
func (f *UintFlag) Apply(set *flag.FlagSet) error { func (f *UintFlag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {
@ -69,7 +70,10 @@ func (f *UintFlag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return fmt.Sprintf("%d", f.defaultValue) return fmt.Sprintf("%d", f.defaultValue)
}
return fmt.Sprintf("%d", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag

View File

@ -25,6 +25,7 @@ func (f *Uint64Flag) GetCategory() string {
func (f *Uint64Flag) Apply(set *flag.FlagSet) error { func (f *Uint64Flag) Apply(set *flag.FlagSet) error {
// set default value so that environment wont be able to overwrite it // set default value so that environment wont be able to overwrite it
f.defaultValue = f.Value f.defaultValue = f.Value
f.defaultValueSet = true
if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found { if val, source, found := flagFromEnvOrFile(f.EnvVars, f.FilePath); found {
if val != "" { if val != "" {
@ -69,7 +70,10 @@ func (f *Uint64Flag) GetDefaultText() string {
if f.DefaultText != "" { if f.DefaultText != "" {
return f.DefaultText return f.DefaultText
} }
if f.defaultValueSet {
return fmt.Sprintf("%d", f.defaultValue) return fmt.Sprintf("%d", f.defaultValue)
}
return fmt.Sprintf("%d", f.Value)
} }
// GetEnvVars returns the env vars for this flag // GetEnvVars returns the env vars for this flag

View File

@ -190,6 +190,15 @@ func (f *Uint64SliceFlag) Get(ctx *Context) []uint64 {
return ctx.Uint64Slice(f.Name) return ctx.Uint64Slice(f.Name)
} }
// RunAction executes flag action if set
func (f *Uint64SliceFlag) RunAction(c *Context) error {
if f.Action != nil {
return f.Action(c, c.Uint64Slice(f.Name))
}
return nil
}
// 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 {

View File

@ -201,6 +201,15 @@ func (f *UintSliceFlag) Get(ctx *Context) []uint {
return ctx.UintSlice(f.Name) return ctx.UintSlice(f.Name)
} }
// RunAction executes flag action if set
func (f *UintSliceFlag) RunAction(c *Context) error {
if f.Action != nil {
return f.Action(c, c.UintSlice(f.Name))
}
return nil
}
// 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 {

View File

@ -35,7 +35,7 @@ var AppHelpTemplate = `NAME:
{{template "helpNameTemplate" .}} {{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}}{{if .Args}}[arguments...]{{end}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
VERSION: VERSION:
{{.Version}}{{end}}{{end}}{{if .Description}} {{.Version}}{{end}}{{end}}{{if .Description}}
@ -136,12 +136,12 @@ var SubcommandHelpTemplate = `NAME:
{{template "helpNameTemplate" .}} {{template "helpNameTemplate" .}}
USAGE: USAGE:
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}{{if .Args}}[arguments...]{{end}}{{end}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}} {{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}} COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}
@ -253,6 +253,8 @@ type App struct {
Usage string Usage string
// Text to override the USAGE section of help // Text to override the USAGE section of help
UsageText string UsageText string
// Whether this command supports arguments
Args bool
// Description of the program argument format. // Description of the program argument format.
ArgsUsage string ArgsUsage string
// Version of the program // Version of the program
@ -357,9 +359,8 @@ func (a *App) RunAndExitOnError()
code in the cli.ExitCoder code in the cli.ExitCoder
func (a *App) RunAsSubcommand(ctx *Context) (err error) func (a *App) RunAsSubcommand(ctx *Context) (err error)
This is a stub function to keep public API unchanged from old code RunAsSubcommand is for legacy/compatibility purposes only. New code should
only use App.RunContext. This function is slated to be removed in v3.
Deprecated: use App.Run or App.RunContext
func (a *App) RunContext(ctx context.Context, arguments []string) (err error) func (a *App) RunContext(ctx context.Context, arguments []string) (err error)
RunContext is like Run except it takes a Context that will be passed to RunContext is like Run except it takes a Context that will be passed to
@ -524,6 +525,8 @@ type Command struct {
UsageText string UsageText string
// A longer explanation of how the command works // A longer explanation of how the command works
Description string Description string
// Whether this command supports arguments
Args bool
// A short description of the arguments of this command // A short description of the arguments of this command
ArgsUsage string ArgsUsage string
// The category the command is part of // The category the command is part of
@ -650,7 +653,7 @@ func (cCtx *Context) Bool(name string) bool
Bool looks up the value of a local BoolFlag, returns false if not found Bool looks up the value of a local BoolFlag, returns false if not found
func (cCtx *Context) Count(name string) int func (cCtx *Context) Count(name string) int
Count returns the num of occurences of this flag Count returns the num of occurrences of this flag
func (cCtx *Context) Duration(name string) time.Duration func (cCtx *Context) Duration(name string) time.Duration
Duration looks up the value of a local DurationFlag, returns 0 if not found Duration looks up the value of a local DurationFlag, returns 0 if not found
@ -2143,6 +2146,9 @@ func (f *Uint64SliceFlag) IsVisible() bool
func (f *Uint64SliceFlag) Names() []string func (f *Uint64SliceFlag) Names() []string
Names returns the names of the flag Names returns the names of the flag
func (f *Uint64SliceFlag) RunAction(c *Context) error
RunAction executes flag action if set
func (f *Uint64SliceFlag) String() string func (f *Uint64SliceFlag) String() string
String returns a readable representation of this value (for usage defaults) String returns a readable representation of this value (for usage defaults)
@ -2308,6 +2314,9 @@ func (f *UintSliceFlag) IsVisible() bool
func (f *UintSliceFlag) Names() []string func (f *UintSliceFlag) Names() []string
Names returns the names of the flag Names returns the names of the flag
func (f *UintSliceFlag) RunAction(c *Context) error
RunAction executes flag action if set
func (f *UintSliceFlag) String() string func (f *UintSliceFlag) String() string
String returns a readable representation of this value (for usage defaults) String returns a readable representation of this value (for usage defaults)

View File

@ -42,6 +42,7 @@ var helpCommand = &Command{
// 3 $ app foo // 3 $ app foo
// 4 $ app help foo // 4 $ app help foo
// 5 $ app foo help // 5 $ app foo help
// 6 $ app foo -h (with no other sub-commands nor flags defined)
// Case 4. when executing a help command set the context to parent // Case 4. when executing a help command set the context to parent
// to allow resolution of subsequent args. This will transform // to allow resolution of subsequent args. This will transform
@ -68,7 +69,7 @@ var helpCommand = &Command{
} }
// Case 3, 5 // Case 3, 5
if (len(cCtx.Command.Subcommands) == 1 && !cCtx.Command.HideHelp) || if (len(cCtx.Command.Subcommands) == 1 && !cCtx.Command.HideHelp && !cCtx.Command.HideHelpCommand) ||
(len(cCtx.Command.Subcommands) == 0 && cCtx.Command.HideHelp) { (len(cCtx.Command.Subcommands) == 0 && cCtx.Command.HideHelp) {
templ := cCtx.Command.CustomHelpTemplate templ := cCtx.Command.CustomHelpTemplate
if templ == "" { if templ == "" {
@ -77,6 +78,8 @@ var helpCommand = &Command{
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command) HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
return nil return nil
} }
// Case 6, handling incorporated in the callee itself
return ShowSubcommandHelp(cCtx) return ShowSubcommandHelp(cCtx)
}, },
} }
@ -206,9 +209,15 @@ func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) {
func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) { func DefaultCompleteWithFlags(cmd *Command) func(cCtx *Context) {
return func(cCtx *Context) { return func(cCtx *Context) {
if len(os.Args) > 2 { var lastArg string
lastArg := os.Args[len(os.Args)-2]
// TODO: This shouldnt depend on os.Args rather it should
// depend on root arguments passed to App
if len(os.Args) > 2 {
lastArg = os.Args[len(os.Args)-2]
}
if lastArg != "" {
if strings.HasPrefix(lastArg, "-") { if strings.HasPrefix(lastArg, "-") {
if cmd != nil { if cmd != nil {
printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer) printFlagSuggestions(lastArg, cmd.Flags, cCtx.App.Writer)
@ -292,8 +301,12 @@ func ShowSubcommandHelp(cCtx *Context) error {
if cCtx == nil { if cCtx == nil {
return nil return nil
} }
// use custom template when provided (fixes #1703)
HelpPrinter(cCtx.App.Writer, SubcommandHelpTemplate, cCtx.Command) templ := SubcommandHelpTemplate
if cCtx.Command != nil && cCtx.Command.CustomHelpTemplate != "" {
templ = cCtx.Command.CustomHelpTemplate
}
HelpPrinter(cCtx.App.Writer, templ, cCtx.Command)
return nil return nil
} }
@ -363,17 +376,26 @@ 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) templates := map[string]string{
t.New("usageTemplate").Parse(usageTemplate) "helpNameTemplate": helpNameTemplate,
t.New("descriptionTemplate").Parse(descriptionTemplate) "usageTemplate": usageTemplate,
t.New("visibleCommandTemplate").Parse(visibleCommandTemplate) "descriptionTemplate": descriptionTemplate,
t.New("copyrightTemplate").Parse(copyrightTemplate) "visibleCommandTemplate": visibleCommandTemplate,
t.New("versionTemplate").Parse(versionTemplate) "copyrightTemplate": copyrightTemplate,
t.New("visibleFlagCategoryTemplate").Parse(visibleFlagCategoryTemplate) "versionTemplate": versionTemplate,
t.New("visibleFlagTemplate").Parse(visibleFlagTemplate) "visibleFlagCategoryTemplate": visibleFlagCategoryTemplate,
t.New("visibleGlobalFlagCategoryTemplate").Parse(strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1)) "visibleFlagTemplate": visibleFlagTemplate,
t.New("authorsTemplate").Parse(authorsTemplate) "visibleGlobalFlagCategoryTemplate": strings.Replace(visibleFlagCategoryTemplate, "OPTIONS", "GLOBAL OPTIONS", -1),
t.New("visibleCommandCategoryTemplate").Parse(visibleCommandCategoryTemplate) "authorsTemplate": authorsTemplate,
"visibleCommandCategoryTemplate": visibleCommandCategoryTemplate,
}
for name, value := range templates {
if _, err := t.New(name).Parse(value); err != nil {
if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" {
_, _ = fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err)
}
}
}
err := t.Execute(w, data) err := t.Execute(w, data)
if err != nil { if err != nil {
@ -402,6 +424,9 @@ func checkVersion(cCtx *Context) bool {
} }
func checkHelp(cCtx *Context) bool { func checkHelp(cCtx *Context) bool {
if HelpFlag == nil {
return false
}
found := false found := false
for _, name := range HelpFlag.Names() { for _, name := range HelpFlag.Names() {
if cCtx.Bool(name) { if cCtx.Bool(name) {
@ -413,24 +438,6 @@ func checkHelp(cCtx *Context) bool {
return found return found
} }
func checkCommandHelp(c *Context, name string) bool {
if c.Bool("h") || c.Bool("help") {
_ = ShowCommandHelp(c, name)
return true
}
return false
}
func checkSubcommandHelp(cCtx *Context) bool {
if cCtx.Bool("h") || cCtx.Bool("help") {
_ = ShowSubcommandHelp(cCtx)
return true
}
return false
}
func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) { func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) {
if !a.EnableBashCompletion { if !a.EnableBashCompletion {
return false, arguments return false, arguments

View File

@ -1,7 +1,7 @@
# NOTE: the mkdocs dependencies will need to be installed out of # NOTE: the mkdocs dependencies will need to be installed out of
# band until this whole thing gets more automated: # band until this whole thing gets more automated:
# #
# pip install -r mkdocs-requirements.txt # pip install -r mkdocs-reqs.txt
# #
site_name: urfave/cli site_name: urfave/cli

View File

@ -21,7 +21,7 @@ func suggestFlag(flags []Flag, provided string, hideHelp bool) string {
for _, flag := range flags { for _, flag := range flags {
flagNames := flag.Names() flagNames := flag.Names()
if !hideHelp { if !hideHelp && HelpFlag != nil {
flagNames = append(flagNames, HelpFlag.Names()...) flagNames = append(flagNames, HelpFlag.Names()...)
} }
for _, name := range flagNames { for _, name := range flagNames {

View File

@ -1,7 +1,7 @@
package cli package cli
var helpNameTemplate = `{{$v := offset .HelpName 6}}{{wrap .HelpName 3}}{{if .Usage}} - {{wrap .Usage $v}}{{end}}` 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 usageTemplate = `{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}{{if .Args}}[arguments...]{{end}}[arguments...]{{end}}{{end}}`
var descriptionTemplate = `{{wrap .Description 3}}` var descriptionTemplate = `{{wrap .Description 3}}`
var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: var authorsTemplate = `{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}:
{{range $index, $author := .Authors}}{{if $index}} {{range $index, $author := .Authors}}{{if $index}}
@ -35,7 +35,7 @@ var AppHelpTemplate = `NAME:
{{template "helpNameTemplate" .}} {{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}}{{if .Args}}[arguments...]{{end}}{{end}}{{end}}{{if .Version}}{{if not .HideVersion}}
VERSION: VERSION:
{{.Version}}{{end}}{{end}}{{if .Description}} {{.Version}}{{end}}{{end}}{{if .Description}}
@ -83,12 +83,12 @@ var SubcommandHelpTemplate = `NAME:
{{template "helpNameTemplate" .}} {{template "helpNameTemplate" .}}
USAGE: USAGE:
{{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} {{if .UsageText}}{{wrap .UsageText 3}}{{else}}{{.HelpName}} {{if .VisibleFlags}}command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}{{if .Args}}[arguments...]{{end}}{{end}}{{end}}{{if .Description}}
DESCRIPTION: DESCRIPTION:
{{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}} {{template "descriptionTemplate" .}}{{end}}{{if .VisibleCommands}}
COMMANDS:{{template "visibleCommandTemplate" .}}{{end}}{{if .VisibleFlagCategories}} COMMANDS:{{template "visibleCommandCategoryTemplate" .}}{{end}}{{if .VisibleFlagCategories}}
OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}} OPTIONS:{{template "visibleFlagCategoryTemplate" .}}{{else if .VisibleFlags}}

View File

@ -24,6 +24,7 @@ type Float64SliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *Float64Slice defaultValue *Float64Slice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -70,6 +71,7 @@ type GenericFlag struct {
EnvVars []string EnvVars []string
defaultValue Generic defaultValue Generic
defaultValueSet bool
TakesFile bool TakesFile bool
@ -121,6 +123,7 @@ type Int64SliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *Int64Slice defaultValue *Int64Slice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -167,6 +170,7 @@ type IntSliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *IntSlice defaultValue *IntSlice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -213,6 +217,7 @@ type PathFlag struct {
EnvVars []string EnvVars []string
defaultValue Path defaultValue Path
defaultValueSet bool
TakesFile bool TakesFile bool
@ -264,6 +269,7 @@ type StringSliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *StringSlice defaultValue *StringSlice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -314,6 +320,7 @@ type TimestampFlag struct {
EnvVars []string EnvVars []string
defaultValue *Timestamp defaultValue *Timestamp
defaultValueSet bool
Layout string Layout string
@ -367,6 +374,7 @@ type Uint64SliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *Uint64Slice defaultValue *Uint64Slice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -413,6 +421,7 @@ type UintSliceFlag struct {
EnvVars []string EnvVars []string
defaultValue *UintSlice defaultValue *UintSlice
defaultValueSet bool
separator separatorSpec separator separatorSpec
@ -459,6 +468,7 @@ type BoolFlag struct {
EnvVars []string EnvVars []string
defaultValue bool defaultValue bool
defaultValueSet bool
Count *int Count *int
@ -512,6 +522,7 @@ type Float64Flag struct {
EnvVars []string EnvVars []string
defaultValue float64 defaultValue float64
defaultValueSet bool
Action func(*Context, float64) error Action func(*Context, float64) error
} }
@ -561,6 +572,7 @@ type IntFlag struct {
EnvVars []string EnvVars []string
defaultValue int defaultValue int
defaultValueSet bool
Base int Base int
@ -612,6 +624,7 @@ type Int64Flag struct {
EnvVars []string EnvVars []string
defaultValue int64 defaultValue int64
defaultValueSet bool
Base int Base int
@ -663,6 +676,7 @@ type StringFlag struct {
EnvVars []string EnvVars []string
defaultValue string defaultValue string
defaultValueSet bool
TakesFile bool TakesFile bool
@ -714,6 +728,7 @@ type DurationFlag struct {
EnvVars []string EnvVars []string
defaultValue time.Duration defaultValue time.Duration
defaultValueSet bool
Action func(*Context, time.Duration) error Action func(*Context, time.Duration) error
} }
@ -763,6 +778,7 @@ type UintFlag struct {
EnvVars []string EnvVars []string
defaultValue uint defaultValue uint
defaultValueSet bool
Base int Base int
@ -814,6 +830,7 @@ type Uint64Flag struct {
EnvVars []string EnvVars []string
defaultValue uint64 defaultValue uint64
defaultValueSet bool
Base int Base int

View File

@ -6,36 +6,58 @@ import (
// The Soundex encoding. It is a phonetic algorithm that considers how the words sound in English. Soundex maps a string to a 4-byte code consisting of the first letter of the original string and three numbers. Strings that sound similar should map to the same code. // The Soundex encoding. It is a phonetic algorithm that considers how the words sound in English. Soundex maps a string to a 4-byte code consisting of the first letter of the original string and three numbers. Strings that sound similar should map to the same code.
func Soundex(s string) string { func Soundex(s string) string {
m := map[byte]string{ b := strings.Builder{}
'B': "1", 'P': "1", 'F': "1", 'V': "1", b.Grow(4)
'C': "2", 'S': "2", 'K': "2", 'G': "2", 'J': "2", 'Q': "2", 'X': "2", 'Z': "2",
'D': "3", 'T': "3",
'L': "4",
'M': "5", 'N': "5",
'R': "6",
}
s = strings.ToUpper(s)
r := string(s[0])
p := s[0] p := s[0]
for i := 1; i < len(s) && len(r) < 4; i++ { if p <= 'z' && p >= 'a' {
p -= 32 // convert to uppercase
}
b.WriteByte(p)
n := 0
for i := 1; i < len(s); i++ {
c := s[i] c := s[i]
if (c < 'A' || c > 'Z') || (c == p) { if c <= 'z' && c >= 'a' {
c -= 32 // convert to uppercase
} else if c < 'A' || c > 'Z' {
continue
}
if c == p {
continue continue
} }
p = c p = c
if n, ok := m[c]; ok { switch c {
r += n case 'B', 'P', 'F', 'V':
c = '1'
case 'C', 'S', 'K', 'G', 'J', 'Q', 'X', 'Z':
c = '2'
case 'D', 'T':
c = '3'
case 'L':
c = '4'
case 'M', 'N':
c = '5'
case 'R':
c = '6'
default:
continue
}
b.WriteByte(c)
n++
if n == 3 {
break
} }
} }
for i := len(r); i < 4; i++ { for i := n; i < 3; i++ {
r += "0" b.WriteByte('0')
} }
return r return b.String()
} }

6
vendor/modules.txt vendored
View File

@ -1,12 +1,12 @@
# github.com/cpuguy83/go-md2man/v2 v2.0.2 # github.com/cpuguy83/go-md2man/v2 v2.0.3
## explicit; go 1.11 ## explicit; go 1.11
github.com/cpuguy83/go-md2man/v2/md2man github.com/cpuguy83/go-md2man/v2/md2man
# github.com/russross/blackfriday/v2 v2.1.0 # github.com/russross/blackfriday/v2 v2.1.0
## explicit ## explicit
github.com/russross/blackfriday/v2 github.com/russross/blackfriday/v2
# github.com/urfave/cli/v2 v2.25.1 # github.com/urfave/cli/v2 v2.27.0
## explicit; go 1.18 ## explicit; go 1.18
github.com/urfave/cli/v2 github.com/urfave/cli/v2
# github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 # github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e
## explicit ## explicit
github.com/xrash/smetrics github.com/xrash/smetrics