Skip to content

Commit 93f45e1

Browse files
authored
Merge pull request #82 from SimonBaeumer/read-environment-variables
Read environment variables
2 parents bf885ad + e778856 commit 93f45e1

File tree

11 files changed

+138
-50
lines changed

11 files changed

+138
-50
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# v1.2.0
22

3-
- Add `interval` option for `retries` which allows to execute a retry after a given period of time. I.e. `interval: 50ms`
3+
- Add reading envrionment variables from shell
4+
- Add `interval` option for `retries` which allows to execute a retry after a given period of time. I.e. `interval: 50ms`
45

56
# v1.1.0
67

cmd/commander/commander.go

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,32 +36,13 @@ func createCliApp() *cli.App {
3636
cliapp.Version = version
3737

3838
cliapp.Commands = []cli.Command{
39+
createTestCommand(),
3940
createAddCommand(),
40-
{
41-
Name: "add",
42-
Usage: "Automatically add a test to your test suite",
43-
ArgsUsage: "[command]",
44-
Flags: []cli.Flag{
45-
cli.BoolFlag{
46-
Name: "stdout",
47-
Usage: "Output test file to stdout",
48-
},
49-
cli.BoolFlag{
50-
Name: "no-file",
51-
Usage: "Don't create a commander.yaml",
52-
},
53-
cli.StringFlag{
54-
Name: "file",
55-
Usage: "Write to another file, default is commander.yaml",
56-
},
57-
},
58-
Action: addCommand,
59-
},
6041
}
6142
return cliapp
6243
}
6344

64-
func createAddCommand() cli.Command {
45+
func createTestCommand() cli.Command {
6546
return cli.Command{
6647
Name: "test",
6748
Usage: "Execute the test suite",
@@ -89,35 +70,56 @@ func createAddCommand() cli.Command {
8970
}
9071
}
9172

92-
func addCommand(c *cli.Context) error {
93-
file := ""
94-
var existedContent []byte
73+
func createAddCommand() cli.Command {
74+
return cli.Command{
75+
Name: "add",
76+
Usage: "Automatically add a test to your test suite",
77+
ArgsUsage: "[command]",
78+
Flags: []cli.Flag{
79+
cli.BoolFlag{
80+
Name: "stdout",
81+
Usage: "Output test file to stdout",
82+
},
83+
cli.BoolFlag{
84+
Name: "no-file",
85+
Usage: "Don't create a commander.yaml",
86+
},
87+
cli.StringFlag{
88+
Name: "file",
89+
Usage: "Write to another file, default is commander.yaml",
90+
},
91+
},
92+
Action: func(c *cli.Context) error {
93+
file := ""
94+
var existedContent []byte
9595

96-
if !c.Bool("no-file") {
97-
dir, _ := os.Getwd()
98-
file = path.Join(dir, app.CommanderFile)
99-
if c.String("file") != "" {
100-
file = c.String("file")
101-
}
102-
existedContent, _ = ioutil.ReadFile(file)
103-
}
96+
if !c.Bool("no-file") {
97+
dir, _ := os.Getwd()
98+
file = path.Join(dir, app.CommanderFile)
99+
if c.String("file") != "" {
100+
file = c.String("file")
101+
}
102+
existedContent, _ = ioutil.ReadFile(file)
103+
}
104104

105-
content, err := app.AddCommand(strings.Join(c.Args(), " "), existedContent)
105+
content, err := app.AddCommand(strings.Join(c.Args(), " "), existedContent)
106106

107-
if err != nil {
108-
return err
109-
}
107+
if err != nil {
108+
return err
109+
}
110110

111-
if c.Bool("stdout") {
112-
fmt.Println(string(content))
113-
}
114-
if !c.Bool("no-file") {
115-
fmt.Println("written to", file)
116-
err := ioutil.WriteFile(file, content, 0755)
117-
if err != nil {
118-
return err
119-
}
120-
}
111+
if c.Bool("stdout") {
112+
fmt.Println(string(content))
113+
}
114+
if !c.Bool("no-file") {
115+
fmt.Println("written to", file)
116+
err := ioutil.WriteFile(file, content, 0755)
117+
if err != nil {
118+
return err
119+
}
120+
}
121121

122-
return nil
122+
return nil
123+
},
124+
}
123125
}

commander_unix.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,14 @@ tests:
3232

3333
test global and local configurations:
3434
command: ./commander test ./integration/unix/config_test.yaml
35+
config:
36+
env:
37+
COMMANDER_FROM_SHELL: from_shell
3538
stdout:
3639
contains:
3740
- ✓ should print global env value
3841
- ✓ should print local env value
42+
- ✓ should print env var from shell
3943
exit-code: 0
4044

4145
test add command:

commander_windows.yaml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ tests:
3636

3737
test global and local configurations:
3838
command: commander.exe test ./integration/windows/config_test.yaml
39+
config:
40+
env:
41+
COMMANDER_FROM_SHELL: from_shell
3942
stdout:
4043
contains:
4144
- should print global
@@ -55,4 +58,4 @@ tests:
5558
stdout:
5659
contains:
5760
- ✗ echo hello, retries 3
58-
exit-code: 1
61+
exit-code: 1

docs/manual.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ config: # Config for all tests
3333
dir: /tmp #Set working directory
3434
env: # Environment variables
3535
KEY: global
36+
PATH_FROM_SHELL: ${PATH} # Read an env variable from the current shell
3637
timeout: 5000 # Timeout in ms
3738
retries: 2 # Define retries for each test
3839

integration/unix/config_test.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ config:
22
env:
33
KEY: value
44
ANOTHER: global
5+
COMMANDER_FROM_SHELL: ${COMMANDER_FROM_SHELL}
56
tests:
67
should print global env value:
78
command: echo $KEY
@@ -27,4 +28,9 @@ tests:
2728
command: echo hello
2829
config:
2930
timeout: 100ms
31+
exit-code: 0
32+
33+
should print env var from shell:
34+
command: echo read ${COMMANDER_FROM_SHELL} $KEY
35+
stdout: read from_shell value
3036
exit-code: 0

integration/windows/config_test.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ config:
22
env:
33
KEY: value
44
ANOTHER: global
5+
COMMANDER_FROM_SHELL: ${COMMANDER_FROM_SHELL}
56
tests:
67
should print global env value:
78
command: echo %KEY%

integration/windows/shell_env.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
tests:
2+
it should read from shell env:
3+
env:

pkg/cmd/command.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ package cmd
33
import (
44
"bytes"
55
"fmt"
6+
"os"
67
"os/exec"
8+
"regexp"
9+
"strings"
710
"syscall"
811
"time"
912
)
@@ -31,10 +34,29 @@ func NewCommand(cmd string) *Command {
3134
}
3235

3336
// AddEnv adds an environment variable to the command
37+
// If a variable gets passed like ${VAR_NAME} the env variable will be read out by the current shell
3438
func (c *Command) AddEnv(key string, value string) {
39+
vars := parseEnvVariableFromShell(value)
40+
for _, v := range vars {
41+
value = strings.Replace(value, v, os.Getenv(removeEnvVarSyntax(v)), -1)
42+
}
43+
3544
c.Env = append(c.Env, fmt.Sprintf("%s=%s", key, value))
3645
}
3746

47+
// Removes the ${...} characters
48+
func removeEnvVarSyntax(v string) string {
49+
return v[2:(len(v) - 1)]
50+
}
51+
52+
//Read all environment variables from the given value
53+
//with the syntax ${VAR_NAME}
54+
func parseEnvVariableFromShell(val string) []string {
55+
reg := regexp.MustCompile(`\$\{.*?\}`)
56+
matches := reg.FindAllString(val, -1)
57+
return matches
58+
}
59+
3860
//SetTimeoutMS sets the timeout in milliseconds
3961
func (c *Command) SetTimeoutMS(ms int) {
4062
if ms == 0 {

pkg/cmd/command_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package cmd
33
import (
44
"fmt"
55
"github.com/stretchr/testify/assert"
6+
"os"
67
"runtime"
78
"testing"
89
"time"
@@ -64,6 +65,48 @@ func TestCommand_AddEnv(t *testing.T) {
6465
assert.Equal(t, []string{"key=value"}, c.Env)
6566
}
6667

68+
func TestCommand_AddEnvWithShellVariable(t *testing.T) {
69+
const TestEnvKey = "COMMANDER_TEST_SOME_KEY"
70+
os.Setenv(TestEnvKey, "test from shell")
71+
defer os.Unsetenv(TestEnvKey)
72+
73+
c := NewCommand(getCommand())
74+
c.AddEnv("SOME_KEY", fmt.Sprintf("${%s}", TestEnvKey))
75+
76+
err := c.Execute()
77+
78+
assert.Nil(t, err)
79+
assert.Equal(t, "test from shell", c.Stdout())
80+
}
81+
82+
func TestCommand_AddMultipleEnvWithShellVariable(t *testing.T) {
83+
const TestEnvKeyPlanet = "COMMANDER_TEST_PLANET"
84+
const TestEnvKeyName = "COMMANDER_TEST_NAME"
85+
os.Setenv(TestEnvKeyPlanet, "world")
86+
os.Setenv(TestEnvKeyName, "Simon")
87+
defer func() {
88+
os.Unsetenv(TestEnvKeyPlanet)
89+
os.Unsetenv(TestEnvKeyName)
90+
}()
91+
92+
c := NewCommand(getCommand())
93+
envValue := fmt.Sprintf("Hello ${%s}, I am ${%s}", TestEnvKeyPlanet, TestEnvKeyName)
94+
c.AddEnv("SOME_KEY", envValue)
95+
96+
err := c.Execute()
97+
98+
assert.Nil(t, err)
99+
assert.Equal(t, "Hello world, I am Simon", c.Stdout())
100+
}
101+
102+
func getCommand() string {
103+
command := "echo $SOME_KEY"
104+
if runtime.GOOS == "windows" {
105+
command = "echo %SOME_KEY%"
106+
}
107+
return command
108+
}
109+
67110
func TestCommand_SetTimeoutMS_DefaultTimeout(t *testing.T) {
68111
c := NewCommand("echo test")
69112
c.SetTimeoutMS(0)

0 commit comments

Comments
 (0)