|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# local-wp - WP-CLI wrapper for Local by Flywheel sites |
| 4 | +# |
| 5 | +# Runs WP-CLI commands against a Local by Flywheel installation without |
| 6 | +# needing to know the exact PHP binary path for that site. |
| 7 | +# |
| 8 | +# Usage: |
| 9 | +# local-wp <site-name> <wp-cli-command> [args...] |
| 10 | +# local-wp --help |
| 11 | +# |
| 12 | +# Examples: |
| 13 | +# local-wp my-site db query "SELECT * FROM wp_posts LIMIT 10" |
| 14 | +# local-wp my-site option get blogname |
| 15 | +# local-wp my-site plugin list |
| 16 | +# |
| 17 | +# Environment: |
| 18 | +# PHP_BIN Override the PHP binary path (skip auto-detection) |
| 19 | +# WP_CLI Override the WP-CLI binary path (default: wp) |
| 20 | +# |
| 21 | +# © Copyright 2025 Hypercart (a DBA of Neochrome, Inc.) |
| 22 | +# License: Apache-2.0 |
| 23 | +# Version: 1.0.0 |
| 24 | + |
| 25 | +set -euo pipefail |
| 26 | + |
| 27 | +# ============================================================ |
| 28 | +# Colors |
| 29 | +# ============================================================ |
| 30 | + |
| 31 | +RED='\033[0;31m' |
| 32 | +GREEN='\033[0;32m' |
| 33 | +YELLOW='\033[1;33m' |
| 34 | +BLUE='\033[0;34m' |
| 35 | +CYAN='\033[0;36m' |
| 36 | +BOLD='\033[1m' |
| 37 | +NC='\033[0m' # No Color |
| 38 | + |
| 39 | +# ============================================================ |
| 40 | +# Usage / Help (must come BEFORE any PHP detection) |
| 41 | +# ============================================================ |
| 42 | + |
| 43 | +usage() { |
| 44 | + cat << EOF |
| 45 | +${BOLD}local-wp — WP-CLI wrapper for Local by Flywheel sites${NC} |
| 46 | +
|
| 47 | +${BOLD}USAGE:${NC} |
| 48 | + local-wp <site-name> <wp-cli-command> [args...] |
| 49 | + local-wp --help |
| 50 | +
|
| 51 | +${BOLD}EXAMPLES:${NC} |
| 52 | + # Database query |
| 53 | + local-wp my-site db query "SELECT * FROM wp_posts LIMIT 10" |
| 54 | +
|
| 55 | + # Get a WordPress option |
| 56 | + local-wp my-site option get blogname |
| 57 | +
|
| 58 | + # List installed plugins |
| 59 | + local-wp my-site plugin list |
| 60 | +
|
| 61 | + # Export database |
| 62 | + local-wp my-site db export ~/backup.sql |
| 63 | +
|
| 64 | +${BOLD}ENVIRONMENT VARIABLES:${NC} |
| 65 | + PHP_BIN Override the PHP binary (skip auto-detection) |
| 66 | + WP_CLI Override the WP-CLI binary path (default: wp) |
| 67 | +
|
| 68 | +${BOLD}HOW IT WORKS:${NC} |
| 69 | + local-wp searches for the PHP binary used by your Local by Flywheel |
| 70 | + site and delegates all arguments to WP-CLI using that PHP. This lets |
| 71 | + you run WP-CLI commands without knowing the exact PHP path. |
| 72 | +
|
| 73 | + On macOS, Local stores PHP binaries under: |
| 74 | + ~/Library/Application Support/Local/lightning-services/php-*/ |
| 75 | +
|
| 76 | +${BOLD}REQUIREMENTS:${NC} |
| 77 | + - Local by Flywheel must be installed (macOS) or PHP_BIN must be set |
| 78 | + - WP-CLI must be installed and available as 'wp' (or set WP_CLI) |
| 79 | +
|
| 80 | +${BOLD}EXIT CODES:${NC} |
| 81 | + 0 Command succeeded |
| 82 | + 1 Error (see message) |
| 83 | +
|
| 84 | +${BOLD}MORE INFO:${NC} |
| 85 | + Repository: https://github.com/Hypercart-Dev-Tools/WP-Code-Check |
| 86 | +
|
| 87 | +EOF |
| 88 | +} |
| 89 | + |
| 90 | +# Handle --help / -h immediately, before any environment probing |
| 91 | +for arg in "$@"; do |
| 92 | + case "$arg" in |
| 93 | + --help|-h) |
| 94 | + usage |
| 95 | + exit 0 |
| 96 | + ;; |
| 97 | + esac |
| 98 | +done |
| 99 | + |
| 100 | +# ============================================================ |
| 101 | +# PHP binary detection (only reached for non-help invocations) |
| 102 | +# ============================================================ |
| 103 | + |
| 104 | +# detect_php_bin — search macOS Local by Flywheel for a PHP binary. |
| 105 | +# Prints the path to stdout on success; prints nothing and returns 0 |
| 106 | +# on failure so callers are not broken by set -e. |
| 107 | +detect_php_bin() { |
| 108 | + local search_dirs=( |
| 109 | + "${HOME}/Library/Application Support/Local/lightning-services" |
| 110 | + "/Applications/Local.app/Contents/Resources/extraResources/lightning-services" |
| 111 | + ) |
| 112 | + |
| 113 | + for dir in "${search_dirs[@]}"; do |
| 114 | + if [[ ! -d "$dir" ]]; then |
| 115 | + continue |
| 116 | + fi |
| 117 | + # Find the highest-version PHP binary available |
| 118 | + local php_bin |
| 119 | + php_bin=$(find "$dir" -name "php-fpm" -o -name "php" 2>/dev/null \ |
| 120 | + | grep -v "php-fpm" \ |
| 121 | + | sort -rV \ |
| 122 | + | head -n 1) |
| 123 | + if [[ -x "$php_bin" ]]; then |
| 124 | + echo "$php_bin" |
| 125 | + return 0 |
| 126 | + fi |
| 127 | + done |
| 128 | + |
| 129 | + # No Local PHP found — return 0 (not 1) so set -e does not abort the |
| 130 | + # caller. The empty output signals "not found" to the caller. |
| 131 | + return 0 |
| 132 | +} |
| 133 | + |
| 134 | +# Resolve PHP_BIN. The || true guard ensures that even if detect_php_bin |
| 135 | +# were ever changed to return non-zero, set -e cannot silently kill the |
| 136 | +# script here — we fall through to the explicit error check below. |
| 137 | +PHP_BIN="${PHP_BIN:-$(detect_php_bin || true)}" |
| 138 | + |
| 139 | +# ============================================================ |
| 140 | +# Argument validation |
| 141 | +# ============================================================ |
| 142 | + |
| 143 | +if [[ $# -lt 1 ]]; then |
| 144 | + echo -e "${RED}Error:${NC} site name required.\n" >&2 |
| 145 | + usage >&2 |
| 146 | + exit 1 |
| 147 | +fi |
| 148 | + |
| 149 | +SITE_NAME="$1" |
| 150 | +shift |
| 151 | + |
| 152 | +if [[ $# -lt 1 ]]; then |
| 153 | + echo -e "${RED}Error:${NC} WP-CLI command required after site name '${SITE_NAME}'.\n" >&2 |
| 154 | + usage >&2 |
| 155 | + exit 1 |
| 156 | +fi |
| 157 | + |
| 158 | +# ============================================================ |
| 159 | +# WP-CLI binary resolution |
| 160 | +# ============================================================ |
| 161 | + |
| 162 | +WP_CLI="${WP_CLI:-wp}" |
| 163 | + |
| 164 | +if ! command -v "$WP_CLI" &>/dev/null; then |
| 165 | + echo -e "${RED}Error:${NC} WP-CLI not found. Install it from https://wp-cli.org/ or set WP_CLI." >&2 |
| 166 | + exit 1 |
| 167 | +fi |
| 168 | + |
| 169 | +# ============================================================ |
| 170 | +# PHP resolution / fallback |
| 171 | +# ============================================================ |
| 172 | + |
| 173 | +if [[ -z "$PHP_BIN" ]]; then |
| 174 | + # Fall back to the system PHP if Local's PHP cannot be found |
| 175 | + if command -v php &>/dev/null; then |
| 176 | + PHP_BIN="$(command -v php)" |
| 177 | + echo -e "${YELLOW}Warning:${NC} Local by Flywheel PHP not found for '${SITE_NAME}'. Using system PHP: ${PHP_BIN}" >&2 |
| 178 | + else |
| 179 | + echo -e "${RED}Error:${NC} No PHP binary found." >&2 |
| 180 | + echo " Set PHP_BIN to your PHP path, e.g.:" >&2 |
| 181 | + echo " PHP_BIN=/usr/bin/php local-wp ${SITE_NAME} $*" >&2 |
| 182 | + exit 1 |
| 183 | + fi |
| 184 | +fi |
| 185 | + |
| 186 | +# ============================================================ |
| 187 | +# Execute WP-CLI |
| 188 | +# ============================================================ |
| 189 | + |
| 190 | +exec "$PHP_BIN" "$(command -v "$WP_CLI")" "$@" |
0 commit comments