Skip to content

Commit 6249ea2

Browse files
committed
os/exec: add Cmd.String
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent eb00167 commit 6249ea2

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

src/os/exec/exec.go

+19
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,25 @@ func CommandContext(ctx context.Context, name string, arg ...string) *Cmd {
190190
return cmd
191191
}
192192

193+
// String returns a human-readable description of c.
194+
// It is intended only for debugging.
195+
// In particular, it is not suitable for use as input to a shell.
196+
// The output of String may vary across Go releases.
197+
func (c *Cmd) String() string {
198+
if c.lookPathErr != nil {
199+
// failed to resolve path; report the original requested path (plus args)
200+
return strings.Join(c.Args, " ")
201+
}
202+
// report the exact executable path (plus args)
203+
b := new(strings.Builder)
204+
b.WriteString(c.Path)
205+
for _, a := range c.Args[1:] {
206+
b.WriteByte(' ')
207+
b.WriteString(a)
208+
}
209+
return b.String()
210+
}
211+
193212
// interfaceEqual protects against panics from doing equality tests on
194213
// two interfaces with non-comparable underlying types.
195214
func interfaceEqual(a, b interface{}) bool {

src/os/exec/exec_test.go

+34
Original file line numberDiff line numberDiff line change
@@ -1150,3 +1150,37 @@ func TestDedupEnvEcho(t *testing.T) {
11501150
t.Errorf("output = %q; want %q", got, want)
11511151
}
11521152
}
1153+
1154+
func TestString(t *testing.T) {
1155+
echoPath, err := exec.LookPath("echo")
1156+
if err != nil {
1157+
t.Skip(err)
1158+
}
1159+
tests := [...]struct {
1160+
path string
1161+
args []string
1162+
want string
1163+
}{
1164+
{"echo", nil, echoPath},
1165+
{"echo", []string{"a"}, echoPath + " a"},
1166+
{"echo", []string{"a", "b"}, echoPath + " a b"},
1167+
}
1168+
for _, test := range tests {
1169+
cmd := exec.Command(test.path, test.args...)
1170+
if got := cmd.String(); got != test.want {
1171+
t.Errorf("String(%q, %q) = %q, want %q", test.path, test.args, got, test.want)
1172+
}
1173+
}
1174+
}
1175+
1176+
func TestStringPathNotResolved(t *testing.T) {
1177+
_, err := exec.LookPath("makemeasandwich")
1178+
if err == nil {
1179+
t.Skip("wow, thanks")
1180+
}
1181+
cmd := exec.Command("makemeasandwich", "-lettuce")
1182+
want := "makemeasandwich -lettuce"
1183+
if got := cmd.String(); got != want {
1184+
t.Errorf("String(%q, %q) = %q, want %q", "makemeasandwich", "-lettuce", got, want)
1185+
}
1186+
}

0 commit comments

Comments
 (0)