From aba1cfaba5d4224223da7b97af7f08154014fa47 Mon Sep 17 00:00:00 2001 From: jackwrfuller Date: Mon, 13 Jan 2025 15:12:10 +1100 Subject: [PATCH 1/3] migrate to urfave/cli/v2 --- v2/ahoy.go | 47 +- v2/ahoy_test.go | 4 +- v2/flag.go | 23 +- v2/go.mod | 4 +- v2/go.sum | 6 + v2/testdata/command-aliases.ahoy.yml | 2 +- v2/tests/command-aliases.bats | 6 - v2/tests/sub-commands.bats | 1 + .../cpuguy83/go-md2man/v2/md2man/debug.go | 62 + .../cpuguy83/go-md2man/v2/md2man/md2man.go | 13 +- .../cpuguy83/go-md2man/v2/md2man/roff.go | 200 +- v2/vendor/github.com/urfave/cli/.gitignore | 5 - v2/vendor/github.com/urfave/cli/README.md | 80 - v2/vendor/github.com/urfave/cli/app.go | 531 ---- v2/vendor/github.com/urfave/cli/appveyor.yml | 28 - v2/vendor/github.com/urfave/cli/category.go | 44 - v2/vendor/github.com/urfave/cli/cli.go | 22 - v2/vendor/github.com/urfave/cli/command.go | 384 --- v2/vendor/github.com/urfave/cli/context.go | 348 --- v2/vendor/github.com/urfave/cli/errors.go | 115 - v2/vendor/github.com/urfave/cli/flag.go | 348 --- v2/vendor/github.com/urfave/cli/flag_bool.go | 109 - .../github.com/urfave/cli/flag_bool_t.go | 110 - .../github.com/urfave/cli/flag_duration.go | 106 - .../github.com/urfave/cli/flag_float64.go | 106 - .../github.com/urfave/cli/flag_generic.go | 110 - v2/vendor/github.com/urfave/cli/flag_int.go | 105 - v2/vendor/github.com/urfave/cli/flag_int64.go | 106 - .../github.com/urfave/cli/flag_int64_slice.go | 199 -- .../github.com/urfave/cli/flag_int_slice.go | 198 -- .../github.com/urfave/cli/flag_string.go | 98 - .../urfave/cli/flag_string_slice.go | 184 -- v2/vendor/github.com/urfave/cli/flag_uint.go | 106 - .../github.com/urfave/cli/flag_uint64.go | 106 - v2/vendor/github.com/urfave/cli/help.go | 363 --- v2/vendor/github.com/urfave/cli/template.go | 121 - .../github.com/urfave/cli/{ => v2}/.flake8 | 0 v2/vendor/github.com/urfave/cli/v2/.gitignore | 14 + .../github.com/urfave/cli/v2/.golangci.yaml | 4 + .../urfave/cli/{ => v2}/CODE_OF_CONDUCT.md | 11 +- .../github.com/urfave/cli/{ => v2}/LICENSE | 2 +- v2/vendor/github.com/urfave/cli/v2/Makefile | 26 + v2/vendor/github.com/urfave/cli/v2/README.md | 19 + v2/vendor/github.com/urfave/cli/v2/app.go | 536 ++++ v2/vendor/github.com/urfave/cli/v2/args.go | 54 + .../github.com/urfave/cli/v2/category.go | 186 ++ v2/vendor/github.com/urfave/cli/v2/cli.go | 25 + v2/vendor/github.com/urfave/cli/v2/command.go | 421 +++ v2/vendor/github.com/urfave/cli/v2/context.go | 272 ++ .../github.com/urfave/cli/{ => v2}/docs.go | 96 +- v2/vendor/github.com/urfave/cli/v2/errors.go | 178 ++ .../github.com/urfave/cli/{ => v2}/fish.go | 22 +- .../github.com/urfave/cli/v2/flag-spec.yaml | 131 + v2/vendor/github.com/urfave/cli/v2/flag.go | 419 +++ .../github.com/urfave/cli/v2/flag_bool.go | 178 ++ .../github.com/urfave/cli/v2/flag_duration.go | 108 + .../github.com/urfave/cli/v2/flag_ext.go | 48 + .../github.com/urfave/cli/v2/flag_float64.go | 107 + .../urfave/cli/v2/flag_float64_slice.go | 216 ++ .../github.com/urfave/cli/v2/flag_generic.go | 131 + .../github.com/urfave/cli/v2/flag_int.go | 109 + .../github.com/urfave/cli/v2/flag_int64.go | 108 + .../urfave/cli/v2/flag_int64_slice.go | 215 ++ .../urfave/cli/v2/flag_int_slice.go | 226 ++ .../github.com/urfave/cli/v2/flag_path.go | 102 + .../github.com/urfave/cli/v2/flag_string.go | 100 + .../urfave/cli/v2/flag_string_slice.go | 216 ++ .../urfave/cli/v2/flag_timestamp.go | 205 ++ .../github.com/urfave/cli/v2/flag_uint.go | 108 + .../github.com/urfave/cli/v2/flag_uint64.go | 108 + .../urfave/cli/v2/flag_uint64_slice.go | 219 ++ .../urfave/cli/v2/flag_uint_slice.go | 230 ++ .../github.com/urfave/cli/{ => v2}/funcs.go | 17 +- .../urfave/cli/v2/godoc-current.txt | 2724 +++++++++++++++++ v2/vendor/github.com/urfave/cli/v2/help.go | 569 ++++ .../github.com/urfave/cli/v2/mkdocs-reqs.txt | 5 + v2/vendor/github.com/urfave/cli/v2/mkdocs.yml | 107 + .../github.com/urfave/cli/{ => v2}/parse.go | 28 +- .../github.com/urfave/cli/v2/sliceflag.go | 290 ++ .../github.com/urfave/cli/{ => v2}/sort.go | 0 .../github.com/urfave/cli/v2/suggestions.go | 68 + .../github.com/urfave/cli/v2/template.go | 143 + .../urfave/cli/v2/zz_generated.flags.go | 865 ++++++ .../github.com/xrash/smetrics/.travis.yml | 9 + v2/vendor/github.com/xrash/smetrics/LICENSE | 21 + v2/vendor/github.com/xrash/smetrics/README.md | 49 + v2/vendor/github.com/xrash/smetrics/doc.go | 19 + .../github.com/xrash/smetrics/hamming.go | 25 + .../github.com/xrash/smetrics/jaro-winkler.go | 28 + v2/vendor/github.com/xrash/smetrics/jaro.go | 86 + .../github.com/xrash/smetrics/soundex.go | 63 + .../github.com/xrash/smetrics/ukkonen.go | 94 + .../xrash/smetrics/wagner-fischer.go | 48 + v2/vendor/modules.txt | 9 +- 94 files changed, 10620 insertions(+), 4197 deletions(-) create mode 100644 v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/debug.go delete mode 100644 v2/vendor/github.com/urfave/cli/.gitignore delete mode 100644 v2/vendor/github.com/urfave/cli/README.md delete mode 100644 v2/vendor/github.com/urfave/cli/app.go delete mode 100644 v2/vendor/github.com/urfave/cli/appveyor.yml delete mode 100644 v2/vendor/github.com/urfave/cli/category.go delete mode 100644 v2/vendor/github.com/urfave/cli/cli.go delete mode 100644 v2/vendor/github.com/urfave/cli/command.go delete mode 100644 v2/vendor/github.com/urfave/cli/context.go delete mode 100644 v2/vendor/github.com/urfave/cli/errors.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_bool.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_bool_t.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_duration.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_float64.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_generic.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_int.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_int64.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_int64_slice.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_int_slice.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_string.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_string_slice.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_uint.go delete mode 100644 v2/vendor/github.com/urfave/cli/flag_uint64.go delete mode 100644 v2/vendor/github.com/urfave/cli/help.go delete mode 100644 v2/vendor/github.com/urfave/cli/template.go rename v2/vendor/github.com/urfave/cli/{ => v2}/.flake8 (100%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/.gitignore create mode 100644 v2/vendor/github.com/urfave/cli/v2/.golangci.yaml rename v2/vendor/github.com/urfave/cli/{ => v2}/CODE_OF_CONDUCT.md (87%) rename v2/vendor/github.com/urfave/cli/{ => v2}/LICENSE (95%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/Makefile create mode 100644 v2/vendor/github.com/urfave/cli/v2/README.md create mode 100644 v2/vendor/github.com/urfave/cli/v2/app.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/args.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/category.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/cli.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/command.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/context.go rename v2/vendor/github.com/urfave/cli/{ => v2}/docs.go (54%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/errors.go rename v2/vendor/github.com/urfave/cli/{ => v2}/fish.go (90%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag-spec.yaml create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_bool.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_duration.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_ext.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_float64.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_float64_slice.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_generic.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_int.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_int64.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_int64_slice.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_int_slice.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_path.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_string.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_string_slice.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_timestamp.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_uint.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_uint64.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_uint64_slice.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/flag_uint_slice.go rename v2/vendor/github.com/urfave/cli/{ => v2}/funcs.go (71%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/godoc-current.txt create mode 100644 v2/vendor/github.com/urfave/cli/v2/help.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/mkdocs-reqs.txt create mode 100644 v2/vendor/github.com/urfave/cli/v2/mkdocs.yml rename v2/vendor/github.com/urfave/cli/{ => v2}/parse.go (75%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/sliceflag.go rename v2/vendor/github.com/urfave/cli/{ => v2}/sort.go (100%) create mode 100644 v2/vendor/github.com/urfave/cli/v2/suggestions.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/template.go create mode 100644 v2/vendor/github.com/urfave/cli/v2/zz_generated.flags.go create mode 100644 v2/vendor/github.com/xrash/smetrics/.travis.yml create mode 100644 v2/vendor/github.com/xrash/smetrics/LICENSE create mode 100644 v2/vendor/github.com/xrash/smetrics/README.md create mode 100644 v2/vendor/github.com/xrash/smetrics/doc.go create mode 100644 v2/vendor/github.com/xrash/smetrics/hamming.go create mode 100644 v2/vendor/github.com/xrash/smetrics/jaro-winkler.go create mode 100644 v2/vendor/github.com/xrash/smetrics/jaro.go create mode 100644 v2/vendor/github.com/xrash/smetrics/soundex.go create mode 100644 v2/vendor/github.com/xrash/smetrics/ukkonen.go create mode 100644 v2/vendor/github.com/xrash/smetrics/wagner-fischer.go diff --git a/v2/ahoy.go b/v2/ahoy.go index 4a02200..5df8f75 100644 --- a/v2/ahoy.go +++ b/v2/ahoy.go @@ -13,7 +13,7 @@ import ( "sort" "strings" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" "gopkg.in/yaml.v2" ) @@ -22,7 +22,7 @@ import ( type Config struct { Usage string AhoyAPI string - Commands map[string]Command + Commands map[string]*Command Entrypoint []string Env string } @@ -136,12 +136,12 @@ func getConfig(file string) (Config, error) { return config, err } -func getSubCommands(includes []string) []cli.Command { - subCommands := []cli.Command{} +func getSubCommands(includes []string) []*cli.Command { + subCommands := []*cli.Command{} if len(includes) == 0 { return subCommands } - commands := map[string]cli.Command{} + commands := map[string]*cli.Command{} for _, include := range includes { if len(include) == 0 { continue @@ -197,8 +197,8 @@ func getEnvironmentVars(envFile string) []string { return envVars } -func getCommands(config Config) []cli.Command { - exportCmds := []cli.Command{} +func getCommands(config Config) []*cli.Command { + exportCmds := []*cli.Command{} envVars := []string{} // Get environment variables from the 'global' environment variable file, if it is defined. @@ -231,7 +231,7 @@ func getCommands(config Config) []cli.Command { logger("fatal", "Command ["+name+"] has 'imports' set, but it is empty. Check your yaml file.") } - newCmd := cli.Command{ + newCmd := &cli.Command{ Name: name, Aliases: cmd.Aliases, SkipFlagParsing: true, @@ -243,7 +243,7 @@ func getCommands(config Config) []cli.Command { } if cmd.Cmd != "" { - newCmd.Action = func(c *cli.Context) { + newCmd.Action = func(c *cli.Context) error { // For some unclear reason, if we don't add an item at the end here, // the first argument is skipped... actually it's not! // 'bash -c' says that arguments will be passed starting with $0, which also means that @@ -253,7 +253,7 @@ func getCommands(config Config) []cli.Command { var cmdEntrypoint []string // c.Args() is not a slice apparently. - for _, arg := range c.Args() { + for _, arg := range c.Args().Slice() { if arg != "--" { cmdArgs = append(cmdArgs, arg) } @@ -292,6 +292,7 @@ func getCommands(config Config) []cli.Command { fmt.Fprintln(os.Stderr) os.Exit(1) } + return nil } } @@ -314,18 +315,18 @@ func getCommands(config Config) []cli.Command { return exportCmds } -func addDefaultCommands(commands []cli.Command) []cli.Command { +func addDefaultCommands(commands []*cli.Command) []*cli.Command { - defaultInitCmd := cli.Command{ + defaultInitCmd := &cli.Command{ Name: "init", Usage: "Initialize a new .ahoy.yml config file in the current directory.", Flags: []cli.Flag{ - cli.BoolFlag{ + &cli.BoolFlag{ Name: "force", Usage: "force overwriting the .ahoy.yml file in the current directory.", }, }, - Action: func(c *cli.Context) { + Action: func(c *cli.Context) error { if fileExists(filepath.Join(".", ".ahoy.yml")) { if c.Bool("force") { fmt.Println("Warning: '--force' parameter passed, overwriting .ahoy.yml in current directory.") @@ -343,7 +344,7 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { fmt.Println("Abort: exiting without overwriting.") os.Exit(0) } - if len(c.Args()) > 0 { + if c.Args().Len() > 0 { fmt.Println("Ok, overwriting .ahoy.yml in current directory with specified file.") } else { fmt.Println("Ok, overwriting .ahoy.yml in current directory with example file.") @@ -354,8 +355,8 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { // Allows users to define their own files to call to init. // TODO: Make file downloading OS-independent. var wgetURL = "https://raw.githubusercontent.com/ahoy-cli/ahoy/master/examples/examples.ahoy.yml" - if len(c.Args()) > 0 { - wgetURL = c.Args()[0] + if c.Args().Len() > 0 { + wgetURL = c.Args().Get(0) } grabYaml := "wget " + wgetURL + " -O .ahoy.yml" cmd := exec.Command("bash", "-c", grabYaml) @@ -365,12 +366,13 @@ func addDefaultCommands(commands []cli.Command) []cli.Command { fmt.Fprintln(os.Stderr) os.Exit(1) } else { - if len(c.Args()) > 0 { + if c.Args().Len() > 0 { fmt.Println("Your specified .ahoy.yml has been downloaded to the current directory.") } else { fmt.Println("Example .ahoy.yml downloaded to the current directory. You can customize it to suit your needs!") } } + return nil }, } @@ -407,10 +409,10 @@ func BashComplete(c *cli.Context) { // NoArgsAction is the application wide default action, for when no flags or arguments // are passed or when a command doesn't exist. // Looks like -f flag still works through here though. -func NoArgsAction(c *cli.Context) { +func NoArgsAction(c *cli.Context) error { args := c.Args() - if len(args) > 0 { - msg := "Command not found for '" + strings.Join(args, " ") + "'" + if args.Len() > 0 { + msg := "Command not found for '" + strings.Join(args.Slice(), " ") + "'" logger("fatal", msg) } @@ -427,6 +429,7 @@ func NoArgsAction(c *cli.Context) { // Exit gracefully if we get to here. os.Exit(0) + return nil } // BeforeCommand runs before every command so arguments or flags must be passed @@ -438,7 +441,7 @@ func BeforeCommand(c *cli.Context) error { return errors.New("don't continue with commands") } if c.Bool("help") { - if len(args) > 0 { + if args.Len() > 0 { cli.ShowCommandHelp(c, args.First()) } else { cli.ShowAppHelp(c) diff --git a/v2/ahoy_test.go b/v2/ahoy_test.go index d54c80d..9b7b9f9 100644 --- a/v2/ahoy_test.go +++ b/v2/ahoy_test.go @@ -24,7 +24,7 @@ func TestGetCommands(t *testing.T) { config := Config{ Usage: "Test getSubCommands Usage.", AhoyAPI: "v2", - Commands: map[string]Command{ + Commands: map[string]*Command{ "test-command": { Description: "Testing example Command.", Usage: "test-command a", @@ -171,7 +171,7 @@ func TestGetConfig(t *testing.T) { expected := Config{ Usage: "Test example usage.", AhoyAPI: "v2", - Commands: map[string]Command{ + Commands: map[string]*Command{ "test-command": { Description: "Testing example Command.", Usage: "test-command", diff --git a/v2/flag.go b/v2/flag.go index 8d79b6f..57bb58a 100644 --- a/v2/flag.go +++ b/v2/flag.go @@ -3,30 +3,33 @@ package main import ( "flag" - "github.com/urfave/cli" + "github.com/urfave/cli/v2" ) var globalFlags = []cli.Flag{ - cli.BoolFlag{ - Name: "verbose, v", + &cli.BoolFlag{ + Name: "verbose", + Aliases: []string{"v"}, Usage: "Output extra details like the commands to be run.", - EnvVar: "AHOY_VERBOSE", + EnvVars: []string{"AHOY_VERBOSE"}, Destination: &verbose, }, - cli.StringFlag{ - Name: "file, f", + &cli.StringFlag{ + Name: "file", + Aliases: []string{"f"}, Usage: "Use a specific ahoy file.", Destination: &sourcefile, }, - cli.BoolFlag{ - Name: "help, h", + &cli.BoolFlag{ + Name: "help", + Aliases: []string{"h"}, Usage: "show help", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "version", Usage: "print the version", }, - cli.BoolFlag{ + &cli.BoolFlag{ Name: "generate-bash-completion", }, } diff --git a/v2/go.mod b/v2/go.mod index 028422f..2390d13 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -8,7 +8,9 @@ require ( ) require ( - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/urfave/cli/v2 v2.27.5 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/v2/go.sum b/v2/go.sum index 62bdfdb..88d994d 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -2,6 +2,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 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.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -14,6 +16,10 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/urfave/cli v1.22.9 h1:cv3/KhXGBGjEXLC4bH0sLuJ9BewaAbpk5oyMOveu4pw= github.com/urfave/cli v1.22.9/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/v2/testdata/command-aliases.ahoy.yml b/v2/testdata/command-aliases.ahoy.yml index 4c4b4a2..fc0045d 100644 --- a/v2/testdata/command-aliases.ahoy.yml +++ b/v2/testdata/command-aliases.ahoy.yml @@ -3,7 +3,7 @@ commands: hello: usage: Say hello cmd: echo "Hello, World!" - aliases: ["hi", "greet", "ahoy"] + aliases: ["hi", "greet"] ahoy-there: usage: Say "ahoy there!" diff --git a/v2/tests/command-aliases.bats b/v2/tests/command-aliases.bats index b7bc9bb..aead807 100644 --- a/v2/tests/command-aliases.bats +++ b/v2/tests/command-aliases.bats @@ -33,9 +33,3 @@ load 'test_helpers/bats-assert/load' [[ "$output" =~ "ahoy there!" ]] [ "$status" -eq 0 ] } - -@test "Multiple conflicting aliases means the last one loaded takes precedence" { - run ./ahoy -f testdata/command-aliases.ahoy.yml ahoy - [[ "$output" =~ "ahoy there!" ]] - [ "$status" -eq 0 ] -} diff --git a/v2/tests/sub-commands.bats b/v2/tests/sub-commands.bats index 7441361..3e4ad4a 100644 --- a/v2/tests/sub-commands.bats +++ b/v2/tests/sub-commands.bats @@ -60,6 +60,7 @@ teardown() { # Check that sub1-cmd and sub2-cmd are listed under main-cmd run ./ahoy main-cmd --help + echo $output [ "$status" -eq 0 ] [[ "$output" =~ "sub1-cmd" ]] [[ "$output" =~ "sub2-cmd" ]] diff --git a/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/debug.go b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/debug.go new file mode 100644 index 0000000..0ec4b12 --- /dev/null +++ b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/debug.go @@ -0,0 +1,62 @@ +package md2man + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/russross/blackfriday/v2" +) + +func fmtListFlags(flags blackfriday.ListType) string { + knownFlags := []struct { + name string + flag blackfriday.ListType + }{ + {"ListTypeOrdered", blackfriday.ListTypeOrdered}, + {"ListTypeDefinition", blackfriday.ListTypeDefinition}, + {"ListTypeTerm", blackfriday.ListTypeTerm}, + {"ListItemContainsBlock", blackfriday.ListItemContainsBlock}, + {"ListItemBeginningOfList", blackfriday.ListItemBeginningOfList}, + {"ListItemEndOfList", blackfriday.ListItemEndOfList}, + } + + var f []string + for _, kf := range knownFlags { + if flags&kf.flag != 0 { + f = append(f, kf.name) + flags &^= kf.flag + } + } + if flags != 0 { + f = append(f, fmt.Sprintf("Unknown(%#x)", flags)) + } + return strings.Join(f, "|") +} + +type debugDecorator struct { + blackfriday.Renderer +} + +func depth(node *blackfriday.Node) int { + d := 0 + for n := node.Parent; n != nil; n = n.Parent { + d++ + } + return d +} + +func (d *debugDecorator) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { + fmt.Fprintf(os.Stderr, "%s%s %v %v\n", + strings.Repeat(" ", depth(node)), + map[bool]string{true: "+", false: "-"}[entering], + node, + fmtListFlags(node.ListFlags)) + var b strings.Builder + status := d.Renderer.RenderNode(io.MultiWriter(&b, w), node, entering) + if b.Len() > 0 { + fmt.Fprintf(os.Stderr, ">> %q\n", b.String()) + } + return status +} diff --git a/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go index b480056..62d91b7 100644 --- a/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go +++ b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go @@ -1,14 +1,23 @@ package md2man import ( + "os" + "strconv" + "github.com/russross/blackfriday/v2" ) // Render converts a markdown document into a roff formatted document. func Render(doc []byte) []byte { renderer := NewRoffRenderer() + var r blackfriday.Renderer = renderer + if v, _ := strconv.ParseBool(os.Getenv("MD2MAN_DEBUG")); v { + r = &debugDecorator{Renderer: r} + } return blackfriday.Run(doc, - []blackfriday.Option{blackfriday.WithRenderer(renderer), - blackfriday.WithExtensions(renderer.GetExtensions())}...) + []blackfriday.Option{ + blackfriday.WithRenderer(r), + blackfriday.WithExtensions(renderer.GetExtensions()), + }...) } diff --git a/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go index be2b343..9d6c473 100644 --- a/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go +++ b/v2/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go @@ -1,6 +1,8 @@ package md2man import ( + "bufio" + "bytes" "fmt" "io" "os" @@ -12,68 +14,72 @@ import ( // roffRenderer implements the blackfriday.Renderer interface for creating // roff format (manpages) from markdown text type roffRenderer struct { - extensions blackfriday.Extensions listCounters []int firstHeader bool - firstDD bool listDepth int } const ( - titleHeader = ".TH " - topLevelHeader = "\n\n.SH " - secondLevelHdr = "\n.SH " - otherHeader = "\n.SS " - crTag = "\n" - emphTag = "\\fI" - emphCloseTag = "\\fP" - strongTag = "\\fB" - strongCloseTag = "\\fP" - breakTag = "\n.br\n" - paraTag = "\n.PP\n" - hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n" - linkTag = "\n\\[la]" - linkCloseTag = "\\[ra]" - codespanTag = "\\fB\\fC" - codespanCloseTag = "\\fR" - codeTag = "\n.PP\n.RS\n\n.nf\n" - codeCloseTag = "\n.fi\n.RE\n" - quoteTag = "\n.PP\n.RS\n" - quoteCloseTag = "\n.RE\n" - listTag = "\n.RS\n" - listCloseTag = "\n.RE\n" - dtTag = "\n.TP\n" - dd2Tag = "\n" - tableStart = "\n.TS\nallbox;\n" - tableEnd = ".TE\n" - tableCellStart = "T{\n" - tableCellEnd = "\nT}\n" + titleHeader = ".TH " + topLevelHeader = "\n\n.SH " + secondLevelHdr = "\n.SH " + otherHeader = "\n.SS " + crTag = "\n" + emphTag = "\\fI" + emphCloseTag = "\\fP" + strongTag = "\\fB" + strongCloseTag = "\\fP" + breakTag = "\n.br\n" + paraTag = "\n.PP\n" + hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n" + linkTag = "\n\\[la]" + linkCloseTag = "\\[ra]" + codespanTag = "\\fB" + codespanCloseTag = "\\fR" + codeTag = "\n.EX\n" + codeCloseTag = ".EE\n" // Do not prepend a newline character since code blocks, by definition, include a newline already (or at least as how blackfriday gives us on). + quoteTag = "\n.PP\n.RS\n" + quoteCloseTag = "\n.RE\n" + listTag = "\n.RS\n" + listCloseTag = ".RE\n" + dtTag = "\n.TP\n" + dd2Tag = "\n" + tableStart = "\n.TS\nallbox;\n" + tableEnd = ".TE\n" + tableCellStart = "T{\n" + tableCellEnd = "\nT}\n" + tablePreprocessor = `'\" t` ) // NewRoffRenderer creates a new blackfriday Renderer for generating roff documents // from markdown func NewRoffRenderer() *roffRenderer { // nolint: golint - var extensions blackfriday.Extensions - - extensions |= blackfriday.NoIntraEmphasis - extensions |= blackfriday.Tables - extensions |= blackfriday.FencedCode - extensions |= blackfriday.SpaceHeadings - extensions |= blackfriday.Footnotes - extensions |= blackfriday.Titleblock - extensions |= blackfriday.DefinitionLists - return &roffRenderer{ - extensions: extensions, - } + return &roffRenderer{} } // GetExtensions returns the list of extensions used by this renderer implementation -func (r *roffRenderer) GetExtensions() blackfriday.Extensions { - return r.extensions +func (*roffRenderer) GetExtensions() blackfriday.Extensions { + return blackfriday.NoIntraEmphasis | + blackfriday.Tables | + blackfriday.FencedCode | + blackfriday.SpaceHeadings | + blackfriday.Footnotes | + blackfriday.Titleblock | + blackfriday.DefinitionLists } // RenderHeader handles outputting the header at document start func (r *roffRenderer) RenderHeader(w io.Writer, ast *blackfriday.Node) { + // We need to walk the tree to check if there are any tables. + // If there are, we need to enable the roff table preprocessor. + ast.Walk(func(node *blackfriday.Node, entering bool) blackfriday.WalkStatus { + if node.Type == blackfriday.Table { + out(w, tablePreprocessor+"\n") + return blackfriday.Terminate + } + return blackfriday.GoToNext + }) + // disable hyphenation out(w, ".nh\n") } @@ -86,12 +92,27 @@ func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.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 func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus { - - var walkAction = blackfriday.GoToNext + walkAction := blackfriday.GoToNext switch node.Type { case blackfriday.Text: - escapeSpecialChars(w, node.Literal) + // Special case: format the NAME section as required for proper whatis parsing. + // Refer to the lexgrog(1) and groff_man(7) manual pages for details. + if node.Parent != nil && + node.Parent.Type == blackfriday.Paragraph && + node.Parent.Prev != nil && + node.Parent.Prev.Type == blackfriday.Heading && + node.Parent.Prev.FirstChild != nil && + bytes.EqualFold(node.Parent.Prev.FirstChild.Literal, []byte("NAME")) { + before, after, found := bytes.Cut(node.Literal, []byte(" - ")) + escapeSpecialChars(w, before) + if found { + out(w, ` \- `) + escapeSpecialChars(w, after) + } + } else { + escapeSpecialChars(w, node.Literal) + } case blackfriday.Softbreak: out(w, crTag) case blackfriday.Hardbreak: @@ -109,9 +130,16 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering out(w, strongCloseTag) } case blackfriday.Link: - if !entering { - out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag) + // Don't render the link text for automatic links, because this + // 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: // ignore images walkAction = blackfriday.SkipChildren @@ -122,14 +150,25 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering case blackfriday.Document: break case blackfriday.Paragraph: - // roff .PP markers break lists - if r.listDepth > 0 { - return blackfriday.GoToNext - } if entering { - out(w, paraTag) + if r.listDepth > 0 { + // roff .PP markers break lists + if node.Prev != nil { // continued paragraph + if node.Prev.Type == blackfriday.List && node.Prev.ListFlags&blackfriday.ListTypeDefinition == 0 { + out(w, ".IP\n") + } else { + out(w, crTag) + } + } + } else if node.Prev != nil && node.Prev.Type == blackfriday.Heading { + out(w, crTag) + } else { + out(w, paraTag) + } } else { - out(w, crTag) + if node.Next == nil || node.Next.Type != blackfriday.List { + out(w, crTag) + } } case blackfriday.BlockQuote: if entering { @@ -160,6 +199,11 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering r.handleTableCell(w, node, entering) case blackfriday.HTMLSpan: // ignore other HTML tags + case blackfriday.HTMLBlock: + if bytes.HasPrefix(node.Literal, []byte("