Merge branch 'master' into patch-1
This commit is contained in:
commit
efad8c4d92
9
.github/workflows/cli.yml
vendored
9
.github/workflows/cli.yml
vendored
@ -46,19 +46,20 @@ jobs:
|
||||
chmod +x $GOPATH/bin/gfmrun
|
||||
npm install markdown-toc
|
||||
|
||||
- name: Run Tests (v1)
|
||||
if: contains(github.base_ref, 'v1')
|
||||
- name: Run Tests
|
||||
run: |
|
||||
go run build.go vet
|
||||
go run build.go test
|
||||
|
||||
- name: Run Tests (v1)
|
||||
if: contains(github.base_ref, 'v1')
|
||||
run: |
|
||||
go run build.go gfmrun docs/v1/manual.md
|
||||
go run build.go toc docs/v1/manual.md
|
||||
|
||||
- name: Run Tests (v2)
|
||||
if: contains(github.base_ref, 'master')
|
||||
run: |
|
||||
go run build.go vet
|
||||
go run build.go test
|
||||
go run build.go gfmrun docs/v2/manual.md
|
||||
go run build.go toc docs/v2/manual.md
|
||||
|
||||
|
@ -28,6 +28,9 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
||||
if parentCtx != nil {
|
||||
c.Context = parentCtx.Context
|
||||
c.shellComplete = parentCtx.shellComplete
|
||||
if parentCtx.flagSet == nil {
|
||||
parentCtx.flagSet = &flag.FlagSet{}
|
||||
}
|
||||
}
|
||||
|
||||
c.Command = &Command{}
|
||||
|
@ -344,6 +344,81 @@ func TestContextPropagation(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextAttributeAccessing(t *testing.T) {
|
||||
tdata := []struct {
|
||||
testCase string
|
||||
setBoolInput string
|
||||
ctxBoolInput string
|
||||
newContextInput *Context
|
||||
}{
|
||||
{
|
||||
testCase: "empty",
|
||||
setBoolInput: "",
|
||||
ctxBoolInput: "",
|
||||
newContextInput: nil,
|
||||
},
|
||||
{
|
||||
testCase: "empty_with_background_context",
|
||||
setBoolInput: "",
|
||||
ctxBoolInput: "",
|
||||
newContextInput: &Context{Context: context.Background()},
|
||||
},
|
||||
{
|
||||
testCase: "empty_set_bool_and_present_ctx_bool",
|
||||
setBoolInput: "",
|
||||
ctxBoolInput: "ctx-bool",
|
||||
newContextInput: nil,
|
||||
},
|
||||
{
|
||||
testCase: "present_set_bool_and_present_ctx_bool_with_background_context",
|
||||
setBoolInput: "",
|
||||
ctxBoolInput: "ctx-bool",
|
||||
newContextInput: &Context{Context: context.Background()},
|
||||
},
|
||||
{
|
||||
testCase: "present_set_bool_and_present_ctx_bool",
|
||||
setBoolInput: "ctx-bool",
|
||||
ctxBoolInput: "ctx-bool",
|
||||
newContextInput: nil,
|
||||
},
|
||||
{
|
||||
testCase: "present_set_bool_and_present_ctx_bool_with_background_context",
|
||||
setBoolInput: "ctx-bool",
|
||||
ctxBoolInput: "ctx-bool",
|
||||
newContextInput: &Context{Context: context.Background()},
|
||||
},
|
||||
{
|
||||
testCase: "present_set_bool_and_different_ctx_bool",
|
||||
setBoolInput: "ctx-bool",
|
||||
ctxBoolInput: "not-ctx-bool",
|
||||
newContextInput: nil,
|
||||
},
|
||||
{
|
||||
testCase: "present_set_bool_and_different_ctx_bool_with_background_context",
|
||||
setBoolInput: "ctx-bool",
|
||||
ctxBoolInput: "not-ctx-bool",
|
||||
newContextInput: &Context{Context: context.Background()},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tdata {
|
||||
t.Run(test.testCase, func(t *testing.T) {
|
||||
// setup
|
||||
set := flag.NewFlagSet("some-flag-set-name", 0)
|
||||
set.Bool(test.setBoolInput, false, "usage documentation")
|
||||
ctx := NewContext(nil, set, test.newContextInput)
|
||||
|
||||
// logic under test
|
||||
value := ctx.Bool(test.ctxBoolInput)
|
||||
|
||||
// assertions
|
||||
if value != false {
|
||||
t.Errorf("expected \"value\" to be false, but it was not")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckRequiredFlags(t *testing.T) {
|
||||
tdata := []struct {
|
||||
testCase string
|
||||
|
@ -6,6 +6,12 @@
|
||||
|
||||
View [unreleased 2.X] series changes.
|
||||
|
||||
## [2.1.1] - 2019-12-24
|
||||
|
||||
### Fixed
|
||||
|
||||
* Fixed a `Context` regression introduced in `v2.1.0` in [urfave/cli/pull/1014](https://github.com/urfave/cli/pull/1014) via [@lynncyrin](https://github.com/lynncyrin)
|
||||
|
||||
## [2.1.0] - 2019-12-24
|
||||
|
||||
These release notes were written for the git hash [ae84df4cef4a2a6f1a0cb1d41ea0f3af8755e5a8](https://github.com/urfave/cli/tree/ae84df4cef4a2a6f1a0cb1d41ea0f3af8755e5a8)
|
||||
@ -541,7 +547,8 @@ signature of `func(*cli.Context) error`, as defined by `cli.ActionFunc`.
|
||||
### Added
|
||||
- Initial implementation.
|
||||
|
||||
[unreleased 2.X]: https://github.com/urfave/cli/compare/v2.1.0...HEAD
|
||||
[unreleased 2.X]: https://github.com/urfave/cli/compare/v2.1.1...HEAD
|
||||
[2.1.1]: https://github.com/urfave/cli/compare/v2.1.0...v2.1.1
|
||||
[2.1.0]: https://github.com/urfave/cli/compare/v2.0.0...v2.1.0
|
||||
[2.0.0]: https://github.com/urfave/cli/compare/v1.22.2...v2.0.0
|
||||
|
||||
|
@ -13,6 +13,7 @@ cli v2 manual
|
||||
+ [Values from the Environment](#values-from-the-environment)
|
||||
+ [Values from files](#values-from-files)
|
||||
+ [Values from alternate input sources (YAML, TOML, and others)](#values-from-alternate-input-sources-yaml-toml-and-others)
|
||||
+ [Required Flags](#required-flags)
|
||||
+ [Default Values for help output](#default-values-for-help-output)
|
||||
+ [Precedence](#precedence)
|
||||
* [Subcommands](#subcommands)
|
||||
@ -641,6 +642,63 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
#### Required Flags
|
||||
|
||||
You can make a flag required by setting the `Required` field to `true`. If a user
|
||||
does not provide a required flag, they will be shown an error message.
|
||||
|
||||
Take for example this app that reqiures the `lang` flag:
|
||||
|
||||
<!-- {
|
||||
"error": "Required flag \"lang\" not set"
|
||||
} -->
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := cli.NewApp()
|
||||
|
||||
app.Flags = []cli.Flag {
|
||||
cli.StringFlag{
|
||||
Name: "lang",
|
||||
Value: "english",
|
||||
Usage: "language for the greeting",
|
||||
Required: true,
|
||||
},
|
||||
}
|
||||
|
||||
app.Action = func(c *cli.Context) error {
|
||||
var output string
|
||||
if c.String("lang") == "spanish" {
|
||||
output = "Hola"
|
||||
} else {
|
||||
output = "Hello"
|
||||
}
|
||||
fmt.Println(output)
|
||||
return nil
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If the app is run without the `lang` flag, the user will see the following message
|
||||
|
||||
```
|
||||
Required flag "lang" not set
|
||||
```
|
||||
|
||||
#### Default Values for help output
|
||||
|
||||
Sometimes it's useful to specify a flag's default help-text value within the flag declaration. This can be useful if the default value for a flag is a computed value. The default value can be set via the `DefaultText` struct field.
|
||||
@ -1447,13 +1505,15 @@ func main() {
|
||||
cli.ShowVersion(c)
|
||||
|
||||
fmt.Printf("%#v\n", c.App.Command("doo"))
|
||||
if c.Bool("infinite") {
|
||||
c.App.Run([]string{"app", "doo", "wop"})
|
||||
}
|
||||
// // uncomment when https://github.com/urfave/cli/pull/1014 is released
|
||||
// if c.Bool("infinite") {
|
||||
// c.App.Run([]string{"app", "doo", "wop"})
|
||||
// }
|
||||
|
||||
if c.Bool("forevar") {
|
||||
c.App.RunAsSubcommand(c)
|
||||
}
|
||||
// // uncomment when https://github.com/urfave/cli/pull/1014 is released
|
||||
// if c.Bool("forevar") {
|
||||
// c.App.RunAsSubcommand(c)
|
||||
// }
|
||||
c.App.Setup()
|
||||
fmt.Printf("%#v\n", c.App.VisibleCategories())
|
||||
fmt.Printf("%#v\n", c.App.VisibleCommands())
|
||||
@ -1469,28 +1529,29 @@ func main() {
|
||||
set := flag.NewFlagSet("contrive", 0)
|
||||
nc := cli.NewContext(c.App, set, c)
|
||||
|
||||
fmt.Printf("%#v\n", nc.Args())
|
||||
fmt.Printf("%#v\n", nc.Bool("nope"))
|
||||
fmt.Printf("%#v\n", !nc.Bool("nerp"))
|
||||
fmt.Printf("%#v\n", nc.Duration("howlong"))
|
||||
fmt.Printf("%#v\n", nc.Float64("hay"))
|
||||
fmt.Printf("%#v\n", nc.Generic("bloop"))
|
||||
fmt.Printf("%#v\n", nc.Int64("bonk"))
|
||||
fmt.Printf("%#v\n", nc.Int64Slice("burnks"))
|
||||
fmt.Printf("%#v\n", nc.Int("bips"))
|
||||
fmt.Printf("%#v\n", nc.IntSlice("blups"))
|
||||
fmt.Printf("%#v\n", nc.String("snurt"))
|
||||
fmt.Printf("%#v\n", nc.StringSlice("snurkles"))
|
||||
fmt.Printf("%#v\n", nc.Uint("flub"))
|
||||
fmt.Printf("%#v\n", nc.Uint64("florb"))
|
||||
|
||||
fmt.Printf("%#v\n", nc.FlagNames())
|
||||
fmt.Printf("%#v\n", nc.IsSet("wat"))
|
||||
fmt.Printf("%#v\n", nc.Set("wat", "nope"))
|
||||
fmt.Printf("%#v\n", nc.NArg())
|
||||
fmt.Printf("%#v\n", nc.NumFlags())
|
||||
fmt.Printf("%#v\n", nc.Lineage()[1])
|
||||
// // uncomment when https://github.com/urfave/cli/pull/1014 is released
|
||||
// fmt.Printf("%#v\n", nc.Args())
|
||||
// fmt.Printf("%#v\n", nc.Bool("nope"))
|
||||
// fmt.Printf("%#v\n", !nc.Bool("nerp"))
|
||||
// fmt.Printf("%#v\n", nc.Duration("howlong"))
|
||||
// fmt.Printf("%#v\n", nc.Float64("hay"))
|
||||
// fmt.Printf("%#v\n", nc.Generic("bloop"))
|
||||
// fmt.Printf("%#v\n", nc.Int64("bonk"))
|
||||
// fmt.Printf("%#v\n", nc.Int64Slice("burnks"))
|
||||
// fmt.Printf("%#v\n", nc.Int("bips"))
|
||||
// fmt.Printf("%#v\n", nc.IntSlice("blups"))
|
||||
// fmt.Printf("%#v\n", nc.String("snurt"))
|
||||
// fmt.Printf("%#v\n", nc.StringSlice("snurkles"))
|
||||
// fmt.Printf("%#v\n", nc.Uint("flub"))
|
||||
// fmt.Printf("%#v\n", nc.Uint64("florb"))
|
||||
|
||||
// // uncomment when https://github.com/urfave/cli/pull/1014 is released
|
||||
// fmt.Printf("%#v\n", nc.FlagNames())
|
||||
// fmt.Printf("%#v\n", nc.IsSet("wat"))
|
||||
// fmt.Printf("%#v\n", nc.Set("wat", "nope"))
|
||||
// fmt.Printf("%#v\n", nc.NArg())
|
||||
// fmt.Printf("%#v\n", nc.NumFlags())
|
||||
// fmt.Printf("%#v\n", nc.Lineage()[1])
|
||||
nc.Set("wat", "also-nope")
|
||||
|
||||
ec := cli.Exit("ohwell", 86)
|
||||
|
Loading…
Reference in New Issue
Block a user