# ahab A wrapper around `docker compose` for our dockerized django projects, so the same commands work in every repository. ## installing You will need rust installed. Clone repo and run: ```bash cargo install --path . ``` To print the underlying docker commands as they run, build with debug assertions: ```bash cargo install --path . --debug ``` ## shell completion `ahab completions ` writes a completion script to stdout, for bash, elvish, fish, powershell or zsh: ```bash ahab completions zsh > ~/.local/share/zsh/completions/_ahab eval "$(ahab completions zsh)" # or one line in .zshrc, never goes stale ``` Completions are also generated during the build. They land in `target/*/build/*/out/` by default, and `SHELL_COMPLETIONS_DIR_` installs a single shell's file straight into place: ```bash SHELL_COMPLETIONS_DIR_ZSH=~/.local/share/zsh/completions \ SHELL_COMPLETIONS_DIR_FISH=~/.config/fish/completions \ cargo install --path . ``` `SHELL_COMPLETIONS_DIR` writes every shell into one directory instead. ## the compose file `ahab` does not pass `-f`. docker compose finds the file itself, so set docker's own `COMPOSE_FILE` when it is not in the working directory, including its `base.yaml:override.yaml` form. A project's `.env` is a good place for it, since docker reads that too: ``` COMPOSE_FILE=docker/docker-compose.yaml ``` ## compose Wrappers around the matching `docker compose` call, plus `exec` and `bash` which default to the django service. ```bash ahab compose up # also build, down, ps, start, stop ahab compose rebuild # stop, build, up ahab compose restart # stop, up, so containers are recreated ahab compose bash # shell in the django service ahab compose exec ``` ## service detection `ahab` finds the services it needs in `docker compose config`, so they can be named anything: - **postgres**: the service whose image is a postgres flavour, matching `postg`, `timescale`, `pgvector` or `citus` - **django**: the service that both builds an image and sets `DJANGO_SETTINGS_MODULE`. A worker sharing the same build and `env_file` matches too, so the one publishing ports wins If nothing matches, or two candidates cannot be told apart, `ahab` says so and lists the services it looked at rather than guessing. `POSTGRES_USER` and `POSTGRES_DB` are read off the detected postgres service, so `dropdb`, `createdb`, `pg_restore` and `pg_dump` use the role and database the project declares, falling back to `db` when it declares neither. ## django ```bash ahab django manage # manage.py in a fresh container ahab django makemigrations ahab django migrate ahab django shell ahab django test ahab django make-command ``` ## postgres ```bash ahab postgres dump # pg_dump, custom format ahab postgres import # drop, create, pg_restore ``` ## link `ahab link` moves untracked paths out of the repository into an out-of-repo store and symlinks them back, so a sandbox that mounts the repository sees a dangling symlink instead of the contents, while the host resolves it as before. ```bash ahab link add .env secrets/ # move out, leave symlinks behind ahab link check # what a sandbox can still read ahab link check --porcelain # ` `, for scripts ``` The store lives under `${XDG_DATA_HOME:-$HOME/.local/share}/ahab////`, derived from the git `origin` remote. ## configuration Currently `ahab` respects the following environment variables. - `AHAB_LINK_ROOT`: root of the out-of-repo store `ahab link` moves paths into - defaults to `${XDG_DATA_HOME:-$HOME/.local/share}/ahab`