Created
May 21, 2026 22:26
-
-
Save mattbloomfield/da096ba4b90e77d26a79cae0b5caad2f to your computer and use it in GitHub Desktop.
A baseline helper we use for all ddev custom commands
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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