ghooks-org/ghooks

Installation fails on npm ≤ 2.15.2

ta2edchimp opened this issue · 13 comments

When ghooks is installed as a dependency using npm@"^2.0.0" (as done here), its own dependency opt-cli cannot be found when running the install npm script.

I found that to be an issue related only to npm versions 2.15.*.
npm versions ≤ 2.14.22 and ≥ 3.0.0 are not affected.

Don't know if this is something we should invest much more energy into ... ¯_(ツ)_/¯

Interesting thing is, this behavior not reliably reproducible:

(The log output is from a local test package with ghooks and opt-cli as its sole dependencies.)

$ npm i -g npm@"^2.0.0"
/usr/local/bin/npm -> /usr/local/lib/node_modules/npm/bin/npm-cli.js
npm@2.15.2 /usr/local/lib/node_modules/npm
$ npm i
npm WARN package.json test-case@1.0.0 No description
npm WARN package.json test-case@1.0.0 No repository field.
npm WARN package.json test-case@1.0.0 No README data
\
> ghooks@1.1.1 install <snip>/test-case/node_modules/ghooks
> opt --out ghooks-install --exec "node ./bin/install"

This does not seem to be a git project.
Although ghooks was installed, the actual git hooks have not.
Run "git init" and then "npm run ghooks install".

Please ignore this message if you are not using ghooks directly.
opt-cli@1.4.0 node_modules/opt-cli
├── spawn-command@0.0.2-1
├── manage-path@2.0.0
├── lodash.clone@4.3.1 (lodash._baseclone@4.5.3)
└── cli@0.11.2 (exit@0.1.2, glob@5.0.15)

ghooks@1.1.1 node_modules/ghooks
├── spawn-command@0.0.2
├── manage-path@2.0.0
├── lodash.clone@4.3.2 (lodash._baseclone@4.5.3)
├── path-exists@2.1.0 (pinkie-promise@2.0.0)
├── findup@0.1.5 (commander@2.1.0, colors@0.6.2)
└── execa@0.2.2 (strip-eof@1.0.0, path-key@1.0.0, npm-run-path@1.0.0, object-assign@4.0.1, cross-spawn-async@2.1.9)
$ rm -rf node_modules
$ npm i
npm WARN package.json test-case@1.0.0 No description
npm WARN package.json test-case@1.0.0 No repository field.
npm WARN package.json test-case@1.0.0 No README data

> ghooks@1.1.1 install <snip>/test-case/node_modules/ghooks
> opt --out ghooks-install --exec "node ./bin/install"

sh: opt: command not found
npm ERR! Darwin 15.4.0
npm ERR! argv "node" "/usr/local/bin/npm" "i"
npm ERR! node v0.12.12
npm ERR! npm  v2.15.2
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn

npm ERR! ghooks@1.1.1 install: `opt --out ghooks-install --exec "node ./bin/install"`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the ghooks@1.1.1 install script 'opt --out ghooks-install --exec "node ./bin/install"'.
npm ERR! This is most likely a problem with the ghooks package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     opt --out ghooks-install --exec "node ./bin/install"
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs ghooks
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!
npm ERR!     npm owner ls ghooks
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!    <snip>/test-case/npm-debug.log

wow, this is weird… We have opt-cli as a dependency of ghooks
I can't really think about a reason why this would happen.
Maybe using postinstall would help (although we can't reliably tell the order those things run)? Or this would be a case where using bundledDependencies (cc/ @kentcdodds) would be useful?

Had the same idea about bundledDependencies...

What I observed, throughout the whole day until now is, that there's absolutely no guarantee as to in which order the dependencies are resolved in the test case above, opt-cli sometimes gets installed before ghooks and sometimes after it.
In the second case (on npm 2.15.x), ghooks' install script will be invoked (and fail) directly after it has been installed, but opt-cli has not yet, although npm knows, that it's also a dependency for ghooks.

For the record, postinstall will also not fix this, as it gets called immediately after install.

So it'll still be

install ghooks
postinstall ghooks
install opt-cli
postinstall opt-cli

(I let a script run for approx. 2 hours, constantly removing the node_modules, switching node versions between 0.10.43 and 0.12.12, installing npm 2.15.x and running npm install with opt-cli and ghooks as the only dependencies.)

Something to consider... I think we may be an exception to this, but from the npm docs:

Don't use install. Use a .gyp file for compilation, and prepublish for anything else. You should almost never have to explicitly set a preinstall or install script. If you are doing this, please consider if there is another option. The only valid use of install or preinstall scripts is for compilation which must be done on the target architecture.

We could do the following:

  • create some bin/module-install
  • invoke the initial npm install script in a dependency agnostic "Node core" way
  • catch any errors and provide an info to the user to manually invoke after installation completes
  • call bin/module-install as npm install script instead

Wouldn't this suffice, given the fact only a thin margin of versions of npm are affected?
What do you think? I'd do a PR tomorrow if you guys approve ...

And maybe we should add at least one Node <= 0.12 with npm 2.15.x build to the builds on Travis.

I think what you've suggested sounds alright

@ta2edchimp, @gtramontina any follow up on this? I'm stuck on npm 2.15.5 right now and this breaks everything 😞

Unfortunately not.
I'll try to set up a PR with my proposal from #71 (comment) during the day.

@cwhenderson20 if you have the time for it, could you try to change the dependency of ghooks to the following (it's the #109 PR's branch), see if that would be sufficient to solve the issue for you and report back?

  "devDependencies": {
    "ghooks": "git://github.com/ta2edchimp/ghooks.git#fix/npm-2.15-compat"
  }

Closing in favor of #210