-
Notifications
You must be signed in to change notification settings - Fork 788
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use best-matching version #352
Comments
Hm, currently asdf is very dumb about versions, they can actually be anything. I mean, not only semantic versions, but things like "system", "ref:master", even "foobar" is valid (I have things like "java intellij" or "android-tools brew" used with my asdf-link plugin) My primary use for asdf is keeping a single So I'd say implementing this would cause more problems (not allowing you to not be really sure what was the exact version you are using just by looking at the source code of your project). I'd consider this issue as something not desirable. But if you really like to have the behaviour you want, you could easily do: ln -s ~/.asdf/installs/ruby/2.3.7 ~/.asdf/installs/ruby/2.3 Yes, you'd have to update that symlink as you see fit. But again it's only on your development environment and not for all people in the world ^^. |
That's definitely one of my use cases, but I also use it for side projects, scripts, etc. where I don't care about the exact version. This change wouldn't impact any existing users. If you specify 2.3.7, it will use that exact version. If you just specify 2.3, it will find the best versions available. In my mind, it just adds more flexibility and doesn't take anything away. |
Perhaps something better would be allowing some custom hooks for pre-post tool installation (so you can create the symlinks I mentioned, IIRC other people have asked for executing some commands like reshiming, or installing essential packages after tool installation. Can't remember right now if there's an issue for that). Again, I guess I understand your use case (and yeah, for things like postgres, I think it'd make sense not to care about the minor version), but I'm still not convinced asdf should do anything of this kind by itself. If it did, you'd also have to have a way to ask asdf what it understands for Actually you could create a gist of such a script as a prove of concept, and it doesn't even have to be in asdf core, it can source all the asdf functions to get the list of installed versions and stuff, and just create the symlink. I'd like to know what other people think on this matter. I'm just in favor of not adding unnecessary complexity (best code is deleted-or-never-written-code) and keeping asdf as agnostic as possible (keep in mind that every tool can have its own versioning semantics or none at all). |
Yeah, I think hooks could support what I want to do. I can imagine post-install being useful for a bunch of things |
#216 #226 are two issues related to this. I agree with @vic that this is the sort of thing that doesn't belong in asdf core. Every tool can have it's own versioning quirks. For example, the Erlang plugin has to deal with two version schemes since the way Erlang is versioned changed. There is also no guarantee to that tools will continue to use semantic versioning. In the future new version schemes could become popular. To do this properly we'd have to account for all of this, and handle every scenario correctly. In my experience just trying to sort semantic versions in Bash is hard enough to make me want to avoid this entirely in asdf core (we've even got stuff in the plugin guide about this). Now there are other solutions to this problem that wouldn't necessarily require this to be implemented in asdf. As @vic said a simple script to create symlinks could achieve what you need. You could also create some sort of "resolver" Bash script that would actually generate the |
This would be great. Are there plans for doing it? I think it would be especially useful for people that come from nvm, where this is supported. |
Awesome! I'll give it a try |
+1 for the feature coming from rvm (ruby). It is even more unexpected when Pre/post install scripts won't fix the issue if no suitable version was installed beforehand. On the other hand, introducing fuzzy matching between version specified in Great tool btw, it feels nice to drop rvm/kiex/nvm and use a single version manager 👍. UPD: actually, right now plugins that support |
New user of asdf, and enjoying it. I'd also be pleased to see this. I'd suggest that Use CaseI 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 would be sufficient to follow along with the nodejs LTS releases. ImplementationThe 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. Even a comparatively lightweight implementation like azhi references above would be convenient. Edit: After reading Stratus3D's comment above, if this can be done in the individual plugins, that would be fantastic. |
Could this perhaps be something that plugins could opt in to doing. I wouldn't want to assume that every language has the same versioning semantics. However, the Ruby plugin could know that 2.5.3 is semantically OB for In other words, the Ruby plugin is best positioned to decide whether it should add a
This would be consistent with chruby and perhaps others like RVM/rbenv, without opting in all languages to such behaviour. |
FWIW, I use a tactic like the following for a few langs to build my $ asdf list all ruby |
grep -vE 'truffle|rbx|ree|jruby|preview|-rc[0-9]|mruby|maglev|-dev' |
sort -r |
xargs echo ruby |
tee -a ~/.tool-versions
ruby 2.7.0 2.6.5 2.6.4 2.6.3 2.6.2 2.6.1 2.6.0 2.5.7 2.5.6 2.5.5 2.5.4 2.5.3 2.5.2 2.5.1 2.5.0 2.4.9 2.4.8 2.4.7 2.4.6 2
.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 2.3.8 2.3.7 2.3.6 2.3.5 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 2.2.7 2.2.6 2.2.5 2
.2.4 2.2.3 2.2.2 2.2.10 2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 2.1.2 2.1.10 2.1.1 2.1.0 2.0.0-p648 2.0.0-
p647 2.0.0-p645 2.0.0-p643 2.0.0-p598 2.0.0-p594 2.0.0-p576 2.0.0-p481 2.0.0-p451 2.0.0-p353 2.0.0-p247 2.0.0-p195 2.0.0
-p0 1.9.3-p551 1.9.3-p550 1.9.3-p547 1.9.3-p545 1.9.3-p484 1.9.3-p448 1.9.3-p429 1.9.3-p426 1.9.3-p392 1.9.3-p385 1.9.3-
p374 1.9.3-p362 1.9.3-p327 1.9.3-p286 1.9.3-p194 1.9.3-p125 1.9.3-p105 1.9.3-p0 1.9.2-p330 1.9.2-p326 1.9.2-p320 1.9.2-p
318 1.9.2-p290 1.9.2-p180 1.9.2-p136 1.9.2-p0 1.9.1-p431 1.9.1-p430 1.9.1-p429 1.9.1-p378 1.9.1-p376 1.9.1-p243 1.9.1-p1
29 1.9.1-p0 1.9.0-5 1.9.0-4 1.9.0-3 1.9.0-2 1.9.0-1 1.9.0-0 1.8.7-p72 1.8.7-p71 1.8.7-p375 1.8.7-p374 1.8.7-p373 1.8.7-p
371 1.8.7-p370 1.8.7-p358 1.8.7-p357 1.8.7-p352 1.8.7-p334 1.8.7-p330 1.8.7-p302 1.8.7-p301 1.8.7-p299 1.8.7-p249 1.8.7-
p248 1.8.7-p22 1.8.7-p174 1.8.7-p173 1.8.7-p17 1.8.7-p160 1.8.7 1.8.6-p420 1.8.6-p399 1.8.6-p398 1.8.6-p388 1.8.6-p383 1
.8.6-p369 1.8.6-p368 1.8.6-p36 1.8.6-p287 1.8.6-p286 1.8.6-p230 1.8.6-p114 1.8.6-p111 1.8.6-p110 1.8.6 1.8.5-p52 1.8.5-p
231 1.8.5-p115 1.8.5-p114 1.8.5-p113 |
Maybe plug |
I'd like to propose a solution that
I think it's best expressed by an example interaction:
There's no need for a knowledge of semantic versioning in core (or anywhere else). It would simply show partial matches when there is no exact match to an interactive command. |
interesting proposal... when is this prompt displayed if you aren't explicitly choosing a version (for instance, you've If it is possible to do well given the above, it seems nice. I'd advocate we sort the version list with |
@brandondrew proposal is interesting 🤔 |
Ah fair enough, though I think one could port the heuristic it uses fairly simply if the outcome was satisfactory.
Agreed. Though is this a substring match or a prefix match? Some versions have a "type" prefix, such as ruby's |
@jthegedus Thanks! |
🤔 I'm not sure what is best... I was thinking of prefixes but may be the the things that match from the beginning can be prioritized and other substring matches can be below... or maybe substring matches only appear if no prefix matches are available? I guess it's open to experimentation... |
Honestly all the |
I was hoping I could define multiple compatible versions, like this:
Basically like package.json's dependencies. I think you want to switch to the highest compatible version every time. Also, can ASDF please automatically install the best compatible version? I'm asking too much for an open source / free product maybe :) |
You can filter on most commands, eg: asdf list all java adopt
# or
asdf list all java zulu
# another command
asdf current java
# another command
asdf latest nodejs
# with filter
asdf latest nodejs 14 |
It's not that it's too much, it's just antithetical to the purpose of tools like So far, I think @brandondrew has proposed the soution that best aligns Using # works (if the nodejs version is installed)
asdf local nodejs latest
# does not work
asdf local nodejs latest 14 If the filter worked that would somewhat help the situation (I think #633 introduces that). It would also probably make sense to just auto-install the version being added to Nonetheless, IMO the idea of using non-specific version in I say all this as the OP of #226 |
I've just come to asdf and found myself at this ticket having done:
From a CI and repeatable builds point of view, I can see a reason for enforcing an exact version. Perhaps the way to go would be to allow developer workstations to be lax, but CI to be exact. This is done well in the npm ecosystem via yarn.lock and package-lock.json, but could be done much more concisely here:
This would result in .tool-versions:
And if using asdf in CI, then we should then be able to have
and it'll install version 16.11.1 As a newbie, I wonder whether I'm missing something here? Edit: And for the java projects I work on I really would not want to have multiple versions of each of Java 11 or Java 17 which starts getting rather bloated (although the total size of node_modules across various projects on my system has redefined the term bloat 😭 ) |
After having read carefully the whole thread, it seems that there are some subtle differences between the needs of the different users here. To sum up what I have grasped so far:
The example of
The benefits are obvious on the developer workstation, as already stated above. Moreover, it could bring quite easily to ASDF some missing (or tricky to achieve) features that can be found in other version managers (
Latest note, this lack of “best-matching version” is for me something that still brings my preference to other version managers over ASDF on my workstation ( |
The reproducibility point still applies to workstations though (the classic "works on my machine" problem).
I mentioned the usage of I still prefer to have a custom hook for each tool. Semver works really well for node.js but not so much for other languages. There are also different tags in different stacks ( I'm my opinion asdf in general is hardly a tool for CI/CD. We already have good ways of versioning environments (be it containers or platform-specific pipeline configuration), environments hardly need to switch tool versions between directories/contexts. I think we should focus primarily on developer experience and versatility. Being a universal tool versioning manager means just being flexible enough for all these different tools and use cases |
+1 for your mention on To make it short and simple, given two developers, one with NodeJS 16.9.1 on his workstation, the other with NodeJS 16.12.0, being able to get the same project working with a simple OK, in my example, it's NodeJS and it's based on a semver logic, but my proposals try to give some lead on the different ways to comply with this need. To be honest, not being able to do that is, according to me, a weakness of ASDF compared to other version managers. I don't really see how it can be efficiently handle by plugins or hooks. Perhaps you can give me some helpful feedback of why I may be wrong and some acceptable compromises that I missed. |
You are not wrong, you can't be wrong in expressing your opinion. I was just adding something extra from my side. I did mention the idea of a Pinning on a version is not that hard. For example, if your project only works on node 16.x you can pin it to the latest version for that major version (16.13.1), and everyone will get the same version. So what are the benefits of having a dynamic version over a pinned version? I only see automatic updates for bug fixes and skipping some bits of commits when changing |
Sorry for my misunderstanding, but I don't grasp your proposal here. What do you suggest by using tag or aliases and how it answers the concern I have explained?
It's just something super handy when you get some developers with some slightly different minor/patch versions of the build/run tools on their workstations. For instance, when you have some automatic security updates on your workstation, a new minor/patch version can be automatically installed. In the case where you will be able to use an already provided system installation (see the benefits in my first message), your build/run can suddenly stop working with the requirements of ASDF-VM. I concede that when you install the exact version through ASDF-VM for each product you work on, you don't get this problem, but it can be very tedious and hog a lot of disk space with a lot of different but almost identical versions of the same tool. It's precisely this concern that make me post at first (again, it's detailed in my last comment). |
Maybe one way to "easily" fix this would be to create symlinks to the latest version? I tried this as a workaround for compatibility with So, whenever a version of something is installed, asdf could try to parse the version of that tool as a semver ( This requires only an additional step after installing a tool, no change in logic during installation or shimming. Using symlinks to manage tool versions is how the nix package manager handles things, too, and it seems quite elegant to me. |
To throw my own use case onto the pile, consider:
Desired behavior:
Actual behavior:
I have to think far more use cases would benefit from more flexible version pinning, as opposed to necessarily experiencing dependency rot for want of an >= feature. |
This is a serious issue. I already have tons of different Java installations because this feature is lacking.
I work with many projects, and I don't mind the minor versions of those Java versions. I only do care about the major, i.e. 11, 17 etc. Not having this feature makes me want to disable this tool for multi-project workflows. I don't want to install a 6th version of java-11 into my machine. |
@Dogacel just use rtx |
It's not called rtx anymore, but that is actually a pretty good suggestion. See mise.jdx.dev |
I am new to this tool and I am wondering how possible it would be to allow .tool_versions to accept a variable like: Instead of:
This could perhaps be:
Those of us which support dozens of libraries would then only have to update a single env when we update our Java runtimes. CI would need to define whatever variable we would define but that would also allow us to lock version for reproducibility without forcing all local dev envs to lock step update. As someone else has mentioned (for Java at least) minor patch releases tend to not be so important for Java. |
You can do that by setting |
@kennyp I support some number of projects using Java 8 and others using a more modern version so I guess I could do this with some hook via cd? I was just thinking for Ruby and Java (two things I use) making
So the idea is not best matching but it does feel like an alternative which would take most of the sting out of the need for this issue. |
@enebo You could use P.S. |
Couldn't be start simple and check if matches a single version that starts with that input?
In which I could This way it could work easily for other plugins that don't have semantical versions. I was playing around to see if I could get something working and made a PR here |
The need for this is quite high and I reached a point where I really consider writing a script that can perform the action of updating tool versions. My primary need is for python, and I use multiple versions of python, but I do not want to get behind. New releases happen quite often, almost monthly, for each major python version. PS. I have 7 python versions in my global
|
Steps to reproduce
Expected behavior
Use version 2.3.7, since it is the highest version that matches the given value.
Actual behavior
version 2.3 is not installed for ruby
Environment
OS: macOS 10.13.6
asdf version: 0.5.1
Similar to #226, I'd love to be able to be less specific about versions and get the highest matching installed version. For something like postgres, I might just say
9
or10
, for ruby, I might use major and minor. I think this would make the tool a lot more useable.If this sounds good, I could probably put together a PR, although I'm not sure how much overlap there will be in the logic for installing a highest-matching version.
The text was updated successfully, but these errors were encountered: