Code Monkey home page Code Monkey logo

nodenv-package-json-engine's Introduction

nodenv-package-json-engine

Latest GitHub Release Latest npm Release Test

This is a plugin for nodenv that detects the Node version based on the engines field of the current tree's package.json file. The $NODENV_VERSION environment variable (set with nodenv shell) and .node-version files still take precedence.

When engines is configured with a range this plugin chooses the greatest installed version matching the range, or exits with an error if none match.

Installation

Installing with Git

$ git clone https://github.com/nodenv/nodenv-package-json-engine.git $(nodenv root)/plugins/nodenv-package-json-engine

Installing with Homebrew

Mac OS X users can install many nodenv plugins with Homebrew.

This is the recommended method of installation if you installed nodenv with Homebrew.

$ brew tap nodenv/nodenv
$ brew install nodenv-package-json-engine

Usage

Once you've installed the plugin you can verify that it's working by cding into a project that has a package.json file with engines and does not have a .node-version file. From anywhere in the project's tree, run nodenv which node.

Contributing

npm install and npm test from within the project.

Credits

package.json inspection and SemVer integration heavily inspired by nvmish [1] [2] and rbenv-bundler-ruby-version.

Shell semver range support provided by sh-semver.

package.json parsing provided by JSON.sh.

nodenv-package-json-engine's People

Contributors

depfu[bot] avatar hurrymaplelad avatar jasonkarns avatar neersighted avatar novemberborn avatar toc-me[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

nodenv-package-json-engine's Issues

`nodenv version-name` doesn't recognize this plugin

package.json has engines.node specified:

$ cat package.json 
{
  "engines": {
    "node": "6.10.3",
    // ...

node -v then behaves as expected:

$ node -v
v6.10.3

However, node version (and node version-name) do not behave as expected (they are returning my globally set version):

$ nodenv version
8.9.4 (set by /Users/i2190/.nodenv/version)

$ nodenv version-name
8.9.4

Better instructions to verify an installation?

Once you've installed the plugin you can verify that it's working by cding into a project that has a package.json file with engines and does not have a .node-version file. From anywhere in the project's tree, run nodenv which node

Doing this in a project that specified a node version that was not currently installed just caused my nodenv to hang (which made me think the plugin was not correctly installed) Perhaps there is a more robust way to verify an installation?

potential refactor to avoid `which`

Nothing to do now, but keep an eye on rbenv/rbenv#739

As you know, nodenv doesn't currently have a hook that allows the selected version to be modified in a consistent fashion. The which hook is suboptimal for a couple reasons (duplication of path to bin; misreported version by version-name and version-origin; misreported version in PS1, etc)

The pull request listed above creates two new hooks that would be ideal for injecting package.json version lookup in a consistent way. if it gets merged into rbenv, then it would be quickly merged into nodenv and we could leverage it here as well.

Thanks for the plugin!

Let NODENV_VERSION take precedence

Like .node-version, it'd be useful if NODENV_VERSION could take precedence. I have a package.json which allows Node.js >=4. This plugin automatically selects the highest version I have installed, which makes it hard to test on older Node.js versions.

Measure and improve performance

This plugin is too slow. When enabled, it makes running nodenv-version-name in shell prompt almost unusable.

Need to track down the cause of the slowness (my money is on JSON.sh) and find ways to speed it up.

Noisy warnings about non semver-compatible nodes

Error message (or warning, really):

/usr/local/var/nodenv/plugins/nodenv-package-json-engine/bin/../node_modules/sh-semver/semver.sh: line 142: [: rc: integer expression expected

This occurs when there exists a nodenv version that doesn't conform to semver. Like say, a version named rc or something.

Vendor sh-semver dep differently

Discussion:

The current npm script (curl) for updating the sh-semver dep is useful. However, it has some deficiencies. Most notably, there is no indication which version is currently bundled.

Some options:

  1. wait and hope for qzb/sh-semver#9 to be merged and we can just add it as an npm dependency
  2. git submodule
  3. git subtree

No. 1 is the best option. But if that PR isn't merged in a few weeks, I suggest we move to 2 or 3. Option 2 has the benefit of being the most well-known. However, submodules aren't typically fetched automatically and as this plugin is likely installed via git in half of all installations, that rather rules this out. (Unless there's a way we can ensure that git installations get the submodule automatically?)

Option 3 has the benefits of getting actual sha/commit references to the sh-semver repo so we know precisely which revision of the dependency we are using. Using the --squash option, we can keep subtree from importing all of sh-semver's history. And the actual contents of sh-semver's repo will be in our repo, a single git-clone of this repo is sufficient without any submodule fetching necessary. Downsides: our repo would contain the full repo of sh-semver, not just the semver.sh file itself. But this can be avoided with some more pre/post scripting (if desired).

For reference, the step for merging subtree is:

git subtree add --prefix deps/sh-semver https://github.com/qzb/sh-semver master --squash

And later to get latest:

git subtree pull --prefix deps/sh-semver https://github.com/qzb/sh-semver master --squash

limit to only installed versions

Awesome plugin!

Do you have any thoughts around restricting the version to those that are installed? As it stands now (correct me if I'm wrong), the plugin will select the maximum version that satisfies the version spec from versions, regardless whether that version is installed on the machine or not. This would mean that the moment semver.io sees new versions, my local install will stop working. Correct?

I opened an issue for discussion at semver.io to accept a list of versions to match against (still satisfying the semver spec, of course) but I don't have much hope that it would be implemented since the feature is kind of an edge case for them.

As an alternative, we could modify the semver spec from package.json by appending the max installed version. (nodenv versions is already a sorted list. We would just need to grab the last one listed, excluding iojs versions; prepend <= to it, and then append that to the semver.io query) This would effectively limit the semver.io response to installed versions.

Given specified engine: >=4.0.0
Given installed versions: 4.0.0, 4.1.0, 4.2.1
semver.io (given >= 4.0.0) would return 5.0.0
but if we query semver.io with >=4.0.0 <=4.2.1 the response would be 4.2.1

In the case that none of the installed versions match the supplied engine spec, we could default to semver.io's standard query:

Given specified engine: >=4.0.0
Given installed versions: 0.10.0, 0.12.0
semver.io: >=4.0.0 <=0.12.0 returns 5.0.0 (seems to return max available if semver spec excludes everything)

Auto-installation

Hey there ๐Ÿ‘‹

Would you consider an auto-installation feature in your plugin?

Right now, I'm relying on multiple project/hooks/configurations on my setup to achieve that (e.g.: watch the package.json file, auto-install and enable the missing Node.js versions). It would be great to have the whole thing in one place.

I'm willing to create a PR by the way, but as I never contributed to nodenv, I would appreciate some guidance on the API design.

Should this be a subcommand?

I see that this plugin exposes a subcommand, thanks to the bin/nodenv-* executable. Is this intentional? Is this something we expect end users will want to check? I can see the utility in being able to inspect the version that nodenv will pick up from the package.json (for debugging purposes), but there might be easier ways.

I can also see the desire to have it as a subcommand for parity. Presently, there exists nodenv-shell, nodenv-local, and nodenv-global. Each of these can be used as setters or getters. For parity, I would recommend that this plugin expose a similarly named subcommand; perhaps nodenv-package or nodenv-package-json to be more similar in spirit to shell, local, and global. For parity, I would also hope the subcommand would function as a setter and actually write the given version to package.json. Additionally, I would hope it accepts a --unset flag to remove the engine specification from package.json. This would make the interface for the version selection match shell/local/global almost exactly.

And if this plugin should be exposing a subcommand, I would suggest that it conform to the standard of other plugins. That is, offering tab completion, help/usage output, etc.

If it is not desired that this plugin expose a subcommand, then I propose the current executable be moved out of bin/ and into libexec/ following the pattern of other plugins and nodenv itself.

If the vote is to retain the subcommand, I can open separate issues for the other features I mentioned so that their discussion doesn't happen here.

Relative paths broken for Homebrew install

After installing with Homebrew I get this error:

โ€บ nodenv which node
/usr/local/bin/nodenv-package-json-engine: line 42: /usr/local/bin/../deps/semver.sh: No such file or directory
package-json-engine: no version satisfying `4.1.2' installed

It's correct, there are no dependencies available in /usr/local; that path is completely wrong. I don't know enough about how Homebrew packages are installed to correct it, but installing via git in the $(nodenv root) directory (the other listed installation method) works perfectly.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.