Description
This is a full rewrite of asdf in Golang. 🚀 🎉
I've taken the existing BATS tests and used them as a guide in building a completely new version of asdf that is 100% Go and doesn't rely on any of the existing code. The Go implementation contained in this PR is feature complete, and unless specified, as all the features of the Bash version. I've been working on this for several months and have been using it myself every day for several weeks. I've found it to be very fast and stable for my uses.
Special thanks those that helped me with this rewrite:
@chrisjpalmer
@mikelorant
@DeedleFake
And @danhper for https://github.com/danhper/asdf-exec, which I referenced extensively when implementing the version resolution functionality.
Breaking Changes
While my aim was to copy the behavior of the existing Bash implementation exactly, I came across several features that were no longer needed, two that couldn't be easily done in Go (asdf update self-update, asdf shell env var setting), and a bunch of things that were overly complicated with no real benefit.
All breaking changes are documented here: here: https://github.com/asdf-vm/asdf/blob/97d48aa179c666f94cf821091db312678c926aee/docs/guide/upgrading-from-v0-14-to-v0-15.md#breaking-changes
If you notice unexpected behavior when testing this code, and it's not on that list, it is a bug. Please report it.
@asdf-vm/core @HashNuke @vic @danhper @jthegedus I would appreciate your input on this on this PR.
PR highlights
- List of breaking changes: https://github.com/asdf-vm/asdf/pull/1805/files#diff-5d47f486b32b6bebdd161850d173084b0a5e08d63187fd8f626ba1bad8ac50efR9
go.modfile with list of dependencies: https://github.com/asdf-vm/asdf/pull/1805/files#diff-33ef32bf6c23acb95f5902d7097b7a1d5128ca061167ec0716715b0b9eeaa5f6- Makefile (for local dev convenience only): https://github.com/asdf-vm/asdf/pull/1805/files#diff-76ed074a9305c04054cdebb9e9aad2d818052b07091de1f20cad0bbac34ffb52
- Updated
.tool-versionsfile: https://github.com/asdf-vm/asdf/pull/1805/files#diff-751af1a340658c7b8176fe32d7db9fadbe15d1d075daba1919a91df04155bc70
FAQ
Why a rewrite?
This project is widely used, and many people (myself included) rely on it every day to work on dozens of different projects each with their own distinct dependencies. I need to continue to use asdf, and many others do as well.
This project has grown challenging to maintain due to what I deem three distinct things:
- Number of users and the number of bugs and feature requests they submit
- It is all written in Bash, and as a result the codebase is harder change than most codebases of similar size
- Performance is a problem
A rewrite can solve two of these problems.
Why Go?
I actually tried out Rust for a time, and eventually settled on Go. Go is a simple language with a fast compiler. It's easy to learn, and has a large ecosystem. It feels very well suited to CLI apps. Many people including existing maintainers @jthegedus and @danhper already know Go. I found it quick to pick up and am now very productive with it myself.
How can I test out these changes?
The changes for this rewrite were managed in the https://github.com/asdf-vm/asdf-core-go repository prior to opening this PR. You can download prebuilt binaries here - https://github.com/asdf-vm/asdf-core-go/releases or install via Go with go install github.com/asdf-vm/asdf-core-go@latest
What is left to do?
Not much. I'm aware of a few things:
-
🏷️ Tag the last non-Go version of asdf so we've got a stable Bash version for those that choose not to upgrade yet. -
👨💻 Figure out how to handle shell completions. Currently completions are separate files, but I think it may make sense to bake them into the Go binary for easier distribution. Thoughts? - 📖 Update documentation
- 🏗️ Update release process so it builds Go binaries
- 🚀 Release new tag
How does this improve runtime performance?
From manual testing this new implementation is anywhere between 2x - 15x faster than the existing Bash implementation. This is not surprising given the general inefficiency of most of the Bash code.
I'm not going to do any thorough benchmarks right now. But I do plan on doing them in the future and writing another blog post similar to http://stratus3d.com/blog/2022/08/11/asdf-performance/ with the updated numbers.
How stable is this code?
I've written tests for everything that I could easily write tests for, and I've been using this code exclusively since November 22nd.
How is this going to be released?
There are a couple ways:
- Package manager (apt-get, Brew, etc...)
- Pre-built binary (we can publish binaries for common OS-architecture combos here on GitHub)
go install ...- Build from source