1package cli
2
3import (
4	"flag"
5	"fmt"
6	"strconv"
7)
8
9// BoolFlag is a flag with type bool
10type BoolFlag struct {
11	Name        string
12	Usage       string
13	EnvVar      string
14	FilePath    string
15	Required    bool
16	Hidden      bool
17	Destination *bool
18}
19
20// String returns a readable representation of this value
21// (for usage defaults)
22func (f BoolFlag) String() string {
23	return FlagStringer(f)
24}
25
26// GetName returns the name of the flag
27func (f BoolFlag) GetName() string {
28	return f.Name
29}
30
31// IsRequired returns whether or not the flag is required
32func (f BoolFlag) IsRequired() bool {
33	return f.Required
34}
35
36// TakesValue returns true of the flag takes a value, otherwise false
37func (f BoolFlag) TakesValue() bool {
38	return false
39}
40
41// GetUsage returns the usage string for the flag
42func (f BoolFlag) GetUsage() string {
43	return f.Usage
44}
45
46// GetValue returns the flags value as string representation and an empty
47// string if the flag takes no value at all.
48func (f BoolFlag) GetValue() string {
49	return ""
50}
51
52// Bool looks up the value of a local BoolFlag, returns
53// false if not found
54func (c *Context) Bool(name string) bool {
55	return lookupBool(name, c.flagSet)
56}
57
58// GlobalBool looks up the value of a global BoolFlag, returns
59// false if not found
60func (c *Context) GlobalBool(name string) bool {
61	if fs := lookupGlobalFlagSet(name, c); fs != nil {
62		return lookupBool(name, fs)
63	}
64	return false
65}
66
67// Apply populates the flag given the flag set and environment
68// Ignores errors
69func (f BoolFlag) Apply(set *flag.FlagSet) {
70	_ = f.ApplyWithError(set)
71}
72
73// ApplyWithError populates the flag given the flag set and environment
74func (f BoolFlag) ApplyWithError(set *flag.FlagSet) error {
75	val := false
76	if envVal, ok := flagFromFileEnv(f.FilePath, f.EnvVar); ok {
77		if envVal == "" {
78			val = false
79		} else {
80			envValBool, err := strconv.ParseBool(envVal)
81			if err != nil {
82				return fmt.Errorf("could not parse %s as bool value for flag %s: %s", envVal, f.Name, err)
83			}
84			val = envValBool
85		}
86	}
87
88	eachName(f.Name, func(name string) {
89		if f.Destination != nil {
90			set.BoolVar(f.Destination, name, val, f.Usage)
91			return
92		}
93		set.Bool(name, val, f.Usage)
94	})
95
96	return nil
97}
98
99func lookupBool(name string, set *flag.FlagSet) bool {
100	f := set.Lookup(name)
101	if f != nil {
102		parsed, err := strconv.ParseBool(f.Value.String())
103		if err != nil {
104			return false
105		}
106		return parsed
107	}
108	return false
109}
110