fix: resolve ShellCheck violations in shell scripts (#91)

- SC2155 (bin/localwp-setup.sh): declare local variables separately from
  command substitution assignments to avoid masking return values (13 fixes)
- SC2034 (bin/localwp-setup.sh): remove unused PLUGIN_TEXT_DOMAIN variable
- SC2162 (bin/localwp-setup.sh): add -r flag to read to avoid backslash mangling
- SC2154 (bin/setup-test-env.sh): add shellcheck disable for PHP variables in
  heredoc that ShellCheck incorrectly identifies as unassigned shell variables
- bin/setup-test-env.sh: remove self-modifying chmod +x $0 (unnecessary and
  bad practice; file permissions should be set once in version control)
- bin/setup-test-env.sh: change == to = in POSIX [ ] test expressions
- build.sh: add ./ prefix to directory glob copies for clarity
- build.sh: use subshell (cd build || exit 1; zip ...) instead of bare cd/cd..
  to avoid SC2103 and ensure working directory is always restored

Fixes part of #20 (shell script quality issues)
This commit is contained in:
2026-03-18 11:47:38 +00:00
committed by GitHub
parent 9fdfa7a8a9
commit 7d0ee0adea
3 changed files with 319 additions and 309 deletions

View File

@@ -28,7 +28,6 @@ set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")" PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
PLUGIN_SLUG="wp-plugin-starter-template" PLUGIN_SLUG="wp-plugin-starter-template"
PLUGIN_TEXT_DOMAIN="wp-plugin-starter-template"
# LocalWP paths (macOS) # LocalWP paths (macOS)
LOCAL_SITES_DIR="$HOME/Local Sites" LOCAL_SITES_DIR="$HOME/Local Sites"
@@ -51,363 +50,375 @@ NC='\033[0m' # No Color
# Helper functions # Helper functions
log_info() { log_info() {
echo -e "${BLUE}[INFO]${NC} $1" echo -e "${BLUE}[INFO]${NC} $1"
} }
log_success() { log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1" echo -e "${GREEN}[SUCCESS]${NC} $1"
} }
log_warning() { log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1" echo -e "${YELLOW}[WARNING]${NC} $1"
} }
log_error() { log_error() {
echo -e "${RED}[ERROR]${NC} $1" echo -e "${RED}[ERROR]${NC} $1"
} }
log_step() { log_step() {
echo -e "${CYAN}[STEP]${NC} $1" echo -e "${CYAN}[STEP]${NC} $1"
} }
# Check if LocalWP is installed # Check if LocalWP is installed
check_localwp() { check_localwp() {
if [ ! -d "$LOCAL_APP" ]; then if [ ! -d "$LOCAL_APP" ]; then
log_error "LocalWP is not installed at $LOCAL_APP" log_error "LocalWP is not installed at $LOCAL_APP"
log_info "Download from: https://localwp.com/" log_info "Download from: https://localwp.com/"
exit 1 exit 1
fi fi
if [ ! -f "$LOCAL_WP_CLI" ]; then if [ ! -f "$LOCAL_WP_CLI" ]; then
log_error "WP-CLI not found in LocalWP installation" log_error "WP-CLI not found in LocalWP installation"
exit 1 exit 1
fi fi
local version=$("$LOCAL_WP_CLI" --version 2>/dev/null || echo "unknown") local version
log_info "LocalWP WP-CLI version: $version" version=$("$LOCAL_WP_CLI" --version 2>/dev/null || echo "unknown")
log_info "LocalWP WP-CLI version: $version"
} }
# Get site path # Get site path
get_site_path() { get_site_path() {
local site_name="$1" local site_name="$1"
echo "$LOCAL_SITES_DIR/$site_name" echo "$LOCAL_SITES_DIR/$site_name"
} }
# Get WordPress path within site # Get WordPress path within site
get_wp_path() { get_wp_path() {
local site_name="$1" local site_name="$1"
local site_path=$(get_site_path "$site_name") local site_path
site_path=$(get_site_path "$site_name")
# LocalWP uses app/public for WordPress files # LocalWP uses app/public for WordPress files
echo "$site_path/app/public" echo "$site_path/app/public"
} }
# Check if site exists # Check if site exists
site_exists() { site_exists() {
local site_name="$1" local site_name="$1"
local site_path=$(get_site_path "$site_name") local site_path
[ -d "$site_path" ] site_path=$(get_site_path "$site_name")
[ -d "$site_path" ]
} }
# Get plugin destination path # Get plugin destination path
get_plugin_path() { get_plugin_path() {
local site_name="$1" local site_name="$1"
local wp_path=$(get_wp_path "$site_name") local wp_path
echo "$wp_path/wp-content/plugins/$PLUGIN_SLUG" wp_path=$(get_wp_path "$site_name")
echo "$wp_path/wp-content/plugins/$PLUGIN_SLUG"
} }
# Sync plugin files to LocalWP site # Sync plugin files to LocalWP site
sync_plugin() { sync_plugin() {
local site_name="$1" local site_name="$1"
local plugin_dest=$(get_plugin_path "$site_name") local plugin_dest
plugin_dest=$(get_plugin_path "$site_name")
if ! site_exists "$site_name"; then if ! site_exists "$site_name"; then
log_error "Site '$site_name' does not exist" log_error "Site '$site_name' does not exist"
return 1 return 1
fi fi
log_info "Syncing plugin to $site_name..." log_info "Syncing plugin to $site_name..."
# Create plugin directory if it doesn't exist # Create plugin directory if it doesn't exist
mkdir -p "$plugin_dest" mkdir -p "$plugin_dest"
# Sync files using rsync (excludes dev files) # Sync files using rsync (excludes dev files)
rsync -av --delete \ rsync -av --delete \
--exclude 'node_modules' \ --exclude 'node_modules' \
--exclude 'vendor' \ --exclude 'vendor' \
--exclude '.git' \ --exclude '.git' \
--exclude 'dist' \ --exclude 'dist' \
--exclude 'tests' \ --exclude 'tests' \
--exclude 'cypress' \ --exclude 'cypress' \
--exclude '.github' \ --exclude '.github' \
--exclude '.agents' \ --exclude '.agents' \
--exclude '.wiki' \ --exclude '.wiki' \
--exclude 'reference-plugins' \ --exclude 'reference-plugins' \
--exclude '*.zip' \ --exclude '*.zip' \
--exclude '.playground.*' \ --exclude '.playground.*' \
--exclude 'composer.lock' \ --exclude 'composer.lock' \
--exclude 'package-lock.json' \ --exclude 'package-lock.json' \
"$PROJECT_DIR/" "$plugin_dest/" "$PROJECT_DIR/" "$plugin_dest/"
log_success "Plugin synced to: $plugin_dest" log_success "Plugin synced to: $plugin_dest"
} }
# Create a new LocalWP site # Create a new LocalWP site
create_site() { create_site() {
local multisite=false local multisite=false
# Parse arguments # Parse arguments
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
--multisite) --multisite)
multisite=true multisite=true
shift shift
;; ;;
*) *)
shift shift
;; ;;
esac esac
done done
local site_name="$SINGLE_SITE_NAME" local site_name="$SINGLE_SITE_NAME"
local domain="$SINGLE_SITE_DOMAIN" local domain="$SINGLE_SITE_DOMAIN"
local mode="single site" local mode="single site"
if [ "$multisite" = true ]; then if [ "$multisite" = true ]; then
site_name="$MULTISITE_NAME" site_name="$MULTISITE_NAME"
domain="$MULTISITE_DOMAIN" domain="$MULTISITE_DOMAIN"
mode="multisite" mode="multisite"
fi fi
check_localwp check_localwp
local site_path=$(get_site_path "$site_name") local site_path
site_path=$(get_site_path "$site_name")
if site_exists "$site_name"; then if site_exists "$site_name"; then
log_warning "Site '$site_name' already exists at: $site_path" log_warning "Site '$site_name' already exists at: $site_path"
log_info "Use 'npm run localwp:reset' to reset it, or 'npm run localwp:sync' to update files" log_info "Use 'npm run localwp:reset' to reset it, or 'npm run localwp:sync' to update files"
return 0 return 0
fi fi
echo "" echo ""
echo "============================================" echo "============================================"
echo " LocalWP Site Setup ($mode)" echo " LocalWP Site Setup ($mode)"
echo "============================================" echo "============================================"
echo "" echo ""
echo "This script will guide you through creating a" echo "This script will guide you through creating a"
echo "LocalWP site for testing the plugin." echo "LocalWP site for testing the plugin."
echo "" echo ""
echo "Site Details:" echo "Site Details:"
echo " Name: $site_name" echo " Name: $site_name"
echo " Domain: $domain" echo " Domain: $domain"
echo " Path: $site_path" echo " Path: $site_path"
echo "" echo ""
log_step "Creating LocalWP Site" log_step "Creating LocalWP Site"
echo "" echo ""
log_info "LocalWP doesn't have a CLI for site creation." log_info "LocalWP doesn't have a CLI for site creation."
log_info "Please create the site manually in LocalWP:" log_info "Please create the site manually in LocalWP:"
echo "" echo ""
echo "1. Open LocalWP application" echo "1. Open LocalWP application"
echo "2. Click the '+' button to create a new site" echo "2. Click the '+' button to create a new site"
echo "3. Use these settings:" echo "3. Use these settings:"
echo " - Site name: ${CYAN}$site_name${NC}" echo " - Site name: ${CYAN}$site_name${NC}"
echo " - Local site domain: ${CYAN}$domain${NC}" echo " - Local site domain: ${CYAN}$domain${NC}"
echo " - PHP version: 8.0 or higher" echo " - PHP version: 8.0 or higher"
echo " - Web server: nginx (preferred)" echo " - Web server: nginx (preferred)"
echo " - MySQL version: 8.0+" echo " - MySQL version: 8.0+"
if [ "$multisite" = true ]; then if [ "$multisite" = true ]; then
echo "" echo ""
echo "4. After site creation, convert to multisite:" echo "4. After site creation, convert to multisite:"
echo " - Open Site Shell in LocalWP" echo " - Open Site Shell in LocalWP"
echo " - Run: wp core multisite-convert --subdomains=0" echo " - Run: wp core multisite-convert --subdomains=0"
echo " - Update wp-config.php if needed" echo " - Update wp-config.php if needed"
fi fi
echo "" echo ""
log_info "After creating the site, run: npm run localwp:sync" log_info "After creating the site, run: npm run localwp:sync"
echo "" echo ""
# Wait for user to create site # Wait for user to create site
read -p "Press Enter after you've created the site in LocalWP..." read -r -p "Press Enter after you've created the site in LocalWP..."
if site_exists "$site_name"; then if site_exists "$site_name"; then
log_success "Site detected at: $site_path" log_success "Site detected at: $site_path"
sync_plugin "$site_name" sync_plugin "$site_name"
# Install recommended plugins # Install recommended plugins
install_recommended_plugins "$site_name" install_recommended_plugins "$site_name"
show_site_info "$site_name" "$domain" "$multisite" show_site_info "$site_name" "$domain" "$multisite"
else else
log_warning "Site not found at expected location" log_warning "Site not found at expected location"
log_info "Expected path: $site_path" log_info "Expected path: $site_path"
log_info "You can run 'npm run localwp:sync' later to sync files" log_info "You can run 'npm run localwp:sync' later to sync files"
fi fi
} }
# Install recommended plugins (matching Playground blueprint) # Install recommended plugins (matching Playground blueprint)
install_recommended_plugins() { install_recommended_plugins() {
local site_name="$1" local site_name="$1"
local wp_path=$(get_wp_path "$site_name") local wp_path
wp_path=$(get_wp_path "$site_name")
log_info "Note: Install these plugins to match Playground environment:" log_info "Note: Install these plugins to match Playground environment:"
echo " - Plugin Toggle (plugin-toggle)" echo " - Plugin Toggle (plugin-toggle)"
echo " - Kadence Blocks (kadence-blocks)" echo " - Kadence Blocks (kadence-blocks)"
echo "" echo ""
log_info "You can install them via LocalWP's WP Admin or Site Shell" log_info "You can install them via LocalWP's WP Admin or Site Shell"
} }
# Show site information # Show site information
show_site_info() { show_site_info() {
local site_name="$1" local site_name="$1"
local domain="$2" local domain="$2"
local multisite="$3" local multisite="$3"
local site_path=$(get_site_path "$site_name") local site_path
local plugin_path=$(get_plugin_path "$site_name") site_path=$(get_site_path "$site_name")
local plugin_path
plugin_path=$(get_plugin_path "$site_name")
echo "" echo ""
echo "============================================" echo "============================================"
echo " LocalWP Site Ready" echo " LocalWP Site Ready"
echo "============================================" echo "============================================"
echo " Site: $site_name" echo " Site: $site_name"
echo " URL: http://$domain" echo " URL: http://$domain"
echo " Admin: http://$domain/wp-admin/" echo " Admin: http://$domain/wp-admin/"
echo " Plugin Path: $plugin_path" echo " Plugin Path: $plugin_path"
echo "============================================" echo "============================================"
if [ "$multisite" = true ]; then if [ "$multisite" = true ]; then
echo " Network Admin: http://$domain/wp-admin/network/" echo " Network Admin: http://$domain/wp-admin/network/"
echo "============================================" echo "============================================"
fi fi
echo "" echo ""
log_info "Remember to:" log_info "Remember to:"
echo " 1. Start the site in LocalWP" echo " 1. Start the site in LocalWP"
echo " 2. Activate the plugin in WordPress admin" echo " 2. Activate the plugin in WordPress admin"
echo " 3. Run 'npm run localwp:sync' after making changes" echo " 3. Run 'npm run localwp:sync' after making changes"
echo "" echo ""
} }
# Reset site to clean state # Reset site to clean state
reset_site() { reset_site() {
local site_name="${1:-$SINGLE_SITE_NAME}" local site_name="${1:-$SINGLE_SITE_NAME}"
if ! site_exists "$site_name"; then if ! site_exists "$site_name"; then
log_error "Site '$site_name' does not exist" log_error "Site '$site_name' does not exist"
exit 1 exit 1
fi fi
log_warning "This will delete the plugin files and resync them." log_warning "This will delete the plugin files and resync them."
read -p "Continue? (y/n) " -n 1 -r read -p "Continue? (y/n) " -n 1 -r
echo echo
if [[ $REPLY =~ ^[Yy]$ ]]; then if [[ $REPLY =~ ^[Yy]$ ]]; then
local plugin_path=$(get_plugin_path "$site_name") local plugin_path
plugin_path=$(get_plugin_path "$site_name")
log_info "Removing plugin files..." log_info "Removing plugin files..."
rm -rf "$plugin_path" rm -rf "$plugin_path"
log_info "Resyncing plugin..." log_info "Resyncing plugin..."
sync_plugin "$site_name" sync_plugin "$site_name"
log_success "Site reset complete" log_success "Site reset complete"
else else
log_info "Reset cancelled" log_info "Reset cancelled"
fi fi
} }
# Sync all existing sites # Sync all existing sites
sync_all() { sync_all() {
local synced=0 local synced=0
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
if site_exists "$site_name"; then if site_exists "$site_name"; then
sync_plugin "$site_name" sync_plugin "$site_name"
synced=$((synced + 1)) synced=$((synced + 1))
fi fi
done done
if [ $synced -eq 0 ]; then if [ $synced -eq 0 ]; then
log_warning "No LocalWP sites found for this plugin" log_warning "No LocalWP sites found for this plugin"
log_info "Run 'npm run localwp:create' to create one" log_info "Run 'npm run localwp:create' to create one"
else else
log_success "Synced $synced site(s)" log_success "Synced $synced site(s)"
fi fi
} }
# Show info about all sites # Show info about all sites
show_info() { show_info() {
echo "" echo ""
echo "LocalWP Sites for $PLUGIN_SLUG" echo "LocalWP Sites for $PLUGIN_SLUG"
echo "===============================" echo "==============================="
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
local site_path=$(get_site_path "$site_name") local site_path
site_path=$(get_site_path "$site_name")
if site_exists "$site_name"; then if site_exists "$site_name"; then
echo "" echo ""
echo " ${GREEN}${NC} $site_name" echo " ${GREEN}${NC} $site_name"
echo " Path: $site_path" echo " Path: $site_path"
local plugin_path=$(get_plugin_path "$site_name") local plugin_path
if [ -d "$plugin_path" ]; then plugin_path=$(get_plugin_path "$site_name")
echo " Plugin: ${GREEN}Installed${NC}" if [ -d "$plugin_path" ]; then
else echo " Plugin: ${GREEN}Installed${NC}"
echo " Plugin: ${YELLOW}Not synced${NC}" else
fi echo " Plugin: ${YELLOW}Not synced${NC}"
else fi
echo "" else
echo " ${YELLOW}${NC} $site_name (not created)" echo ""
fi echo " ${YELLOW}${NC} $site_name (not created)"
done fi
done
echo "" echo ""
echo "Commands:" echo "Commands:"
echo " npm run localwp:create Create single site" echo " npm run localwp:create Create single site"
echo " npm run localwp:create:multisite Create multisite" echo " npm run localwp:create:multisite Create multisite"
echo " npm run localwp:sync Sync plugin files" echo " npm run localwp:sync Sync plugin files"
echo " npm run localwp:reset Reset plugin files" echo " npm run localwp:reset Reset plugin files"
echo "" echo ""
} }
# Main command handler # Main command handler
case "${1:-}" in case "${1:-}" in
create) create)
shift shift
create_site "$@" create_site "$@"
;; ;;
sync) sync)
sync_all sync_all
;; ;;
reset) reset)
shift shift
reset_site "$@" reset_site "$@"
;; ;;
info) info)
show_info show_info
;; ;;
*) *)
echo "LocalWP Integration Script" echo "LocalWP Integration Script"
echo "" echo ""
echo "Usage:" echo "Usage:"
echo " $0 create [--multisite] Create a new LocalWP site" echo " $0 create [--multisite] Create a new LocalWP site"
echo " $0 sync Sync plugin files to all sites" echo " $0 sync Sync plugin files to all sites"
echo " $0 reset [site-name] Reset site plugin to clean state" echo " $0 reset [site-name] Reset site plugin to clean state"
echo " $0 info Show info about LocalWP sites" echo " $0 info Show info about LocalWP sites"
echo "" echo ""
echo "npm scripts:" echo "npm scripts:"
echo " npm run localwp:create Create single site" echo " npm run localwp:create Create single site"
echo " npm run localwp:create:multisite Create multisite" echo " npm run localwp:create:multisite Create multisite"
echo " npm run localwp:sync Sync plugin files" echo " npm run localwp:sync Sync plugin files"
echo " npm run localwp:reset Reset plugin files" echo " npm run localwp:reset Reset plugin files"
echo "" echo ""
echo "URL Patterns:" echo "URL Patterns:"
echo " Single site: http://${PLUGIN_SLUG}-single.local" echo " Single site: http://${PLUGIN_SLUG}-single.local"
echo " Multisite: http://${PLUGIN_SLUG}-multisite.local" echo " Multisite: http://${PLUGIN_SLUG}-multisite.local"
echo "" echo ""
exit 1 exit 1
;; ;;
esac esac

View File

@@ -1,8 +1,5 @@
#!/bin/bash #!/bin/bash
# Make this script executable
chmod +x "$0"
# Check if environment type is provided # Check if environment type is provided
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "Usage: $0 [single|multisite|playground-single|playground-multisite]" echo "Usage: $0 [single|multisite|playground-single|playground-multisite]"
@@ -49,7 +46,7 @@ install_wp_playground() {
fi fi
} }
if [ "$ENV_TYPE" == "single" ]; then if [ "$ENV_TYPE" = "single" ]; then
echo "Setting up single site environment..." echo "Setting up single site environment..."
# Install wp-env if needed # Install wp-env if needed
@@ -83,7 +80,7 @@ if [ "$ENV_TYPE" == "single" ]; then
echo "Site: http://localhost:8888" echo "Site: http://localhost:8888"
echo "Admin login: admin / password" echo "Admin login: admin / password"
elif [ "$ENV_TYPE" == "multisite" ]; then elif [ "$ENV_TYPE" = "multisite" ]; then
echo "Setting up multisite environment..." echo "Setting up multisite environment..."
# Install wp-env if needed # Install wp-env if needed
@@ -124,7 +121,7 @@ elif [ "$ENV_TYPE" == "multisite" ]; then
echo "Test site: http://localhost:8888/testsite" echo "Test site: http://localhost:8888/testsite"
echo "Admin login: admin / password" echo "Admin login: admin / password"
elif [ "$ENV_TYPE" == "playground-single" ]; then elif [ "$ENV_TYPE" = "playground-single" ]; then
echo "Setting up WordPress Playground single site environment..." echo "Setting up WordPress Playground single site environment..."
# Install wp-playground if needed # Install wp-playground if needed
@@ -193,7 +190,7 @@ EOF
echo "Admin login: admin / password" echo "Admin login: admin / password"
echo "Press Ctrl+C to stop the server when done." echo "Press Ctrl+C to stop the server when done."
elif [ "$ENV_TYPE" == "playground-multisite" ]; then elif [ "$ENV_TYPE" = "playground-multisite" ]; then
echo "Setting up WordPress Playground multisite environment..." echo "Setting up WordPress Playground multisite environment..."
# Install wp-playground if needed # Install wp-playground if needed
@@ -205,6 +202,7 @@ elif [ "$ENV_TYPE" == "playground-multisite" ]; then
zip -r dist/plugin.zip . -x "node_modules/*" "dist/*" ".git/*" zip -r dist/plugin.zip . -x "node_modules/*" "dist/*" ".git/*"
# Update blueprint to use local plugin # Update blueprint to use local plugin
# shellcheck disable=SC2154
cat >playground/multisite-blueprint.json <<EOF cat >playground/multisite-blueprint.json <<EOF
{ {
"landingPage": "/wp-admin/network/", "landingPage": "/wp-admin/network/",

View File

@@ -46,9 +46,9 @@ cp -R README.md LICENSE CHANGELOG.md readme.txt composer.json "$BUILD_DIR/"
# Copy directories # Copy directories
echo "Copying directories..." echo "Copying directories..."
mkdir -p "$BUILD_DIR/admin" "$BUILD_DIR/includes" "$BUILD_DIR/languages" "$BUILD_DIR/assets" mkdir -p "$BUILD_DIR/admin" "$BUILD_DIR/includes" "$BUILD_DIR/languages" "$BUILD_DIR/assets"
cp -R admin/* "$BUILD_DIR/admin/" cp -R ./admin/* "$BUILD_DIR/admin/"
cp -R includes/* "$BUILD_DIR/includes/" cp -R ./includes/* "$BUILD_DIR/includes/"
cp -R languages/* "$BUILD_DIR/languages/" cp -R ./languages/* "$BUILD_DIR/languages/"
# Create assets directory structure # Create assets directory structure
mkdir -p "$BUILD_DIR/assets/banner" "$BUILD_DIR/assets/icon" "$BUILD_DIR/assets/screenshots" mkdir -p "$BUILD_DIR/assets/banner" "$BUILD_DIR/assets/icon" "$BUILD_DIR/assets/screenshots"
@@ -73,9 +73,10 @@ fi
# Create ZIP file. # Create ZIP file.
echo "Creating ZIP file..." echo "Creating ZIP file..."
cd build || exit 1 (
zip -r "../$ZIP_FILE" "$PLUGIN_SLUG" -x "*.DS_Store" -x "*.git*" -x "*.github*" cd build || exit 1
cd .. zip -r "../$ZIP_FILE" "$PLUGIN_SLUG" -x "*.DS_Store" -x "*.git*" -x "*.github*"
)
# Check if ZIP file was created successfully # Check if ZIP file was created successfully
if [ -f "$ZIP_FILE" ]; then if [ -f "$ZIP_FILE" ]; then