]> Cypherpunks repositories - gostls13.git/commitdiff
os/exec: add Cmd.String
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 20 Mar 2019 21:09:51 +0000 (14:09 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 21 Mar 2019 13:19:55 +0000 (13:19 +0000)
The initial implementation is intentionally simple.
Let's see how far it gets us.

Fixes #30638

Change-Id: I240afae2b401744ab2ff2a69952c4eb0fd3feb56
Reviewed-on: https://go-review.googlesource.com/c/go/+/168518
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/os/exec/exec.go
src/os/exec/exec_test.go

index 424b49cf061dbfae39711e4ef0a688c31027c85a..d481cf7798d0ddc0a09adcb4d53faa0fc048e139 100644 (file)
@@ -190,6 +190,25 @@ func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
        return cmd
 }
 
+// String returns a human-readable description of c.
+// It is intended only for debugging.
+// In particular, it is not suitable for use as input to a shell.
+// The output of String may vary across Go releases.
+func (c *Cmd) String() string {
+       if c.lookPathErr != nil {
+               // failed to resolve path; report the original requested path (plus args)
+               return strings.Join(c.Args, " ")
+       }
+       // report the exact executable path (plus args)
+       b := new(strings.Builder)
+       b.WriteString(c.Path)
+       for _, a := range c.Args[1:] {
+               b.WriteByte(' ')
+               b.WriteString(a)
+       }
+       return b.String()
+}
+
 // interfaceEqual protects against panics from doing equality tests on
 // two interfaces with non-comparable underlying types.
 func interfaceEqual(a, b interface{}) bool {
index 3e6b7bb95e1580a974f96df63b4b1c84eff8e1c9..26be62dd920bb2c796dfdbd3ff05d89dc02a3b0f 100644 (file)
@@ -1150,3 +1150,37 @@ func TestDedupEnvEcho(t *testing.T) {
                t.Errorf("output = %q; want %q", got, want)
        }
 }
+
+func TestString(t *testing.T) {
+       echoPath, err := exec.LookPath("echo")
+       if err != nil {
+               t.Skip(err)
+       }
+       tests := [...]struct {
+               path string
+               args []string
+               want string
+       }{
+               {"echo", nil, echoPath},
+               {"echo", []string{"a"}, echoPath + " a"},
+               {"echo", []string{"a", "b"}, echoPath + " a b"},
+       }
+       for _, test := range tests {
+               cmd := exec.Command(test.path, test.args...)
+               if got := cmd.String(); got != test.want {
+                       t.Errorf("String(%q, %q) = %q, want %q", test.path, test.args, got, test.want)
+               }
+       }
+}
+
+func TestStringPathNotResolved(t *testing.T) {
+       _, err := exec.LookPath("makemeasandwich")
+       if err == nil {
+               t.Skip("wow, thanks")
+       }
+       cmd := exec.Command("makemeasandwich", "-lettuce")
+       want := "makemeasandwich -lettuce"
+       if got := cmd.String(); got != want {
+               t.Errorf("String(%q, %q) = %q, want %q", "makemeasandwich", "-lettuce", got, want)
+       }
+}