Skip to content

Ansible role for installing and configuring the fish shell

License

Notifications You must be signed in to change notification settings

jwillikers/ansible_fish

Repository files navigation

Ansible fish Role

GitHub Workflow Status

An Ansible role to configure the fish shell, primarily for my personal preferences.

Synopsis

Installs the newest fish shell on Ubuntu via the fish PPA repository, allows fish as a login shell, and configures the fish shell according to my preferences for remote user. It also configures fish as the login shell for this user.

Supported Platforms
Variables
user

The name of user for whom to configure fish.

Use

To use this role, you’ll need to install Ansible and the role.

  1. Install Ansible.

    Ubuntu
    1. Install pip for python3.

      ➜ sudo apt -y install python3-pip
    2. Install the Ansible package.

      ➜ python3 -m pip --user install ansible
    3. Ensure that ~/.local/bin is on your path.

      fish
      ➜ fish_add_path -p ~/.local/bin
      Bash / ZSH
      export PATH=~/.local/bin:$PATH
    Fedora
    ➜ sudo dnf -y install ansible
  2. Create a roles directory in the current folder to place the role.

    ➜ mkdir roles
  3. Checkout the role’s repository from GitHub into the roles directory.

    ➜ git clone https://github.com/jwillikers/ansible_fish.git roles/ansible_fish
  4. Run the role. Here, the role is run against the local machine.

    Command-Line
    ➜ ansible localhost --connection=local --ask-become-pass -m include_role \
      -a name=ansible_fish -e user=$USER
    Playbook
    1. Create a playbook which includes the role.

      my-playbook.yml
      ---
      - hosts: localhost
        roles:
          - role: ansible_fish
    2. Execute the playbook.

      ➜ ansible-playbook my-playbook.yml -i "localhost," --connection=local \
        --ask-become-pass

Test With Molecule

This project uses Molecule for testing. The sections below describe how to setup Molecule and run the tests.

Prerequisites

This project uses Ansible, Python, Molecule, and Podman. asdf is used to manage the Python runtime along with direnv and Pipenv to manage the project’s virtual environment and Python dependencies. This promotes flexible, cross-distribution environments and makes builds more reproducible. Instructions for installing everything are provided below.

  1. Install the dependencies needed for asdf.

    ➜ sudo apt -y install curl git
  2. If you use Btrfs and want to exclude the ~/.asdf directory from snapshots of your home directory, create a subvolume for it.

    ➜ btrfs subvolume create ~/.asdf
  3. Pull down the asdf repository in to your home directory.

    ➜ git clone https://github.com/asdf-vm/asdf.git ~/.asdf
  4. Checkout the latest version of asdf.

    fish
    ➜ git -C ~/.asdf switch --detach (git -C ~/.asdf describe --abbrev=0 --tags)
    HEAD is now at c6145d0 Update version to 0.8.0
    Bash / ZSH
    ➜ git -C ~/.asdf switch --detach $(git -C ~/.asdf describe --abbrev=0 --tags)
    HEAD is now at c6145d0 Update version to 0.8.0
  5. Enable asdf in your shell.

    fish
    ➜ mkdir -p ~/.config/fish/conf.d; \
      and echo "source ~/.asdf/asdf.fish" > ~/.config/fish/conf.d/asdf.fish
    Bash
    echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc
    ZSH
    echo '. $HOME/.asdf/asdf.sh' >> ~/.zshrc
  6. Install shell completions for asdf.

    fish
    ➜ mkdir -p ~/.config/fish/completions; \
      and ln -s ~/.asdf/completions/asdf.fish ~/.config/fish/completions
    Bash
    echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc
    ZSH
    echo -e 'fpath=(${ASDF_DIR}/completions $fpath)\nautoload -Uz compinit\ncompinit' >> ~/.zshrc
  7. To make asdf available, reload your shell.

    fish
    exec fish
    Bash
    source ~/.bashrc
    ZSH
    source ~/.zshrc
  8. Install the necessary dependencies to build Python which are helpfully documented in the Pyenv Wiki.

    ➜ sudo apt -y install make build-essential libssl-dev zlib1g-dev libbz2-dev \
      libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev xz-utils \
      tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
  9. Add the Python plugin to asdf.

    ➜ asdf plugin add python
  10. Before installing Pipenv, configure the default global Python version for the user.

    You can use the system version of Python by default or another version of your choice.

    Whenever the user’s global version of Python is updated, Pipenv must be reinstalled which may require that all virtual environments be rebuilt.

    • Use the system’s Python as the default.

      1. Ubuntu installs Python as either python2 or python3 on the system.

        This means that asdf won’t be able to detect the system version of python. Install the Python package python-is-python3 to install a python executable for the system which uses python3.

        ➜ sudo apt -y install python-is-python3
      2. Install pip and venv because they are not installed by default on Ubuntu.

        ➜ sudo apt -y install python3-pip python3-venv
      3. Set the user’s Python to the system-wide version.

        ➜ asdf global python system
    • Or, you can use another version of Python for your user such as the latest and greatest version.

      1. Build and install the latest version of Python.

        ➜ asdf install python latest
      2. Set the user’s Python to the latest version available at this time.

        fish
        ➜ asdf global python (asdf latest python)
        Bash / ZSH
        ➜ asdf global python $(asdf latest python)
  11. Install pipx for installing Pipenv in an isolated environment.

    ➜ python -m pip install --user pipx
  12. Add the directory where pip installs executables for the local user to PATH.

    ➜ python -m pipx ensurepath
  13. To make executables installed by pipx available, reload your shell.

    fish
    exec fish
    Bash
    source ~/.bashrc
    ZSH
    source ~/.zshrc
  14. Install Pipenv.

    ➜ python -m pipx install pipenv
  15. Add the direnv plugin to asdf.

    ➜ asdf plugin add direnv
  16. Integrate direnv with your shell.

    fish
    ➜ mkdir -p ~/.config/fish/conf.d; \
      and echo "asdf exec direnv hook fish | source" > ~/.config/fish/conf.d/direnv.fish
    Bash
    echo 'eval "$(asdf exec direnv hook bash)"' >> ~/.bashrc
    ZSH
    echo 'eval "$(asdf exec direnv hook zsh)"' >> ~/.zshrc
  17. Make the asdf feature, i.e. the command use asdf, available in direnv.

    fish
    ➜ mkdir -p ~/.config/direnv; \
      and echo 'source "$(asdf direnv hook asdf)"' >> ~/.config/direnv/direnvrc
    Bash / ZSH
    ➜ mkdir -p ~/.config/direnv; echo 'source "$(asdf direnv hook asdf)"' >> ~/.config/direnv/direnvrc
    ℹ️
    The direnvrc file should only use Bash syntax.
  18. Add completions for Pipenv to your shell.

    fish
    echo "eval (pipenv --completion)" > ~/.config/fish/completions/pipenv.fish
    Bash
    echo 'eval "$(pipenv --completion)"' >> ~/.bashrc
    ZSH
    echo 'eval "$(pipenv --completion)"' >> ~/.zshrc
  19. Clone this project’s Git repository.

    ➜ git clone https://github.com/jwillikers/ansible_fish.git ~/Projects/ansible_fish
  20. Change to the project directory.

    cd ~/Projects/ansible_fish
  21. Run asdf to automatically install Python and direnv.

    ➜ asdf install
    💡

    If you haven’t set a default global version of direnv, you should do so now.

    fish
    ➜ asdf global direnv (asdf list direnv | awk 'FNR <= 1')
    Bash / ZSH
    ➜ asdf global direnv $(asdf list direnv | awk 'FNR <= 1')
  22. Reload your shell for direnv to be available.

    fish
    exec fish
    direnv: error /home/ubuntu/Source/MyProject/.envrc is blocked. Run `direnv allow` to approve its content
    Bash
    source ~/.bashrc
    direnv: error /home/ubuntu/Source/MyProject/.envrc is blocked. Run `direnv allow` to approve its content
    ZSH
    source ~/.zshrc
    direnv: error /home/ubuntu/Source/MyProject/.envrc is blocked. Run `direnv allow` to approve its content
  23. Enable automatic loading of the project’s environment.

    ➜ direnv allow

Now, whenever you change into the project directory, the project’s virtual environment will automatically be loaded for you.

Test

To create the container, run everything, test, and subsequently destroy the container, use molecule test from the project directory.

➜ molecule test

References

For further reading on the use of Ansible, Molecule, and Podman, see Ansible’s blog post series, Developing and Testing Ansible Roles with Molecule and Podman_.

Contributing

Contributions in the form of issues, feedback, and even pull requests are welcome. Make sure to adhere to the project’s Code of Conduct.

Open Source Software

This project is built on the hard work of countless open source contributors. Several of these projects are enumerated below.

Code of Conduct

The project’s Code of Conduct is available in the Code of Conduct file.

License

This repository is licensed under the GPLv3, available in the license file.

© 2021 Jordan Williams

Authors