spindle/engine: helpers to convert step.Environment to []string{} and set them #247

merged
opened by anirudh.fi targeting master from push-pmtpswykplzr
Changed files
+107 -1
spindle
+5 -1
spindle/engine/engine.go
···
}()
for _, step := range steps {
+
envs := ConstructEnvs(step.Environment)
+
envs.AddEnv("HOME", workspaceDir)
+
e.l.Debug("envs for step", "step", step.Name, "envs", envs.Slice())
+
hostConfig := hostConfig(wid)
resp, err := e.docker.ContainerCreate(ctx, &container.Config{
Image: image,
···
WorkingDir: workspaceDir,
Tty: false,
Hostname: "spindle",
-
Env: []string{"HOME=" + workspaceDir},
+
Env: envs.Slice(),
}, hostConfig, nil, nil, "")
if err != nil {
return fmt.Errorf("creating container: %w", err)
+32
spindle/engine/envs.go
···
+
package engine
+
+
import (
+
"fmt"
+
+
"tangled.sh/tangled.sh/core/api/tangled"
+
)
+
+
type EnvVars []string
+
+
// ConstructEnvs converts a tangled.Pipeline_Step_Environment_Elem.{Key,Value}
+
// representation into a docker-friendly []string{"KEY=value", ...} slice.
+
func ConstructEnvs(envs []*tangled.Pipeline_Step_Environment_Elem) EnvVars {
+
var dockerEnvs EnvVars
+
for _, env := range envs {
+
if env != nil {
+
ev := fmt.Sprintf("%s=%s", env.Key, env.Value)
+
dockerEnvs = append(dockerEnvs, ev)
+
}
+
}
+
return dockerEnvs
+
}
+
+
// Slice returns the EnvVar as a []string slice.
+
func (ev EnvVars) Slice() []string {
+
return ev
+
}
+
+
// AddEnv adds a key=value string to the EnvVar.
+
func (ev *EnvVars) AddEnv(key, value string) {
+
*ev = append(*ev, fmt.Sprintf("%s=%s", key, value))
+
}
+70
spindle/engine/envs_test.go
···
+
package engine
+
+
import (
+
"reflect"
+
"testing"
+
+
"tangled.sh/tangled.sh/core/api/tangled"
+
)
+
+
func TestConstructEnvs(t *testing.T) {
+
tests := []struct {
+
name string
+
in []*tangled.Pipeline_Step_Environment_Elem
+
want EnvVars
+
}{
+
{
+
name: "empty input",
+
in: []*tangled.Pipeline_Step_Environment_Elem{},
+
want: EnvVars{},
+
},
+
{
+
name: "single env var",
+
in: []*tangled.Pipeline_Step_Environment_Elem{
+
{Key: "FOO", Value: "bar"},
+
},
+
want: EnvVars{"FOO=bar"},
+
},
+
{
+
name: "multiple env vars",
+
in: []*tangled.Pipeline_Step_Environment_Elem{
+
{Key: "FOO", Value: "bar"},
+
{Key: "BAZ", Value: "qux"},
+
},
+
want: EnvVars{"FOO=bar", "BAZ=qux"},
+
},
+
{
+
name: "nil entries are skipped",
+
in: []*tangled.Pipeline_Step_Environment_Elem{
+
nil,
+
{Key: "FOO", Value: "bar"},
+
},
+
want: EnvVars{"FOO=bar"},
+
},
+
}
+
+
for _, tt := range tests {
+
t.Run(tt.name, func(t *testing.T) {
+
got := ConstructEnvs(tt.in)
+
+
if got == nil {
+
got = EnvVars{}
+
}
+
+
if !reflect.DeepEqual(got, tt.want) {
+
t.Errorf("ConstructEnvs() = %v, want %v", got, tt.want)
+
}
+
})
+
}
+
}
+
+
func TestAddEnv(t *testing.T) {
+
ev := EnvVars{}
+
ev.AddEnv("FOO", "bar")
+
ev.AddEnv("BAZ", "qux")
+
+
want := EnvVars{"FOO=bar", "BAZ=qux"}
+
if !reflect.DeepEqual(ev, want) {
+
t.Errorf("AddEnv result = %v, want %v", ev, want)
+
}
+
}