Directory specific bash aliases
When using Docker for development, especially Docker Compose, commands that used to be short and sweet in pre-Docker days end up lengthier in order to route commands through a running container, e.g.
docker-compose run web rails g controller users
While there are some obvious solutions, such as defining aliases in your shell config, e.g.
alias web="docker-compose run web"
these require you to adopt global conventions that might not always apply if you are collaborating on multiple projects.
While the following shell hack can certainly be used in any context, I use it primarily to scope commands to specific directory trees on my dev box. This way, when I leave the tree, everything gets cleaned up, avoiding global bloat.
First, add the following functions to your bash config - either directly to ~/.bashrc or in a separate file that is then sourced by your .bashrc:
function on_leave_dir() {
if [ -e .aliases ]; then
export OLD_ALIAS_DIR="$PWD"
fi
}
function on_enter_dir() {
if [ -n "$OLD_ALIAS_DIR" ] && ! is_subdirectory "$PWD" "$OLD_ALIAS_DIR" ; then
aliases="$OLD_ALIAS_DIR/.aliases"
while IFS=':' read -r key value || [ -n "$key" ]; do
unalias "$key" > /dev/null 2>&1
done < $aliases
unset OLD_ALIAS_DIR
echo "Unloaded local aliases"
fi
if [ -e .aliases ]; then
while IFS=':' read -r key value || [ -n "$key" ]; do
alias "$key"="${value##*( )}"
done < ".aliases"
echo "Loaded local aliases"
fi
}
function is_subdirectory() {
local child="$1"
local parent="$2"
if [[ "${child##${parent}}" != "$child" ]]; then
return 0
else
return 1
fi
}
function cd() {
on_leave_dir
builtin cd "$@"
on_enter_dir
}
Next, in any directory you'd like to trigger one or more aliases, added an .aliases file, using a simple key value format:
logs: docker-compose logs web
rails: docker-compose run --rm web rails
Now, any time you enter that directory, you can run the (short and sweet) commands:
rails g controller users
While the above command looks and feels like a normal rails executable, it is actually an alias that is routing the command to the rails executable running inside my Docker container.
You can also re-define the aliases in other directories using the same key names without any conflicts.