Ahoy Ahoy
winget install --id=Ahoy.Ahoy -e
Automate and organize your workflows, no matter what technology you use
Ahoy is a workflow automation tool designed to streamline and organize your processes across any technology stack. It allows you to create self-documenting CLI programs from YAML files, enabling seamless integration with various tools such as bash, npm, Docker, and more.
Key Features:
- YAML Configuration: Define workflows using simple YAML files for clarity and ease of maintenance.
- Cross-Platform Compatibility: Works seamlessly across different technologies and environments.
- Self-Documenting CLI: Automatically generates documentation for your commands, improving team collaboration.
- Standardized Processes: Wrap any tool or script into a standardized CLI interface, ensuring consistency across projects.
Audience & Benefit: Ideal for developers, DevOps engineers, and teams looking to standardize their workflows. Ahoy enhances efficiency by reducing manual errors and improving process transparency.
Available via winget for easy installation.
README
AHOY! - Automate and organize your workflows, no matter what technology you use.
Ahoy is command line tool that gives each of your projects their own CLI app with zero code and dependencies.
Write your commands in a YAML file and then Ahoy gives you lots of features like:
- a command listing
- per-command help text
- command tab completion
- run commands from any subdirectory
Ahoy makes it easy to create aliases and templates for commands that are useful. It was created to help with running interactive commands within Docker containers, but it's just as useful for local commands, commands over ssh
, or really anything that could be run from the command line in a single clean interface.
Examples
Say you want to import a MySQL database running in docker-compose
using another container called cli
. The command could look like this:
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.sql
With Ahoy, you can turn this into:
ahoy mysql-import < some-database.sql
Features
- Non-invasive - Use your existing workflow! It can wrap commands and scripts you are already using.
- Consistent - Commands always run relative to the
.ahoy.yml
file, but can be called from any subfolder. - Visual - See a list of all your commands in one place, along with helpful descriptions.
- Flexible - Commands are specific to a single folder tree, so each repo/workspace can have its own commands.
- Command templates - Use regular
bash
syntax like"$@"
for all arguments, or$1
for the first argument. - Fully interactive - Your shells (like MySQL) and prompts still work.
- Import multiple config files using the "imports" field.
- Uses the "last in wins" rule to deal with duplicate commands amongst the config files.
- Command aliases - oft-used or long commands can have aliases.
- Use a different entrypoint (the thing that runs your commands) if you wish, instead of
bash
. E.g. using PHP, Node.js, Python, etc. is possible. - Plugins are possible by overriding the entrypoint.
- Self-documenting - Commands and help declared in
.ahoy.yml
show up as ahoy command help and shell completion of commands (see bash/zsh completion) is also available. We now have a dedicated Zsh plugin for completions at ahoy-cli/zsh-ahoy. - Support for environment variables at both file and command level using the
env
field - Environment variables from a global file are loaded first, then command-specific variables override them
- Environment files use standard shell format with one variable per line, comments supported
Installation
macOS
Using Homebrew / Linuxbrew:
brew install ahoy
Linux
Download the latest release from GitHub, move the appropriate binary for your plaform into someplace in your $PATH and rename it ahoy
.
Example:
os=$(uname -s | tr '[:upper:]' '[:lower:]') && architecture=$(case $(uname -m) in x86_64 | amd64) echo "amd64" ;; aarch64 | arm64 | armv8) echo "arm64" ;; *) echo "amd64" ;; esac) && 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/ahoy
Windows
For WSL2, use the Linux binary above for your architecture.
Environment Variables
An example of the newly added environment variable support.
Ahoy YAML config file:
ahoyapi: v2
# Global environment file relative to .ahoy.yml
env: .env
commands:
db-import:
# Command-specific environment file, overrides global vars
env: .env.db
usage: Import a database
cmd: mysql -u$DB_USER -p$DB_PASSWORD $DB_NAME < $1
Env files:
# Global .env file
DB_USER=root
DB_PASSWORD=root
# Command-specific .env.db file
DB_USER=custom_user
DB_PASSWORD=secret
DB_NAME=mydb
Command Aliases
Ahoy now supports command aliases. This feature allows you to define alternative names for your commands, making them more convenient to use and remember.
Usage
In your .ahoy.yml
file, you can add an aliases
field to any command definition. The aliases
field should be an array of strings, each representing one or more alternative names for the command.
Example:
ahoyapi: v2
commands:
hello:
usage: Say hello
cmd: echo "Hello, World!"
aliases: ["hi", "greet"]
In this example, the hello
command can also be invoked using hi
or greet
.
Benefits
- Improved usability: Users can call commands using shorter or more intuitive names.
- Flexibility: You can provide multiple ways to access the same functionality without duplicating command definitions.
- Backward compatibility: You can introduce new, more descriptive command names while keeping old names as aliases.
Notes
- Aliases are displayed in the help output for each command.
- Bash completion works with aliases as well as primary command names.
- If multiple commands share the same alias, the "last in wins" rule is used and the last matching command will be executed.
Shell autocompletions
Zsh
For Zsh completions, we have a standalone plugin available at ahoy-cli/zsh-ahoy.
Bash
For Bash, you'll need to make sure you have bash-completion installed and setup. See bash/zsh completion for further instructions.
Example of the YAML file setup
# All files must have v2 set or you'll get an error
ahoyapi: v2
# You can now override the entrypoint. This is the default if you don't override it.
# {{cmd}} is replaced with your command and {{name}} is the name of the command that was run (available as $0)
entrypoint:
- bash
- "-c"
- '{{cmd}}'
- '{{name}}'
commands:
simple-command:
usage: An example of a single-line command.
cmd: echo "Do stuff with bash"
complex-command:
usage: Show more advanced features.
cmd: | # We support multi-line commands with pipes.
echo "multi-line bash script";
# You can call other ahoy commands.
ahoy simple-command
# you can take params
echo "your params were: $@"
# you can use numbered params, same as bash.
echo "param1: $1"
echo "param2: $2"
# Everything bash supports is available, if statements, etc.
# Hate bash? Use something else like python in a subscript or change the entrypoint.
subcommands:
usage: List the commands from the imported config files.
# These commands will be aggregated together with later files overriding earlier ones if they exist.
imports:
- ./some-file1.ahoy.yml
- ./some-file2.ahoy.yml
- ./some-file3.ahoy.yml
Planned Features
- Enable specifying specific arguments and flags in the ahoy file itself to cut down on parsing arguments in scripts.
- Support for more built-in commands or a "verify" YAML option that would create a yes / no prompt for potentially destructive commands. (Are you sure you want to delete all your containers?)
- Pipe tab completion to another command (allows you to get tab completion).
- Support for configuration.
Sponsors π° π
Contributors β¨
Thanks goes to these wonderful people (emoji key):
<a href="https://github.com/acouch"><img src="https://avatars.githubusercontent.com/u/512243?v=4?s=64" width="64px;" /><b>Aaron Couch</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=acouch">π</a>
<a href="https://github.com/aashil"><img src="https://avatars.githubusercontent.com/u/6216576?v=4?s=64" width="64px;" /><b>Aashil Patel</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=aashil">π»</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=aashil">π</a>
<a href="https://www.drevops.com/"><img src="https://avatars.githubusercontent.com/u/378794?v=4?s=64" width="64px;" /><b>Alex Skrypnyk</b></a><a href="https://github.com/ahoy-cli/Ahoy/issues?q=author%3AAlexSkrypnyk">π</a> <a href="https://github.com/ahoy-cli/Ahoy/pulls?q=is%3Apr+reviewed-by%3AAlexSkrypnyk">π</a> <a href="#question-AlexSkrypnyk">π¬</a> <a href="#promotion-AlexSkrypnyk">π£</a> <a href="#ideas-AlexSkrypnyk">π€</a> <a href="#financial-AlexSkrypnyk">π΅</a> <a href="#security-AlexSkrypnyk">π‘οΈ</a>
<a href="http://www.linkedin.com/in/alexandrerafalovitch"><img src="https://avatars.githubusercontent.com/u/64153?v=4?s=64" width="64px;" /><b>Alexandre Rafalovitch</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=arafalov">π</a>
<a href="https://github.com/hanoii"><img src="https://avatars.githubusercontent.com/u/677879?v=4?s=64" width="64px;" /><b>Ariel Barreiro</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=hanoii">π»</a>
<a href="https://agaric.coop/"><img src="https://avatars.githubusercontent.com/u/27131?v=4?s=64" width="64px;" /><b>Benjamin MelanΓ§on</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=mlncn">π</a>
<a href="https://github.com/ocean"><img src="https://avatars.githubusercontent.com/u/4443?v=4?s=64" width="64px;" /><b>Drew Robinson</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=ocean">π»</a> <a href="https://github.com/ahoy-cli/Ahoy/issues?q=author%3Aocean">π</a> <a href="#content-ocean">π</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=ocean">π</a> <a href="#ideas-ocean">π€</a> <a href="#infra-ocean">π</a> <a href="#maintenance-ocean">π§</a> <a href="#platform-ocean">π¦</a> <a href="#question-ocean">π¬</a> <a href="https://github.com/ahoy-cli/Ahoy/pulls?q=is%3Apr+reviewed-by%3Aocean">π</a> <a href="#security-ocean">π‘οΈ</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=ocean">β οΈ</a>
<a href="https://www.elijahlynn.net/"><img src="https://avatars.githubusercontent.com/u/1504756?v=4?s=64" width="64px;" /><b>Elijah Lynn</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=ElijahLynn">π</a>
<a href="https://botsandbrains.com/"><img src="https://avatars.githubusercontent.com/u/377330?v=4?s=64" width="64px;" /><b>Frank Carey</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=frankcarey">π»</a> <a href="https://github.com/ahoy-cli/Ahoy/issues?q=author%3Afrankcarey">π</a> <a href="#content-frankcarey">π</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=frankcarey">π</a> <a href="#ideas-frankcarey">π€</a> <a href="#infra-frankcarey">π</a> <a href="#maintenance-frankcarey">π§</a> <a href="#platform-frankcarey">π¦</a> <a href="#question-frankcarey">π¬</a> <a href="https://github.com/ahoy-cli/Ahoy/pulls?q=is%3Apr+reviewed-by%3Afrankcarey">π</a> <a href="#security-frankcarey">π‘οΈ</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=frankcarey">β οΈ</a>
<a href="https://github.com/jackwrfuller"><img src="https://avatars.githubusercontent.com/u/78133717?v=4?s=64" width="64px;" /><b>Jack Fuller</b></a><a href="https://github.com/ahoy-cli/Ahoy/issues?q=author%3Ajackwrfuller">π</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=jackwrfuller">π»</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=jackwrfuller">π</a> <a href="https://github.com/ahoy-cli/Ahoy/commits?author=jackwrfuller">β οΈ</a>
<a href="https://msound.net/"><img src="https://avatars.githubusercontent.com/u/432912?v=4?s=64" width="64px;" /><b>Mani Soundararajan</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=msound">π</a>
<a href="https://morpht.com/"><img src="https://avatars.githubusercontent.com/u/1254919?v=4?s=64" width="64px;" /><b>Marji Cermak</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=marji">π</a>
<a href="https://github.com/dkinzer"><img src="https://avatars.githubusercontent.com/u/444215?v=4?s=64" width="64px;" /><b>david kinzer (he/him)</b></a><a href="https://github.com/ahoy-cli/Ahoy/commits?author=dkinzer">π»</a>
This project follows the all-contributors specification. Contributions of any kind welcome!