config: generalize and simplify value string/from_variable parsing

This commit is contained in:
Simone Gotti 2019-04-10 17:12:39 +02:00
parent 751361daea
commit 298ffc3529
3 changed files with 76 additions and 150 deletions

View File

@ -44,13 +44,13 @@ type Config struct {
} }
type Task struct { type Task struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Runtime string `yaml:"runtime"` Runtime string `yaml:"runtime"`
Environment map[string]EnvVar `yaml:"environment,omitempty"` Environment map[string]Value `yaml:"environment,omitempty"`
WorkingDir string `yaml:"working_dir"` WorkingDir string `yaml:"working_dir"`
Shell string `yaml:"shell"` Shell string `yaml:"shell"`
User string `yaml:"user"` User string `yaml:"user"`
Steps []interface{} `yaml:"steps"` Steps []interface{} `yaml:"steps"`
} }
type RuntimeType string type RuntimeType string
@ -67,11 +67,11 @@ type Runtime struct {
} }
type Container struct { type Container struct {
Image string `yaml:"image,omitempty"` Image string `yaml:"image,omitempty"`
Environment map[string]EnvVar `yaml:"environment,omitempty"` Environment map[string]Value `yaml:"environment,omitempty"`
User string `yaml:"user"` User string `yaml:"user"`
Privileged bool `yaml:"privileged"` Privileged bool `yaml:"privileged"`
Entrypoint string `yaml:"entrypoint"` Entrypoint string `yaml:"entrypoint"`
} }
type Pipeline struct { type Pipeline struct {
@ -111,22 +111,22 @@ type CloneStep struct {
type RunStep struct { type RunStep struct {
Step `yaml:",inline"` Step `yaml:",inline"`
Command string `yaml:"command"` Command string `yaml:"command"`
Environment map[string]EnvVar `yaml:"environment,omitempty"` Environment map[string]Value `yaml:"environment,omitempty"`
WorkingDir string `yaml:"working_dir"` WorkingDir string `yaml:"working_dir"`
Shell string `yaml:"shell"` Shell string `yaml:"shell"`
User string `yaml:"user"` User string `yaml:"user"`
} }
type EnvVarType int type ValueType int
const ( const (
EnvVarTypeString EnvVarType = iota ValueTypeString ValueType = iota
EnvVarTypeFromVariable ValueTypeFromVariable
) )
type EnvVar struct { type Value struct {
Type EnvVarType Type ValueType
Value string Value string
} }
@ -146,73 +146,11 @@ type RestoreWorkspaceStep struct {
DestDir string `yaml:"dest_dir"` DestDir string `yaml:"dest_dir"`
} }
func (s *RunStep) UnmarshalYAML(unmarshal func(interface{}) error) error {
type runStep struct {
Step `yaml:",inline"`
Command string `yaml:"command"`
Environment map[string]interface{} `yaml:"environment,omitempty"`
WorkingDir string `yaml:"working_dir"`
Shell string `yaml:"shell"`
User string `yaml:"user"`
}
var st *runStep
if err := unmarshal(&st); err != nil {
return err
}
s.Step = st.Step
s.Command = st.Command
s.WorkingDir = st.WorkingDir
s.Shell = st.Shell
s.User = st.User
if st.Environment != nil {
env, err := parseEnv(st.Environment)
if err != nil {
return err
}
s.Environment = env
}
return nil
}
func (c *Container) UnmarshalYAML(unmarshal func(interface{}) error) error {
type container struct {
Image string `yaml:"image,omitempty"`
Environment map[string]interface{} `yaml:"environment,omitempty"`
User string `yaml:"user"`
Privileged bool `yaml:"privileged"`
Entrypoint string `yaml:"entrypoint"`
}
var ct *container
if err := unmarshal(&ct); err != nil {
return err
}
c.Image = ct.Image
c.User = ct.User
c.Privileged = ct.Privileged
c.Entrypoint = ct.Entrypoint
if ct.Environment != nil {
env, err := parseEnv(ct.Environment)
if err != nil {
return err
}
c.Environment = env
}
return nil
}
func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error { func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
type task struct { type task struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Runtime string `yaml:"runtime"` Runtime string `yaml:"runtime"`
Environment map[string]interface{} `yaml:"environment,omitempty"` Environment map[string]Value `yaml:"environment,omitempty"`
WorkingDir string `yaml:"working_dir"` WorkingDir string `yaml:"working_dir"`
Shell string `yaml:"shell"` Shell string `yaml:"shell"`
User string `yaml:"user"` User string `yaml:"user"`
@ -226,6 +164,7 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
t.Name = tt.Name t.Name = tt.Name
t.Runtime = tt.Runtime t.Runtime = tt.Runtime
t.Environment = tt.Environment
t.WorkingDir = tt.WorkingDir t.WorkingDir = tt.WorkingDir
t.Shell = tt.Shell t.Shell = tt.Shell
t.User = tt.User t.User = tt.User
@ -282,14 +221,6 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error {
t.Steps = steps t.Steps = steps
if tt.Environment != nil {
env, err := parseEnv(tt.Environment)
if err != nil {
return err
}
t.Environment = env
}
return nil return nil
} }
@ -388,34 +319,31 @@ func (e *Element) UnmarshalYAML(unmarshal func(interface{}) error) error {
return nil return nil
} }
func parseEnv(ienv map[string]interface{}) (map[string]EnvVar, error) { func (val *Value) UnmarshalYAML(unmarshal func(interface{}) error) error {
env := map[string]EnvVar{} var ival interface{}
for envName, envEntry := range ienv { if err := unmarshal(&ival); err != nil {
switch envValue := envEntry.(type) { return err
case string:
env[envName] = EnvVar{
Type: EnvVarTypeString,
Value: envValue,
}
case map[interface{}]interface{}:
for k, v := range envValue {
if k == "from_variable" {
switch v.(type) {
case string:
default:
return nil, errors.Errorf("unknown environment value: %v", v)
}
env[envName] = EnvVar{
Type: EnvVarTypeFromVariable,
Value: v.(string),
}
}
}
default:
return nil, errors.Errorf("unknown environment value: %v", envValue)
}
} }
return env, nil switch valValue := ival.(type) {
case string:
val.Type = ValueTypeString
val.Value = valValue
case map[interface{}]interface{}:
for k, v := range valValue {
if k == "from_variable" {
switch v.(type) {
case string:
default:
return errors.Errorf("unknown value format: %v", v)
}
val.Type = ValueTypeFromVariable
val.Value = v.(string)
}
}
default:
return errors.Errorf("unknown value format: %v", ival)
}
return nil
} }
func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) { func parseWhenConditions(wi interface{}) (*types.WhenConditions, error) {

View File

@ -183,9 +183,9 @@ func TestParseOutput(t *testing.T) {
Containers: []*Container{ Containers: []*Container{
&Container{ &Container{
Image: "image01", Image: "image01",
Environment: map[string]EnvVar{ Environment: map[string]Value{
"ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, "ENV01": Value{Type: ValueTypeString, Value: "ENV01"},
"ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"},
}, },
User: "", User: "",
}, },
@ -196,9 +196,9 @@ func TestParseOutput(t *testing.T) {
"task01": &Task{ "task01": &Task{
Name: "task01", Name: "task01",
Runtime: "runtime01", Runtime: "runtime01",
Environment: map[string]EnvVar{ Environment: map[string]Value{
"ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, "ENV01": Value{Type: ValueTypeString, Value: "ENV01"},
"ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"},
}, },
WorkingDir: "", WorkingDir: "",
Shell: "", Shell: "",
@ -224,9 +224,9 @@ func TestParseOutput(t *testing.T) {
Name: "command03", Name: "command03",
}, },
Command: "command03", Command: "command03",
Environment: map[string]EnvVar{ Environment: map[string]Value{
"ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, "ENV01": Value{Type: ValueTypeString, Value: "ENV01"},
"ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"},
}, },
}, },
}, },

View File

@ -30,11 +30,7 @@ func genRuntime(c *config.Config, runtimeName string, variables map[string]strin
containers := []*rstypes.Container{} containers := []*rstypes.Container{}
for _, cc := range ce.Containers { for _, cc := range ce.Containers {
env := genEnv(cc.Environment, variables)
env, err := genEnv(cc.Environment, variables)
if err != nil {
return nil
}
container := &rstypes.Container{ container := &rstypes.Container{
Image: cc.Image, Image: cc.Image,
Environment: env, Environment: env,
@ -44,6 +40,7 @@ func genRuntime(c *config.Config, runtimeName string, variables map[string]strin
} }
containers = append(containers, container) containers = append(containers, container)
} }
return &rstypes.Runtime{ return &rstypes.Runtime{
Type: rstypes.RuntimeType(ce.Type), Type: rstypes.RuntimeType(ce.Type),
Containers: containers, Containers: containers,
@ -99,10 +96,7 @@ fi
case *config.RunStep: case *config.RunStep:
rs := &rstypes.RunStep{} rs := &rstypes.RunStep{}
env, err := genEnv(cs.Environment, variables) env := genEnv(cs.Environment, variables)
if err != nil {
return nil
}
rs.Type = cs.Type rs.Type = cs.Type
rs.Name = cs.Name rs.Name = cs.Name
@ -161,10 +155,7 @@ func GenRunConfigTasks(uuid util.UUIDGenerator, c *config.Config, pipelineName s
steps[i] = stepFromConfigStep(cpts, variables) steps[i] = stepFromConfigStep(cpts, variables)
} }
tEnv, err := genEnv(cpt.Environment, variables) tEnv := genEnv(cpt.Environment, variables)
if err != nil {
return nil
}
t := &rstypes.RunConfigTask{ t := &rstypes.RunConfigTask{
ID: uuid.New(cpe.Name).String(), ID: uuid.New(cpe.Name).String(),
@ -361,15 +352,22 @@ func GetAllParents(rcts map[string]*rstypes.RunConfigTask, task *rstypes.RunConf
return parents return parents
} }
func genEnv(cenv map[string]config.EnvVar, variables map[string]string) (map[string]string, error) { func genEnv(cenv map[string]config.Value, variables map[string]string) map[string]string {
env := map[string]string{} env := map[string]string{}
for envName, envVar := range cenv { for envName, envVar := range cenv {
switch envVar.Type { env[envName] = genValue(envVar, variables)
case config.EnvVarTypeString:
env[envName] = envVar.Value
case config.EnvVarTypeFromVariable:
env[envName] = variables[envVar.Value]
}
} }
return env, nil return env
}
func genValue(val config.Value, variables map[string]string) string {
switch val.Type {
case config.ValueTypeString:
return val.Value
case config.ValueTypeFromVariable:
return variables[val.Value]
default:
panic(fmt.Errorf("wrong value type: %q", val.Value))
}
return ""
} }