Skip to content

Instantly share code, notes, and snippets.

@mattbloomfield
Created May 21, 2026 22:26
Show Gist options
  • Select an option

  • Save mattbloomfield/da096ba4b90e77d26a79cae0b5caad2f to your computer and use it in GitHub Desktop.

Select an option

Save mattbloomfield/da096ba4b90e77d26a79cae0b5caad2f to your computer and use it in GitHub Desktop.
A baseline helper we use for all ddev custom commands
#!/usr/bin/env bash
#
# Shared helper library for DDEV custom commands.
# DDEV skips dot-prefixed files during command discovery.
#
# Usage: source "$(dirname "$0")/.helpers.sh"
#
# ─── Colors ───────────────────────────────────────────────────────────────────
# Using $'\e[' syntax — works on bash 3.2+ (macOS) and Linux
GRAY=$'\e[0;37m'
RED=$'\e[1;31m'
GREEN=$'\e[1;32m'
YELLOW=$'\e[1;33m'
BLUE=$'\e[1;34m'
DIM=$'\e[2m'
BOLD=$'\e[1m'
RESET=$'\e[0m'
# ─── Output functions ─────────────────────────────────────────────────────────
# Print a step indicator: ==> message
ddev_step() {
echo "${BLUE}==> ${RESET}${BOLD}$1${RESET}"
}
# Print a success message: [ok] message
ddev_success() {
echo "${GREEN}[ok]${RESET} $1"
}
# Print a warning: [warn] message
ddev_warn() {
echo "${YELLOW}[warn]${RESET} $1"
}
# Print an error: [error] message
ddev_error() {
echo "${RED}[error]${RESET} $1" >&2
}
# Print dimmed text (for secondary info)
ddev_dim() {
echo "${DIM}$1${RESET}"
}
# Print a section header
ddev_header() {
echo ""
echo "${BLUE}${BOLD}$1${RESET}"
}
# ─── Prompt functions ─────────────────────────────────────────────────────────
# Yes/no prompt with default.
# ddev_prompt_yn "Pull database?" "y" → displays "Pull database? [Y/n]: "
# ddev_prompt_yn "Pull assets?" "n" → displays "Pull assets? [y/N]: "
# Returns: sets REPLY to "y" or "n"
ddev_prompt_yn() {
local prompt="$1"
local default="${2:-y}"
local hint
if [[ "$default" == "y" ]]; then
hint="Y/n"
else
hint="y/N"
fi
while true; do
read -r -p "${prompt} ${DIM}[${hint}]:${RESET} " REPLY
REPLY="${REPLY:-$default}"
REPLY=$(echo "$REPLY" | tr '[:upper:]' '[:lower:]')
case "$REPLY" in
y|yes) REPLY="y"; return 0 ;;
n|no) REPLY="n"; return 0 ;;
*) echo " Please answer y or n." ;;
esac
done
}
# Choice prompt with default.
# ddev_prompt_choice "Environment" "production" "development staging production"
# → displays "Environment (development/staging/production) [production]: "
# Returns: sets REPLY to the chosen value
ddev_prompt_choice() {
local prompt="$1"
local default="$2"
local options="$3"
local options_display="${options// //}"
while true; do
read -r -p "${prompt} ${DIM}(${options_display}) [${default}]:${RESET} " REPLY
REPLY="${REPLY:-$default}"
# Validate the choice
for opt in $options; do
if [[ "$REPLY" == "$opt" ]]; then
return 0
fi
done
echo " Invalid choice. Options: ${options_display}"
done
}
# ─── Summary / Confirm ───────────────────────────────────────────────────────
# Print a labeled summary line (right-aligned label)
# ddev_summary_line "Environment" "production"
ddev_summary_line() {
printf " ${DIM}%-20s${RESET} %s\n" "$1:" "$2"
}
# Ask for confirmation or abort.
# ddev_confirm_or_abort "Proceed with sync?"
# Aborts the script if the user says no.
ddev_confirm_or_abort() {
local prompt="${1:-Proceed?}"
echo ""
ddev_prompt_yn "$prompt" "y"
if [[ "$REPLY" != "y" ]]; then
echo ""
ddev_error "Aborted."
exit 1
fi
echo ""
}
# ─── Argument helpers ─────────────────────────────────────────────────────────
# Check if an argument exists in the args list.
# ddev_has_arg "db" "$@" && echo "has db"
ddev_has_arg() {
local needle="$1"; shift
for arg in "$@"; do
[[ "$arg" == "$needle" ]] && return 0
done
return 1
}
# Extract an environment name from args.
# ENV=$(ddev_get_env_arg "development staging production" "$@")
# Returns the first arg that matches one of the valid environments, or empty string.
ddev_get_env_arg() {
local valid_envs="$1"; shift
for arg in "$@"; do
for env in $valid_envs; do
[[ "$arg" == "$env" ]] && echo "$arg" && return 0
done
done
return 1
}
# Check if --help or -h was passed.
ddev_check_help() {
for arg in "$@"; do
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
return 0 # Signal that help was requested
fi
done
return 1 # No help requested
}
# Print help text and exit. Call after ddev_check_help returns 0.
ddev_print_help() {
echo ""
for line in "$@"; do
echo "$line"
done
echo ""
exit 0
}
# ─── Error handling ───────────────────────────────────────────────────────────
# Enable strict error handling. Call at the top of commands.
ddev_setup_error_handling() {
set -eo pipefail
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment