From 12a69092d01fbdbc6409eddd7283a1501459cc39 Mon Sep 17 00:00:00 2001 From: Cristi Constantin Date: Tue, 16 Jul 2019 23:28:01 +0100 Subject: [PATCH 1/3] Implement Cmd.Clone --- cmd.go | 18 ++++++++++++++++++ cmd_test.go | 20 ++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/cmd.go b/cmd.go index f01b177..2f003bd 100644 --- a/cmd.go +++ b/cmd.go @@ -153,6 +153,24 @@ func NewCmdOptions(options Options, name string, args ...string) *Cmd { return out } +// Clone clones a Cmd. All the options are transferred, +// but the state of the original object is lost. +func (c *Cmd) Clone() *Cmd { + clone := NewCmdOptions( + Options{ + Buffered: c.buffered, + Streaming: c.Stdout != nil, + }, + c.Name, + c.Args..., + ) + clone.Lock() + defer clone.Unlock() + clone.Dir = c.Dir + clone.Env = c.Env + return clone +} + // Start starts the command and immediately returns a channel that the caller // can use to receive the final Status of the command when it ends. The caller // can start the command and wait like, diff --git a/cmd_test.go b/cmd_test.go index c5e26bc..1bde53e 100644 --- a/cmd_test.go +++ b/cmd_test.go @@ -47,6 +47,26 @@ func TestCmdOK(t *testing.T) { } } +func TestCmdClone(t *testing.T) { + opt := cmd.Options{ + Buffered: true, + } + c1 := cmd.NewCmdOptions(opt, "ls") + c1.Dir = "/tmp/" + c1.Env = []string{"YES=please"} + c2 := c1.Clone() + + if c1.Name != c2.Name { + t.Errorf("got Name %s, expecting %s", c2.Name, c1.Name) + } + if c1.Dir != c2.Dir { + t.Errorf("got Dir %s, expecting %s", c2.Dir, c1.Dir) + } + if diffs := deep.Equal(c1.Env, c2.Env); diffs != nil { + t.Error(diffs) + } +} + func TestCmdNonzeroExit(t *testing.T) { p := cmd.NewCmd("false") gotStatus := <-p.Start() From 52d7b058069a2c55e585931dd7500a1f50ffed82 Mon Sep 17 00:00:00 2001 From: Cristi Constantin Date: Tue, 16 Jul 2019 23:33:41 +0100 Subject: [PATCH 2/3] Updated the comment from Clone --- cmd.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd.go b/cmd.go index 2f003bd..dcefac8 100644 --- a/cmd.go +++ b/cmd.go @@ -155,6 +155,8 @@ func NewCmdOptions(options Options, name string, args ...string) *Cmd { // Clone clones a Cmd. All the options are transferred, // but the state of the original object is lost. +// Cmd is one-use only, so if you need to re-start a Cmd, +// you need to Clone it. func (c *Cmd) Clone() *Cmd { clone := NewCmdOptions( Options{ From 83ee232a3b73303eeec633e8fac13eb7aff34de5 Mon Sep 17 00:00:00 2001 From: Cristi Constantin Date: Thu, 18 Jul 2019 23:00:59 +0100 Subject: [PATCH 3/3] Removed obsolete lock --- cmd.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmd.go b/cmd.go index dcefac8..46787dc 100644 --- a/cmd.go +++ b/cmd.go @@ -154,7 +154,7 @@ func NewCmdOptions(options Options, name string, args ...string) *Cmd { } // Clone clones a Cmd. All the options are transferred, -// but the state of the original object is lost. +// but the internal state of the original object is lost. // Cmd is one-use only, so if you need to re-start a Cmd, // you need to Clone it. func (c *Cmd) Clone() *Cmd { @@ -166,8 +166,6 @@ func (c *Cmd) Clone() *Cmd { c.Name, c.Args..., ) - clone.Lock() - defer clone.Unlock() clone.Dir = c.Dir clone.Env = c.Env return clone