Skip to content

Instantly share code, notes, and snippets.

@sharmashivanand
Last active September 24, 2025 05:37
Show Gist options
  • Select an option

  • Save sharmashivanand/d6e7cd09826288434fca5afd157e3af1 to your computer and use it in GitHub Desktop.

Select an option

Save sharmashivanand/d6e7cd09826288434fca5afd157e3af1 to your computer and use it in GitHub Desktop.
GPT5 generated phpcbf and WPCS installer. Works as of Sept 2025
#!/usr/bin/env bash
# Install phpcbf/phpcs + WordPress Coding Standards + PHPCSExtra globally
# Focus: phpcbf-first (auto-fixing). Safe to re-run. Non-destructive.
set -euo pipefail
log() { printf "\033[1;32m==>\033[0m %s\n" "$*"; }
warn() { printf "\033[1;33m[warn]\033[0m %s\n" "$*"; }
die() { printf "\033[1;31m[err]\033[0m %s\n" "$*" >&2; exit 1; }
# --- 0) Requirements ---------------------------------------------------------
command -v php >/dev/null 2>&1 || die "PHP not found. Install PHP and re-run."
command -v composer >/dev/null 2>&1 || die "Composer not found. Install from https://getcomposer.org"
# --- 1) Resolve Composer home & vendor/bin -----------------------------------
COMPOSER_HOME="$(composer global config home 2>/dev/null || true)"
[ -n "${COMPOSER_HOME:-}" ] || die "Could not determine Composer home (composer global config home)."
VENDOR_BIN="$COMPOSER_HOME/vendor/bin"
PHPCS_BIN="$VENDOR_BIN/phpcs"
PHPCBF_BIN="$VENDOR_BIN/phpcbf"
log "Composer home: $COMPOSER_HOME"
log "Vendor bin: $VENDOR_BIN"
# --- 2) Ensure vendor/bin is on PATH now and persistently --------------------
ensure_path() {
case "${SHELL:-}" in
*/zsh) PROFILE="$HOME/.zshrc" ;;
*/fish) PROFILE="$HOME/.config/fish/config.fish" ;;
*) PROFILE="$HOME/.bashrc" ;;
esac
if ! echo ":$PATH:" | grep -q ":$VENDOR_BIN:"; then
if [[ "$PROFILE" = *fish* ]]; then
mkdir -p "$(dirname "$PROFILE")"
grep -q "$VENDOR_BIN" "$PROFILE" 2>/dev/null || echo "set -Ux PATH $VENDOR_BIN \$PATH" >> "$PROFILE"
warn "Added vendor/bin to Fish PATH. Restart shell or run: exec fish"
else
grep -q "$VENDOR_BIN" "$PROFILE" 2>/dev/null || echo "export PATH=\"$VENDOR_BIN:\$PATH\"" >> "$PROFILE"
export PATH="$VENDOR_BIN:$PATH"
warn "Added vendor/bin to PATH. Restart shell or run: export PATH=\"$VENDOR_BIN:\$PATH\""
fi
fi
}
ensure_path
# --- 3) Install PHPCS (phpcs/phpcbf) + WPCS + PHPCSExtra ---------------------
log "Installing/updating PHP_CodeSniffer (phpcbf/phpcs), WPCS, and PHPCSExtra…"
# Clean up any old/bad plugin names silently
composer global remove dealerdirect/phpcodesniffer-plugin >/dev/null 2>&1 || true
composer global require \
squizlabs/php_codesniffer:* \
wp-coding-standards/wpcs:* \
phpcsstandards/phpcsextra:^1.2 \
phpcsstandards/phpcsutils:^1.0 \
--no-interaction
# --- 4) Register standards in installed_paths (WPCS + PHPCSExtra) ------------
WPCS_PATH="$COMPOSER_HOME/vendor/wp-coding-standards/wpcs"
EXTRA_PATH="$COMPOSER_HOME/vendor/phpcsstandards/phpcsextra"
[ -d "$WPCS_PATH" ] || die "WPCS not found at $WPCS_PATH (Composer install failed?)."
[ -d "$EXTRA_PATH" ] || die "PHPCSExtra not found at $EXTRA_PATH (Composer install failed?)."
merge_installed_paths() {
local existing targets all dedup
existing="$("$PHPCS_BIN" --config-show installed_paths 2>/dev/null | awk -F': ' 'NF>1{print $2}')"
targets="$WPCS_PATH,$EXTRA_PATH"
if [ -n "${existing:-}" ] && [ "$existing" != "." ] && [ "$existing" != "null" ]; then
all="$existing,$targets"
else
all="$targets"
fi
# Deduplicate, keep order of first occurrence
dedup="$(echo "$all" | tr ',' '\n' | awk 'NF' | awk '!seen[$0]++' | paste -sd',' -)"
"$PHPCS_BIN" --config-set installed_paths "$dedup" >/dev/null
}
merge_installed_paths
# Set default standard to WordPress (so phpcbf runs without flags)
"$PHPCS_BIN" --config-set default_standard WordPress >/dev/null || true
# --- 5) Add a convenience wrapper: wpcbf ------------------------------------
USER_BIN="${HOME}/.local/bin"
mkdir -p "$USER_BIN"
WPCBF="$USER_BIN/wpcbf"
cat > "$WPCBF" <<'WRAP'
#!/usr/bin/env bash
set -euo pipefail
# wpcbf: WordPress-first auto-fixer (phpcbf wrapper)
# Usage:
# wpcbf # fix current dir
# wpcbf file.php # fix a file
# wpcbf src tests # fix multiple paths
ARGS=("$@")
if [ ${#ARGS[@]} -eq 0 ]; then ARGS=("."); fi
exec phpcbf \
--standard=WordPress \
--extensions=php,php5,phtml \
--report=summary \
--parallel="$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)" \
"${ARGS[@]}"
WRAP
chmod +x "$WPCBF"
# Ensure ~/.local/bin is on PATH too
if ! echo ":$PATH:" | grep -q ":$USER_BIN:"; then
case "${SHELL:-}" in
*/fish)
PROFILE="$HOME/.config/fish/config.fish"
mkdir -p "$(dirname "$PROFILE")"
grep -q "$USER_BIN" "$PROFILE" 2>/dev/null || echo "set -Ux PATH $USER_BIN \$PATH" >> "$PROFILE"
warn "Added $USER_BIN to Fish PATH. Restart shell or run: exec fish"
;;
*)
PROFILE="${PROFILE:-$HOME/.bashrc}"
grep -q "$USER_BIN" "$PROFILE" 2>/dev/null || echo "export PATH=\"$USER_BIN:\$PATH\"" >> "$PROFILE"
export PATH="$USER_BIN:$PATH"
warn "Added $USER_BIN to PATH. Restart shell or run: export PATH=\"$USER_BIN:\$PATH\""
;;
esac
fi
# --- 6) Sanity checks --------------------------------------------------------
log "Sanity check:"
"$PHPCBF_BIN" --version || true
"$PHPCS_BIN" -i || true
"$PHPCS_BIN" --config-show default_standard | sed 's/^/ /'
cat <<'NOTE'
Done. You now have:
• phpcbf installed globally (via PHP_CodeSniffer)
• WordPress Coding Standards + PHPCSExtra registered globally
• DEFAULT STANDARD set to: WordPress
• 'wpcbf' helper command for quick fixing
Quick start:
wpcbf .
phpcs --config-show
phpcs -i
If your editor reports "spawn phpcbf ENOENT":
export PATH="$COMPOSER_HOME/vendor/bin:$HOME/.local/bin:$PATH"
# Then point your editor’s "phpcbf executablePath" to:
# $COMPOSER_HOME/vendor/bin/phpcbf
NOTE
log "All set for phpcbf-first WordPress fixing."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment