Skip to content

Latest commit

Β 

History

533 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Ahoy logo

Ahoy!

Automate and organise your workflows, no matter what technology you use.

Build and test Go Report Card

All Contributors

Ahoy is a command line tool that gives each of your projects its 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.

What's New in v3

Ahoy v3 is a major internal rewrite that brings improved CLI handling whilst maintaining full backwards compatibility with all existing .ahoy.yml configuration files. Your workflows will not break.

Key Changes

  • New CLI framework - Migrated from urfave/cli to Cobra, providing a more robust and maintainable foundation.
  • ahoy config subcommand group - Built-in management commands are now grouped under ahoy config:
    • ahoy config init [url] - Download an example config to get started (replaces the old ahoy init).
    • ahoy config validate - Check your .ahoy.yml for issues and get actionable suggestions.
  • Command descriptions - Commands now support a separate description field for longer, multiline help text, in addition to the existing usage field for short summaries.
  • Optional imports - Import commands can now be marked with optional: true so that missing import files are gracefully skipped instead of causing errors.
  • Command aliases - Commands support an aliases field for alternative names, displayed inline in help output.
  • Multiple environment files - The env field now accepts an array of files at both global and command level.
  • Runtime environment variables - Ahoy injects AHOY_COMMAND_NAME (the command being run) and AHOY_CMD (path to the ahoy binary) into every command's environment.
  • Improved help output - Custom help template displays command aliases inline for better discoverability.
  • Full backwards compatibility - Existing .ahoy.yml files continue to work without modification. The YAML API version remains v2.

Upgrading from v2

No changes to your .ahoy.yml files are required. Simply replace the ahoy binary with the v3 version. All existing commands, aliases, imports, entrypoints, and environment file configurations will continue to work as before.

The only behavioural change you may notice is that ahoy init now prints a deprecation notice and redirects to ahoy config init. Both work identically.

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

Quick Start

Get started immediately with our comprehensive examples file:

# Create a new project with example commands
ahoy config init

# Or download the examples file directly
curl -o .ahoy.yml https://raw.githubusercontent.com/ahoy-cli/ahoy/master/examples/examples.ahoy.yml

The examples file includes 30+ usable example commands for:

  • Local Development Environments - up, down, restart, status
  • Testing & Quality - test, lint with multi-language support
  • Database Operations - db, db:backup for MySQL/PostgreSQL
  • Build & Deployment - build, deploy with safety checks
  • Drupal Integration - drush, cr, uli, cex, cim for Drupal projects

View the complete examples file

Try it out:

ahoy status    # Show service status
ahoy urls      # Show available URLs
ahoy shell     # Open a shell in your container

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 config files.
  • Command aliases - oft-used or long commands can have aliases.
  • Command descriptions - commands can have both short usage text and longer multiline descriptions.
  • Optional imports - import commands can gracefully handle missing files.
  • Config validation - ahoy config validate checks your config and reports issues.
  • Use a different entrypoint (the thing that runs your commands) if you wish, instead of bash. E.g. using PHP, Node.js, Python, etc.
  • 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 is also available. We have a dedicated Zsh plugin for completions at ahoy-cli/zsh-ahoy.
  • Environment variables at both file and command level using the env field, with support for multiple env files.
  • Runtime variables - AHOY_COMMAND_NAME and AHOY_CMD are injected into every command so scripts can introspect how they were invoked.

Installation

macOS

Using Homebrew / Linuxbrew:

brew install ahoy

Linux

Download the latest release from GitHub, move the appropriate binary for your platform 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" ;; (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/ahoy

Windows

For WSL2, use the Linux binary above for your architecture.

Command Descriptions

Commands support both a short usage field and a longer description field. The usage appears in the command listing, whilst the description provides detailed help text when viewing a specific command.

ahoyapi: v2
commands:
  deploy:
    usage: Deploy the application
    description: |
      Deploys the application to the configured environment.

      This command will:
      - Build the production assets
      - Run database migrations
      - Clear all caches
      - Notify the deployment channel

      Use with caution in production environments.
    cmd: ./scripts/deploy.sh

Environment Variables

Ahoy supports loading environment variables from files at both global and command levels, with support for multiple environment files.

Single Environment File (backwards compatible):

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

Multiple Environment Files:

ahoyapi: v2

# Multiple global environment files loaded in order
env:
  - .env.base
  - .env.local
  - .env.override

commands:
  deploy:
    # Multiple command-specific env files
    env:
      - .env.deploy
      - .env.secrets
    usage: Deploy the application
    cmd: ./deploy.sh

Environment File Format:

# Global .env file
DB_USER=root
DB_PASSWORD=root

# Command-specific .env.db file
DB_USER=custom_user
DB_PASSWORD=secret
DB_NAME=mydb

Key Features:

  • Files are loaded in order, with later files overriding earlier ones.
  • Command-level env files override global env files.
  • Non-existent files are gracefully ignored.
  • Supports comments and empty lines in env files.
  • Maintains full backwards compatibility with single file syntax.

Runtime Environment Variables

Ahoy automatically injects two variables into every command's environment:

Variable Value
AHOY_COMMAND_NAME The name of the command being run
AHOY_CMD Path to the ahoy binary

These are useful for scripts that need to know how they were invoked, or that want to call other ahoy commands via $AHOY_CMD.

Command Aliases

Ahoy supports command aliases, allowing you to define alternative names for your commands.

Usage

In your .ahoy.yml file, add an aliases field to any command definition:

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.

Notes

  • Aliases are displayed in the help output next to 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.

Optional Imports

Import commands can be marked as optional, allowing missing import files to be gracefully skipped rather than causing a fatal error. This is useful for separating commands into public and private sets, or for supporting optional tooling.

ahoyapi: v2
commands:
  local-tools:
    usage: Local development tools
    optional: true
    imports:
      - ./local-tools.ahoy.yml
      - ./team-tools.ahoy.yml

  core-tools:
    usage: Core project tools
    imports:
      - ./core.ahoy.yml

If optional: true is set and none of the imported files can be found, the command is silently omitted from the command listing. Without optional, missing imports will produce a fatal error.

Config Validation

Ahoy v3 includes a built-in configuration validator:

ahoy config validate

This checks your .ahoy.yml (and any imported files) for common issues, including:

  • Unsupported fields or YAML API version mismatches
  • Missing import files (without optional: true)
  • Features that require a newer version of Ahoy

Validation warnings are shown in verbose mode (-v); errors are always shown. The validator also provides actionable suggestions when it finds a problem.

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 set up. 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 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.
      description: |
        Demonstrates multi-line commands, parameter passing,
        and calling other ahoy commands from within a command.
      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 to all these wonderful people (emoji key):

Aaron Couch
Aaron Couch

πŸ“–
Aashil Patel
Aashil Patel

πŸ’» πŸ“–
Alex Skrypnyk
Alex Skrypnyk

πŸ› πŸ‘€ πŸ’¬ πŸ“£ πŸ€” πŸ’΅ πŸ›‘οΈ
Alexandre Rafalovitch
Alexandre Rafalovitch

πŸ“–
Ariel Barreiro
Ariel Barreiro

πŸ’»
Benjamin MelanΓ§on
Benjamin MelanΓ§on

πŸ“–
Drew Robinson
Drew Robinson

πŸ’» πŸ› πŸ–‹ πŸ“– πŸ€” πŸš‡ 🚧 πŸ“¦ πŸ’¬ πŸ‘€ πŸ›‘οΈ ⚠️
Elijah Lynn
Elijah Lynn

πŸ“–
Frank Carey
Frank Carey

πŸ’» πŸ› πŸ–‹ πŸ“– πŸ€” πŸš‡ 🚧 πŸ“¦ πŸ’¬ πŸ‘€ πŸ›‘οΈ ⚠️
Jack Fuller
Jack Fuller

πŸ› πŸ’» πŸ“– ⚠️
Jonathan Nagy
Jonathan Nagy

πŸ› πŸ’»
Mani Soundararajan
Mani Soundararajan

πŸ“–
Marji Cermak
Marji Cermak

πŸ“–
david kinzer (he/him)
david kinzer (he/him)

πŸ’»

This project follows the all-contributors specification. Contributions of any kind welcome!

About

Create shareable, self-documenting command-line tools from simple YAML files. Easily wrap shell, npm, docker... anything, to standardize your processes and make the lives of the people working on your project better.

Topics

Resources

Code of conduct

Stars

286 stars

Watchers

11 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages