Skip to content

Commit

Permalink
Fix sprintf templating and exec.Option grouping (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
kke authored Aug 18, 2021
1 parent c59d8f2 commit 869724d
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 16 deletions.
26 changes: 13 additions & 13 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,14 @@ func (c Connection) Sudo(cmd string) (string, error) {

// Execf is just like `Exec` but you can use Sprintf templating for the command
func (c Connection) Execf(s string, params ...interface{}) error {
opts, args := groupParams(params)
opts, args := GroupParams(params)
return c.Exec(fmt.Sprintf(s, args...), opts...)
}

// ExecOutputf is like ExecOutput but you can use Sprintf
// templating for the command
func (c Connection) ExecOutputf(s string, params ...interface{}) (string, error) {
opts, args := groupParams(params)
opts, args := GroupParams(params)
return c.ExecOutput(fmt.Sprintf(s, args...), opts...)
}

Expand Down Expand Up @@ -289,18 +289,18 @@ func defaultClient() client {
return c
}

// separates exec.Options from sprintf templating args
func groupParams(params ...interface{}) (opts []exec.Option, args []interface{}) {
// GroupParams separates exec.Options from other sprintf templating args
func GroupParams(params ...interface{}) (opts []exec.Option, args []interface{}) {
for _, v := range params {
if fn, ok := v.(exec.Option); ok {
opts = append(opts, fn)
} else {
switch vv := v.(type) {
case []interface{}:
args = append(args, vv...)
default:
args = append(args, v)
}
switch vv := v.(type) {
case []interface{}:
o, a := GroupParams(vv...)
opts = append(opts, o...)
args = append(args, a...)
case exec.Option:
opts = append(opts, vv)
default:
args = append(args, vv)
}
}
return
Expand Down
56 changes: 56 additions & 0 deletions connection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,35 @@ type Host struct {
Connection
}

type mockClient struct {
commands []string
}

func (m *mockClient) Connect() error { return nil }
func (m *mockClient) Disconnect() {}
func (m *mockClient) Upload(_, _ string, _ ...exec.Option) error { return nil }
func (m *mockClient) IsWindows() bool { return false }
func (m *mockClient) ExecInteractive(_ string) error { return nil }
func (m *mockClient) String() string { return "mockclient" }
func (m *mockClient) Protocol() string { return "null" }
func (m *mockClient) IPAddress() string { return "127.0.0.1" }
func (m *mockClient) IsConnected() bool { return true }
func (m *mockClient) Exec(cmd string, opts ...exec.Option) error {
o := exec.Build(opts...)
cmd, err := o.Command(cmd)
if err != nil {
return err
}

m.commands = append(m.commands, cmd)

return nil
}

var stubSudofunc = func(in string) string {
return "sudo-goes-here " + in
}

func TestHostFunctions(t *testing.T) {
h := Host{
Connection: Connection{
Expand Down Expand Up @@ -58,3 +87,30 @@ func TestOutputWriter(t *testing.T) {
require.NoError(t, h.Exec("echo hello world", exec.Writer(writer)))
require.Equal(t, "hello world\n", writer.String())
}

func TestGrouping(t *testing.T) {
mc := mockClient{}
h := Host{
Connection: Connection{
client: &mc,
sudofunc: stubSudofunc,
},
}

opts, args := GroupParams(h, "ls", 1, exec.HideOutput(), exec.Sudo(h))
require.Len(t, opts, 2)
require.Len(t, args, 3)
}

func TestSudo(t *testing.T) {
mc := mockClient{}
h := Host{
Connection: Connection{
client: &mc,
sudofunc: stubSudofunc,
},
}

require.NoError(t, h.Execf("ls %s", "/tmp", exec.Sudo(h)))
require.Contains(t, mc.commands, "sudo-goes-here ls /tmp")
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/alessio/shellescape v1.4.1
github.com/creasty/defaults v1.5.1
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/masterzen/winrm v0.0.0-20201030141608-56ca5c5f2380
github.com/mitchellh/go-homedir v1.1.0
github.com/sirupsen/logrus v1.8.1
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/testify v1.2.2
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
)
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/crypto v0.0.0-20190222235706-ffb98f73852f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
Expand Down

0 comments on commit 869724d

Please sign in to comment.