From 298ffc3529897b19b9f0cc950d24b5c743b31859 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Wed, 10 Apr 2019 17:12:39 +0200 Subject: [PATCH] config: generalize and simplify value string/from_variable parsing --- internal/config/config.go | 168 +++++++++----------------------- internal/config/config_test.go | 18 ++-- internal/runconfig/runconfig.go | 40 ++++---- 3 files changed, 76 insertions(+), 150 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index 356e6f1..e97f18a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -44,13 +44,13 @@ type Config struct { } type Task struct { - Name string `yaml:"name"` - Runtime string `yaml:"runtime"` - Environment map[string]EnvVar `yaml:"environment,omitempty"` - WorkingDir string `yaml:"working_dir"` - Shell string `yaml:"shell"` - User string `yaml:"user"` - Steps []interface{} `yaml:"steps"` + Name string `yaml:"name"` + Runtime string `yaml:"runtime"` + Environment map[string]Value `yaml:"environment,omitempty"` + WorkingDir string `yaml:"working_dir"` + Shell string `yaml:"shell"` + User string `yaml:"user"` + Steps []interface{} `yaml:"steps"` } type RuntimeType string @@ -67,11 +67,11 @@ type Runtime struct { } type Container struct { - Image string `yaml:"image,omitempty"` - Environment map[string]EnvVar `yaml:"environment,omitempty"` - User string `yaml:"user"` - Privileged bool `yaml:"privileged"` - Entrypoint string `yaml:"entrypoint"` + Image string `yaml:"image,omitempty"` + Environment map[string]Value `yaml:"environment,omitempty"` + User string `yaml:"user"` + Privileged bool `yaml:"privileged"` + Entrypoint string `yaml:"entrypoint"` } type Pipeline struct { @@ -111,22 +111,22 @@ type CloneStep struct { type RunStep struct { Step `yaml:",inline"` - Command string `yaml:"command"` - Environment map[string]EnvVar `yaml:"environment,omitempty"` - WorkingDir string `yaml:"working_dir"` - Shell string `yaml:"shell"` - User string `yaml:"user"` + Command string `yaml:"command"` + Environment map[string]Value `yaml:"environment,omitempty"` + WorkingDir string `yaml:"working_dir"` + Shell string `yaml:"shell"` + User string `yaml:"user"` } -type EnvVarType int +type ValueType int const ( - EnvVarTypeString EnvVarType = iota - EnvVarTypeFromVariable + ValueTypeString ValueType = iota + ValueTypeFromVariable ) -type EnvVar struct { - Type EnvVarType +type Value struct { + Type ValueType Value string } @@ -146,73 +146,11 @@ type RestoreWorkspaceStep struct { 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 { type task struct { Name string `yaml:"name"` Runtime string `yaml:"runtime"` - Environment map[string]interface{} `yaml:"environment,omitempty"` + Environment map[string]Value `yaml:"environment,omitempty"` WorkingDir string `yaml:"working_dir"` Shell string `yaml:"shell"` User string `yaml:"user"` @@ -226,6 +164,7 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error { t.Name = tt.Name t.Runtime = tt.Runtime + t.Environment = tt.Environment t.WorkingDir = tt.WorkingDir t.Shell = tt.Shell t.User = tt.User @@ -282,14 +221,6 @@ func (t *Task) UnmarshalYAML(unmarshal func(interface{}) error) error { t.Steps = steps - if tt.Environment != nil { - env, err := parseEnv(tt.Environment) - if err != nil { - return err - } - t.Environment = env - } - return nil } @@ -388,34 +319,31 @@ func (e *Element) UnmarshalYAML(unmarshal func(interface{}) error) error { return nil } -func parseEnv(ienv map[string]interface{}) (map[string]EnvVar, error) { - env := map[string]EnvVar{} - for envName, envEntry := range ienv { - switch envValue := envEntry.(type) { - 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) - } +func (val *Value) UnmarshalYAML(unmarshal func(interface{}) error) error { + var ival interface{} + if err := unmarshal(&ival); err != nil { + return err } - 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) { diff --git a/internal/config/config_test.go b/internal/config/config_test.go index 89558ff..77d17cc 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -183,9 +183,9 @@ func TestParseOutput(t *testing.T) { Containers: []*Container{ &Container{ Image: "image01", - Environment: map[string]EnvVar{ - "ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, - "ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, + Environment: map[string]Value{ + "ENV01": Value{Type: ValueTypeString, Value: "ENV01"}, + "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"}, }, User: "", }, @@ -196,9 +196,9 @@ func TestParseOutput(t *testing.T) { "task01": &Task{ Name: "task01", Runtime: "runtime01", - Environment: map[string]EnvVar{ - "ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, - "ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, + Environment: map[string]Value{ + "ENV01": Value{Type: ValueTypeString, Value: "ENV01"}, + "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"}, }, WorkingDir: "", Shell: "", @@ -224,9 +224,9 @@ func TestParseOutput(t *testing.T) { Name: "command03", }, Command: "command03", - Environment: map[string]EnvVar{ - "ENV01": EnvVar{Type: EnvVarTypeString, Value: "ENV01"}, - "ENVFROMVARIABLE01": EnvVar{Type: EnvVarTypeFromVariable, Value: "variable01"}, + Environment: map[string]Value{ + "ENV01": Value{Type: ValueTypeString, Value: "ENV01"}, + "ENVFROMVARIABLE01": Value{Type: ValueTypeFromVariable, Value: "variable01"}, }, }, }, diff --git a/internal/runconfig/runconfig.go b/internal/runconfig/runconfig.go index 72ee169..62292b2 100644 --- a/internal/runconfig/runconfig.go +++ b/internal/runconfig/runconfig.go @@ -30,11 +30,7 @@ func genRuntime(c *config.Config, runtimeName string, variables map[string]strin containers := []*rstypes.Container{} for _, cc := range ce.Containers { - - env, err := genEnv(cc.Environment, variables) - if err != nil { - return nil - } + env := genEnv(cc.Environment, variables) container := &rstypes.Container{ Image: cc.Image, Environment: env, @@ -44,6 +40,7 @@ func genRuntime(c *config.Config, runtimeName string, variables map[string]strin } containers = append(containers, container) } + return &rstypes.Runtime{ Type: rstypes.RuntimeType(ce.Type), Containers: containers, @@ -99,10 +96,7 @@ fi case *config.RunStep: rs := &rstypes.RunStep{} - env, err := genEnv(cs.Environment, variables) - if err != nil { - return nil - } + env := genEnv(cs.Environment, variables) rs.Type = cs.Type rs.Name = cs.Name @@ -161,10 +155,7 @@ func GenRunConfigTasks(uuid util.UUIDGenerator, c *config.Config, pipelineName s steps[i] = stepFromConfigStep(cpts, variables) } - tEnv, err := genEnv(cpt.Environment, variables) - if err != nil { - return nil - } + tEnv := genEnv(cpt.Environment, variables) t := &rstypes.RunConfigTask{ ID: uuid.New(cpe.Name).String(), @@ -361,15 +352,22 @@ func GetAllParents(rcts map[string]*rstypes.RunConfigTask, task *rstypes.RunConf 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{} for envName, envVar := range cenv { - switch envVar.Type { - case config.EnvVarTypeString: - env[envName] = envVar.Value - case config.EnvVarTypeFromVariable: - env[envName] = variables[envVar.Value] - } + env[envName] = genValue(envVar, variables) } - 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 "" }