Skip to content

Commit

Permalink
Merge pull request #43 from evilmarty/env-vars
Browse files Browse the repository at this point in the history
feat(inputs): Includes original inputs in env vars
  • Loading branch information
evilmarty authored Oct 9, 2024
2 parents e09c4a6 + 2fd927e commit 544a151
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 30 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ input before the command will be executed. Inputs can be passed as arguments or
as environment variables that are prefixed with `ILC_INPUT_`. Inputs that have
been passed as arguments will not be asked, only for the inputs that have yet a value.

All inputs will also be accessible via environment variables prefixed with `ILC_INPUT_`.

#### Example of passing inputs as arguments

```shell
Expand Down
40 changes: 25 additions & 15 deletions command_set.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,24 @@ func (cs CommandSet) Inputs() []ConfigInput {
return inputs
}

func (cs CommandSet) Env() map[string]string {
envs := make(map[string]string)
func (cs CommandSet) Env() EnvMap {
em := NewEnvMap([]string{})
for _, command := range cs.Commands {
for name, value := range command.Env {
envs[name] = value
}
em = em.Merge(command.Env)
}
return envs
return em
}

func (cs CommandSet) RenderEnv(data TemplateData) ([]string, error) {
var renderedEnvs []string
for name, template := range cs.Env() {
func (cs CommandSet) RenderEnv(data TemplateData) (EnvMap, error) {
env := cs.Env()
for name, template := range env {
if value, err := RenderTemplate(template, data); err != nil {
return renderedEnvs, fmt.Errorf("template error for environment variable: '%s' - %v", name, err)
return env, fmt.Errorf("template error for environment variable: '%s' - %v", name, err)
} else {
renderedEnvs = append(renderedEnvs, fmt.Sprintf("%s=%s", name, value))
env[name] = value
}
}
return renderedEnvs, nil
return env, nil
}

func (cs CommandSet) RenderScript(data TemplateData) (string, error) {
Expand Down Expand Up @@ -222,9 +220,20 @@ func (cs CommandSet) ParseEnv(values *map[string]any, environ []string) {
}
}

func (cs CommandSet) getInputsEnv(data TemplateData) EnvMap {
inputs := cs.Inputs()
env := make(EnvMap, len(inputs))
for _, input := range inputs {
value := data.getInput(input.Name)
key := fmt.Sprintf("%s%s", EnvVarPrefix, input.SafeName())
env[key] = fmt.Sprintf("%s", value)
}
return env
}

func (cs CommandSet) Cmd(data TemplateData, moreEnviron []string) (*exec.Cmd, error) {
var scriptFile string
var env []string
var env EnvMap
var err error
shell := cs.Shell()
scriptFile, err = cs.RenderScriptToTemp(data)
Expand All @@ -235,12 +244,13 @@ func (cs CommandSet) Cmd(data TemplateData, moreEnviron []string) (*exec.Cmd, er
if err != nil {
return nil, err
}
env = cs.getInputsEnv(data).Merge(env)
if !cs.Pure() {
env = append(moreEnviron, env...)
env = NewEnvMap(moreEnviron).Merge(env)
}
shell = append(shell, scriptFile)
cmd := exec.Command(shell[0], shell[1:]...)
cmd.Env = env
cmd.Env = env.ToList()
return cmd, nil
}

Expand Down
41 changes: 33 additions & 8 deletions command_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func TestCommandSetEnv(t *testing.T) {
},
},
}
expected := map[string]string{
expected := EnvMap{
"A": "aa",
"B": "b",
"C": "c",
Expand Down Expand Up @@ -164,14 +164,14 @@ func TestCommandSetRenderEnv_NonError(t *testing.T) {
},
},
}
expected := []string{
"A=aa",
"B=b",
"C=c",
expected := EnvMap{
"A": "aa",
"B": "b",
"C": "c",
}
actual, err := cs.RenderEnv(data)
assert.NoError(t, err, "CommandSet.RenderEnv() returned an unexpected error")
assert.ElementsMatch(t, expected, actual, "CommandSet.RenderEnv() returned unexpected results")
assert.Equal(t, expected, actual, "CommandSet.RenderEnv() returned unexpected results")
}

func TestCommandSetRenderEnv_TemplateError(t *testing.T) {
Expand Down Expand Up @@ -391,6 +391,10 @@ func TestCommandSetCmd_IsPure(t *testing.T) {
"A": "{{.Input.A}}",
"B": "{{.Input.B}}",
},
Inputs: ConfigInputs{
ConfigInput{Name: "A"},
ConfigInput{Name: "B"},
},
},
{
Shell: []string{"/bin/bash", "-x"},
Expand All @@ -399,13 +403,21 @@ func TestCommandSetCmd_IsPure(t *testing.T) {
"A": "aa",
"C": "{{.Input.C}}",
},
Inputs: ConfigInputs{
ConfigInput{Name: "C"},
},
Pure: true,
},
},
}
cmd, err := cs.Cmd(data, moreEnviron)
assert.NoError(t, err, "CommandSet.Cmd() returned an unexpected error")
assert.ElementsMatch(t, []string{"A=aa", "B=b", "C=c"}, cmd.Env, "CommandSet.Cmd() did not set cmd.Env with correct values")
assert.ElementsMatch(
t,
[]string{"ILC_INPUT_A=a", "ILC_INPUT_B=b", "ILC_INPUT_C=c", "A=aa", "B=b", "C=c"},
cmd.Env,
"CommandSet.Cmd() did not set cmd.Env with correct values",
)
assert.Equal(t, "/bin/bash", cmd.Path, "CommandSet.Cmd() did not set cmd.Path to the shell path")
assert.Equal(t, []string{"/bin/bash", "-x"}, cmd.Args[:len(cmd.Args)-1], "CommandSet.Cmd() did not set cmd.Args with the correct values")
}
Expand All @@ -419,6 +431,7 @@ func TestCommandSetCmd_NotPure(t *testing.T) {
},
}
moreEnviron := []string{
"C=x",
"D=d",
}
cs := CommandSet{
Expand All @@ -430,6 +443,10 @@ func TestCommandSetCmd_NotPure(t *testing.T) {
"A": "{{.Input.A}}",
"B": "{{.Input.B}}",
},
Inputs: ConfigInputs{
ConfigInput{Name: "A"},
ConfigInput{Name: "B"},
},
},
{
Shell: []string{"/bin/bash", "-x"},
Expand All @@ -438,12 +455,20 @@ func TestCommandSetCmd_NotPure(t *testing.T) {
"A": "aa",
"C": "{{.Input.C}}",
},
Inputs: ConfigInputs{
ConfigInput{Name: "C"},
},
},
},
}
cmd, err := cs.Cmd(data, moreEnviron)
assert.NoError(t, err, "CommandSet.Cmd() returned an unexpected error")
assert.ElementsMatch(t, []string{"A=aa", "B=b", "C=c", "D=d"}, cmd.Env, "CommandSet.Cmd() did not set cmd.Env with correct values")
assert.ElementsMatch(
t,
[]string{"ILC_INPUT_A=a", "ILC_INPUT_B=b", "ILC_INPUT_C=c", "A=aa", "B=b", "C=c", "D=d"},
cmd.Env,
"CommandSet.Cmd() did not set cmd.Env with correct values",
)
assert.Equal(t, "/bin/bash", cmd.Path, "CommandSet.Cmd() did not set cmd.Path to the shell path")
assert.Equal(t, []string{"/bin/bash", "-x"}, cmd.Args[:len(cmd.Args)-1], "CommandSet.Cmd() did not set cmd.Args with the correct values")
}
Expand Down
5 changes: 5 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"
"regexp"
"strings"

"gopkg.in/yaml.v3"
)
Expand Down Expand Up @@ -74,6 +75,10 @@ type ConfigInput struct {
Description string
}

func (input *ConfigInput) SafeName() string {
return strings.ReplaceAll(input.Name, "-", "_")
}

func (input *ConfigInput) Selectable() bool {
return input.Options.Len() > 0
}
Expand Down
7 changes: 7 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ func TestConfigInputSelectable(t *testing.T) {
assert.Equal(t, true, input.Selectable(), "ConfigInput.Selectable() with options expected to return true")
}

func TestConfigInputSafeName(t *testing.T) {
input := ConfigInput{
Name: "foo-bar",
}
assert.Equal(t, "foo_bar", input.SafeName(), "ConfigInput.SafeName() returned unexpected result")
}

func TestConfigInputValid(t *testing.T) {
input := ConfigInput{
Options: ConfigInputOptions{},
Expand Down
23 changes: 20 additions & 3 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,29 @@ func NewTemplateData(input map[string]any, env []string) TemplateData {
}
return TemplateData{
Input: safeInputs,
Env: EnvMap(env),
Env: NewEnvMap(env),
}
}

func EnvMap(env []string) map[string]string {
m := make(map[string]string, len(env))
type EnvMap map[string]string

func (em EnvMap) Merge(other map[string]string) EnvMap {
for name, value := range other {
em[name] = value
}
return em
}

func (em EnvMap) ToList() []string {
var env []string
for name, value := range em {
env = append(env, fmt.Sprintf("%s=%s", name, value))
}
return env
}

func NewEnvMap(env []string) EnvMap {
m := make(EnvMap, len(env))
for _, item := range env {
entry := strings.SplitN(item, "=", 2)
if len(entry) > 1 {
Expand Down
8 changes: 4 additions & 4 deletions utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (
"github.com/stretchr/testify/assert"
)

func TestEnvMap(t *testing.T) {
func TestNewEnvMap(t *testing.T) {
env := []string{
"A=a",
"B=",
"C",
}
expected := map[string]string{"A": "a", "B": "", "C": ""}
actual := EnvMap(env)
assert.Equal(t, expected, actual, "EnvMap() returned unexpected results")
expected := EnvMap{"A": "a", "B": "", "C": ""}
actual := NewEnvMap(env)
assert.Equal(t, expected, actual, "NewEnvMap() returned unexpected results")
}

func TestNewTemplateData(t *testing.T) {
Expand Down

0 comments on commit 544a151

Please sign in to comment.