Setup asdf & direnv
Tags: asdf, direnv, webdev, tutorial
Published: 2022-06-14 22:23:16

# :gear: Environment setup

## ASDF Version Manager

`asdf` is a tool version manager. All tool version definitions are contained within one file (`.tool-versions`) which you can check in to your project's Git repository to share with your team, ensuring everyone is using the exact same versions of tools.

Reference: <https://asdf-vm.com/guide/introduction.html>

### Install asdf

- Make sure you have `curl`, `git`, and `unzip` installed.
- Download asdf with

    ```bash
    git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.10.0
    ```

- If you are using bash, add the following to your `~/.bashrc` file:

    ```bash
    . $HOME/.asdf/asdf.sh

    # configure completions
    . $HOME/.asdf/completions/asdf.bash
    ```

- If you are using zsh, add the following to your `~/.zshrc` file:

    ```bash
    . $HOME/.asdf/asdf.sh

    # if using oh-my-zsh, add `asdf` to your plugins list
    # for example: plugins=(... asdf ...)

    # if you are not using oh-my-zsh, add the following to your `.zshrc` file:

    # append completions to fpath
    fpath=(${ASDF_DIR}/completions $fpath)

    # initialise completions with ZSH's compinit
    autoload -Uz compinit && compinit
    ```

### Install plugins

After installing `asdf`, add all the plugins found in the `.tool-versions` file. This depends on the tools defined in your `.tool-versions` file depending on the repository.

```bash
# Add all the plugins to asdf.
cat .tool-versions | awk '{print $1}' | xargs -I _ asdf plugin add _

# Install all tools according to .tool-versions.
asdf install
```

#### Example

If your project's `.tool-versions` file contains the following:

```md
ruby 2.6.3
python 3.10.4
nodejs 16.0.0
```

Then you can install all the tools with their specified versions by running `asdf install`.

### Global tool versions

Optionally, you can add the following `.tool-versions` file to your home directory:

```md
direnv 2.31.0
nodejs 16.13.2
pnpm 7.1.5
java adoptopenjdk-8.0.272+10
minikube 1.25.1
helm 3.6.3
helmfile 0.139.9
kubectl 1.23.3
kubespy 0.6.0
kubectx 0.9.4
jq 1.6
golang 1.15.15
poetry 1.1.13
```

!!! Note
    Make sure you stay up to date with the latest or stable versions of tools.

Refer to [official asdf documentation](https://asdf-vm.com/guide/getting-started.html#_1-install-dependencies) for more information.

## Direnv

[`direnv`](https://direnv.net/) is an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.

- Install [`direnv`](https://direnv.net/docs/installation.html)
- [Hook](https://direnv.net/docs/hook.html) direnv with your shell

Setup any project with `direnv` by creating a `.envrc` file that looks like the following:

```bash
#!/usr/bin/env bash
export CR_PAT=<YOUR_GITHUB_PAT_WITH_REPO_READ_AND_WRITE>
export NODE_AUTH_TOKEN=$CR_PAT
export DEBUG="*"

cat <<EOF >.env
VITE_BASE_URL=${VITE_BASE_URL}
NODE_AUTH_TOKEN=${CR_PAT}
EOF
```

## Hook asdf with direnv

### Setup

- Install [asdf-plugin](https://github.com/asdf-community/asdf-direnv) for direnv using the following:

    ```bash
    asdf plugin-add direnv
    ```

- Setup shell

    ```bash
    # change --shell flag based on your current shell (bash, zsh, fish, etc.)
    asdf direnv setup --shell zsh --version latest
    ```

- Once direnv is hooked up, you can run the following command on the root directory of your project to update your environment given that you have a `.envrc` file in your project root.

    ```bash
    asdf direnv local
    ```

### Creating temporary environments

You can create a temporary environment without editing `.envrc` or `.tool-versions`

```bash
# Enter a new shell having python and node
asdf direnv shell python 3.8.10 nodejs 14.18.2

# Just execute a npx command under some node version
asdf direnv shell nodejs 14.18.2 -- npx create-react-app
```

References:

- <https://asdf-vm.com/guide/introduction.html#direnv>
- <https://github.com/asdf-community/asdf-direnv#setup>
- <https://github.com/asdf-community/asdf-direnv#per-project-environments>