Skip to content

Commit 930dd9b

Browse files
committed
parse commands passed to -shellcheck and -pyflakes persistently
1 parent 895f01a commit 930dd9b

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

process.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (proc *concurrentProcess) wait() {
111111
// is resolved in this function.
112112
func (proc *concurrentProcess) newCommandRunner(exe string, combineOutput bool) (*externalCommand, error) {
113113
var args []string
114-
p, args, err := findExe(exe)
114+
p, args, err := parseExternalCommand(exe)
115115
if err != nil {
116116
return nil, err
117117
}
@@ -124,20 +124,16 @@ func (proc *concurrentProcess) newCommandRunner(exe string, combineOutput bool)
124124
return cmd, nil
125125
}
126126

127-
func findExe(exe string) (string, []string, error) {
128-
p, err := execabs.LookPath(exe)
129-
if err == nil {
130-
return p, nil, nil
127+
func parseExternalCommand(cmd string) (string, []string, error) {
128+
a, err := shellwords.Parse(cmd)
129+
if err != nil || len(a) == 0 {
130+
return "", nil, fmt.Errorf("broken command line %q: %w", cmd, err)
131131
}
132-
// See if the command string contains args. As it is best effort, we do not
133-
// handle parse errors.
134-
if exeArgs, _ := shellwords.Parse(exe); len(exeArgs) > 0 {
135-
if p, err := execabs.LookPath(exeArgs[0]); err == nil {
136-
return p, exeArgs[1:], nil
137-
}
132+
c, err := execabs.LookPath(a[0])
133+
if err != nil {
134+
return "", nil, err
138135
}
139-
140-
return "", nil, err
136+
return c, a[1:], nil
141137
}
142138

143139
// externalCommand is struct to run specific command concurrently with concurrentProcess bounding

process_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,3 +343,33 @@ func TestProcessCommandExitStatusNonZero(t *testing.T) {
343343
t.Fatalf("Unexpected error happened: %q", msg)
344344
}
345345
}
346+
347+
func TestProcessCommandlineParseError(t *testing.T) {
348+
tests := []struct {
349+
what string
350+
cmd string
351+
want string
352+
}{
353+
{
354+
cmd: "'broken' 'arg",
355+
want: "broken command line",
356+
},
357+
{
358+
cmd: "this-command-does-not-exist",
359+
want: "executable file not found",
360+
},
361+
}
362+
363+
p := newConcurrentProcess(1)
364+
for _, tc := range tests {
365+
t.Run(tc.want, func(t *testing.T) {
366+
_, err := p.newCommandRunner(tc.cmd, true)
367+
if err == nil {
368+
t.Fatalf("Command %q caused no error", tc)
369+
}
370+
if msg := err.Error(); !strings.Contains(msg, tc.want) {
371+
t.Fatalf("Wanted error message %q to contain %q", msg, tc.want)
372+
}
373+
})
374+
}
375+
}

0 commit comments

Comments
 (0)