github.com/webwurst/docker@v1.7.0/builder/bflag.go (about) 1 package builder 2 3 import ( 4 "fmt" 5 "strings" 6 ) 7 8 type FlagType int 9 10 const ( 11 boolType FlagType = iota 12 stringType 13 ) 14 15 type BuilderFlags struct { 16 Args []string // actual flags/args from cmd line 17 flags map[string]*Flag 18 used map[string]*Flag 19 Err error 20 } 21 22 type Flag struct { 23 bf *BuilderFlags 24 name string 25 flagType FlagType 26 Value string 27 } 28 29 func NewBuilderFlags() *BuilderFlags { 30 return &BuilderFlags{ 31 flags: make(map[string]*Flag), 32 used: make(map[string]*Flag), 33 } 34 } 35 36 func (bf *BuilderFlags) AddBool(name string, def bool) *Flag { 37 flag := bf.addFlag(name, boolType) 38 if flag == nil { 39 return nil 40 } 41 if def { 42 flag.Value = "true" 43 } else { 44 flag.Value = "false" 45 } 46 return flag 47 } 48 49 func (bf *BuilderFlags) AddString(name string, def string) *Flag { 50 flag := bf.addFlag(name, stringType) 51 if flag == nil { 52 return nil 53 } 54 flag.Value = def 55 return flag 56 } 57 58 func (bf *BuilderFlags) addFlag(name string, flagType FlagType) *Flag { 59 if _, ok := bf.flags[name]; ok { 60 bf.Err = fmt.Errorf("Duplicate flag defined: %s", name) 61 return nil 62 } 63 64 newFlag := &Flag{ 65 bf: bf, 66 name: name, 67 flagType: flagType, 68 } 69 bf.flags[name] = newFlag 70 71 return newFlag 72 } 73 74 func (fl *Flag) IsUsed() bool { 75 if _, ok := fl.bf.used[fl.name]; ok { 76 return true 77 } 78 return false 79 } 80 81 func (fl *Flag) IsTrue() bool { 82 if fl.flagType != boolType { 83 // Should never get here 84 panic(fmt.Errorf("Trying to use IsTrue on a non-boolean: %s", fl.name)) 85 } 86 return fl.Value == "true" 87 } 88 89 func (bf *BuilderFlags) Parse() error { 90 // If there was an error while defining the possible flags 91 // go ahead and bubble it back up here since we didn't do it 92 // earlier in the processing 93 if bf.Err != nil { 94 return fmt.Errorf("Error setting up flags: %s", bf.Err) 95 } 96 97 for _, arg := range bf.Args { 98 if !strings.HasPrefix(arg, "--") { 99 return fmt.Errorf("Arg should start with -- : %s", arg) 100 } 101 102 if arg == "--" { 103 return nil 104 } 105 106 arg = arg[2:] 107 value := "" 108 109 index := strings.Index(arg, "=") 110 if index >= 0 { 111 value = arg[index+1:] 112 arg = arg[:index] 113 } 114 115 flag, ok := bf.flags[arg] 116 if !ok { 117 return fmt.Errorf("Unknown flag: %s", arg) 118 } 119 120 if _, ok = bf.used[arg]; ok { 121 return fmt.Errorf("Duplicate flag specified: %s", arg) 122 } 123 124 bf.used[arg] = flag 125 126 switch flag.flagType { 127 case boolType: 128 // value == "" is only ok if no "=" was specified 129 if index >= 0 && value == "" { 130 return fmt.Errorf("Missing a value on flag: %s", arg) 131 } 132 133 lower := strings.ToLower(value) 134 if lower == "" { 135 flag.Value = "true" 136 } else if lower == "true" || lower == "false" { 137 flag.Value = lower 138 } else { 139 return fmt.Errorf("Expecting boolean value for flag %s, not: %s", arg, value) 140 } 141 142 case stringType: 143 if index < 0 { 144 return fmt.Errorf("Missing a value on flag: %s", arg) 145 } 146 flag.Value = value 147 148 default: 149 panic(fmt.Errorf("No idea what kind of flag we have! Should never get here!")) 150 } 151 152 } 153 154 return nil 155 }