Skip to content

Commit

Permalink
parse commands passed to -shellcheck and -pyflakes persistently
Browse files Browse the repository at this point in the history
  • Loading branch information
rhysd committed Jan 4, 2025
1 parent 895f01a commit 930dd9b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
22 changes: 9 additions & 13 deletions process.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func (proc *concurrentProcess) wait() {
// is resolved in this function.
func (proc *concurrentProcess) newCommandRunner(exe string, combineOutput bool) (*externalCommand, error) {
var args []string
p, args, err := findExe(exe)
p, args, err := parseExternalCommand(exe)
if err != nil {
return nil, err
}
Expand All @@ -124,20 +124,16 @@ func (proc *concurrentProcess) newCommandRunner(exe string, combineOutput bool)
return cmd, nil
}

func findExe(exe string) (string, []string, error) {
p, err := execabs.LookPath(exe)
if err == nil {
return p, nil, nil
func parseExternalCommand(cmd string) (string, []string, error) {
a, err := shellwords.Parse(cmd)
if err != nil || len(a) == 0 {
return "", nil, fmt.Errorf("broken command line %q: %w", cmd, err)
}
// See if the command string contains args. As it is best effort, we do not
// handle parse errors.
if exeArgs, _ := shellwords.Parse(exe); len(exeArgs) > 0 {
if p, err := execabs.LookPath(exeArgs[0]); err == nil {
return p, exeArgs[1:], nil
}
c, err := execabs.LookPath(a[0])
if err != nil {
return "", nil, err
}

return "", nil, err
return c, a[1:], nil
}

// externalCommand is struct to run specific command concurrently with concurrentProcess bounding
Expand Down
30 changes: 30 additions & 0 deletions process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,33 @@ func TestProcessCommandExitStatusNonZero(t *testing.T) {
t.Fatalf("Unexpected error happened: %q", msg)
}
}

func TestProcessCommandlineParseError(t *testing.T) {
tests := []struct {
what string
cmd string
want string
}{
{
cmd: "'broken' 'arg",
want: "broken command line",
},
{
cmd: "this-command-does-not-exist",
want: "executable file not found",
},
}

p := newConcurrentProcess(1)
for _, tc := range tests {
t.Run(tc.want, func(t *testing.T) {
_, err := p.newCommandRunner(tc.cmd, true)
if err == nil {
t.Fatalf("Command %q caused no error", tc)
}
if msg := err.Error(); !strings.Contains(msg, tc.want) {
t.Fatalf("Wanted error message %q to contain %q", msg, tc.want)
}
})
}
}

0 comments on commit 930dd9b

Please sign in to comment.