Sebastian's personal website

How to change the bash prompt to show which guix profile is active

Written by Sebastian Dümcke on

I am using GNU Guix as my package manager on top of Fedora Silverblue. Guix has several advantages over other package managers: packages can be installed with user privileges, several versions of the same packages can be installed in parallel, tools exists for reproducibility and versioning. The one I use regularly being the creation of different profiles each with a distinct set of packages (at specific versions). You activate a profile with: guix shell -p path/to/profile. I wanted to have my shell indicate when I am within a guix profile/environment and in which one.

On my system, the profiles are installed into $HOME/.guix_extra_profiles. A Guix profile is nothing more than a link to a directory in the Guix store that will be sourced (and thus sets specific PATH and related environment variables that ensures the right version of the software is called). However, profiles are versioned, and one can rollback to a previous state of any profile. If you activate a profile/environment, the variable GUIX_ENVIRONMENT is set to the directory in the store that is sourced into the profile.

With this information, we can create a bash function that maps the links found in the profile directory to the respective target directories in the Guix store and then display the name of the active profile in the bash prompt by changing the PS1 variable. I have added the code below to my .bashrc file so that it gets run for each new shell.

#create an associative array associating guix store paths to profile names
PROFILE_PATH="$HOME/.guix_extra_profiles"
declare -A ASSOC=()
for l in "${PROFILE_PATH}"/*-link
do      
        ASSOC[$(readlink "${l}")]=$(basename "${l%%-*}");
done
#function to return the profile name or empty string if in default profile
get_guix_profile() {
if ! [ -z ${GUIX_ENVIRONMENT+x} ]; 
then 
        echo "${ASSOC[$GUIX_ENVIRONMENT]} "
fi
}
#set PS1 that calls get_guix_profile on each new prompt
PS1='\[\033[01;32m\][\[\033[00;35m\]$(get_guix_profile)\[\033[00m\]\[\033[01;32m\]\u@\h\[\033[01;37m\] \W\[\033[01;32m\]]\$\[\033[00m\] '