Ahoy gives each of your projects its own CLI app with zero code and zero dependencies. Write your commands in a YAML file, and Ahoy turns them into a real command line tool with a command listing, per-command help, shell tab completion, and the ability to run your commands from any subdirectory.
It was created to help with running interactive commands inside Docker containers, but it works just as well for local commands, aliases for commands with complex parameters, commands over ssh, or anything else you would otherwise run by hand.
Say you want to import a MySQL database running in docker-compose via a container called cli. Without Ahoy:
docker exec -i $(docker-compose ps -q cli) bash -c 'mysql -u$DB_ENV_MYSQL_USER -p$DB_ENV_MYSQL_PASSWORD -h$DB_PORT_3306_TCP_ADDR $DB_ENV_MYSQL_DATABASE' < some-database.sqlWith Ahoy:
ahoy mysql-import < some-database.sqlmacOS - using Homebrew / Linuxbrew:
brew install ahoyLinux - download the latest release, put the binary for your platform somewhere in your $PATH and rename it ahoy. Or use the one-liner:
os=$(uname -s | tr '[:upper:]' '[:lower:]') && architecture=$(case $(uname -m) in (x86_64 | amd64) echo "amd64" ;; (aarch64 | arm64 | armv8*) echo "arm64" ;; (armv7*) echo "armv7" ;; (armv6*) echo "armv6" ;; esac) && { [ -n "$architecture" ] || { echo "Unsupported architecture: $(uname -m)" >&2; false; }; } && sudo wget -q https://github.com/ahoy-cli/ahoy/releases/latest/download/ahoy-bin-$os-$architecture -O /usr/local/bin/ahoy && sudo chown $USER /usr/local/bin/ahoy && chmod +x /usr/local/bin/ahoyWindows - native builds are published as ahoy-bin-windows-amd64.exe and ahoy-bin-windows-arm64.exe on the latest release page (also available as ahoy-windows-amd64.zip / ahoy-windows-arm64.zip). Download the one for your architecture, rename it ahoy.exe, and put it in a directory that is on your PATH - for example %USERPROFILE%\bin, adding that folder under Settings β System β About β Advanced system settings β Environment Variables. Note that Ahoy runs command bodies through bash -c by default, so bash needs to be available (Git Bash, for instance) unless your config sets a custom entrypoint.
For WSL2, use the Linux binary above.
Full instructions: Installation & Setup
# Download an example config into your project
ahoy config init
# See what you can run
ahoyThe example file ships with more than 20 ready-to-use commands covering local environments (up, down, restart), testing and linting, database operations, build and deploy, and Drupal integration. View it here.
# All files must have v2 set or you'll get an error.
ahoyapi: v2
# Optional: load environment variables. Accepts one file or a list.
env: .env
commands:
simple-command:
usage: An example of a single-line command.
cmd: echo "Do stuff with bash"
deploy:
usage: Deploy the application
aliases: ["dep"]
description: |
Deploys the application to the configured environment.
Builds assets, runs migrations, and clears caches.
cmd: ./scripts/deploy.sh
multi-line:
usage: Show more advanced features.
cmd: |
echo "multi-line bash script";
ahoy simple-command # call other ahoy commands
echo "your params were: $@" # standard bash argument handling
echo "param1: $1"
subcommands:
usage: Group commands from other config files.
# Later files override earlier ones. Add `optional: true` to tolerate
# missing files.
imports:
- ./some-file1.ahoy.yml
- ./some-file2.ahoy.ymlEvery field is documented in the YAML Schema reference.
- Non-invasive - wraps the commands and scripts you already use.
- Consistent - commands always run relative to the
.ahoy.ymlfile, but can be called from any subfolder. - Visual - see all your commands in one place with helpful descriptions.
- Flexible - each repo or workspace gets its own commands.
- Fully interactive - shells like MySQL and interactive prompts still work.
- Command templates - use regular bash syntax like
"$@"or$1. - Imports - split commands across multiple files, with "last in wins" for duplicates, and
optional: trueto skip missing files gracefully. - Aliases and descriptions - give commands short alternative names and longer multi-line help text.
- Environment variables - load one or more env files at both file and command level. Ahoy also injects
AHOY_COMMAND_NAMEandAHOY_CMDinto every command. - Shell completion - commands and help are self-documenting. There's a dedicated Zsh plugin at ahoy-cli/zsh-ahoy.
- Custom entrypoints - swap
bashfor PHP, Node.js, Python or anything else. This is also how plugins work. - Config validation -
ahoy config validatechecks your config and suggests fixes.
Ahoy v3 is a major internal rewrite that brings improved CLI handling whilst maintaining full backwards compatibility with existing .ahoy.yml files. Your workflows will not break.
- New CLI framework - migrated from
urfave/clito Cobra for a more robust foundation. ahoy configsubcommand group -ahoy config init [url]downloads an example config (replacingahoy init), andahoy config validatechecks your config for issues.- Command descriptions - a
descriptionfield for longer multi-line help, alongside the existing shortusagefield. - Optional imports - mark imports with
optional: trueso missing files are skipped instead of erroring. - Command aliases - an
aliasesfield for alternative names, shown inline in help output. - Multiple environment files -
envnow accepts an array, at both global and command level. - Runtime environment variables -
AHOY_COMMAND_NAMEandAHOY_CMDare injected into every command.
No changes to your .ahoy.yml files are required - just replace the binary. All existing commands, aliases, imports, entrypoints and environment configuration continue to work, and the YAML API version stays at v2.
The one behavioural change: ahoy init and ahoy config init create exactly the same configuration file, but ahoy init now also prints a deprecation notice pointing you at ahoy config init.
Full documentation lives at ahoy-cli.github.io:
| Installation & Setup | Getting Ahoy onto your machine |
| Writing Commands | Usage text, descriptions, aliases, arguments |
| Command Execution | How commands run, chaining, entrypoints |
| Importing & Overriding | Splitting configs across files |
| Environment | Env files and runtime variables |
| Shell Autocompletion | Bash and Zsh completions |
| CLI Reference | Every command and flag |
| YAML Schema | Every configuration field |
- Specify arguments and flags in the ahoy file itself, to cut down on argument parsing in scripts.
- A "verify" YAML option creating a yes/no prompt for potentially destructive commands.
- Pipe tab completion to another command.
Thanks to all these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!