Merge pull request #410 from codegangsta/remove-global-lookups
Remove all Context.Global* methods
This commit is contained in:
commit
9eaa109385
12
CHANGELOG.md
12
CHANGELOG.md
@ -5,6 +5,12 @@
|
|||||||
## 2.0.0 - (unreleased 2.x series)
|
## 2.0.0 - (unreleased 2.x series)
|
||||||
### Added
|
### Added
|
||||||
- `NewStringSlice` and `NewIntSlice` for creating their related types
|
- `NewStringSlice` and `NewIntSlice` for creating their related types
|
||||||
|
- `Context.Lineage` to get all contexts from current up to global
|
||||||
|
- `Context.LocalFlagNames` to get the flag names from *only* the current context
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `Context.FlagNames` now returns all flags in the context lineage
|
||||||
|
- `Context.IsSet` now considers the full context lineage
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- the ability to specify `&StringSlice{...string}` or `&IntSlice{...int}`.
|
- the ability to specify `&StringSlice{...string}` or `&IntSlice{...int}`.
|
||||||
@ -19,6 +25,12 @@
|
|||||||
for this reordering.
|
for this reordering.
|
||||||
- adapter code for deprecated `Action` func signature
|
- adapter code for deprecated `Action` func signature
|
||||||
- deprecated `App.Author`, `App.Email`, and `Command.ShortName` fields
|
- deprecated `App.Author`, `App.Email`, and `Command.ShortName` fields
|
||||||
|
- All `Context.Global*` methods, as the non-global versions now traverse up
|
||||||
|
the context lineage automatically.
|
||||||
|
- `Context.Parent` method, as this is now available via `Context.Lineage`
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `Context.BoolT` now returns `true` when not found
|
||||||
|
|
||||||
## [Unreleased] - (1.x series)
|
## [Unreleased] - (1.x series)
|
||||||
### Added
|
### Added
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
package altsrc
|
package altsrc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
wd, _ = os.Getwd()
|
||||||
|
)
|
||||||
|
|
||||||
func expect(t *testing.T, a interface{}, b interface{}) {
|
func expect(t *testing.T, a interface{}, b interface{}) {
|
||||||
if !reflect.DeepEqual(b, a) {
|
_, fn, line, _ := runtime.Caller(1)
|
||||||
t.Errorf("Expected %#v (type %v) - Got %#v (type %v)", b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
fn = strings.Replace(fn, wd+"/", "", -1)
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(a, b) {
|
||||||
|
t.Errorf("(%s:%d) Expected %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
256
context.go
256
context.go
@ -13,12 +13,11 @@ import (
|
|||||||
// can be used to retrieve context-specific Args and
|
// can be used to retrieve context-specific Args and
|
||||||
// parsed command-line options.
|
// parsed command-line options.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
App *App
|
App *App
|
||||||
Command Command
|
Command Command
|
||||||
flagSet *flag.FlagSet
|
|
||||||
setFlags map[string]bool
|
flagSet *flag.FlagSet
|
||||||
globalSetFlags map[string]bool
|
parentContext *Context
|
||||||
parentContext *Context
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext creates a new context. For use in when invoking an App or Command action.
|
// NewContext creates a new context. For use in when invoking an App or Command action.
|
||||||
@ -28,129 +27,76 @@ func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context {
|
|||||||
|
|
||||||
// Int looks up the value of a local int flag, returns 0 if no int flag exists
|
// Int looks up the value of a local int flag, returns 0 if no int flag exists
|
||||||
func (c *Context) Int(name string) int {
|
func (c *Context) Int(name string) int {
|
||||||
return lookupInt(name, c.flagSet)
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
}
|
|
||||||
|
|
||||||
// Duration looks up the value of a local time.Duration flag, returns 0 if no
|
|
||||||
// time.Duration flag exists
|
|
||||||
func (c *Context) Duration(name string) time.Duration {
|
|
||||||
return lookupDuration(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Float64 looks up the value of a local float64 flag, returns 0 if no float64
|
|
||||||
// flag exists
|
|
||||||
func (c *Context) Float64(name string) float64 {
|
|
||||||
return lookupFloat64(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bool looks up the value of a local bool flag, returns false if no bool flag exists
|
|
||||||
func (c *Context) Bool(name string) bool {
|
|
||||||
return lookupBool(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists
|
|
||||||
func (c *Context) BoolT(name string) bool {
|
|
||||||
return lookupBoolT(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// String looks up the value of a local string flag, returns "" if no string flag exists
|
|
||||||
func (c *Context) String(name string) string {
|
|
||||||
return lookupString(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// StringSlice looks up the value of a local string slice flag, returns nil if no
|
|
||||||
// string slice flag exists
|
|
||||||
func (c *Context) StringSlice(name string) []string {
|
|
||||||
return lookupStringSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IntSlice looks up the value of a local int slice flag, returns nil if no int
|
|
||||||
// slice flag exists
|
|
||||||
func (c *Context) IntSlice(name string) []int {
|
|
||||||
return lookupIntSlice(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic looks up the value of a local generic flag, returns nil if no generic
|
|
||||||
// flag exists
|
|
||||||
func (c *Context) Generic(name string) interface{} {
|
|
||||||
return lookupGeneric(name, c.flagSet)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalInt looks up the value of a global int flag, returns 0 if no int flag exists
|
|
||||||
func (c *Context) GlobalInt(name string) int {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupInt(name, fs)
|
return lookupInt(name, fs)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalFloat64 looks up the value of a global float64 flag, returns float64(0)
|
// Duration looks up the value of a local time.Duration flag, returns 0 if no
|
||||||
// if no float64 flag exists
|
// time.Duration flag exists
|
||||||
func (c *Context) GlobalFloat64(name string) float64 {
|
func (c *Context) Duration(name string) time.Duration {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
return lookupFloat64(name, fs)
|
|
||||||
}
|
|
||||||
return float64(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GlobalDuration looks up the value of a global time.Duration flag, returns 0
|
|
||||||
// if no time.Duration flag exists
|
|
||||||
func (c *Context) GlobalDuration(name string) time.Duration {
|
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupDuration(name, fs)
|
return lookupDuration(name, fs)
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalBool looks up the value of a global bool flag, returns false if no bool
|
// Float64 looks up the value of a local float64 flag, returns 0 if no float64
|
||||||
// flag exists
|
// flag exists
|
||||||
func (c *Context) GlobalBool(name string) bool {
|
func (c *Context) Float64(name string) float64 {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
|
return lookupFloat64(name, fs)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bool looks up the value of a local bool flag, returns false if no bool flag exists
|
||||||
|
func (c *Context) Bool(name string) bool {
|
||||||
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
return lookupBool(name, fs)
|
return lookupBool(name, fs)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalBoolT looks up the value of a global bool flag, returns true if no bool
|
// BoolT looks up the value of a local boolT flag, returns false if no bool flag exists
|
||||||
// flag exists
|
func (c *Context) BoolT(name string) bool {
|
||||||
func (c *Context) GlobalBoolT(name string) bool {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupBoolT(name, fs)
|
return lookupBoolT(name, fs)
|
||||||
}
|
}
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalString looks up the value of a global string flag, returns "" if no
|
// String looks up the value of a local string flag, returns "" if no string flag exists
|
||||||
// string flag exists
|
func (c *Context) String(name string) string {
|
||||||
func (c *Context) GlobalString(name string) string {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
|
||||||
return lookupString(name, fs)
|
return lookupString(name, fs)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalStringSlice looks up the value of a global string slice flag, returns
|
// StringSlice looks up the value of a local string slice flag, returns nil if no
|
||||||
// nil if no string slice flag exists
|
// string slice flag exists
|
||||||
func (c *Context) GlobalStringSlice(name string) []string {
|
func (c *Context) StringSlice(name string) []string {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
return lookupStringSlice(name, fs)
|
return lookupStringSlice(name, fs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalIntSlice looks up the value of a global int slice flag, returns nil if
|
// IntSlice looks up the value of a local int slice flag, returns nil if no int
|
||||||
// no int slice flag exists
|
// slice flag exists
|
||||||
func (c *Context) GlobalIntSlice(name string) []int {
|
func (c *Context) IntSlice(name string) []int {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
return lookupIntSlice(name, fs)
|
return lookupIntSlice(name, fs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalGeneric looks up the value of a global generic flag, returns nil if no
|
// Generic looks up the value of a local generic flag, returns nil if no generic
|
||||||
// generic flag exists
|
// flag exists
|
||||||
func (c *Context) GlobalGeneric(name string) interface{} {
|
func (c *Context) Generic(name string) interface{} {
|
||||||
if fs := lookupGlobalFlagSet(name, c); fs != nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
return lookupGeneric(name, fs)
|
return lookupGeneric(name, fs)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -166,66 +112,47 @@ func (c *Context) Set(name, value string) error {
|
|||||||
return c.flagSet.Set(name, value)
|
return c.flagSet.Set(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalSet sets a context flag to a value on the global flagset
|
|
||||||
func (c *Context) GlobalSet(name, value string) error {
|
|
||||||
return globalContext(c).flagSet.Set(name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsSet determines if the flag was actually set
|
// IsSet determines if the flag was actually set
|
||||||
func (c *Context) IsSet(name string) bool {
|
func (c *Context) IsSet(name string) bool {
|
||||||
if c.setFlags == nil {
|
if fs := lookupFlagSet(name, c); fs != nil {
|
||||||
c.setFlags = make(map[string]bool)
|
isSet := false
|
||||||
c.flagSet.Visit(func(f *flag.Flag) {
|
fs.Visit(func(f *flag.Flag) {
|
||||||
c.setFlags[f.Name] = true
|
if f.Name == name {
|
||||||
|
isSet = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
return isSet
|
||||||
}
|
}
|
||||||
return c.setFlags[name] == true
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalIsSet determines if the global flag was actually set
|
// LocalFlagNames returns a slice of flag names used in this context.
|
||||||
func (c *Context) GlobalIsSet(name string) bool {
|
func (c *Context) LocalFlagNames() []string {
|
||||||
if c.globalSetFlags == nil {
|
names := []string{}
|
||||||
c.globalSetFlags = make(map[string]bool)
|
c.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||||
ctx := c
|
return names
|
||||||
if ctx.parentContext != nil {
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
for ; ctx != nil && c.globalSetFlags[name] == false; ctx = ctx.parentContext {
|
|
||||||
ctx.flagSet.Visit(func(f *flag.Flag) {
|
|
||||||
c.globalSetFlags[f.Name] = true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return c.globalSetFlags[name]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlagNames returns a slice of flag names used in this context.
|
// FlagNames returns a slice of flag names used by the this context and all of
|
||||||
func (c *Context) FlagNames() (names []string) {
|
// its parent contexts.
|
||||||
for _, flag := range c.Command.Flags {
|
func (c *Context) FlagNames() []string {
|
||||||
name := strings.Split(flag.GetName(), ",")[0]
|
names := []string{}
|
||||||
if name == "help" {
|
for _, ctx := range c.Lineage() {
|
||||||
continue
|
ctx.flagSet.Visit(makeFlagNameVisitor(&names))
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
}
|
||||||
return
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
// GlobalFlagNames returns a slice of global flag names used by the app.
|
// Lineage returns *this* context and all of its ancestor contexts in order from
|
||||||
func (c *Context) GlobalFlagNames() (names []string) {
|
// child to parent
|
||||||
for _, flag := range c.App.Flags {
|
func (c *Context) Lineage() []*Context {
|
||||||
name := strings.Split(flag.GetName(), ",")[0]
|
lineage := []*Context{}
|
||||||
if name == "help" || name == "version" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
names = append(names, name)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parent returns the parent context, if any
|
for cur := c; cur != nil; cur = cur.parentContext {
|
||||||
func (c *Context) Parent() *Context {
|
lineage = append(lineage, cur)
|
||||||
return c.parentContext
|
}
|
||||||
|
|
||||||
|
return lineage
|
||||||
}
|
}
|
||||||
|
|
||||||
// Args contains apps console arguments
|
// Args contains apps console arguments
|
||||||
@ -278,28 +205,13 @@ func (a Args) Swap(from, to int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func globalContext(ctx *Context) *Context {
|
func lookupFlagSet(name string, ctx *Context) *flag.FlagSet {
|
||||||
if ctx == nil {
|
for _, c := range ctx.Lineage() {
|
||||||
return nil
|
if f := c.flagSet.Lookup(name); f != nil {
|
||||||
}
|
return c.flagSet
|
||||||
|
|
||||||
for {
|
|
||||||
if ctx.parentContext == nil {
|
|
||||||
return ctx
|
|
||||||
}
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func lookupGlobalFlagSet(name string, ctx *Context) *flag.FlagSet {
|
|
||||||
if ctx.parentContext != nil {
|
|
||||||
ctx = ctx.parentContext
|
|
||||||
}
|
|
||||||
for ; ctx != nil; ctx = ctx.parentContext {
|
|
||||||
if f := ctx.flagSet.Lookup(name); f != nil {
|
|
||||||
return ctx.flagSet
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,7 +313,7 @@ func lookupBoolT(name string, set *flag.FlagSet) bool {
|
|||||||
return val
|
return val
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) {
|
||||||
@ -445,3 +357,21 @@ func normalizeFlags(flags []Flag, set *flag.FlagSet) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeFlagNameVisitor(names *[]string) func(*flag.Flag) {
|
||||||
|
return func(f *flag.Flag) {
|
||||||
|
nameParts := strings.Split(f.Name, ",")
|
||||||
|
name := strings.TrimSpace(nameParts[0])
|
||||||
|
|
||||||
|
for _, part := range nameParts {
|
||||||
|
part = strings.TrimSpace(part)
|
||||||
|
if len(part) > len(name) {
|
||||||
|
name = part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if name != "" {
|
||||||
|
(*names) = append(*names, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
226
context_test.go
226
context_test.go
@ -2,6 +2,7 @@ package cli
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -19,8 +20,6 @@ func TestNewContext(t *testing.T) {
|
|||||||
c.Command = command
|
c.Command = command
|
||||||
expect(t, c.Int("myflag"), 12)
|
expect(t, c.Int("myflag"), 12)
|
||||||
expect(t, c.Float64("myflag64"), float64(17))
|
expect(t, c.Float64("myflag64"), float64(17))
|
||||||
expect(t, c.GlobalInt("myflag"), 42)
|
|
||||||
expect(t, c.GlobalFloat64("myflag64"), float64(47))
|
|
||||||
expect(t, c.Command.Name, "mycommand")
|
expect(t, c.Command.Name, "mycommand")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,14 +30,6 @@ func TestContext_Int(t *testing.T) {
|
|||||||
expect(t, c.Int("myflag"), 12)
|
expect(t, c.Int("myflag"), 12)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_GlobalInt(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
set.Int("myflag", 12, "doc")
|
|
||||||
c := NewContext(nil, set, nil)
|
|
||||||
expect(t, c.GlobalInt("myflag"), 12)
|
|
||||||
expect(t, c.GlobalInt("nope"), 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Float64(t *testing.T) {
|
func TestContext_Float64(t *testing.T) {
|
||||||
set := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
set.Float64("myflag", float64(17), "doc")
|
set.Float64("myflag", float64(17), "doc")
|
||||||
@ -46,14 +37,6 @@ func TestContext_Float64(t *testing.T) {
|
|||||||
expect(t, c.Float64("myflag"), float64(17))
|
expect(t, c.Float64("myflag"), float64(17))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_GlobalFloat64(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
set.Float64("myflag", float64(17), "doc")
|
|
||||||
c := NewContext(nil, set, nil)
|
|
||||||
expect(t, c.GlobalFloat64("myflag"), float64(17))
|
|
||||||
expect(t, c.GlobalFloat64("nope"), float64(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Duration(t *testing.T) {
|
func TestContext_Duration(t *testing.T) {
|
||||||
set := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
set.Duration("myflag", time.Duration(12*time.Second), "doc")
|
set.Duration("myflag", time.Duration(12*time.Second), "doc")
|
||||||
@ -82,30 +65,6 @@ func TestContext_BoolT(t *testing.T) {
|
|||||||
expect(t, c.BoolT("myflag"), true)
|
expect(t, c.BoolT("myflag"), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_GlobalBool(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
|
|
||||||
globalSet := flag.NewFlagSet("test-global", 0)
|
|
||||||
globalSet.Bool("myflag", false, "doc")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
expect(t, c.GlobalBool("myflag"), false)
|
|
||||||
expect(t, c.GlobalBool("nope"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_GlobalBoolT(t *testing.T) {
|
|
||||||
set := flag.NewFlagSet("test", 0)
|
|
||||||
|
|
||||||
globalSet := flag.NewFlagSet("test-global", 0)
|
|
||||||
globalSet.Bool("myflag", true, "doc")
|
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
|
||||||
|
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
expect(t, c.GlobalBoolT("myflag"), true)
|
|
||||||
expect(t, c.GlobalBoolT("nope"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Args(t *testing.T) {
|
func TestContext_Args(t *testing.T) {
|
||||||
set := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
set.Bool("myflag", false, "doc")
|
set.Bool("myflag", false, "doc")
|
||||||
@ -125,37 +84,22 @@ func TestContext_NArg(t *testing.T) {
|
|||||||
|
|
||||||
func TestContext_IsSet(t *testing.T) {
|
func TestContext_IsSet(t *testing.T) {
|
||||||
set := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
set.Bool("myflag", false, "doc")
|
set.Bool("one-flag", false, "doc")
|
||||||
set.String("otherflag", "hello world", "doc")
|
set.Bool("two-flag", false, "doc")
|
||||||
globalSet := flag.NewFlagSet("test", 0)
|
set.String("three-flag", "hello world", "doc")
|
||||||
globalSet.Bool("myflagGlobal", true, "doc")
|
parentSet := flag.NewFlagSet("test", 0)
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
parentSet.Bool("top-flag", true, "doc")
|
||||||
c := NewContext(nil, set, globalCtx)
|
parentCtx := NewContext(nil, parentSet, nil)
|
||||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
ctx := NewContext(nil, set, parentCtx)
|
||||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
|
||||||
expect(t, c.IsSet("myflag"), true)
|
|
||||||
expect(t, c.IsSet("otherflag"), false)
|
|
||||||
expect(t, c.IsSet("bogusflag"), false)
|
|
||||||
expect(t, c.IsSet("myflagGlobal"), false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_GlobalIsSet(t *testing.T) {
|
set.Parse([]string{"--one-flag", "--two-flag", "--three-flag", "frob"})
|
||||||
set := flag.NewFlagSet("test", 0)
|
parentSet.Parse([]string{"--top-flag"})
|
||||||
set.Bool("myflag", false, "doc")
|
|
||||||
set.String("otherflag", "hello world", "doc")
|
expect(t, ctx.IsSet("one-flag"), true)
|
||||||
globalSet := flag.NewFlagSet("test", 0)
|
expect(t, ctx.IsSet("two-flag"), true)
|
||||||
globalSet.Bool("myflagGlobal", true, "doc")
|
expect(t, ctx.IsSet("three-flag"), true)
|
||||||
globalSet.Bool("myflagGlobalUnset", true, "doc")
|
expect(t, ctx.IsSet("top-flag"), true)
|
||||||
globalCtx := NewContext(nil, globalSet, nil)
|
expect(t, ctx.IsSet("bogus"), false)
|
||||||
c := NewContext(nil, set, globalCtx)
|
|
||||||
set.Parse([]string{"--myflag", "bat", "baz"})
|
|
||||||
globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"})
|
|
||||||
expect(t, c.GlobalIsSet("myflag"), false)
|
|
||||||
expect(t, c.GlobalIsSet("otherflag"), false)
|
|
||||||
expect(t, c.GlobalIsSet("bogusflag"), false)
|
|
||||||
expect(t, c.GlobalIsSet("myflagGlobal"), true)
|
|
||||||
expect(t, c.GlobalIsSet("myflagGlobalUnset"), false)
|
|
||||||
expect(t, c.GlobalIsSet("bogusGlobal"), false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_NumFlags(t *testing.T) {
|
func TestContext_NumFlags(t *testing.T) {
|
||||||
@ -171,62 +115,6 @@ func TestContext_NumFlags(t *testing.T) {
|
|||||||
expect(t, c.NumFlags(), 2)
|
expect(t, c.NumFlags(), 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_GlobalFlag(t *testing.T) {
|
|
||||||
var globalFlag string
|
|
||||||
var globalFlagSet bool
|
|
||||||
app := NewApp()
|
|
||||||
app.Flags = []Flag{
|
|
||||||
StringFlag{Name: "global, g", Usage: "global"},
|
|
||||||
}
|
|
||||||
app.Action = func(c *Context) error {
|
|
||||||
globalFlag = c.GlobalString("global")
|
|
||||||
globalFlagSet = c.GlobalIsSet("global")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
app.Run([]string{"command", "-g", "foo"})
|
|
||||||
expect(t, globalFlag, "foo")
|
|
||||||
expect(t, globalFlagSet, true)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_GlobalFlagsInSubcommands(t *testing.T) {
|
|
||||||
subcommandRun := false
|
|
||||||
parentFlag := false
|
|
||||||
app := NewApp()
|
|
||||||
|
|
||||||
app.Flags = []Flag{
|
|
||||||
BoolFlag{Name: "debug, d", Usage: "Enable debugging"},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Commands = []Command{
|
|
||||||
{
|
|
||||||
Name: "foo",
|
|
||||||
Flags: []Flag{
|
|
||||||
BoolFlag{Name: "parent, p", Usage: "Parent flag"},
|
|
||||||
},
|
|
||||||
Subcommands: []Command{
|
|
||||||
{
|
|
||||||
Name: "bar",
|
|
||||||
Action: func(c *Context) error {
|
|
||||||
if c.GlobalBool("debug") {
|
|
||||||
subcommandRun = true
|
|
||||||
}
|
|
||||||
if c.GlobalBool("parent") {
|
|
||||||
parentFlag = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
app.Run([]string{"command", "-d", "foo", "-p", "bar"})
|
|
||||||
|
|
||||||
expect(t, subcommandRun, true)
|
|
||||||
expect(t, parentFlag, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestContext_Set(t *testing.T) {
|
func TestContext_Set(t *testing.T) {
|
||||||
set := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
set.Int("int", 5, "an int")
|
set.Int("int", 5, "an int")
|
||||||
@ -236,21 +124,73 @@ func TestContext_Set(t *testing.T) {
|
|||||||
expect(t, c.Int("int"), 1)
|
expect(t, c.Int("int"), 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContext_GlobalSet(t *testing.T) {
|
func TestContext_LocalFlagNames(t *testing.T) {
|
||||||
gSet := flag.NewFlagSet("test", 0)
|
set := flag.NewFlagSet("test", 0)
|
||||||
gSet.Int("int", 5, "an int")
|
set.Bool("one-flag", false, "doc")
|
||||||
|
set.String("two-flag", "hello world", "doc")
|
||||||
|
parentSet := flag.NewFlagSet("test", 0)
|
||||||
|
parentSet.Bool("top-flag", true, "doc")
|
||||||
|
parentCtx := NewContext(nil, parentSet, nil)
|
||||||
|
ctx := NewContext(nil, set, parentCtx)
|
||||||
|
set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||||
|
parentSet.Parse([]string{"--top-flag"})
|
||||||
|
|
||||||
set := flag.NewFlagSet("sub", 0)
|
actualFlags := ctx.LocalFlagNames()
|
||||||
set.Int("int", 3, "an int")
|
sort.Strings(actualFlags)
|
||||||
|
|
||||||
pc := NewContext(nil, gSet, nil)
|
expect(t, actualFlags, []string{"one-flag", "two-flag"})
|
||||||
c := NewContext(nil, set, pc)
|
}
|
||||||
|
|
||||||
c.Set("int", "1")
|
func TestContext_FlagNames(t *testing.T) {
|
||||||
expect(t, c.Int("int"), 1)
|
set := flag.NewFlagSet("test", 0)
|
||||||
expect(t, c.GlobalInt("int"), 5)
|
set.Bool("one-flag", false, "doc")
|
||||||
|
set.String("two-flag", "hello world", "doc")
|
||||||
c.GlobalSet("int", "1")
|
parentSet := flag.NewFlagSet("test", 0)
|
||||||
expect(t, c.Int("int"), 1)
|
parentSet.Bool("top-flag", true, "doc")
|
||||||
expect(t, c.GlobalInt("int"), 1)
|
parentCtx := NewContext(nil, parentSet, nil)
|
||||||
|
ctx := NewContext(nil, set, parentCtx)
|
||||||
|
set.Parse([]string{"--one-flag", "--two-flag=foo"})
|
||||||
|
parentSet.Parse([]string{"--top-flag"})
|
||||||
|
|
||||||
|
actualFlags := ctx.FlagNames()
|
||||||
|
sort.Strings(actualFlags)
|
||||||
|
|
||||||
|
expect(t, actualFlags, []string{"one-flag", "top-flag", "two-flag"})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext_Lineage(t *testing.T) {
|
||||||
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.Bool("local-flag", false, "doc")
|
||||||
|
parentSet := flag.NewFlagSet("test", 0)
|
||||||
|
parentSet.Bool("top-flag", true, "doc")
|
||||||
|
parentCtx := NewContext(nil, parentSet, nil)
|
||||||
|
ctx := NewContext(nil, set, parentCtx)
|
||||||
|
set.Parse([]string{"--local-flag"})
|
||||||
|
parentSet.Parse([]string{"--top-flag"})
|
||||||
|
|
||||||
|
lineage := ctx.Lineage()
|
||||||
|
expect(t, len(lineage), 2)
|
||||||
|
expect(t, lineage[0], ctx)
|
||||||
|
expect(t, lineage[1], parentCtx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContext_lookupFlagSet(t *testing.T) {
|
||||||
|
set := flag.NewFlagSet("test", 0)
|
||||||
|
set.Bool("local-flag", false, "doc")
|
||||||
|
parentSet := flag.NewFlagSet("test", 0)
|
||||||
|
parentSet.Bool("top-flag", true, "doc")
|
||||||
|
parentCtx := NewContext(nil, parentSet, nil)
|
||||||
|
ctx := NewContext(nil, set, parentCtx)
|
||||||
|
set.Parse([]string{"--local-flag"})
|
||||||
|
parentSet.Parse([]string{"--top-flag"})
|
||||||
|
|
||||||
|
fs := lookupFlagSet("top-flag", ctx)
|
||||||
|
expect(t, fs, parentCtx.flagSet)
|
||||||
|
|
||||||
|
fs = lookupFlagSet("local-flag", ctx)
|
||||||
|
expect(t, fs, ctx.flagSet)
|
||||||
|
|
||||||
|
if fs := lookupFlagSet("frob", ctx); fs != nil {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
help.go
8
help.go
@ -209,7 +209,7 @@ func checkVersion(c *Context) bool {
|
|||||||
found := false
|
found := false
|
||||||
if VersionFlag.Name != "" {
|
if VersionFlag.Name != "" {
|
||||||
eachName(VersionFlag.Name, func(name string) {
|
eachName(VersionFlag.Name, func(name string) {
|
||||||
if c.GlobalBool(name) || c.Bool(name) {
|
if c.Bool(name) {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -221,7 +221,7 @@ func checkHelp(c *Context) bool {
|
|||||||
found := false
|
found := false
|
||||||
if HelpFlag.Name != "" {
|
if HelpFlag.Name != "" {
|
||||||
eachName(HelpFlag.Name, func(name string) {
|
eachName(HelpFlag.Name, func(name string) {
|
||||||
if c.GlobalBool(name) || c.Bool(name) {
|
if c.Bool(name) {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -239,7 +239,7 @@ func checkCommandHelp(c *Context, name string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkSubcommandHelp(c *Context) bool {
|
func checkSubcommandHelp(c *Context) bool {
|
||||||
if c.GlobalBool("h") || c.GlobalBool("help") {
|
if c.Bool("h") || c.Bool("help") {
|
||||||
ShowSubcommandHelp(c)
|
ShowSubcommandHelp(c)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ func checkSubcommandHelp(c *Context) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func checkCompletions(c *Context) bool {
|
func checkCompletions(c *Context) bool {
|
||||||
if (c.GlobalBool(BashCompletionFlag.Name) || c.Bool(BashCompletionFlag.Name)) && c.App.EnableBashCompletion {
|
if c.Bool(BashCompletionFlag.Name) && c.App.EnableBashCompletion {
|
||||||
ShowCompletions(c)
|
ShowCompletions(c)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user