Load Environment on Directory Change

lorenzofelletti

Lorenzo Felletti

Posted on August 21, 2023

Load Environment on Directory Change

Change gcloud context, az login, Kubernetes context, set environment variables, and more just changing directory

During a typical day at work, I often need to change between two, or even three different repos, each with its relative gcloud, or az, or whatever configuration, its Kubernetes context, and so on.

At the beginning, I find it really frustrating and time-consuming to backward-search in history the commands I needed to run to be able to perform my tasks.

Out of frustration, I decided that I needed to find a way to be able to automate this boring task, and I came up with a simple solution that both saves me a lot of time when I need to switch context, but also helps me to track the steps needed to reach a certain configuration, in case I need to replicate it on another project.

After some stack-overflowing, I created these very simple zsh functions (portable to bash with little to no effort), to load hidden scripts on directory change. In particular, the two functions are named cda (that stands for cd and activate, or whatever), and sayonara (that means goodbye in Japanese):

# sourcing hidden files on cd
function cda() {  
        local -a PATHS; PATHS=('.', '.vscode' '.idea')  
        builtin cd "$@" || return  

        for p ("$PATHS[@]"); do  
                local hidden="${p}/.hidden.env"  
                if [[ -f "$hidden" ]]  
                then  
                        source $p  
                fi  
        done  
}

# Cleaning up when leaving, sourcing actions to do (like deactivate venv)  
function sayonara() {  
        local -a PATHS; PATHS=('.', '.vscode' '.idea')  

        for p ("$PATHS[@]"); do  
                local hidden="${p}/.hidden.out.env"  
                if [[ -f "$hidden"]]  
                then  
                        source $p  
                fi  
        done  

        if [[ "$#" -gt 0 ]] && local dest=("$@") || local dest=".."  

        builtin cd $dest || return  
}  
alias sayo="sayonara"
Enter fullscreen mode Exit fullscreen mode

The command sayonara was also aliased with sayo for the sake of brevity.

Why not Just Overriding cd?

I could have named the cda function cd and I could have sourced hidden files completely transparently to the user (I am only taking into account the cda function now, as the other is used more rarely), and initially this was the case. In fact, the cda function is written in a way that supports exactly this — note that I do not use cd but builtin cd instead, otherwise an infinite loop would be caused — but this can cause you problems if you have multiple shells opened, and you visit different directories with a hidden env file.

Let’s suppose, for example, that you need to work in dir1 with the hidden environment env1 and you’re working on this, but you need to visit code in dir2 with hidden env env2. With the hidden env being sourced on cda, you cda in dir1, and “only” cd in dir2, and you have no problems. But, if instead you named the function cd, when you cd in dir1 env1 is sourced, but, when you move to dir2, env2 will be sourced, potentially overriding some configurations of env1 (like the Kubernetes context, or the gcloud configuration).

Thus, for this problem, I preferred to give up on the dream of writing cd and having the right configuration always ready to use, and “settled” for the still very good solution of cda-ing into a directory when I want its environment to be activated, and cd-ing into it when I just want to visit it.

💖 💪 🙅 🚩
lorenzofelletti
Lorenzo Felletti

Posted on August 21, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related