Skip to content

Commit 38269ec

Browse files
committed
pkg/tool/exec: show command arguments in errors as a Go slice
If we render the command arguments as a quoted Go string joining the arguments via spaces, it's always going to be confusing if any of those arguments contain any spaces. We always use a slice now, even when the arguments don't contain any spaces or even when there's just one argument, but consistency seems more important than saving a few characters. An alternative to Go slices with %q quoting, following Go syntax, would be to quote a list of strings in CUE syntax. However, we use Go syntax for lists and string quoting for errors rather consistently, so it seems best to continue doing so here. While here, add a godoc for mkCommand, avoid doing a lookup on the "cmd" field twice, and simplify the code slightly. Updates #3238. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I1a2ae4e0c07236db566ddc9217c1722bb5e99da4 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1197452 Reviewed-by: Roger Peppe <[email protected]> Unity-Result: CUE porcuepine <[email protected]> TryBot-Result: CUEcueckoo <[email protected]>
1 parent 5903ec8 commit 38269ec

File tree

3 files changed

+19
-23
lines changed

3 files changed

+19
-23
lines changed

cmd/cue/cmd/testdata/script/cmd_errcode.txtar

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
! exec cue cmd errcode
22
! stdout .
3-
stderr '^task failed: command "ls --badflags" failed: exit status [12]$'
3+
stderr '^task failed: command \["ls" "--badflags"\] failed: exit status [12]$'
44

55
-- task.cue --
66
package home

cmd/cue/cmd/testdata/script/cmd_execerr.txtar

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ cmp stderr cannotFail-stderr.golden
44
exec cue cmd canFail
55
cmp stdout canFail-stdout.golden
66

7-
# TODO(mvdan): the error message should quote the argument list
8-
# so that any arguments with spaces do not introduce ambiguity.
97
! exec cue cmd withSpaces
108
cmp stderr withSpaces-stderr.golden
119

@@ -14,7 +12,7 @@ module: "example.com"
1412
language: version: "v0.9.0"
1513

1614
-- cannotFail-stderr.golden --
17-
task failed: command "false" failed: exit status 1
15+
task failed: command ["false"] failed: exit status 1
1816
-- canFail-stdout.golden --
1917
errExit:
2018
success=false
@@ -24,7 +22,7 @@ errNotFound:
2422
success=false
2523
hasStderr=true
2624
-- withSpaces-stderr.golden --
27-
task failed: command "false with an ignored argument" failed: exit status 1
25+
task failed: command ["false" "with an ignored argument"] failed: exit status 1
2826
-- foo_tool.cue --
2927
package foo
3028

pkg/tool/exec/exec.go

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,45 +101,43 @@ func (c *execCmd) Run(ctx *task.Context) (res interface{}, err error) {
101101
return nil, fmt.Errorf("command %q failed: %v", doc, err)
102102
}
103103

104-
func mkCommand(ctx *task.Context) (c *exec.Cmd, doc string, err error) {
105-
var bin string
106-
var args []string
107-
104+
// mkCommand builds an [exec.Cmd] from a CUE task value,
105+
// also returning the full list of arguments as a string slice
106+
// so that it can be used in error messages.
107+
func mkCommand(ctx *task.Context) (c *exec.Cmd, doc []string, err error) {
108108
v := ctx.Lookup("cmd")
109109
if ctx.Err != nil {
110-
return nil, "", ctx.Err
110+
return nil, nil, ctx.Err
111111
}
112112

113+
var bin string
114+
var args []string
113115
switch v.Kind() {
114116
case cue.StringKind:
115-
str := ctx.String("cmd")
116-
doc = str
117+
str, _ := v.String()
117118
list := strings.Fields(str)
118-
bin = list[0]
119-
args = append(args, list[1:]...)
119+
bin, args = list[0], list[1:]
120120

121121
case cue.ListKind:
122122
list, _ := v.List()
123123
if !list.Next() {
124-
return nil, "", errors.New("empty command list")
124+
return nil, nil, errors.New("empty command list")
125125
}
126126
bin, err = list.Value().String()
127127
if err != nil {
128-
return nil, "", err
128+
return nil, nil, err
129129
}
130-
doc += bin
131130
for list.Next() {
132131
str, err := list.Value().String()
133132
if err != nil {
134-
return nil, "", err
133+
return nil, nil, err
135134
}
136135
args = append(args, str)
137-
doc += " " + str
138136
}
139137
}
140138

141139
if bin == "" {
142-
return nil, "", errors.New("empty command")
140+
return nil, nil, errors.New("empty command")
143141
}
144142

145143
cmd := exec.CommandContext(ctx.Context, bin, args...)
@@ -153,7 +151,7 @@ func mkCommand(ctx *task.Context) (c *exec.Cmd, doc string, err error) {
153151
v, _ := iter.Value().Default()
154152
str, err := v.String()
155153
if err != nil {
156-
return nil, "", errors.Wrapf(err, v.Pos(),
154+
return nil, nil, errors.Wrapf(err, v.Pos(),
157155
"invalid environment variable value %q", v)
158156
}
159157
cmd.Env = append(cmd.Env, str)
@@ -170,11 +168,11 @@ func mkCommand(ctx *task.Context) (c *exec.Cmd, doc string, err error) {
170168
case cue.IntKind, cue.FloatKind, cue.NumberKind:
171169
str = fmt.Sprint(v)
172170
default:
173-
return nil, "", errors.Newf(v.Pos(),
171+
return nil, nil, errors.Newf(v.Pos(),
174172
"invalid environment variable value %q", v)
175173
}
176174
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", label, str))
177175
}
178176

179-
return cmd, doc, nil
177+
return cmd, append([]string{bin}, args...), nil
180178
}

0 commit comments

Comments
 (0)