diff --git a/helpers/wo-fix-perms.sh b/helpers/wo-fix-perms.sh new file mode 100755 index 0000000..050bc2e --- /dev/null +++ b/helpers/wo-fix-perms.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "Usage: $0 example.com" >&2 + exit 1 +fi + +domain="$1" +root="/var/www/$domain" + +if [[ ! -d "$root" ]]; then + echo "Site root not found: $root" >&2 + exit 1 +fi + +echo "Normalizing ownership and permissions under $root" + +# Ownership +chown -R root:webdev "$root" + +# Directories: 2775, Files: 664 +find "$root" -type d -exec chmod 2775 {} \; +find "$root" -type f -exec chmod 664 {} \; + +echo "Done." diff --git a/helpers/wp-dev-bootstrap.sh b/helpers/wp-dev-bootstrap.sh new file mode 100755 index 0000000..d30f2ed --- /dev/null +++ b/helpers/wp-dev-bootstrap.sh @@ -0,0 +1,190 @@ +#!/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."