#!/usr/bin/env bash set -euo pipefail umask 0002 # # wp-dev-bootstrap.sh # # Usage (called by panel, but can be used manually): # wp-dev-bootstrap.sh \ # --domain example.local \ # --project-name "Example Project" \ # --admin-user vdidev \ # --admin-email dev@example.com \ # [--theme-starter-repo git@github.com:org/starter.git] \ # [--theme-remote-origin git@github.com:org/client-theme.git] # # Defaults DOMAIN="" PROJECT_NAME="" ADMIN_USER="" ADMIN_EMAIL="" THEME_STARTER_REPO="" THEME_REMOTE_ORIGIN="" while [[ $# -gt 0 ]]; do case "$1" in --domain) DOMAIN="$2" shift 2 ;; --project-name) PROJECT_NAME="$2" shift 2 ;; --admin-user) ADMIN_USER="$2" shift 2 ;; --admin-email) ADMIN_EMAIL="$2" shift 2 ;; --theme-starter-repo) THEME_STARTER_REPO="$2" shift 2 ;; --theme-remote-origin) THEME_REMOTE_ORIGIN="$2" shift 2 ;; *) echo "Unknown arg: $1" >&2 exit 1 ;; esac done if [[ -z "$DOMAIN" || -z "$PROJECT_NAME" || -z "$ADMIN_USER" || -z "$ADMIN_EMAIL" ]]; then echo "Usage: $0 --domain DOMAIN --project-name NAME --admin-user USER --admin-email EMAIL [--theme-starter-repo REPO] [--theme-remote-origin REPO]" >&2 exit 1 fi WEBROOT="/var/www/${DOMAIN}/htdocs" if [[ ! -d "$WEBROOT" ]]; then echo "ERROR: Webroot not found: $WEBROOT" >&2 exit 1 fi cd "$WEBROOT" echo "==> Bootstrapping WordPress site" echo "Domain: $DOMAIN" echo "Project name: $PROJECT_NAME" echo "Webroot: $WEBROOT" echo # Basic site options echo "==> Setting basic site options..." wp option update blogname "$PROJECT_NAME" wp option update blogdescription "Development site for $PROJECT_NAME" # Ensure admin user exists (handle 'email already used' case gracefully) echo "==> Ensuring admin user exists..." if wp user get "$ADMIN_USER" >/dev/null 2>&1; then echo "User $ADMIN_USER already exists." else if wp user list --field=user_email | grep -q "^${ADMIN_EMAIL}\$"; then echo "Admin email ${ADMIN_EMAIL} already in use; skipping user create." else wp user create "$ADMIN_USER" "$ADMIN_EMAIL" --role=administrator --user_pass="$(openssl rand -base64 16)" echo "Admin user $ADMIN_USER created with email $ADMIN_EMAIL (random password)." fi fi # Home / blog pages echo "==> Setting up Home / News pages & reading options..." if ! wp post list --post_type=page --field=post_title | grep -q '^Home$'; then HOME_ID=$(wp post create --post_type=page --post_title="Home" --post_status=publish --porcelain) else HOME_ID=$(wp post list --post_type=page --field=ID --title="Home" | head -n1) fi if ! wp post list --post_type=page --field=post_title | grep -q '^News$'; then NEWS_ID=$(wp post create --post_type=page --post_title="News" --post_status=publish --porcelain) else NEWS_ID=$(wp post list --post_type=page --field=ID --title="News" | head -n1) fi wp option update show_on_front 'page' wp option update page_on_front "$HOME_ID" wp option update page_for_posts "$NEWS_ID" # Dev plugins echo "==> Installing standard dev plugins..." DEV_PLUGINS=( query-monitor user-switching debug-bar ) for PLUGIN in "${DEV_PLUGINS[@]}"; do echo "Installing plugin: $PLUGIN" wp plugin install "$PLUGIN" --activate || true done # Theme bootstrap if [[ -n "$THEME_STARTER_REPO" ]]; then echo "==> Bootstrapping theme from starter repo..." TMP_DIR=$(mktemp -d) git clone "$THEME_STARTER_REPO" "$TMP_DIR" # Heuristic: assume theme lives directly under TMP_DIR or a 'theme' subdir THEME_SRC="" if [[ -f "$TMP_DIR/style.css" ]]; then THEME_SRC="$TMP_DIR" elif [[ -d "$TMP_DIR/theme" ]]; then THEME_SRC="$TMP_DIR/theme" else # First directory under repo FIRST_DIR=$(find "$TMP_DIR" -maxdepth 2 -type d -mindepth 1 | head -n1) THEME_SRC="$FIRST_DIR" fi if [[ -z "$THEME_SRC" || ! -d "$THEME_SRC" ]]; then echo "Theme source not found under $TMP_DIR; skipping theme copy." >&2 else THEMES_DIR="${WEBROOT}/wp-content/themes" mkdir -p "$THEMES_DIR" # Slug from project name THEME_SLUG=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-') [[ -z "$THEME_SLUG" ]] && THEME_SLUG="custom-theme" TARGET_THEME_DIR="${THEMES_DIR}/${THEME_SLUG}" if [[ -d "$TARGET_THEME_DIR" ]]; then echo "Target theme dir already exists ($TARGET_THEME_DIR); skipping copy." else cp -a "$THEME_SRC" "$TARGET_THEME_DIR" echo "Theme copied to $TARGET_THEME_DIR" # Reset git and point to remote if requested if [[ -d "$TARGET_THEME_DIR/.git" ]]; then (cd "$TARGET_THEME_DIR" && rm -rf .git) fi if [[ -n "$THEME_REMOTE_ORIGIN" ]]; then ( cd "$TARGET_THEME_DIR" git init git remote add origin "$THEME_REMOTE_ORIGIN" ) echo "Initialized git repo for theme with remote $THEME_REMOTE_ORIGIN" fi # Try to activate it THEME_STYLESHEET=$(basename "$TARGET_THEME_DIR") wp theme activate "$THEME_STYLESHEET" || echo "Theme activation failed; check theme headers." fi fi rm -rf "$TMP_DIR" else echo "==> Theme starter repo not provided; skipping theme bootstrap." fi echo "==> Bootstrap complete."