Skip to content

path.normalize(command) breaks local command on rebased cwd #90

@evocateur

Description

@evocateur

Problem

The recent ginormous v6 commit introduced an unconditional path.normalize() wrapping the command, which breaks spawn('./foo', { cwd: 'subdir' ):

command: path.normalize(command),

I can't say what bug it was intended to fix, as the giant commit perverts all useful context. It is definitely breaking posix "local relative on rebased cwd" calls.

Reproduction

Async vs sync makes no difference, but the sync calls are easier to demonstrate.

subdir/foo:

#!/usr/bin/env node
console.log("foo");

test.js:

const path = require('path');
const childProcess = require('child_process');
const spawn = require('cross-spawn');

const cmd = './foo';
const opts = { cwd: path.resolve(__dirname, 'subdir') };

// works
childProcess.spawnSync(cmd, opts) // stdout: "foo"

// fails
spawn.sync(cmd, opts) // throws ENOENT "foo"

Upgrading cross-spawn to v6 in https://github.com/yargs/yargs current master with no other changes will demonstrate this "in the wild".

yargs test failure log
  485 passing (3s)
  10 failing

  1) integration tests should run as a shell script with no arguments:
     Uncaught Error: spawn bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  2) integration tests should run as a shell script with arguments:
     Uncaught Error: spawn bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  3) integration tests allows --help to be completed without returning help message:
     Uncaught Error: spawn bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  4) integration tests flushes all output when --help is executed:
     Uncaught Error: spawn issue-497.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  5) integration tests correctly fills positional command args with preceding option:
     Uncaught Error: spawn opt-assignment-and-positional-command-arg.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  6) integration tests correctly fills positional command args with = assignment in preceding option:
     Uncaught Error: spawn opt-assignment-and-positional-command-arg.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  7) integration tests load root package.json version # defaults to appropriate version # when yargs is installed normally:
     Uncaught Error: spawn normal-bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  8) integration tests load root package.json version # defaults to appropriate version # when yargs is symlinked:
     Uncaught Error: spawn symlink-bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  9) integration tests load root package.json parser settings reads parser config settings when yargs is installed normally:
     Uncaught Error: spawn normal-bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

  10) integration tests load root package.json parser settings reads parser config settings when yargs is installed as a symlink:
     Uncaught Error: spawn symlink-bin.js ENOENT
      at _errnoException (util.js:1024:11)
      at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
      at onErrorNT (internal/child_process.js:372:16)
      at _combinedTickCallback (internal/process/next_tick.js:138:11)
      at process._tickCallback (internal/process/next_tick.js:180:9)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions