Skip to content

Commit

Permalink
Echo with condition (#241)
Browse files Browse the repository at this point in the history
* add condition support to echo, see #240

* format tests

* clarify condition limitation
  • Loading branch information
umputun authored Dec 18, 2024
1 parent 42e5637 commit 144a44b
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ example installing curl package if not installed already:
cond: "! command -v curl"
```

currently conditions can be used with `script` and `echo` command types only.

### Deferred actions (`on_exit`)

Each command may have `on_exit` parameter defined. It allows executing a command on the remote host after the task with all commands is completed. The command is called regardless of the task's exit code.
Expand Down
11 changes: 11 additions & 0 deletions pkg/runner/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,17 @@ func (ec *execCmd) Wait(ctx context.Context) (resp execCmdResp, err error) {
// Echo prints a message. It enforces the echo command to start with "echo " and adds sudo if needed.
// It returns the result of the echo command as details string.
func (ec *execCmd) Echo(ctx context.Context) (resp execCmdResp, err error) {
// check the condition if it exists
cond, err := ec.checkCondition(ctx)
if err != nil {
return resp, err
}
if !cond {
resp.details = fmt.Sprintf(" {skip: %s}", ec.cmd.Name)
return resp, nil
}

// only proceed with echo if there was no condition or condition passed
tmpl := templater{hostAddr: ec.hostAddr, hostName: ec.hostName, task: ec.tsk, command: ec.cmd.Name, env: ec.cmd.Environment}
echoCmd := tmpl.apply(ec.cmd.Echo)
if !strings.HasPrefix(echoCmd, "echo ") {
Expand Down
66 changes: 66 additions & 0 deletions pkg/runner/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,72 @@ func Test_execCmd(t *testing.T) {
assert.Equal(t, " {echo: foo welcome back}", resp.details)
})

t.Run("echo command with condition true", func(t *testing.T) {
defer os.Remove("/tmp/test.condition")
_, err := sess.Run(ctx, "touch /tmp/test.condition", nil)
require.NoError(t, err)
ec := execCmd{
exec: sess,
tsk: &config.Task{Name: "test"},
cmd: config.Cmd{
Echo: "welcome back",
Name: "test",
Condition: "test -f /tmp/test.condition",
},
}
resp, err := ec.Echo(ctx)
require.NoError(t, err)
assert.Equal(t, " {echo: welcome back}", resp.details)
})

t.Run("echo command with condition false", func(t *testing.T) {
ec := execCmd{
exec: sess,
tsk: &config.Task{Name: "test"},
cmd: config.Cmd{
Echo: "welcome back",
Name: "test",
Condition: "test -f /tmp/nonexistent.condition",
},
}
resp, err := ec.Echo(ctx)
require.NoError(t, err)
assert.Equal(t, " {skip: test}", resp.details)
})

t.Run("echo command with condition true inverted", func(t *testing.T) {
ec := execCmd{
exec: sess,
tsk: &config.Task{Name: "test"},
cmd: config.Cmd{
Echo: "welcome back",
Name: "test",
Condition: "! test -f /tmp/nonexistent.condition",
},
}
resp, err := ec.Echo(ctx)
require.NoError(t, err)
assert.Equal(t, " {echo: welcome back}", resp.details)
})

t.Run("echo command with condition false inverted", func(t *testing.T) {
defer os.Remove("/tmp/test2.condition")
_, err := sess.Run(ctx, "touch /tmp/test2.condition", nil)
require.NoError(t, err)
ec := execCmd{
exec: sess,
tsk: &config.Task{Name: "test"},
cmd: config.Cmd{
Echo: "welcome back",
Name: "test",
Condition: "! test -f /tmp/test2.condition",
},
}
resp, err := ec.Echo(ctx)
require.NoError(t, err)
assert.Equal(t, " {skip: test}", resp.details)
})

t.Run("sync command", func(t *testing.T) {
ec := execCmd{exec: sess, tsk: &config.Task{Name: "test"}, cmd: config.Cmd{Sync: config.SyncInternal{
Source: "testdata", Dest: "/tmp/sync.testdata", Exclude: []string{"conf2.yml"}}, Name: "test"}}
Expand Down

0 comments on commit 144a44b

Please sign in to comment.