I need to jump between different versions of terraform, terragrunt, python, ... all the time for work. asdf is an absolute asset and makes that so much easier. I can heavily recommend giving it a try! I've even embedded it into our default CI image, as it allows me to very easily install consistent versions of many utilities, while also allowing to override versions by choice afterwards.
Sorry, but you misunderstand what asdf is! In Homebrew and Hermit and others, somebody needs to create a PR to add support for a new version - with asdf, it's not necessary and it's always ahead of Homebrew and other package managers, because it directly polls the releases of a project! So, you're not a the mercy of a packages repo maintainer! I've considered Hermit, but many of the tools I needed were severely outdated so I gave up on it!
For terraform and terragrunt, I have been using tfswitch and tgswitch respectively.
Also tfswitch has the ability to parse the required_version constraint in the terraform file and switch to the appropriate version based on that which I find quite handy.
I love asdf. I was a big fan of rbenv and nodenv but it has completely supplanted both of those for me. It uses a very similar model and CLI.
Nearly every lang on my machine is managed by asdf. It's been a while since I last tried but I seem to recall golang and JVM stuff seemed to play better with the default installers.
Anyway, between asdf, homebrew, and my dotfiles setup, I can have a brand new machine up and running with all my favorite stuff in about 20 minutes.
I don't have any real issues with Go. Setting up GoLand requires manually choosing the Go installation to use (at `~/.asdf/installs/golang/1.19`) and manually changing it when I upgrade the project, but since the version of tools per project doesn't change that often, it's not bad.
I'm a huge fan of asdf and have been using for years together with direnv! It's great to see how much effort is put into it! I hope more people adopt it so that we don't have to `curl | sh`! One thing I have issues with asdf is security as are no checksums, so, you if I project get compromised you'll get compromised, too. This, of course, is in addition to the third-party asdf plugin getting itself compromised (which is the greater risk). Last, but not least - I wish asdf came with something like eget [0] incorporated so that it can install 99% of the plugins directly and safely! Last, but not least - 99% of the plugins have almost identical code and all that changes is the repo, so, this should be generalized. For example, many years ago I made just one codebase of all HashiCorp plugins [1] and it's been working great!
I have been gradually moving from asdf to nix shell plus direnv combo. It handles system level dependent packages in addition to programming language version. Pinning the exact version is not a first class feature as of today, though possible by pinning the nixpkg to a specific commit. Hopefully nix flakes will solve this use case well when it is stable.
I've led the implementation of Nix as a dev env at my workplace to pretty good results, but none of us are quite yet willing to touch flakes yet because they're still marked as experimental.
Do you have any thoughts on whether or not we might be missing out? Any docs we should be looking at?
Nix Flakes are stable enough to replace nix-shell and lets you pin versions, so it has a significant reliability advantage.
Things get a bit tricker when flakes are paired with home-manager and especially nix-darwin, as the error handling leaves a lot to be desired (opaque errors that are extremely difficult to debug, leaving you with few choices outside of nuking all nix and re-starting).
I've been really careful to avoid OS-wide environment management with Nix, as we're on macOS; the only thing I do is `nix-env install direnv` imperatively during our setup script so we can sidestep the need for `nix-shell`.
If you’re using something like niv, you’ve got most of what flakes will bring to the table. I’m in the same boat as you, don’t want to have people enable any experimental feature to get the dev environment going. I use flakes for all my personal stuff though, just because it’s easier than adding the niv dependency and because it comes along with using the new command line interface. I also like that flakes let you specify multiple targets in a single file.
We're midway through transitioning engineers to it, as well as building stuff on top of it to make for a really great DX. I'll probably write a blog post when the whole env is a little more complete.
direnv + Nix is a great combo, and once you've gotten going with it there are various options you can use to speed up caching or automatically rebuild in the background on changes.
For project environments, flakes don't bring much new functionality to the table. They are a nice new convention that is probably worth learning, and they do bring faster evaluation. But don't sweat it.
It does work on m1, you might run into more issues compared to intel based Macs though. I wouldn't call nix painless. It might take some time to figure out the packages required, proper env variables to setup etc. But, once somebody in the team figures out the details, it will likely work for everyone in the team and others don't have to go through same pain. The whole setup is isolated to a single project and will not affect other projects. The setup for a old rails project pinned to a ruby version with few dependencies might look like below
I thought that this was going to be about ASDF (Another System Definition Facility; a module manager for Common Lisp): https://asdf.common-lisp.dev/
Turns out that it’s a version manager (now there’s another overloading: ‘VM’ to mean ‘version manager’ vice ‘virtual machine’): https://github.com/asdf-vm/asdf
* virtual machine is itself overloaded (do you mean OS vm or language runtime vm)
* virtual memory is itself overloaded (do you mean mapping one address space to another via MMU for process isolation or using a swapfile to have more "memory" than ram)
I propose we start calling vcs/scm programs "version managers" so we can make this overloading fully recursive! (that is it would make this the 3rd bullet: do you mean switching between version of programming enviornment or keeping track of source code history?)
> virtual machine is itself overloaded (do you mean OS vm or language runtime vm)
there's further different types of virtual "machines". they used to be called "type 1" and "type 2",
* type 1: runs on bare metal with no OS below it (Xen, HyperV, ESXi, ... vsphere?, others)
* type 2: runs on top of an OS (qemu, virtualbox, vmware workstation, others)
kvm is I guess kind of a mix? You need to use the userspace tools to manage it so it's like qemu (type 2) but the kernel exposes lots of things directly to the guest OS/image (type 1-ish).
I was expecting it to be about the "lol so random" series of video skits and segued from there into hoping it was some kind of machine learning architecture for playing QWOP.
Asdf is a good idea in theory and pretty okay considering it's in Bash, but the execution is quite lackluster. I'm glad the maintainer is focusing on performance, but there are other areas that prevent me from using the tool:
- asdf uses way more commands than it needs to. Instead of glob pattern matching for files, it reads the output of `ls` (and _many_ very similar mistakes)
- When running functions, the output tends to be collected using $(). Since this is done so much, this realllyyyy slows down execution since subshell invocations are slowwww in bash. Better is to set the global variable `REPLY` and use that directly from the callee
- The command line interface is kind of verbise and clunky and a little unintuitive
- There are too many separate plugins to use and download. Too much code duplication between plugins
I hope this doesn't sound like a laundry list of gripes, but just things to improve upon for the maintainers - I understand how hard it is to write Bash that works everywhere. Personally, I've opted to build my own (partial) solution that implements these suggestions at https://github.com/hyperupcall/woof, but my hope is that asdf will become substantially better over the years
Plugins are a trade off. It's either code duplication, or put it all inside core, in which case people will complain that it contains things they don't care about ("it's bloated").
Rest are valid, I guess. But wouldn't your efforts be better spent helping improve asdf, instead of creating a whole new system?
Your point about plugins is valid, but I believe a good middleground is having the plugins in core, but disabling them by default. Having an interface to enable particular plugins or plugin groups would be useful in this scenario too.
I thought about contributing to asdf, but unfortunately many of my pain points are deeply integrated within the design and architecture of the code itself. For example, since there is a lot of code duplication within plugins, it would be good to create a "plugin API" (I think that has recently been proposed). But that would be very time consuming to implement not just because of the already-existing code, but also because essentially every plugin is its own separate repository, usually maintained by different people. So I'd think it's not too hard to imagine how difficult making broad improvements or changes will be.
There's also the fact that writing (decently) fast and cross-platform Bash codes necessitates an essentially orthogonal coding style, which would be at odds with asdf's coding style. Even though the `REPLY` and `$()` is probably 80% of it, I would also like to take advantage of my `bash-core` and `bash-term` Bash libraries, which really wouldn't be possible in asdf (implementation-wise, that would necessitate the use of my Bash package manager)
I love asdf but the one thing that bugs me is that running `asdf install` inside a folder containing a .tool-versions file won't automatically install the plugins needed to install the tools mentioned in that file. You first have to install the required plugins by hand[0]. Makes it very annoying to use in CI/CD pipelines.
I've been using asdf for awhile because it's was good and much easier than having a language version manager for every language I was using. Asdf was always pretty good, but I'd sometimes see slowness and starship (my prompt) would occasionally complain that the shims were taking too long.
As languages that I'm using are starting to adopt their own version manager (rust/go), I'm left using asdf pretty much exclusively for node and my eyes wander to some of the node-only tools like volta and fnm which use rust and I wondered if people were watching performance. Glad somebody is.
I switched to asdf years ago for the exact opposite reason, I was tired of having a different tool for each language that I needed to maintain. It adds up, at one point I was using six different vm tools.
I mean -- that's the reason I switched to asdf, but my point is mostly that languages are building these tools into them so there's no split ecosystem, it doesn't require shell hacks and has much better ux than if it were provided externally like asdf is. I appreciate asdf for unifying all the shell hacks but rustup works way better than any other tool. As languages start to do this, asdf starts to become a mono-tasker for node for me.
I'm happy my team switched off asdf, it's not ready for prime time. It has baffling bugs, like selecting the wrong version of installed tools. It introduces asdf specific problems that you have to debug to use it for daily activities. I do not recommend it.
Sounds a lot like our teams' experience with yarn a few years back when every post was like "yarn is a perfect replacement for npm, npm is now deprecated, LOL don't use it or you're an obsolete fool".
It became a running joke that any project attempting to start with yarn (we had lots of JS devs, so of course they all try the new shiny) was only going to make a it a couple weeks before they hit some baffling, misleading, hard-to-diagnose error that was entirely solved by running "npm install". Tons of npm features missing in yarn, tons of sanity checks that npm did that yarn simply omitted. Maybe it's gotten better but it's made me even more skeptical of "common wisdom" around these things.
(To be fair, it may be better now, but this was well in to the time when folks were starting to sneer at people still using npm and running around saying how much better yarn was and how there was no reason not to use it—I can only assume these folks weren't doing much with it, because it was really easy to hit those kinds of problems.)
Yes, there are more than 100 open issues, which unfortunately I don't think the author has enough bandwidth to triage. Bugs keep piling up. https://github.com/asdf-vm/asdf/issues
I have never personally used asdf, but working as DevOps I had to help many fellow Devs untangle their environments because they messed up with asdf and everything broke down. One time someone installed it on a build server to try to manage python binaries and all builds stopped working.
Maybe if I got some time to explore the tool I would have a better appreciation for it, but from my experience it is too easy to mess things up.
asdf is not a good DevOps tool, you shouldn't use it on production, you can use it but is not really it's focus. What it excels is being a consistent development tool, for managing many stacks (node, java, ruby) versions for different environments
Whatever tool I use to get Python onto a system I never call it directly except when running python -m venv <name> to set up the environment my code will run from.
> untangle their environments because they messed up with asdf and everything broke down
I remember the bad old days when all that version management was typically done just right on your machine, often with different versions of python/ruby/etc installed globally with sudo.
Docker can be a pain and can be slow and it's arguably a worse-is-better solution, but it's so much less painful for consistently managing versions.
Really happy to see someone actually caring about performance in tooling, even if the conclusion for now is that it has gotten worse over time until now!
I think it's important to look at the long-term trend regularly. Otherwise small performance penalties each version can accumulate, but not really be apparent when just looking at each change in isolation. I've found what the .NET team does quite interesting. They have automated performance benchmarks running multiple times each day and have a bot that creates GitHub issues whenever a benchmark regresses (e.g. https://github.com/dotnet/runtime/issues/73630). It also makes looking at specific changes interesting, such as JIT improvements and where they show up once they're merged.
Slightly OT, there is an npm package also called asdf, it allows you to start a static dev server at the current directory. All you need to do is just `npx asdf`. I have no idea how I discovered this package, but it is really convenient as I have used it multiple times. (I know there is a python equivalent command, but `npx asdf` is probably shorter.)
asdf + direnv is how I avoid the performance hit of the shims completely. For me that's the sweetspot of developer ergonomics, performance and reproducibility of the dev env.
I've been avoiding using asdf because I hate its global shims. asdf-direnv may have a configuration now that doesn't require them, I need to take another look.
Is bash the bottleneck? Given the linked issue regarding comments in the file slowing down the commands, it makes me think so.
Why not rewrite it in another PL?