from Hacker News

Asdf – language tool version manager

by timhigins on 10/24/22, 10:06 PM with 157 comments

  • by f8 on 10/25/22, 12:02 AM

    Used this at my last company. Super painless and makes setup a breeze. Current company uses Docker and I hate it. Every company I've been at loves to throw everything into a container. Even if you setup your dev configs to maintain hot reloading, it's always slower. Node package management is also a pain no matter how you implement it with Docker it seems.

    I also hate the Docker tagline that it "eliminates 'works on my machine' issues". I believe a tool like asdf would also achieve this (correct me if I'm wrong). Docker itself can go haywire depending on the machine and you're basically in hell fighting with it just to get your dev environment working. You essentially eliminate one problem in exchange for a variety of equally frustrating challenges.

  • by happens on 10/24/22, 11:59 PM

    I've written a rust version of asdf over the last few months, both as an exercise and to fix a few issues I've been having with it - like noticeably slower tool startup times due to the shims resolving the version (my version basically works like direnv under the hood and hooks into the shell directly) and me just wanting a single "use" command which installs a plugin, downloads the requested version and sets it as active. It works very well and I've been daily driving it for a while.

    Having the ecosystem of asdf plugins which are basically just shell scripts has been a huge boon. It's been a breeze to work with, and most of the plugins are well written.

    Now, I've been contemplating switching to NixOS, but most version managers don't work at all with it due to dynamic linking. I absolutely love the idea of NixOS, but this has really bummed me out. I feel like the nix language is still a little clunky for general use, so as long as there is not a straightforward solution like having a tool-versions file I'm really hesitant to make the full switch.

  • by ephaeton on 10/25/22, 4:48 AM

    "ASDF (Another System Definition Facility) is an extensible build facility for Common Lisp software. ASDF comes bundled with all recent releases of active Common Lisp implementations as well as with quicklisp, and it is the most widely used system definition facility for Free Software Lisp libraries."

    Does asdf come with a plugin for asdf & quicklisp? would've preferred for the new guy on the block pay respect to the old guy on the block and used a different name..

  • by letmeinhere on 10/25/22, 1:25 AM

    One tip that I didn't know about and didn't seem to be documented at the time I was looking: if you want to add a plugin for some new project but just defer to what you were already using for everything else, you can set your `global` option to `system`. e.g.:

      asdf global python system
  • by denolfe on 10/25/22, 12:46 AM

    I have been using asdf for quite a few years, and I've always been impressed. It's honestly a breath of fresh air to only have a single set of commands to remember for node, go, ruby, python, even crystal. For node, it even respects existing .nvmrc files.
  • by teilo on 10/25/22, 12:33 AM

    After the pain of pyenv and it's terrible compatibility with poetry, asdf has been a dream come true. It just works, every time. No fragile config. No mess.
  • by rektide on 10/24/22, 10:53 PM

    Rarely have I seen a tool adopted so swiftly and at such scale. It eats the role of hundreds of other language & tool specific version managers, and whatever the secret sauce is, it's nicely fast & relatively low pain. Hats off to asdf. Major major delta in devs lives from this recent-ist new more-meta contender.
  • by thunfisch on 10/25/22, 8:51 AM

    I've been using this at work, sharing with my colleagues, and integrating this into our default CI/CD environment. It's awesome and has taken away the thought of "how do I install version XYZ of tool ABC here?" entirely. Just asdf what I need, done. Huge productivity boost.
  • by tpict on 10/24/22, 11:04 PM

    I wonder how many millions of lines of shell configuration have died by people switching to asdf. Fantastic tool
  • by matsemann on 10/24/22, 11:44 PM

    While asdf solves lots of pains, I still feel it solves the wrong problem. What I've instead started to do is to build docker images for various needs. Like, multiple of our projects need terraform, but all different versions. A project should then include that in its dev-dockerfile. No setup, just git clone a project and ready to go. No messing around with "to install and run X you need to have Y already installed, which half of you don't so for some reason it wont work in your environment".
  • by bluehatbrit on 10/25/22, 9:11 AM

    I'm a big fan of asdf, I switched to it from nvm back when I found it and was using node. To be honest I don't use it much anymore because I've mostly converged on vscode dev containers. But anything I need to do directly on my local machine or for running the odd random tool it's a life saver. Dealing with things like nvm, n, rbenv, and kerl were such a pain before.
  • by pmontra on 10/24/22, 11:10 PM

    I also use it to run different versions of PostgreSQL without having to use docker.
  • by phtrivier on 10/25/22, 7:20 AM

    Probably the only sane way to install Erlang / elixir.

    Sadly, reuses the name of a completely unrelated common lisp tool.

  • by rubyist5eva on 10/24/22, 11:18 PM

    Been using this for years, one of my favourite tools. Ruby, nodejs, python, golang, even direnv - all managed seamlessly. Never had problems with it when things like rvm or nvm would just break one day for no reason, never had it happen with Asdf.
  • by felipelalli on 10/25/22, 12:13 AM

    In a very quick & dirty read I couldn't understand what it's for. Could someone give me a practical example? I think a practical example is lacking in the introduction.
  • by password4321 on 10/25/22, 1:23 AM

    Love this. Can never remember the syntax for installing plugins vs. specific versions without double-checking though.
  • by ivolimmen on 10/25/22, 6:29 AM

    I tried asdf and direnv in the past but they did not cut it when working with Java and Java related tooling. direnv was slow and asdf does not have all the tooling I needed and use. I started using sdkman.io for Java development and it is very complete, up to date and speedy.
  • by Existenceblinks on 10/25/22, 9:23 AM

    Good to see it's still kicking, longevity is hard in cli space for non OS built-in ones.

    Works great in itself, however, PostgreSQL version upgrade is quite hustle. It's plug-in area, though could have some protocol with the core to make it seamless. I didn't upgrade my postgres for a while (on 12.4 right now).

    Not sure if it still requires you to do:

    `POSTGRES_EXTRA_CONFIGURE_OPTIONS=--with-openssl LDFLAGS="-L/usr/local/opt/openssl/lib" CPPFLAGS="-I/usr/local/opt/openssl/include" asdf install postgres x.x`

    And run `pg_upgrade` yourself moving data from previous version to the new one's directory.

  • by throwawaaarrgh on 10/25/22, 3:50 AM

    Downside: it's all shell scripts. Upside: it's all shell scripts.

    Seriously through, it's pretty easy to create an asdf plugin, and it works great. But it would be great if there were a static executable to handle it all.

    A couple projects out there come close, but need people to contribute code to finish the most useful functionality. One example is https://github.com/marcosnils/bin - the developer is fully in favor of improvements and added features, but needs someone with the free time to add them.

  • by robertwt7 on 10/25/22, 3:03 AM

    I love asdf, switched from nvm, jenv, pyenv to one tool

    Sadly this is not available in windows so i had to use WSL to run everything. Development in windows is so wonky once you switched from unix based system

  • by Cloudef on 10/25/22, 12:34 AM

    Just use nix and write shell.nix file.
  • by hiyer on 10/25/22, 3:27 AM

    Love asdf. Been using it for python, java and ruby for some time and it does away with the pain of having multiple version managers. Highly recommend.
  • by derrida on 10/25/22, 10:58 AM

    Being a bit of a tool myself I'd like to define a .toolfile for the whole internet:

    Convert all data / markup to s-expressions

    Make all code lambda calculus in some paren form

    No more "xml being manipulated by a scheme designed to look like imperative language" (javacript manipulating the DOM)

    Thank you have a nice day.

  • by pawelduda on 10/24/22, 11:36 PM

    One version manager to rule them all
  • by tjoff on 10/25/22, 10:24 AM

    I've been qurious about asdf for a while, but looking at the plugins I don't find anything about gcc or clang for instance (but quriously cmake).

    Though asdf itself is language-agnostic, is it in practice used more for web-development or something?

  • by mvaliente2001 on 10/25/22, 6:41 PM

    asdf is very nice, with the exception of its interface. You have `asdf <context> <command>`, `asdf <command> <package>` for others. It's actively hostile for memorisation.
  • by presentation on 10/24/22, 11:36 PM

    I discovered this tool a couple years ago since I’d type asdf into Google to test my internet and it started topping the results list. Great tool!
  • by anonyme-honteux on 10/25/22, 3:28 AM

    Is ASDF supposed to work with fish and macOS?

    My boss loves ASDF and I liked the idea but I tried to use it three times and failed

  • by SighMagi on 10/25/22, 12:43 AM

    It’s also super easy to integrate with non-POSIX shells, if you’re into that kind of thing.
  • by samgranieri on 10/25/22, 2:20 PM

    I've used this for six years on macOS. It's been working nicely.
  • by AbraKdabra on 10/24/22, 11:55 PM

    How does this compare to volta.sh?

    EDIT: Besides being only for JS.

  • by maltalex on 10/25/22, 4:00 AM

    Can anyone suggest a comparable tool for dotnet?
  • by dboreham on 10/25/22, 3:41 AM

    I get on better with sdkman, fwiw.
  • by seandoe on 10/25/22, 12:54 AM

    Great tool. I love it. Thanks!
  • by javier2 on 10/24/22, 11:36 PM

    Does it support java?
  • by mattpallissard on 10/25/22, 2:41 AM

    Have a project that requires multiple versions of terraform? what? you don't want to...

    clone the terraform source repo

      ~  git remote -v
      origin  https://github.com/hashicorp/terraform.git (fetch)
      origin  https://github.com/hashicorp/terraform.git (push)
    
    check out the tag you want

      ~  git tag | tail -1
      v1.1.5
      ~  git checkout v1.1.5
      Previous HEAD position was 516295951 Release v1.1.4
      HEAD is now at fe2ddc22a Release v1.1.5
    
    compile/install the binary in a local bin dirctory,

      ~  go build
      go: downloading github.com/aws/aws-sdk-go v1.42.35
      ~  install terraform ~/bin/terraform-v1.1.5
      ~  ls ~/bin/terraform\*
      /home/matt/bin/terraform          /home/matt/bin/terraform-v0.13.7  /home/matt/bin/terraform-v1.1.4
      /home/matt/bin/terraform-v0.13.4  /home/matt/bin/terraform-v0.14.9  /home/matt/bin/terraform-v1.1.5
    
    then manage a series of brittle aliases to disptach the proper version?

      ~  which terraform
      terraform () {
        binary=terraform
        if [[ $1 == "v"\* ]] && [[ $1 != "validate" ]]
        then
          version=$1
          shift
          binary="$binary-$version"
          [ -f ~/bin/$binary ] || bail 1 "missing binary $binary" || return 1
        else
          binary=/usr/bin/$binary
        fi
        dispatch --name terraform --scope --slice compilers.slice -c 35 -mh 2048M -mm 2048M -s 1M --binary $binary
      "$@"
      }
    
    (dispatch just runs things with memory and cpu limits)

      ~  which dispatch
      dispatch () {
        if [[ $USER == "root" ]]
        then
          command "$binary" "$@"
          return $?
        fi
        declare args=(--user --same-dir -p IOAccounting=yes -p MemoryAccounting=yes -p TasksAccounting=yes)
        while (($#))
        do
          case "$1" in
            (-c) args+="-p"
              args+="CPUWeight=$2"
              shift 2 ;;
            (-mm) args+="-p"
              args+="MemoryMax=$2"
              shift 2 ;;
            (-mh) args+="-p"
              args+="MemoryHigh=$2"
              shift 2 ;;
            (-s) args+="-p"
              args+="MemorySwapMax=$2"
              shift 2 ;;
            (--scope) args+=--scope
              shift ;;
            (--slice) args+="--slice=$2"
              shift 2 ;;
            (--name) name=$1
              shift 2 ;;
            (-P) args+=-P
              shift ;;
            (--binary) [ -z "$name" ] || name=$2
              binary="$2"
              shift ;;
            (*) break ;;
          esac
        done
        systemd-run $args "$@" 2> >(>&2 grep -vE 'Running.*as unit:')
      }
    
    and of course, then you'd need a shitty little script to call your alias when other tools decide they want to call terraform

      ~  cat ~/bin/terraform
      #!/usr/bin/env zsh
      source ~/.zshrc >/dev/null 2>/dev/null || exit 1
      terraform $@
    
    Because that would be silly and dumb, and I totally don't do that for everything.

    Don't even get me started on virtualenvs.