Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Lifecycle scripts silently fail on win32 if cmd.exe is not on the PATH #5267

Closed
edmorley opened this issue May 13, 2014 · 5 comments
Closed

Comments

@edmorley
Copy link
Contributor

Using node v0.10.28 and npm v1.4.9 on Windows 8.1 x64, inside an MSYS bash shell (where the path is overridden by my .bashrc for other reasons):
package.json:

{
  "scripts": {
    "postinstall": "echo foo"
  }
}

Output:

[/c/npmtest]$ echo $PATH
.:/c/Python27:/c/Python27/Scripts:/mingw/bin:/bin:/c/Program Files/nodejs:/c/Users/Ed/AppData/Roaming/npm
[/c/npmtest]$ npm install
npm WARN package.json @ No description
npm WARN package.json @ No repository field.
npm WARN package.json @ No README data

> @ postinstall c:\npmtest
> echo foo


[/c/npmtest]$ export PATH="$PATH:/c/Windows/System32"
[/c/npmtest]$ npm install
npm WARN package.json @ No description
npm WARN package.json @ No repository field.
npm WARN package.json @ No README data

> @ postinstall c:\npmtest
> echo foo

foo

npm-debug.log from the failed (first) |npm install| above:

19 info postinstall @
20 verbose unsafe-perm in lifecycle true
21 error Error: spawn ENOENT
21 error     at errnoException (child_process.js:998:11)
21 error     at Process.ChildProcess._handle.onexit (child_process.js:789:34)
22 error If you need help, you may report this *entire* log,
22 error including the npm and node versions, at:
22 error     <http://github.com/npm/npm/issues>
23 error System Windows_NT 6.2.9200
24 error command "c:\\Program Files\\nodejs\\node.exe" "c:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "install"
25 error cwd c:\npmtest
26 error node -v v0.10.28
27 error npm -v 1.4.9
28 error syscall spawn
29 error code ENOENT
30 error errno ENOENT
31 verbose exit [ 1, true ]

Similar to nodejs/node-v0.x-archive#7616, this is caused by using 'cmd' without an absolute path, and thus relying on it being present on the PATH. More frustratingly the |npm install| appears to succeed, meaning it took some time before I realised it hadn't and so looked at npm-debug.log

As such, I think:

  1. The spawn ENOENT should be output using log.error(), rather than swallowed silently here:

    npm/lib/utils/lifecycle.js

    Lines 212 to 238 in bf761dd

    var proc = spawn(sh, [shFlag, cmd], conf)
    proc.on("close", function (code, signal) {
    if (signal) {
    process.kill(process.pid, signal);
    } else if (code) {
    var er = new Error("Exit status " + code)
    }
    if (er && !npm.ROLLBACK) {
    log.info(pkg._id, "Failed to exec "+stage+" script")
    er.message = pkg._id + " "
    + stage + ": `" + cmd +"`\n"
    + er.message
    if (er.code !== "EPERM") {
    er.code = "ELIFECYCLE"
    }
    er.pkgid = pkg._id
    er.stage = stage
    er.script = cmd
    er.pkgname = pkg.name
    return cb(er)
    } else if (er) {
    log.error(pkg._id+"."+stage, er)
    log.error(pkg._id+"."+stage, "continuing anyway")
    return cb()
    }
    cb(er)
    })
  2. We could be nice and use:
sh = process.env.comspec || "cmd"

...here:

sh = "cmd"

...where process.env.comspec is the full path to the default interpreter (eg: "C:\Windows\System32\cmd.exe").

@smikes
Copy link
Contributor

smikes commented Nov 23, 2014

Thanks for the bug report.

This looks like a Windows-specific bug (with respect to the cmd in/not in path).

There was a change between npm@1.4 and npm@2.1.9 (I'm not sure exactly which version) to provide more information when lifecycle scripts fail. Can you try installing a newer npm and see if at least the first half of this issue is addressed?

To update npm on Windows, follow the instructions here: https://github.com/npm/npm/wiki/Troubleshooting#upgrading-on-windows

Thanks!

@edmorley
Copy link
Contributor Author

Repeating with node v0.10.33 and npm v2.1.9:

> @ postinstall C:\npmtest
> echo foo


npm ERR! Windows_NT 6.2.9200
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Ed\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! node v0.10.33
npm ERR! npm  v2.1.9
npm ERR! file cmd
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! @ postinstall: `echo foo`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the @ postinstall script 'echo foo'.
npm ERR! This is most likely a problem with the  package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     echo foo
npm ERR! You can get their info via:
npm ERR!     npm owner ls
npm ERR! There is likely additional logging output above.
npm ERR! Windows_NT 6.2.9200
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Ed\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "install"
npm ERR! node v0.10.33
npm ERR! npm  v2.1.9
npm ERR! code ELIFECYCLE

npm ERR! @ postinstall: `echo foo`
npm ERR! Exit status -1
npm ERR!
npm ERR! Failed at the @ postinstall script 'echo foo'.
npm ERR! This is most likely a problem with the  package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     echo foo
npm ERR! You can get their info via:
npm ERR!     npm owner ls
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     C:\npmtest\npm-debug.log

So (1) from the OP is fixed, which just leaves (2).

@edmorley
Copy link
Contributor Author

Looks like (1) was fixed by 5af493e

When I get a moment I'll submit a PR for (2).

@smikes
Copy link
Contributor

smikes commented Nov 23, 2014

Thanks!

@othiym23
Copy link
Contributor

Another alternative is to look at https://npm.im/win-spawn, and add the comspec handling to it (as it does a bunch of other useful things). I've been meaning to look at what it would take to get it in use in npm for a while now.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants