Giter Site home page Giter Site logo

asdf-vm / asdf Goto Github PK

View Code? Open in Web Editor NEW
20.4K 123.0 749.0 2.88 MB

Extendable version manager with support for Ruby, Node.js, Elixir, Erlang & more

Home Page: https://asdf-vm.com/

License: MIT License

Shell 90.32% Elvish 2.82% Python 3.61% PowerShell 0.29% Nushell 2.96%
version-manager ruby multiple-languages cli shell asdf-vm bash elvish fish node

asdf's Introduction

asdf Lint Tests

Manage multiple runtime versions with a single CLI tool, extendable via plugins - docs at asdf-vm.com

asdf is a CLI tool that can manage multiple language runtime versions on a per-project basis. It is like gvm, nvm, rbenv & pyenv (and more) all in one! Simply install your language's plugin!

Why use asdf?

  • single CLI for multiple languages
  • consistent commands to manage all your languages
  • single global config keeping defaults in one place
  • single .tool-versions config file per project
  • support for existing config files .node-version, .nvmrc, .ruby-version for easy migration
  • automatically switches runtime versions as you traverse your directories
  • simple plugin system to add support for your language of choice
  • shell completion available for common shells (Bash, Zsh, Fish, Elvish)

Documentation

Please head over to the documentation site for more information!

Contributing

See CONTRIBUTING.md in the repo or the Contributing section on the docs site.

Community & Questions

  • FAQ
  • GitHub Issues GitHub Issues: report a bug or raise a feature request to the asdf core team
  • StackOverflow Tag StackOverflow Tag: see existing Q&A for asdf. Some of the core team watch this tag in addition to our helpful community

Ballad of asdf

Once upon a time there was a programming language
There were many versions of it
So people wrote a version manager for it
To switch between versions for projects
Different, old, new.

Then there came more programming languages
So there came more version managers
And many commands for them

I installed a lot of them
I learnt a lot of commands

Then I said, just one more version manager
Which I will write instead

So, there came another version manager
asdf version manager - https://github.com/asdf-vm/asdf

A version manager so extendable
for which anyone can create a plugin
To support their favourite language
No more installing more version managers
Or learning more commands


This was the mail I wrote to a few friends to tell them about the project. Thanks to @roshanvid for suggesting that this go into the readme
@HashNuke

asdf's People

Contributors

aj-foster avatar android10 avatar danhper avatar deiga avatar dependabot[bot] avatar doughsay avatar elijahr avatar fcrespo82 avatar github-actions[bot] avatar hashnuke avatar hyperupcall avatar jonknapp avatar joschi avatar joseluis-fw avatar jthegedus avatar jwashton avatar kennyp avatar klane avatar magejohn avatar mig4 avatar mtatheonly avatar rliebz avatar rockwood avatar smashedtoatoms avatar stratus3d avatar tejanium avatar threkk avatar vic avatar yacchi avatar ypid 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  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  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  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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asdf's Issues

Order of `list-all`

While setting up my environment, I realised that the erlang and elixir plugin do list the available versions from newest to oldest, while nodejs does it from oldest to newest.

There should be either a "filter" in asdf which does sorts all the version into a specific order, or a requirement to the plugins to list the versions in a particular order.

I'd prefer to see the most recent version as the last item, such that one can see the most recent version of something even in unscrollable environments.

Other Architecture Support

I'm running Fedora Server on a Raspberry Pi (because awesome), and was hoping to install nodejs via asdf. Unfortunately as far as I can tell asdf only offers the standard Intel packages. Node.js does offer ARM binaries, so the only trick is to convince asdf to pull the right package.

It seems like it would be important for this feature to not interfere with the 99% of other use cases, so maybe an opt-in feature? I'm picturing something like a line in a settings file that tells asdf to prefer ARM packages when available. Actually, it should be possible to detect the architecture of the current environment, and get the appropriate package from there.

Update all?

Hi,

if you take feature suggestions, it would be nice to have a hook for updating a package & "update all" command.

Thanks!

If "asdf install" fails, it should realise this

Did "asdf install ruby 2.2.2", and the compile failed. However, attempts to fix this and do "asdf install ruby 2.2.2" again got me "ruby 2.2.2 is already installed" when it very much wasn't...

Add system version

Someday we should support "system" version as a way to use OS-installed stuff. Very useful for Python and other stuff.

[Proposal] Command to get direct path of the binary

We need a way to expose the path to a binary. For example to debug with gdb, we need the direct path of the ruby binary and not the shim.

Something like

$ asdf bin ruby
/Users/HashNuke/.asdf/installs/ruby/2.3.0/bin/ruby

As a tangential discussion

Do we rename asdf which command to asdf version OR asdf current instead?

That way this can be in like with the unix which command. So we can use asdf which ruby

# this is currently what the asdf-which command does
# proposing to change it to asdf-current instead
$ asdf current ruby
2.3.0

# and use asdf-which to return the full path of the binary
$ asdf which ruby
/Users/HashNuke/.asdf/installs/ruby/2.3.0/bin/ruby

No version set for ...

Installed asdf on OSX Yosemite
Installed necessary brews
Set up plugin for erlang (asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git)
Installed Erlang (asdf install erlang 17.5)
Get No version set for erlang

The same happens for elixir as well.

Might be related to a pathing issue that I had while installing asdf.

In ~/.asdf/asdf.sh current_script_path=${BASH_SOURCE[0]} returns an empty string. I changed it it .asdf so that asdf exports properly. I am currently using zsh.

Feature: do not create new .tool-versions if it exists in parent dir

This is not a bug, but rather a question / suggestion.

Per readme, asdf:

searches recursively in the parent directories until it finds a .tool-versions file.

This is great and is working very well. However, now that I am in a nested directory, if I change the version using this command:

asdf local my_language my_version

it creates a new .tool-versions file in this folder, and fairly so.

It would be nice, however, to have a way to write to existing .tool-versions in parent directory upon running asdf local. Something like a -p flag, to indicate that the change should be written to the parent directory:

asdf local -p my_language my_version

When this is useful?

I'm working on a project that has a .tool-versions in the root folder. The .tool-versions file is checked in CVS. Somewhere deep down the project tree, I need to temporarily switch to an older version of the language and do my stuff (verify whether or not my script is working under an older version of a language). Doing asdf local creates a new file that must be removed.

Removing file manually is little work, and yet it's a bit irritating when needed to be done frequently.

[Proposal] A way to treat language installed from local sources

Oftentimes I have a language source downloaded, make change to it, then compile it and run some code of mine against this newly compiled language binary.

Is there a way I could tell asdf where my custom compiled binary reside? This would allow me to quickly switch current version of language to my compiled version, check something, and then switch back to stable version.

Here's the desired API I have in mind right now.

  1. Tell asdf about a locally compiled elixir:

    $ asdf link elixir my_custom_source ~/gmile/elixir/bin
    $ asdf link elixir my_experimental_source ~/gmile/elixir2/bin
  2. Listing all elixir versions now would show two more item in addition to whatever stable versions were already installed:

    $ asdf list elixir
    1.3.2
    my_custom_source (~/gmile/elixir/bin)
    my_experimental_source (~/gmile/elixir2/bin)
  3. Tell asdf to use a custom elixir version:

    $ asdf local elixir my_custom_source
    
  4. Tell asdf to forget about custom elixir versions:

    $ asdf unlink elixir my_custom_source
    $ asdf unlink elixir my_experimental_source

[Proposal] Compiled binaries

Some tools take up a lot of compile time (15-20min for Erlang I've noticed). Not ideal for CI and tiny machines. Can we have pre-built binaries for certain operating systems?

We could start with one language for Mac & Ubuntu. Then fan out to do Erlang.

Assuming we can find a sponsor for hosting over time...

Bins break when called from within a directory whose name has a space

Steps to reproduce:

  1. mkdir My\ Stuff && cd My\ Stuff
  2. Try to run irb, ruby, mix, or iex. On my system they all just sit on a blinking cursor.

I can run any of those commands from any path that doesn't have a space, as far as I can tell. Furthermore, running the bin directly seems to work. (i.e. ~/.asdf/installs/ruby/2.2.3/bin/irb)

Of course, my favorite option would be to avoid naming my directories with spaces, but I don't always have full say in the matter.

*Update I was originally trying this in Bash on Fedora 22. When I try the same thing from OS X, the screen will spam "usage: dirname path".

P.S. I've been quietly using asdf for about six months now, and love it! I don't have much experience with Bash programming, but if the cause of this doesn't seem immediately obvious to you I would be willing to try to track this down.

support for prerelease versions

This is kind of a enhancement request.Will it be possible to add support for git projects of elixir such as 1.3 since it's not showing in the vm.

[Proposal] Maintaining stable releases

There's an increase in fixes happening in the master branch.

  • Good thing: there's always updates
  • Bad thing: there's always updates

Should we have a separate stable branch and release tags that are merged into the stable branch? So whoever gets the stable branch always gets the latest stable release AND can also pick a tag and use just that.

The above idea above was just an opinion. Open to other ideas to maintain a stable release.

Erlang 18.0 - No version set for erlang

Installed Erlang 18.0 and setup the .tool-versions to erlang 18.0.

When running the elixir or erlang command line, it gives the following error
No version set for erlang

Using OSX/zsh

Compiling in parallel

Many of the plugins compile some files through make, that's why I'm opening the issue here, in the parent repository.

Should asdf detect if it can compile in parallel and set proper -jn flags for make? Is this a job for asdf, or should it assume user has proper MAKEFLAGS env variable set?
This can potentially significantly speed up compilation.

command not found: complete

Hi there!
I've just installed asdf for Mac, and every time I start a new zsh it prints the following error:

/Users/user/.asdf/completions/asdf.bash:43: command not found: complete

What can be going wrong?
Thanks in advance!

How to reinstall already installed toolchains

I used the erlang plugin to install several versions of erlang, but now I had to realize, that they are all installed without wx support, which I might need for the next project.

I made already sure, that everything wx relies on is in place, and I compiled an erlang manually just to see if the build process does realize it. Indeed it does.

So I'd like to have asdf to automatically reinstall all existing versions of the erlang toolchain, is this possible in an easy way?

Plugin named erlang already added

Hi. I've been using asdf for about 4 months now on CircleCI. Today it started giving me this error. Is there anything that changed in asdf that could have caused this, and any suggestions to work around it?

$ asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git
Plugin named erlang already added

asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git returned exit code 1

Action failed: asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git

The code that I'm running looks like this (hasn't changed):

if ! asdf | grep version; then git clone https://github.com/HashNuke/asdf.git ~/.asdf; fi
asdf plugin-add erlang https://github.com/HashNuke/asdf-erlang.git
asdf plugin-add elixir https://github.com/HashNuke/asdf-elixir.git
erlang_version=$(awk '/erlang/ { print $2 }' .tool-versions) && asdf install erlang ${erlang_version}
elixir_version=$(awk '/elixir/ { print $2 }' .tool-versions) && asdf install elixir ${elixir_version}
...

The directories that I'm caching also hasn't changed:

~/.asdf
~/.asdf/installs/elixir/1.2.6/.mix
deps
_build

I did a clean rebuild (cleared the cache) last week. Not sure if that's related.

.asdfrc config file

The expected path to the config file is $HOME/.asdfrc. It needs to be in the following format:

key1=value1
key2=value2

The only config option that is required to be supported right now is legacy_version_file. The possible values for this option should be yes or no. The default value should be no.

The config file is optional. If the file is not present, then all options will use the default values.

Plugin uninstall does not remove that plugin's shims

Steps to reproduce

$ asdf plugin-add ruby https://github.com/asdf-vm/asdf-ruby.git
$ asdf install ruby 2.3.1
$ asdf global ruby 2.3.1
$ gem install bundler
$ asdf plugin-remove ruby
$ bundle
No such plugin

Observed behavior

Removing a plugin, leaves it's shims in the asdf shims directory, which leaves them polluting my PATH.

Expected behavior

When removing a plugin, all it's shims are removed as well. Calling bundle should give a "command not found" error.

asdf install <name> [<version>]

When installing a version of a plugin, you need to provide the version. Would be nice if the version became optional, so that it would select the latest version available.

asdf install nodejs

Would do a asdf list-all nodejs, and automatically select the latest one.

[Proposal] Option "-k" to keep source

Inspired by ruby-build's -k option.

Passing this option should uncompress and compile the package in ~/.asdf/sources/<plugin>/<version> instead of the tmp dir. This is plugin specific.

asdf install ruby 2.3.0 -k
  • If -k is passed the plugin's install script is passed a source-compile path as another argument.
  • The plugin's install script uses a temp or the source-compile path to compile the package depending on the option passed.

Atleast for now, this would make it possible to use gdb with ruby. I have this work-in-progress in the keep-source branch.

[improvement] shell command

there are local and global commands that give you ability to set local or global version however sometimes we need to temporary set version for currently running shell session.
So what I propose is addition of shell command

unable to install erlang 19.0.1

When I specify Erlang 19.0.1 in my .tool-versions file

erlang 19.0.1
elixir 1.3.1

The following error when running asdf install:

gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error is not recoverable: exiting now

It works fine with erlang 18.3.

Proper way to set the versions outside of $HOME?

Today I fired up prax (https://github.com/ysbaddaden/prax) only to find that it wasn't working and was printing "No version set for ruby". After fiddling with the .praxconfig file (https://github.com/ysbaddaden/prax/wiki/Ruby-Version-Managers) and doing some debugging I found that Prax invokes ruby from /opt/prax/. I finally just ran sudo cp ~/.tool-versions /opt/prax/ to make the settings in my tool version file available to prax.

Do we have a recommended way of handling scenarios like this? To me this seems kind of ugly, and I'll probably delete the .tool-versions file and replace it with a symlink to the one in my home directory so I can change the versions.

I'll be adding a section on asdf to the prax wiki based on what is decided here.

3 digit semver version of elixir bug

asdf which elixir
failed for .tool-versions file without newline at the end, and with 3 digit SEMVER version

erlang 18.3
elixir 1.2.3

but worked with file

erlang 18.3
elixir 1.2

.tool-versions needs a blank newline?

Just wanted to verify this. I didn't see mention of it in the documentation, but I noticed that if there is no trailing blank line in .tool-versions the last line in the file does not get read.

As an example, I had the following contents:

erlang 18.2.1
elixir 1.2.2
ruby 2.3.0
nodejs 5.5.0

I noticed that it wasn't setting Node; I was getting the error that there was no version configured. To test, I shuffled it around so that Ruby was last and then Node worked but Ruby did not.

After I noticed that I added a blank line after the last item and all items seem to be working properly.

I'm not sure if it's worth changing or just putting some mention up in the README. It's definitely easy to work around (and some editors add the trailing line automatically anyway).

Otherwise, thanks! I really like this version manager.

[Proposal] Update Legacy File Plugin API

The plugin api allows specifying alternative files to .tool-versions (called legacy files) which is very useful for interoperating with other version managers that use files like .ruby-version or .node-version.

The current implementation works great, but has a couple of drawbacks:

  1. Plugins must perform all the work of searching for legacy files and parsing their results, making it possible to plugins to have different behavior (one plugin might look only in the current directory, while another might look in all parent directories)
  2. Plugins don't expose the file(s) their looking for so asdf can't tell a user what file derived the current tool version if it came from a legacy file.

Proposal:

Update the plugins api to make legacy file settings more deterministic. This would involve two new apis:

  1. list-legacy-filenames (required - for plugins that want to implement legacy files)

    Like list-all and list-bin-paths, this would take 0 arguments and return a space separated list of legacy filenames that are supported by this plugin.

    Example output: .node-version .nvmrc

  2. parse-legacy-file(optional)

    Allows plugins to support alternative syntaxes beyond the basic version number. It would take 1 argument: the path to the legacy file, and return the version. (See issue: asdf-vm/asdf-ruby#14)

    By default, asdf will assume the file just lists the version number alone and will simply cat it if parse-legacy-file is not implemented.

    Example output: 0.1.0

Benefits of this change

ASDF will be able to search for version setting files in a more deterministic (and efficient) manner. It can recursively search parent directories for both .tool-version files and legacy files simultaneously.

The plugins currently supported by asdf simply cat the contents of their legacy files so they would only need to implement list-legacy-filenames (relying on the default implementation of parse-legacy-file

Potential Issues

If we go forward with these changes, do we attempt to maintain the existing get-version-from-legacy-file? Removing it obviously is easier, but raises compatibility issues. Since legacy files are turned off by default, maybe we can assume that users who have turned it on are comfortable with upgrading their plugins.

Plugins that want to support both new and old versions of asdf would simply leave their existing implementations of get-version-from-legacy-file

Unify version getter

Me:

Thinking about it, we also have three ways of checking the version local, global and current,
we should also think about simplifying this, but let's have this discussion somewhere else! ๐Ÿ˜„

@rockwood

I wonder how useful the getter versions of local and global are. What's the use case there?

@rockwood I ported the functionality from rbenv, but I think the getters are not very useful, so we should probably use current to get the version, and make global and local setters only, which would make more sense to me.

@asdf-vm/maintainers Would everyone be ok with this change?

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.