asdf-vm / asdf-nodejs

Node.js plugin for asdf version manager
https://github.com/asdf-vm/asdf
MIT License
885 stars 141 forks source link

[Feature] Implement flexible versions #127

Closed dboune closed 1 year ago

dboune commented 5 years ago

It would be useful if version specification could be supported in a manner similar, or the same, to how versions are handled in package.json.

This could help lead to supporting package.json for node engine version selection, and possibly alias support as well (i.e. lts/dubnium or lts/*), thus better "legacy" .nvmrc support as a side-effect.

Examples

Select only 0.12.0:

node.js 0.12.0

Select latest version from lts-dubnium line:

nodejs ^10.13.0

Select newest locally available AWS Lambda supported runtime:

nodejs 6.10 8.10

Select versions less than or equal to 0.11.8, or greater than 0.11.10:

nodejs <=0.11.8 || >0.11.10

Use Cases

I have a number of small, non-public, nodejs projects that follow minor and patch releases along with an LTS release. They each have docker containers that already does the same. Before a production deploy, or during regular development, I will check the current LTS version, install it, and test. In these cases the specific version isn't terribly important, so long as it is an LTS version. It's very rare that I'd need to pin to a specific version. Using common semver syntax, for example, ^10.13.0 should be sufficient to follow along with the nodejs LTS releases.

Another use case might involve a project that is requires one or more vetted versions within an environment. AWS lambda for example currently only makes 6.10 and 8.10 available. If the project supports both runtimes, it's fair to automatically choose one of those two versions, the latest likely being the general preference.

Implementation

The semantic versioning "standard" doesn't specify the syntax, only the precedence rules which I would suggest honoring due to common use. For example, RubyGems and npm both have similar syntax, but differ in a few ways, so I don't suggest any particular syntax, though I believe for this plugin the npm flavor of semver syntax would be most appropriate. Even a comparatively lightweight implementation would be convenient.

Simplification

Full implementation could then potentially support flexible version selection via package.json as is referenced in #60, but a simplified implementation that only handles selecting the newest version from a specified major and/or minor could be sufficient for general use.

Simplified examples could be a simple as:

Select latest available major or minor in version 10:

nodejs 10
-- OR--
nodejs 10.x
-- OR --
nodejs 10.x.x

Select latest patch version for 8.11:

nodejs 8.11
-- OR --
nodejs 8.11.x

Naturally I'd prefer something a bit more powerful as to allow following an LTS line from it's initial release version onward.

Existing SemVer implementations for bash

https://github.com/qzb/sh-semver (MIT) - May 12, 2016

https://github.com/cloudflare/semver_bash (MIT) - Oct 15, 2013

https://github.com/fsaintjacques/semver-tool (GPL) - Oct 5, 2018

There are of course libraries for other languages, but I imagine that would not be reasonable here.

thbar commented 3 years ago

thus better "legacy" .nvmrc support as a side-effect

This point is an important one: if someone uses asdf-nodejs, on a project relying on nvm, and a project containing say version "12", the user will get the error Checksum not found for version 12. This forces to use nvm instead of asdf-nodejs on a per-project basis.

handreistoicescu commented 3 years ago

thus better "legacy" .nvmrc support as a side-effect

This point is an important one: if someone uses asdf-nodejs, on a project relying on nvm, and a project containing say version "12", the user will get the error Checksum not found for version 12. This forces to use nvm instead of asdf-nodejs on a per-project basis.

Exactly this scenario happens in the popular https://github.com/11ty/eleventy project, where .nvmrc contains a simple 12.

jthegedus commented 3 years ago

Comments on this topic discussed in another issue - https://github.com/asdf-vm/asdf-nodejs/issues/235#issuecomment-885809776

codethief commented 2 years ago

@jthegedus Given the comment you linked, I suppose the present issue should probably be closed(?) (CC @dboune)

augustobmoura commented 1 year ago

We changed the way aliases work on #348, now you need to explicitly opt-in with dynamic ranges on legacy version files (.tool-versions and .nvmrc). The .tool-versions file doesn't support non-deterministic versions, and supporting it on .tool-versions is not a feature we are seeking to implement at the moment.

To enable it, you need to provide an ASDF_NODEJS_LEGACY_FILE_DYNAMIC_STRATEGY environment variable choosing between the latest_available and latest_installed strategies, you can read more about it in the appropriate section on the README of the project. To make this choice permanent you can export said variable from your shell rc file like so:

export ASDF_NODEJS_LEGACY_FILE_DYNAMIC_STRATEGY=latest_installed
# OR
export ASDF_NODEJS_LEGACY_FILE_DYNAMIC_STRATEGY=latest_available

Please update the plugin by running asdf plugin-update nodejs. If a new issue arises with the new implementation please open a new issue.

As for dynamic range versions (E.g.: '16 || <18'), is not something we are implementing. That would be a first on the node version managers, and the fix for it would be to always provide a proper version (or partial match in a legacy version file).