asdf, un outil pour toutes vos versions

@sylvain_metayer

photo

Sylvain MÉTAYER

Tech Lead @Onepoint

logo

qualiopi
ecole onepoint

Problématique

There are so many of them…​

Contexte

$ go run main.go

Hello, Breizh Camp ! Go version :1.22.4

$ go run main.go

Need go version between 1.16.0 and 1.16.15

exit status 1

Solution

Installation

git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0
echo . "$HOME/.asdf/asdf.sh" > ~/.bashrc
echo . "$HOME/.asdf/completions/asdf.bash" > ~/.bashrc

Plugins

asdf plugin-add <plugin-name> <optional-repo-url>

.tool-versions

$ cat .tool-versions
go 1.16.15

Installation d’une version

asdf install <plugin> <version>
asdf install go 1.16.15
asdf install

Local vs Global

~/
├── code/
│   ├── go1.16/
│   │   └── .tool-versions
│   └── go1.22/
│       └── .tool-versions
├── .tool-versions
$ asdf global <outil> <version>
$ asdf local <outil> <version>

Shims

$ ls ~/.asdf/shims/
go                      gofmt

$ cat ~/.asdf/shims/go
#!/usr/bin/env bash
exec /home/s.metayer/.asdf/bin/asdf exec "go" "$@"

$ ls ~/.asdf/installs/golang/1.16.15/bin -al
go
gofmt

Démo

./1-usage.sh

Et voilà !

One to rule them all

Création d’un plugin en moins de 10min

Vite, vite !

Présentation de l’outil

Template

Création du template

bash setup.bash

[...]
Setting up plugin: asdf-go

author:        Sylvain
plugin repo:   https://github.com/sylvainmetayer/asdf-go
license:       https://choosealicense.com/licenses/mit/


go github:   https://github.com/golang/go
go docs:     https://github.com/golang/go
go test:     `go version`
After confirmation, the `main` will be replaced with the generated
template using the above information. Please ensure all seems correct.
Type `yes` if you want to continue.

git push --force-with-lease && git grep TODO

Structure d’un plugin

.
├── bin
│   ├── download
│   ├── install
│   ├── latest-stable
│   └── list-all
├── lib
│   └── utils.bash
├── LICENSE
├── README.md
lib/utils.bash
GH_REPO="https://github.com/golang/go"
TOOL_NAME="go"
TOOL_TEST="go version"

sort_versions() { /* ... */ }

list_all_versions() {/* ... */ }

download_release() {/* ... */ }

install_version() {/* ... */ }

Téléchargement d’une version

bin/download
release_file="$ASDF_DOWNLOAD_PATH/$TOOL_NAME-$ASDF_INSTALL_VERSION.tar.gz"
download_release "$ASDF_INSTALL_VERSION" "$release_file"
tar -xzf "$release_file" -C "$ASDF_DOWNLOAD_PATH" --strip-components=1
rm "$release_file"

Téléchargement d’une version

lib/utils.bash
download_release() {
  local version filename url
  version="$1"
  filename="$2"
  local platform=""
  local arch=""
  platform=$(get_platform)
  arch=$(get_arch)
  url="https://dl.google.com/go/go${version}.${platform}-${arch}.tar.gz"
  curl "${curl_opts[@]}" -o "$filename" -C - "$url" || fail "Could not download $url"
}

Installation d’une version

bin/install
install_version "$ASDF_INSTALL_TYPE" "$ASDF_INSTALL_VERSION" "$ASDF_INSTALL_PATH"

Installation d’une version

lib/utils.bash
install_version() {
 local install_type="$1"
 local version="$2"
 local install_path="${3%/bin}"
 mkdir -p "$install_path"
 cp -r "$ASDF_DOWNLOAD_PATH"/* "$install_path"
 test -x "$install_path/bin/$TOOL_NAME" || fail "Expected $install_path/$tool_cmd to be executable."
 echo "$TOOL_NAME $version installation was successful!"
}

Lister toutes les versions

bin/list-all
list_all_versions | sort_versions
lib/utils.bash
sort_versions() { /* regex magic */ }

list_all_versions() {
  git ls-remote --tags --refs "$GH_REPO" "go*"
}

Dernière version stable

bin/latest-stable
curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version' | cut -d "o" -f 2
$ curl -s https://go.dev/dl/?mode=json | jq
[
  {
    "version": "go1.22.4",
  # [...]
  }
]

Besoin de plus ?

Testons ça …​?

asdf plugin test go https://github.com/sylvainmetayer/asdf-go.git "go version"

Gérer vos plugins…​ avec un plugin ?

Pourquoi ?

En théorie
Diagram

Pourquoi ?

En pratique…​
Diagram

Comment ?

asdf plugin add asdf-plugin-manager https://github.com/asdf-community/asdf-plugin-manager.git
asdf plugin update asdf-plugin-manager v1.3.1
asdf install asdf-plugin-manager 1.3.1
asdf global asdf-plugin-manager 1.3.1
asdf-plugin-manager version

[…​] the only plugin you need to validate manually, and the .plugin-versions file will be the source of truth for asdf plugins. Yes, this is an asdf plugin to manage asdf plugins!

.plugin-versions

# plugin-name  git-url                               git-ref (hash, tag, or branch)
go       https://github.com/sylvainmetayer/asdf-go   main

Usage

asdf-plugin-manager add <plugin-name>
asdf-plugin-manager add-all

asdf-plugin-manager update <plugin-name>
asdf-plugin-manager update-all

asdf-plugin-manager remove <plugin-name>
asdf-plugin-manager remove-all

Démo

./2-plugin-manager-demo.sh

Pour aller plus loin

Slides
Slides
Vos retours
Vos retours