mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
e59327aaac
This change starts the process of splitting up the Builder into logical components. Remove builder.flags and move it to the new dispatchRequest object. Use runConfig from dispatchRequest instead of from the builder. More progress removing things from the Builder struct. Signed-off-by: Daniel Nephin <dnephin@docker.com>
183 lines
4.1 KiB
Go
183 lines
4.1 KiB
Go
package dockerfile
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// FlagType is the type of the build flag
|
|
type FlagType int
|
|
|
|
const (
|
|
boolType FlagType = iota
|
|
stringType
|
|
)
|
|
|
|
// BFlags contains all flags information for the builder
|
|
type BFlags struct {
|
|
Args []string // actual flags/args from cmd line
|
|
flags map[string]*Flag
|
|
used map[string]*Flag
|
|
Err error
|
|
}
|
|
|
|
// Flag contains all information for a flag
|
|
type Flag struct {
|
|
bf *BFlags
|
|
name string
|
|
flagType FlagType
|
|
Value string
|
|
}
|
|
|
|
// NewBFlags returns the new BFlags struct
|
|
func NewBFlags() *BFlags {
|
|
return &BFlags{
|
|
flags: make(map[string]*Flag),
|
|
used: make(map[string]*Flag),
|
|
}
|
|
}
|
|
|
|
// NewBFlagsWithArgs returns the new BFlags struct with Args set to args
|
|
func NewBFlagsWithArgs(args []string) *BFlags {
|
|
flags := NewBFlags()
|
|
flags.Args = args
|
|
return flags
|
|
}
|
|
|
|
// AddBool adds a bool flag to BFlags
|
|
// Note, any error will be generated when Parse() is called (see Parse).
|
|
func (bf *BFlags) AddBool(name string, def bool) *Flag {
|
|
flag := bf.addFlag(name, boolType)
|
|
if flag == nil {
|
|
return nil
|
|
}
|
|
if def {
|
|
flag.Value = "true"
|
|
} else {
|
|
flag.Value = "false"
|
|
}
|
|
return flag
|
|
}
|
|
|
|
// AddString adds a string flag to BFlags
|
|
// Note, any error will be generated when Parse() is called (see Parse).
|
|
func (bf *BFlags) AddString(name string, def string) *Flag {
|
|
flag := bf.addFlag(name, stringType)
|
|
if flag == nil {
|
|
return nil
|
|
}
|
|
flag.Value = def
|
|
return flag
|
|
}
|
|
|
|
// addFlag is a generic func used by the other AddXXX() func
|
|
// to add a new flag to the BFlags struct.
|
|
// Note, any error will be generated when Parse() is called (see Parse).
|
|
func (bf *BFlags) addFlag(name string, flagType FlagType) *Flag {
|
|
if _, ok := bf.flags[name]; ok {
|
|
bf.Err = fmt.Errorf("Duplicate flag defined: %s", name)
|
|
return nil
|
|
}
|
|
|
|
newFlag := &Flag{
|
|
bf: bf,
|
|
name: name,
|
|
flagType: flagType,
|
|
}
|
|
bf.flags[name] = newFlag
|
|
|
|
return newFlag
|
|
}
|
|
|
|
// IsUsed checks if the flag is used
|
|
func (fl *Flag) IsUsed() bool {
|
|
if _, ok := fl.bf.used[fl.name]; ok {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsTrue checks if a bool flag is true
|
|
func (fl *Flag) IsTrue() bool {
|
|
if fl.flagType != boolType {
|
|
// Should never get here
|
|
panic(fmt.Errorf("Trying to use IsTrue on a non-boolean: %s", fl.name))
|
|
}
|
|
return fl.Value == "true"
|
|
}
|
|
|
|
// Parse parses and checks if the BFlags is valid.
|
|
// Any error noticed during the AddXXX() funcs will be generated/returned
|
|
// here. We do this because an error during AddXXX() is more like a
|
|
// compile time error so it doesn't matter too much when we stop our
|
|
// processing as long as we do stop it, so this allows the code
|
|
// around AddXXX() to be just:
|
|
// defFlag := AddString("description", "")
|
|
// w/o needing to add an if-statement around each one.
|
|
func (bf *BFlags) Parse() error {
|
|
// If there was an error while defining the possible flags
|
|
// go ahead and bubble it back up here since we didn't do it
|
|
// earlier in the processing
|
|
if bf.Err != nil {
|
|
return fmt.Errorf("Error setting up flags: %s", bf.Err)
|
|
}
|
|
|
|
for _, arg := range bf.Args {
|
|
if !strings.HasPrefix(arg, "--") {
|
|
return fmt.Errorf("Arg should start with -- : %s", arg)
|
|
}
|
|
|
|
if arg == "--" {
|
|
return nil
|
|
}
|
|
|
|
arg = arg[2:]
|
|
value := ""
|
|
|
|
index := strings.Index(arg, "=")
|
|
if index >= 0 {
|
|
value = arg[index+1:]
|
|
arg = arg[:index]
|
|
}
|
|
|
|
flag, ok := bf.flags[arg]
|
|
if !ok {
|
|
return fmt.Errorf("Unknown flag: %s", arg)
|
|
}
|
|
|
|
if _, ok = bf.used[arg]; ok {
|
|
return fmt.Errorf("Duplicate flag specified: %s", arg)
|
|
}
|
|
|
|
bf.used[arg] = flag
|
|
|
|
switch flag.flagType {
|
|
case boolType:
|
|
// value == "" is only ok if no "=" was specified
|
|
if index >= 0 && value == "" {
|
|
return fmt.Errorf("Missing a value on flag: %s", arg)
|
|
}
|
|
|
|
lower := strings.ToLower(value)
|
|
if lower == "" {
|
|
flag.Value = "true"
|
|
} else if lower == "true" || lower == "false" {
|
|
flag.Value = lower
|
|
} else {
|
|
return fmt.Errorf("Expecting boolean value for flag %s, not: %s", arg, value)
|
|
}
|
|
|
|
case stringType:
|
|
if index < 0 {
|
|
return fmt.Errorf("Missing a value on flag: %s", arg)
|
|
}
|
|
flag.Value = value
|
|
|
|
default:
|
|
panic("No idea what kind of flag we have! Should never get here!")
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
}
|