New Upstream Release - golang-github-urfave-cli
Ready changes
Summary
Merged new upstream version: 1.22.12 (was: 1.22.10).
Resulting package
Built on 2023-03-18T00:18 (took 6m42s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases golang-github-urfave-cli-dev
Lintian Result
Diff
diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml
index eccb6a5..544ccfe 100644
--- a/.github/workflows/cli.yml
+++ b/.github/workflows/cli.yml
@@ -3,10 +3,10 @@ name: Run Tests
on:
pull_request:
branches:
- - v1
+ - v1-maint
push:
branches:
- - v1
+ - v1-maint
tags:
- v1.*
@@ -14,8 +14,8 @@ jobs:
test:
strategy:
matrix:
- os: [ubuntu-latest, macos-latest]
- go: [1.16.x, 1.17.x, 1.18.x]
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ go: [1.18.x, 1.19.x]
name: ${{ matrix.os }} @ Go ${{ matrix.go }}
runs-on: ${{ matrix.os }}
steps:
diff --git a/.gitignore b/.gitignore
index 8ae196f..9d18120 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,8 @@ coverage.txt
node_modules/
vendor
.idea
+/.local/
+/internal/
+/site/
+package.json
+package-lock.json
diff --git a/LICENSE b/LICENSE
index 42a597e..99d8559 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2016 Jeremy Saenz & Contributors
+Copyright (c) 2023 Jeremy Saenz & Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index 9c2cf85..c7dd62b 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,10 @@
cli
===
-[![Build Status](https://travis-ci.org/urfave/cli.svg?branch=master)](https://travis-ci.org/urfave/cli)
-[![Windows Build Status](https://ci.appveyor.com/api/projects/status/rtgk5xufi932pb2v?svg=true)](https://ci.appveyor.com/project/urfave/cli)
-
-[![GoDoc](https://godoc.org/github.com/urfave/cli?status.svg)](https://godoc.org/github.com/urfave/cli)
-[![codebeat](https://codebeat.co/badges/0a8f30aa-f975-404b-b878-5fab3ae1cc5f)](https://codebeat.co/projects/github-com-urfave-cli)
+[![Run Tests](https://github.com/urfave/cli/actions/workflows/cli.yml/badge.svg?branch=v1-maint)](https://github.com/urfave/cli/actions/workflows/cli.yml)
+[![Go Reference](https://pkg.go.dev/badge/github.com/urfave/cli/.svg)](https://pkg.go.dev/github.com/urfave/cli/)
[![Go Report Card](https://goreportcard.com/badge/urfave/cli)](https://goreportcard.com/report/urfave/cli)
-[![codecov](https://codecov.io/gh/urfave/cli/branch/master/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
+[![codecov](https://codecov.io/gh/urfave/cli/branch/v1-maint/graph/badge.svg)](https://codecov.io/gh/urfave/cli)
cli is a simple, fast, and fun package for building command line apps in Go. The
goal is to enable developers to write fast and distributable command line
@@ -15,29 +12,19 @@ applications in an expressive way.
## Usage Documentation
-Usage documentation exists for each major version
-
-- `v1` - [./docs/v1/manual.md](./docs/v1/manual.md)
-- `v2` - 🚧 documentation for `v2` is WIP 🚧
+Usage documentation for `v1` is available [at the docs
+site](https://cli.urfave.org/v1/getting-started/) or in-tree at
+[./docs/v1/manual.md](./docs/v1/manual.md)
## Installation
-Make sure you have a working Go environment. Go version 1.10+ is supported. [See
-the install instructions for Go](http://golang.org/doc/install.html).
-
-### GOPATH
-
-Make sure your `PATH` includes the `$GOPATH/bin` directory so your commands can
-be easily used:
-```
-export PATH=$PATH:$GOPATH/bin
-```
+Make sure you have a working Go environment. Go version 1.18+ is supported.
### Supported platforms
-cli is tested against multiple versions of Go on Linux, and against the latest
-released version of Go on OS X and Windows. For full details, see
-[`./.travis.yml`](./.travis.yml) and [`./appveyor.yml`](./appveyor.yml).
+cli is tested against multiple versions of Go on Linux, and against the latest released
+version of Go on OS X and Windows. For full details, see
+[./.github/workflows/cli.yml](./.github/workflows/cli.yml).
### Build tags
@@ -62,19 +49,3 @@ import (
)
...
```
-
-### Using `v2` releases
-
-**Warning**: `v2` is in a pre-release state.
-
-```
-$ go get github.com/urfave/cli.v2
-```
-
-```go
-...
-import (
- "github.com/urfave/cli.v2" // imports as package "cli"
-)
-...
-```
diff --git a/altsrc/flag.go b/altsrc/flag.go
index afb4ad4..6fb275f 100644
--- a/altsrc/flag.go
+++ b/altsrc/flag.go
@@ -5,6 +5,7 @@ import (
"strconv"
"strings"
"syscall"
+ "time"
"github.com/urfave/cli"
)
@@ -85,14 +86,17 @@ func (f *GenericFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourc
func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
- value, err := isc.StringSlice(f.StringSliceFlag.Name)
- if err != nil {
- return err
- }
+ var value []string
+ eachName(f.StringSliceFlag.Name, func(name string) {
+ val, err := isc.StringSlice(name)
+ if err == nil && value == nil {
+ value = val
+ }
+ })
if value != nil {
var sliceValue cli.StringSlice = value
eachName(f.Name, func(name string) {
- underlyingFlag := f.set.Lookup(f.Name)
+ underlyingFlag := f.set.Lookup(name)
if underlyingFlag != nil {
underlyingFlag.Value = &sliceValue
}
@@ -107,14 +111,17 @@ func (f *StringSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputS
func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
- value, err := isc.IntSlice(f.IntSliceFlag.Name)
- if err != nil {
- return err
- }
+ var value []int
+ eachName(f.IntSliceFlag.Name, func(name string) {
+ val, err := isc.IntSlice(name)
+ if err == nil && value == nil {
+ value = val
+ }
+ })
if value != nil {
var sliceValue cli.IntSlice = value
eachName(f.Name, func(name string) {
- underlyingFlag := f.set.Lookup(f.Name)
+ underlyingFlag := f.set.Lookup(name)
if underlyingFlag != nil {
underlyingFlag.Value = &sliceValue
}
@@ -129,13 +136,16 @@ func (f *IntSliceFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
- value, err := isc.Bool(f.BoolFlag.Name)
- if err != nil {
- return err
- }
+ var value bool
+ eachName(f.BoolFlag.Name, func(name string) {
+ val, err := isc.Bool(name)
+ if err == nil && !value {
+ value = val
+ }
+ })
if value {
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, strconv.FormatBool(value))
+ _ = f.set.Set(name, strconv.FormatBool(value))
})
}
}
@@ -147,13 +157,16 @@ func (f *BoolFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCo
func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !context.IsSet(f.Name) && !isEnvVarSet(f.EnvVar) {
- value, err := isc.BoolT(f.BoolTFlag.Name)
- if err != nil {
- return err
- }
+ var value bool
+ eachName(f.BoolTFlag.Name, func(name string) {
+ val, err := isc.Bool(name)
+ if err == nil && !value {
+ value = val
+ }
+ })
if !value {
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, strconv.FormatBool(value))
+ _ = f.set.Set(name, strconv.FormatBool(value))
})
}
}
@@ -165,13 +178,16 @@ func (f *BoolTFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceC
func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
- value, err := isc.String(f.StringFlag.Name)
- if err != nil {
- return err
- }
+ var value string
+ eachName(f.StringFlag.Name, func(name string) {
+ val, err := isc.String(name)
+ if err == nil && value == "" {
+ value = val
+ }
+ })
if value != "" {
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, value)
+ _ = f.set.Set(name, value)
})
}
}
@@ -183,13 +199,16 @@ func (f *StringFlag) ApplyInputSourceValue(context *cli.Context, isc InputSource
func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
- value, err := isc.Int(f.IntFlag.Name)
- if err != nil {
- return err
- }
+ var value int
+ eachName(f.IntFlag.Name, func(name string) {
+ val, err := isc.Int(name)
+ if err == nil && value == 0 {
+ value = val
+ }
+ })
if value > 0 {
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, strconv.FormatInt(int64(value), 10))
+ _ = f.set.Set(name, strconv.FormatInt(int64(value), 10))
})
}
}
@@ -201,13 +220,16 @@ func (f *IntFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceCon
func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
- value, err := isc.Duration(f.DurationFlag.Name)
- if err != nil {
- return err
- }
+ var value time.Duration
+ eachName(f.DurationFlag.Name, func(name string) {
+ val, err := isc.Duration(name)
+ if err == nil && value == 0 {
+ value = val
+ }
+ })
if value > 0 {
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, value.String())
+ _ = f.set.Set(name, value.String())
})
}
}
@@ -219,14 +241,17 @@ func (f *DurationFlag) ApplyInputSourceValue(context *cli.Context, isc InputSour
func (f *Float64Flag) ApplyInputSourceValue(context *cli.Context, isc InputSourceContext) error {
if f.set != nil {
if !(context.IsSet(f.Name) || isEnvVarSet(f.EnvVar)) {
- value, err := isc.Float64(f.Float64Flag.Name)
- if err != nil {
- return err
- }
+ var value float64
+ eachName(f.Float64Flag.Name, func(name string) {
+ val, err := isc.Float64(name)
+ if err == nil && value == 0 {
+ value = val
+ }
+ })
if value > 0 {
floatStr := float64ToString(value)
eachName(f.Name, func(name string) {
- _ = f.set.Set(f.Name, floatStr)
+ _ = f.set.Set(name, floatStr)
})
}
}
diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go
index 90a96d3..bd77898 100644
--- a/altsrc/flag_test.go
+++ b/altsrc/flag_test.go
@@ -57,11 +57,12 @@ func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestStringSliceApplyInputSourceValue(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewStringSliceFlag(cli.StringSliceFlag{Name: "test"}),
+ Flag: NewStringSliceFlag(cli.StringSliceFlag{Name: "test,t"}),
FlagName: "test",
MapValue: []interface{}{"hello", "world"},
})
expect(t, c.StringSlice("test"), []string{"hello", "world"})
+ expect(t, c.StringSlice("t"), []string{"hello", "world"})
}
func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) {
@@ -87,11 +88,12 @@ func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestIntSliceApplyInputSourceValue(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewIntSliceFlag(cli.IntSliceFlag{Name: "test"}),
+ Flag: NewIntSliceFlag(cli.IntSliceFlag{Name: "test,t"}),
FlagName: "test",
MapValue: []interface{}{1, 2},
})
expect(t, c.IntSlice("test"), []int{1, 2})
+ expect(t, c.IntSlice("t"), []int{1, 2})
}
func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) {
@@ -117,11 +119,12 @@ func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestBoolApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewBoolFlag(cli.BoolFlag{Name: "test"}),
+ Flag: NewBoolFlag(cli.BoolFlag{Name: "test,t"}),
FlagName: "test",
MapValue: true,
})
expect(t, true, c.Bool("test"))
+ expect(t, true, c.Bool("t"))
}
func TestBoolApplyInputSourceMethodContextSet(t *testing.T) {
@@ -147,11 +150,12 @@ func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestBoolTApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewBoolTFlag(cli.BoolTFlag{Name: "test"}),
+ Flag: NewBoolTFlag(cli.BoolTFlag{Name: "test, t"}),
FlagName: "test",
MapValue: false,
})
expect(t, false, c.BoolT("test"))
+ expect(t, false, c.BoolT("t"))
}
func TestBoolTApplyInputSourceMethodContextSet(t *testing.T) {
@@ -177,11 +181,12 @@ func TestBoolTApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestStringApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewStringFlag(cli.StringFlag{Name: "test"}),
+ Flag: NewStringFlag(cli.StringFlag{Name: "test,t"}),
FlagName: "test",
MapValue: "hello",
})
expect(t, "hello", c.String("test"))
+ expect(t, "hello", c.String("t"))
}
func TestStringApplyInputSourceMethodContextSet(t *testing.T) {
@@ -207,11 +212,12 @@ func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestIntApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewIntFlag(cli.IntFlag{Name: "test"}),
+ Flag: NewIntFlag(cli.IntFlag{Name: "test,t"}),
FlagName: "test",
MapValue: 15,
})
expect(t, 15, c.Int("test"))
+ expect(t, 15, c.Int("t"))
}
func TestIntApplyInputSourceMethodContextSet(t *testing.T) {
@@ -237,11 +243,12 @@ func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestDurationApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewDurationFlag(cli.DurationFlag{Name: "test"}),
+ Flag: NewDurationFlag(cli.DurationFlag{Name: "test,t"}),
FlagName: "test",
MapValue: 30 * time.Second,
})
expect(t, 30*time.Second, c.Duration("test"))
+ expect(t, 30*time.Second, c.Duration("t"))
}
func TestDurationApplyInputSourceMethodContextSet(t *testing.T) {
@@ -267,11 +274,12 @@ func TestDurationApplyInputSourceMethodEnvVarSet(t *testing.T) {
func TestFloat64ApplyInputSourceMethodSet(t *testing.T) {
c := runTest(t, testApplyInputSource{
- Flag: NewFloat64Flag(cli.Float64Flag{Name: "test"}),
+ Flag: NewFloat64Flag(cli.Float64Flag{Name: "test,t"}),
FlagName: "test",
MapValue: 1.3,
})
expect(t, 1.3, c.Float64("test"))
+ expect(t, 1.3, c.Float64("t"))
}
func TestFloat64ApplyInputSourceMethodContextSet(t *testing.T) {
diff --git a/altsrc/toml_command_test.go b/altsrc/toml_command_test.go
index 1d91d56..ffc1a9d 100644
--- a/altsrc/toml_command_test.go
+++ b/altsrc/toml_command_test.go
@@ -1,8 +1,3 @@
-// Disabling building of toml support in cases where golang is 1.0 or 1.1
-// as the encoding library is not implemented or supported.
-
-// +build go1.2
-
package altsrc
import (
diff --git a/altsrc/toml_file_loader.go b/altsrc/toml_file_loader.go
index 127693a..773ab57 100644
--- a/altsrc/toml_file_loader.go
+++ b/altsrc/toml_file_loader.go
@@ -1,8 +1,3 @@
-// Disabling building of toml support in cases where golang is 1.0 or 1.1
-// as the encoding library is not implemented or supported.
-
-// +build go1.2
-
package altsrc
import (
diff --git a/altsrc/yaml_command_test.go b/altsrc/yaml_command_test.go
index 31f78ce..ad80ef3 100644
--- a/altsrc/yaml_command_test.go
+++ b/altsrc/yaml_command_test.go
@@ -1,8 +1,3 @@
-// Disabling building of yaml support in cases where golang is 1.0 or 1.1
-// as the encoding library is not implemented or supported.
-
-// +build go1.2
-
package altsrc
import (
diff --git a/altsrc/yaml_file_loader.go b/altsrc/yaml_file_loader.go
index 2177c75..1ea1605 100644
--- a/altsrc/yaml_file_loader.go
+++ b/altsrc/yaml_file_loader.go
@@ -1,8 +1,3 @@
-// Disabling building of yaml support in cases where golang is 1.0 or 1.1
-// as the encoding library is not implemented or supported.
-
-// +build go1.2
-
package altsrc
import (
diff --git a/app.go b/app.go
index 382f238..df5a9a9 100644
--- a/app.go
+++ b/app.go
@@ -248,7 +248,7 @@ func (a *App) Run(arguments []string) (err error) {
return cerr
}
- if a.After != nil {
+ if a.After != nil && !context.shellComplete {
defer func() {
if afterErr := a.After(context); afterErr != nil {
if err != nil {
@@ -260,7 +260,7 @@ func (a *App) Run(arguments []string) (err error) {
}()
}
- if a.Before != nil {
+ if a.Before != nil && !context.shellComplete {
beforeErr := a.Before(context)
if beforeErr != nil {
a.handleExitCoder(context, beforeErr)
@@ -374,7 +374,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
return cerr
}
- if a.After != nil {
+ if a.After != nil && !context.shellComplete {
defer func() {
afterErr := a.After(context)
if afterErr != nil {
@@ -388,7 +388,7 @@ func (a *App) RunAsSubcommand(ctx *Context) (err error) {
}()
}
- if a.Before != nil {
+ if a.Before != nil && !context.shellComplete {
beforeErr := a.Before(context)
if beforeErr != nil {
a.handleExitCoder(context, beforeErr)
diff --git a/app_test.go b/app_test.go
index 4dc43ba..e18a9f0 100644
--- a/app_test.go
+++ b/app_test.go
@@ -986,6 +986,58 @@ func TestApp_BeforeFunc(t *testing.T) {
}
}
+func TestApp_BeforeAfterFuncShellCompletion(t *testing.T) {
+ counts := &opCounts{}
+ var err error
+
+ app := &App{
+ EnableBashCompletion: true,
+ Before: func(c *Context) error {
+ counts.Total++
+ counts.Before = counts.Total
+ return nil
+ },
+ After: func(c *Context) error {
+ counts.Total++
+ counts.After = counts.Total
+ return nil
+ },
+ Commands: []Command{
+ {
+ Name: "sub",
+ Action: func(c *Context) error {
+ counts.Total++
+ counts.SubCommand = counts.Total
+ return nil
+ },
+ },
+ },
+ Flags: []Flag{
+ &StringFlag{Name: "opt"},
+ },
+ Writer: ioutil.Discard,
+ }
+
+ // run with the Before() func succeeding
+ err = app.Run([]string{"command", "--opt", "succeed", "sub", "--generate-bash-completion"})
+
+ if err != nil {
+ t.Fatalf("Run error: %s", err)
+ }
+
+ if counts.Before != 0 {
+ t.Errorf("Before() executed when not expected")
+ }
+
+ if counts.After != 0 {
+ t.Errorf("After() executed when not expected")
+ }
+
+ if counts.SubCommand != 0 {
+ t.Errorf("Subcommand executed more than expected")
+ }
+}
+
func TestApp_AfterFunc(t *testing.T) {
counts := &opCounts{}
afterError := fmt.Errorf("fail")
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 8ef2fea..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-version: "{build}"
-
-os: Windows Server 2016
-
-image: Visual Studio 2017
-
-clone_folder: c:\gopath\src\github.com\urfave\cli
-
-cache:
- - node_modules
-
-environment:
- GOPATH: C:\gopath
- GOVERSION: 1.11.x
- GO111MODULE: on
- GOPROXY: https://proxy.golang.org
-
-install:
- - set PATH=%GOPATH%\bin;C:\go\bin;%PATH%
- - go version
- - go env
- - go get github.com/urfave/gfmrun/cmd/gfmrun
- - go mod vendor
-
-build_script:
- - go run build.go vet
- - go run build.go test
- - go run build.go gfmrun docs/v1/manual.md
diff --git a/build.go b/build.go
index 08cf7bb..f5561cd 100644
--- a/build.go
+++ b/build.go
@@ -1,4 +1,5 @@
-//+build ignore
+//go:build ignore
+// +build ignore
package main
@@ -10,6 +11,7 @@ import (
"log"
"os"
"os/exec"
+ "runtime"
"strings"
"github.com/urfave/cli"
@@ -163,6 +165,11 @@ func GfmrunActionFunc(c *cli.Context) error {
}
func TocActionFunc(c *cli.Context) error {
+ if runtime.GOOS == "windows" {
+ log.Println("the toc command is not meant for windows")
+ return nil
+ }
+
filename := c.Args().Get(0)
if filename == "" {
filename = "README.md"
diff --git a/command.go b/command.go
index 09fda16..6c2f9ca 100644
--- a/command.go
+++ b/command.go
@@ -98,8 +98,10 @@ type Commands []Command
// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags
func (c Command) Run(ctx *Context) (err error) {
- if len(c.Subcommands) > 0 {
- return c.startApp(ctx)
+ if !c.SkipFlagParsing {
+ if len(c.Subcommands) > 0 {
+ return c.startApp(ctx)
+ }
}
if !c.HideHelp && (HelpFlag != BoolFlag{}) {
@@ -261,7 +263,7 @@ func reorderArgs(commandFlags []Flag, args []string) []string {
// argIsFlag checks if an arg is one of our command flags
func argIsFlag(commandFlags []Flag, arg string) bool {
- if arg == "-" || arg == "--"{
+ if arg == "-" || arg == "--" {
// `-` is never a flag
// `--` is an option-value when following a flag, and a delimiter indicating the end of options in other cases.
return false
diff --git a/command_test.go b/command_test.go
index 90bcecc..49fd4fc 100644
--- a/command_test.go
+++ b/command_test.go
@@ -119,7 +119,7 @@ func TestParseAndRunHyphenValues(t *testing.T) {
cases := []struct {
testArgs []string
expectedArgs []string
- expectedOpt string
+ expectedOpt string
}{
{[]string{"foo", "test", "argz"}, []string{"argz"}, ""},
{[]string{"foo", "test", "argz", "arga"}, []string{"argz", "arga"}, ""},
@@ -155,10 +155,10 @@ func TestParseAndRunHyphenValues(t *testing.T) {
for _, tc := range cases {
tc := tc
- t.Run(strings.Join(tc.testArgs, "_"), func(t *testing.T){
+ t.Run(strings.Join(tc.testArgs, "_"), func(t *testing.T) {
var (
args []string
- opt string
+ opt string
)
cmd := Command{
@@ -171,8 +171,8 @@ func TestParseAndRunHyphenValues(t *testing.T) {
return nil
},
Flags: []Flag{
- StringFlag{Name: "opt"},
- StringFlag{Name: "opt2"},
+ StringFlag{Name: "opt"},
+ StringFlag{Name: "opt2"},
},
}
@@ -436,6 +436,11 @@ func TestCommandSkipFlagParsing(t *testing.T) {
Flags: []Flag{
StringFlag{Name: "flag"},
},
+ Subcommands: []Command{
+ {
+ Name: "some-arg",
+ },
+ },
Action: func(c *Context) {
fmt.Printf("%+v\n", c.String("flag"))
args = c.Args()
diff --git a/debian/changelog b/debian/changelog
index bf9029a..e7698c8 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+golang-github-urfave-cli (1.22.12-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+ * New upstream release.
+ * Drop patch 0001-go-md2man-v2.0.1-compatibility.patch, present upstream.
+
+ -- Debian Janitor <janitor@jelmer.uk> Sat, 18 Mar 2023 00:12:41 -0000
+
golang-github-urfave-cli (1.22.9-2) unstable; urgency=medium
* Team upload
diff --git a/debian/patches/0001-go-md2man-v2.0.1-compatibility.patch b/debian/patches/0001-go-md2man-v2.0.1-compatibility.patch
deleted file mode 100644
index d58205b..0000000
--- a/debian/patches/0001-go-md2man-v2.0.1-compatibility.patch
+++ /dev/null
@@ -1,93 +0,0 @@
-From: Shengjing Zhu <zhsj@debian.org>
-Date: Thu, 16 Jun 2022 23:34:34 +0800
-Subject: go-md2man v2.0.1 compatibility
-
-Origin: backport, https://github.com/urfave/cli/pull/1321
----
- testdata/expected-doc-full.man | 28 ++++++++++++++--------------
- 1 file changed, 14 insertions(+), 14 deletions(-)
-
-diff --git a/testdata/expected-doc-full.man b/testdata/expected-doc-full.man
-index 5190698..ce75939 100644
---- a/testdata/expected-doc-full.man
-+++ b/testdata/expected-doc-full.man
-@@ -5,7 +5,7 @@
-
- .SH NAME
- .PP
--greet \- Some app
-+greet - Some app
-
-
- .SH SYNOPSIS
-@@ -16,9 +16,9 @@ greet
- .RS
-
- .nf
--[\-\-another\-flag|\-b]
--[\-\-flag|\-\-fl|\-f]=[value]
--[\-\-socket|\-s]=[value]
-+[--another-flag|-b]
-+[--flag|--fl|-f]=[value]
-+[--socket|-s]=[value]
-
- .fi
- .RE
-@@ -26,7 +26,7 @@ greet
-
- .SH DESCRIPTION
- .PP
--app [first\_arg] [second\_arg]
-+app [first_arg] [second_arg]
-
- .PP
- \fBUsage\fP:
-@@ -43,13 +43,13 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
-
- .SH GLOBAL OPTIONS
- .PP
--\fB\-\-another\-flag, \-b\fP: another usage text
-+\fB--another-flag, -b\fP: another usage text
-
- .PP
--\fB\-\-flag, \-\-fl, \-f\fP="":
-+\fB--flag, --fl, -f\fP="":
-
- .PP
--\fB\-\-socket, \-s\fP="": some 'usage' text (default: value)
-+\fB--socket, -s\fP="": some 'usage' text (default: value)
-
-
- .SH COMMANDS
-@@ -58,23 +58,23 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
- another usage test
-
- .PP
--\fB\-\-another\-flag, \-b\fP: another usage text
-+\fB--another-flag, -b\fP: another usage text
-
- .PP
--\fB\-\-flag, \-\-fl, \-f\fP="":
-+\fB--flag, --fl, -f\fP="":
-
--.SS sub\-config, s, ss
-+.SS sub-config, s, ss
- .PP
- another usage test
-
- .PP
--\fB\-\-sub\-command\-flag, \-s\fP: some usage text
-+\fB--sub-command-flag, -s\fP: some usage text
-
- .PP
--\fB\-\-sub\-flag, \-\-sub\-fl, \-s\fP="":
-+\fB--sub-flag, --sub-fl, -s\fP="":
-
- .SH info, i, in
- .PP
- retrieve generic information
-
--.SH some\-command
-\ No newline at end of file
-+.SH some-command
-\ No newline at end of file
diff --git a/debian/patches/series b/debian/patches/series
index e2cebcd..e69de29 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +0,0 @@
-0001-go-md2man-v2.0.1-compatibility.patch
diff --git a/docs/v1/manual.md b/docs/v1/manual.md
index cadd937..ec0b4a0 100644
--- a/docs/v1/manual.md
+++ b/docs/v1/manual.md
@@ -27,6 +27,8 @@ cli v1 manual
* [Version Flag](#version-flag)
+ [Customization](#customization-2)
+ [Full API Example](#full-api-example)
+- [Testing](#testing)
+- [Migrating to V2](#migrating-to-v2)
<!-- tocstop -->
@@ -150,16 +152,19 @@ cli also generates neat help text:
```
$ greet help
NAME:
- greet - fight the loneliness!
+ greet - fight the loneliness!
USAGE:
- main [global options] command [command options] [arguments...]
+ greet [global options] command [command options] [arguments...]
+
+VERSION:
+ 0.0.0
COMMANDS:
- help, h Shows a list of commands or help for one command
+ help, h Shows a list of commands or help for one command
-GLOBAL OPTIONS:
- --help, -h show help
+GLOBAL OPTIONS
+ --version Shows version information
```
### Arguments
@@ -1473,3 +1478,205 @@ func wopAction(c *cli.Context) error {
return nil
}
```
+
+## Testing
+
+In addition to testing units build using urfave/cli, a good idea can also be to
+do test the cli itself - a type of integration testing or interface testing.
+The purpose of these test cases can be to detect option clashes or crashing
+subcommands, and not functional correctness of the units. These problems can be
+hard to detect in a large application.
+
+Here is one example of an application with three subcommands and two flags.
+The flags, `offset` and `topic` both have the alias `o` which is not allowed
+in the same subcommand. The problem would only be detected in run-time if we
+didn't have testing.
+
+We start with a small `go.mod` file requiring only urfave/cli and
+stretchr/testify (to simplify test code):
+
+```
+module example.com/mycliapp
+
+go 1.13
+
+require (
+ github.com/stretchr/testify v1.7.0
+ github.com/urfave/cli v1.22.5
+)
+```
+
+The `main.go` file contains a bug in the intialization of `topicflg`
+(around line 59): a duplicated `o` alias. This will make the subcommand
+crash and some tests to fail.
+
+```
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/urfave/cli"
+)
+
+// hw is the simplest for of hello world.
+func hw(ctx *cli.Context) {
+ fmt.Println("Hi.")
+}
+
+// hello has a configurable world.
+func hello(ctx *cli.Context) {
+ fmt.Println("Hello", ctx.String("topic"))
+}
+
+// helloworld allows advanced usage (spaces before output)
+func helloworld(ctx *cli.Context) {
+ topic := ctx.String("topic")
+ offset := ctx.Int64("offset")
+
+ for ; offset > 0; offset-- {
+ fmt.Print(" ")
+ }
+ fmt.Println("Hello", topic)
+}
+
+// offsetflg contains the number of spaces before output
+var offsetflg cli.Int64Flag
+
+// topicflg contains the configurable "world" string
+var topicflg cli.StringFlag
+
+// These are public in order to test them
+
+// HwCmd is the subcommand for hw
+var HwCmd cli.Command
+
+// HelloCmd is the subcommand for hello
+var HelloCmd cli.Command
+
+// HelloWorldCmd is the subcommand for helloworld
+var HelloWorldCmd cli.Command
+
+// init initializes the flags and subcommands
+func init() {
+
+ offsetflg = cli.Int64Flag{
+ Name: "offset, o",
+ Value: 0,
+ Usage: "Space offset",
+ }
+
+ topicflg = cli.StringFlag{
+ Name: "topic, o", // <<--- Please note that o is duplicated
+ Value: "World",
+ Usage: "Hello topic",
+ }
+
+ HwCmd = cli.Command{
+ Name: "hw",
+ Usage: "Just print hi.",
+ Action: hw,
+ }
+
+ HelloCmd = cli.Command{
+ Name: "hello",
+ Usage: "Hello world with customizable topic.",
+ Action: hello,
+ Flags: []cli.Flag{topicflg},
+ }
+
+ HelloWorldCmd = cli.Command{
+ Name: "helloworld",
+ Usage: "Advanced hello with offset and topic.",
+ Action: helloworld,
+ Flags: []cli.Flag{topicflg, offsetflg},
+ }
+}
+
+// main is the application itself
+func main() {
+ app := cli.NewApp()
+ app.Usage = "Example urfave cli app with flag conflicts."
+ app.Commands = cli.Commands{HwCmd, HelloCmd, HelloWorldCmd}
+
+ err := app.Run(os.Args)
+ if err != nil {
+ fmt.Println("ooops...")
+ }
+}
+```
+
+In `main_test.go` we write three simple test cases that does nothing more
+than run a subcommand each and assert that no errors are created:
+
+```
+package main
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/urfave/cli"
+)
+
+func TestHi(t *testing.T) {
+ app := cli.NewApp()
+ app.Commands = cli.Commands{HwCmd}
+ err := app.Run([]string{"appname", "hw"})
+ assert.Nil(t, err, "HW should not return an error")
+}
+
+func TestHello(t *testing.T) {
+ app := cli.NewApp()
+ app.Commands = cli.Commands{HelloCmd}
+ err := app.Run([]string{"appname", "hello"})
+ assert.Nil(t, err, "Hello should not return an error")
+}
+
+func TestHelloWorld(t *testing.T) {
+ app := cli.NewApp()
+ app.Commands = cli.Commands{HelloWorldCmd}
+ err := app.Run([]string{"appname", "helloworld"})
+ assert.Nil(t, err, "Hello World should not return an error")
+}
+```
+
+We can now run and build the application:
+
+```
+perst@R400:~/go-urfave-test-example
+$ go build
+
+$ ./mycliapp hw
+Hi.
+
+$ ./mycliapp hello --topic Moon
+Hello Moon
+
+$ ./mycliapp helloworld --topic Moon --offset 4
+helloworld flag redefined: o
+panic: helloworld flag redefined: o
+[...]
+```
+
+Similarly we can test it with go's `test` subcommand:
+
+```
+$ go test
+[...]
+--- FAIL: TestHelloWorld (0.00s)
+panic: helloworld flag redefined: o [recovered]
+ panic: helloworld flag redefined: o
+[...]
+```
+
+Modifying the `Name` of `topicflg` from `"topic, o"` to `"topic"`
+will repair both the subcommand and the test.
+
+## Migrating to V2
+
+There are a small set of breaking changes between v1 and v2.
+Converting is relatively straightforward and typically takes less than
+an hour. Specific steps are included in
+[Migration Guide: v1 to v2](../migrate-v1-to-v2.md).
diff --git a/docs_test.go b/docs_test.go
index f4bf1c5..f181df5 100644
--- a/docs_test.go
+++ b/docs_test.go
@@ -5,6 +5,8 @@ package cli
import (
"testing"
+
+ "github.com/stretchr/testify/require"
)
func TestToMarkdownFull(t *testing.T) {
@@ -53,6 +55,6 @@ func TestToMan(t *testing.T) {
res, err := app.ToMan()
// Then
- expect(t, err, nil)
+ require.Nil(t, err)
expectFileContent(t, "testdata/expected-doc-full.man", res)
}
diff --git a/fish_test.go b/fish_test.go
index 62313f0..0fe9286 100644
--- a/fish_test.go
+++ b/fish_test.go
@@ -1,8 +1,11 @@
package cli
import (
- "io/ioutil"
+ "os"
+ "strings"
"testing"
+
+ "github.com/stretchr/testify/require"
)
func testApp() *App {
@@ -66,9 +69,10 @@ func testApp() *App {
}
func expectFileContent(t *testing.T, file, expected string) {
- data, err := ioutil.ReadFile(file)
- expect(t, err, nil)
- expect(t, string(data), expected)
+ data, err := os.ReadFile(file)
+ require.Nil(t, err)
+
+ require.Equal(t, strings.ReplaceAll(string(data), "\r\n", "\n"), expected)
}
func TestFishCompletion(t *testing.T) {
diff --git a/go.mod b/go.mod
index 7d04d20..48129b6 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,8 @@ module github.com/urfave/cli
go 1.11
require (
- github.com/BurntSushi/toml v0.3.1
- github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
- gopkg.in/yaml.v2 v2.2.2
+ github.com/BurntSushi/toml v1.2.1
+ github.com/cpuguy83/go-md2man/v2 v2.0.2
+ github.com/stretchr/testify v1.8.1 // indirect
+ gopkg.in/yaml.v2 v2.4.0
)
diff --git a/go.sum b/go.sum
index ef121ff..0bc5ad9 100644
--- a/go.sum
+++ b/go.sum
@@ -1,14 +1,25 @@
-github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
+github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+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/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+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/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/go116_test.go b/go116_test.go
deleted file mode 100644
index f6b5524..0000000
--- a/go116_test.go
+++ /dev/null
@@ -1,28 +0,0 @@
-//go:build !go1.17
-// +build !go1.17
-
-package cli
-
-import (
- "bytes"
- "errors"
- "flag"
- "testing"
-)
-
-func TestApp_RunAsSubCommandIncorrectUsage(t *testing.T) {
- a := App{
- Flags: []Flag{
- StringFlag{Name: "--foo"},
- },
- Writer: bytes.NewBufferString(""),
- }
-
- set := flag.NewFlagSet("", flag.ContinueOnError)
- _ = set.Parse([]string{"", "---foo"})
- c := &Context{flagSet: set}
-
- err := a.RunAsSubcommand(c)
-
- expect(t, err, errors.New("bad flag syntax: ---foo"))
-}
diff --git a/go117_test.go b/go117_test.go
deleted file mode 100644
index f40ec4e..0000000
--- a/go117_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-//go:build go1.17
-// +build go1.17
-
-package cli
-
-import (
- "bytes"
- "flag"
- "testing"
-)
-
-func TestApp_RunAsSubCommandIncorrectUsage(t *testing.T) {
- a := App{
- Flags: []Flag{
- StringFlag{Name: "--foo"},
- },
- Writer: bytes.NewBufferString(""),
- }
-
- set := flag.NewFlagSet("", flag.ContinueOnError)
- _ = set.Parse([]string{"", "---foo"})
- c := &Context{flagSet: set}
-
- // Go 1.17+ panics when invalid flag is given.
- // Catch it here and consider the test passed.
- defer func() {
- if err := recover(); err == nil {
- t.Fatal("expected error, got nothing")
- }
- }()
-
- _ = a.RunAsSubcommand(c)
-}
diff --git a/helpers_unix_test.go b/helpers_unix_test.go
index ae27fc5..207925c 100644
--- a/helpers_unix_test.go
+++ b/helpers_unix_test.go
@@ -1,3 +1,4 @@
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
// +build darwin dragonfly freebsd linux netbsd openbsd solaris
package cli
diff --git a/testdata/expected-doc-full.man b/testdata/expected-doc-full.man
index 5190698..ce75939 100644
--- a/testdata/expected-doc-full.man
+++ b/testdata/expected-doc-full.man
@@ -5,7 +5,7 @@
.SH NAME
.PP
-greet \- Some app
+greet - Some app
.SH SYNOPSIS
@@ -16,9 +16,9 @@ greet
.RS
.nf
-[\-\-another\-flag|\-b]
-[\-\-flag|\-\-fl|\-f]=[value]
-[\-\-socket|\-s]=[value]
+[--another-flag|-b]
+[--flag|--fl|-f]=[value]
+[--socket|-s]=[value]
.fi
.RE
@@ -26,7 +26,7 @@ greet
.SH DESCRIPTION
.PP
-app [first\_arg] [second\_arg]
+app [first_arg] [second_arg]
.PP
\fBUsage\fP:
@@ -43,13 +43,13 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
.SH GLOBAL OPTIONS
.PP
-\fB\-\-another\-flag, \-b\fP: another usage text
+\fB--another-flag, -b\fP: another usage text
.PP
-\fB\-\-flag, \-\-fl, \-f\fP="":
+\fB--flag, --fl, -f\fP="":
.PP
-\fB\-\-socket, \-s\fP="": some 'usage' text (default: value)
+\fB--socket, -s\fP="": some 'usage' text (default: value)
.SH COMMANDS
@@ -58,23 +58,23 @@ greet [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
another usage test
.PP
-\fB\-\-another\-flag, \-b\fP: another usage text
+\fB--another-flag, -b\fP: another usage text
.PP
-\fB\-\-flag, \-\-fl, \-f\fP="":
+\fB--flag, --fl, -f\fP="":
-.SS sub\-config, s, ss
+.SS sub-config, s, ss
.PP
another usage test
.PP
-\fB\-\-sub\-command\-flag, \-s\fP: some usage text
+\fB--sub-command-flag, -s\fP: some usage text
.PP
-\fB\-\-sub\-flag, \-\-sub\-fl, \-s\fP="":
+\fB--sub-flag, --sub-fl, -s\fP="":
.SH info, i, in
.PP
retrieve generic information
-.SH some\-command
\ No newline at end of file
+.SH some-command
\ No newline at end of file
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/share/gocode/src/github.com/urfave/cli/go116_test.go -rw-r--r-- root/root /usr/share/gocode/src/github.com/urfave/cli/go117_test.go
No differences were encountered in the control files