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

More details

Full run details