Last active
October 14, 2023 09:26
-
-
Save rmpel/899a0d34a63d6a7d0c87e8f725fb255e to your computer and use it in GitHub Desktop.
Local Lightning - The unofficial CLI for the new Local 5.x and 6.x version - this is work in progress.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
######### | |
## Configration: | |
## Set your primary and secondary development paths. | |
## YOU CANNOT HAVE SPACES IN THE PRIMARY PATH - If you have, then most tooling here will fail because of limitations in macOS Terminal. | |
## AND NO - This tool is not built to use a different terminal. | |
## | |
PRIMARY_LOCATION=~/Development | |
SECONDARY_LOCATION=/Volumes/Macintosh\ SD/Development | |
# These paths are for macOS. For windows ... or git bash ... or Linux ... or BeOS ... GOOD LUCK! | |
LOCAL_RUNTIME_DIRECTORY=~/Library/Application\ Support/Local | |
LOCAL_RUN=$LOCAL_RUNTIME_DIRECTORY/run | |
# Configure a shell profile for use with the SSH session | |
# This profile must have an appropriate font, font-size and close window when exited cleanly. | |
# Default profiles in Terminal (In macOS 13 Ventura) are; | |
# Basic, Grass, Homebrew, Man Page, Novel, Ovean, Pro, Red Sands, Silver Aerogel and Solid Colors | |
LBL_SHELL_PROFILE="${LBL_SHELL_PROFILE:-Grass}" | |
######### | |
## Determine the actual path to this file. | |
## Fix the permissions always, just to make sure. | |
## | |
function get_realpath() { | |
[[ ! -f "$1" ]] && return 1 # failure : file does not exist. | |
[[ -n "$no_symlinks" ]] && local pwdp='pwd -P' || local pwdp='pwd' # do symlinks. | |
readlink "$( cd "$( echo "${1%/*}" )" 2>/dev/null; $pwdp )"/"${1##*/}" # echo result. | |
return 0 # success | |
} | |
# ran as script.sh or /full/path/to/script.sh, using the shebang as interpreter | |
FULL_PATH_TO_SCRIPT=$(get_realpath $0) | |
# ran as bash /full/path/to/script.sh, using the cli given interpreter. this should be bash, or sh (which probably IS bash) but not zsh. | |
[ "" = "$FULL_PATH_TO_SCRIPT" ] && FULL_PATH_TO_SCRIPT="${BASH_SOURCE[0]}" | |
if [ "." = "$(dirname "$FULL_PATH_TO_SCRIPT")" ]; then | |
echo "Script located in 'current directory', prepending full path" >&2 | |
FULL_PATH_TO_SCRIPT="$(pwd -P)/$(basename "$FULL_PATH_TO_SCRIPT")" | |
fi | |
# fix permissions | |
[ "" != "$FULL_PATH_TO_SCRIPT" ] && chmod 755 "$FULL_PATH_TO_SCRIPT" | |
######### | |
## Create a safe path to the secondary location for use with tooling. | |
## in case you are wondering WHY | |
## using the Terminal app with "run inside shell" off ergo RunCommandAsShell true in a .terminal plist file | |
## spaces are not allowed AT ALL in the path. This is probably a bug as the correctly escaped path works perfectly | |
## with "run inside shell" on, ergo RunCommandAsShell false. | |
## To combat this, we replace the secondary location with a symlinked location | |
## obviously, this will break when the primary location has spaces in it ... | |
## | |
if [ ! -L $PRIMARY_LOCATION/.secondary_location ]; then | |
# symlink not available, create this. | |
ln -s "$SECONDARY_LOCATION" $PRIMARY_LOCATION/.secondary_location | |
fi | |
SECONDARY_LOCATION_REAL="$SECONDARY_LOCATION" | |
SECONDARY_LOCATION=$PRIMARY_LOCATION/.secondary_location | |
######### | |
## Find or install the nodeJS package local-cli | |
## | |
if [ "" = "$(which nvm)" ]; then | |
export NVM_DIR=~/.nvm | |
if [ ! -d "$NVM_DIR" ]; then | |
brew install nvm | |
fi | |
source $(brew --prefix nvm)/nvm.sh | |
fi | |
######### | |
## Install the Flywheel Local-CLI using Node12 | |
## We temporarily switch the node version to 12 to do this. | |
## | |
NODE_VERSION_SET=$(nvm current); | |
# nvm current || ( echo HELP; exit; ) | |
[[ $(nvm version) =~ v12 ]] || nvm use 12 >/dev/null 2>&1 | |
[ "$NODE_VERSION_SET" = "$(nvm current)" ] && NODE_VERSION_SET="" | |
LOCAL_CLI=$(which local-cli) | |
if [ "" = "$LOCAL_CLI" ]; then | |
if [ "" != "$(which npm)" ]; then | |
if [ $(node --version | awk -F. '{print $1}' | sed 's/[^0-9]//') -gt 9 ]; then | |
echo Installing local-cli with NodeJS version $(node --version) >&2 | |
npm install -g @getflywheel/local-cli | |
LOCAL_CLI=$(which local-cli) | |
fi | |
if [ "" = "$LOCAL_CLI" ]; then | |
echo "Installation seemed to have failed. Please try to correct this manually and try again." >&2 | |
echo " - switch to node version 12" >&2 | |
echo " - globally install the package @getflywheel/local-cli" >&2 | |
echo "you should now have the command local-cli in your PATH" >&2 | |
exit. | |
fi | |
fi | |
fi | |
######### | |
## Test local-cli and LocalWP by trying to access the site list. | |
## | |
if [ "" != "$LOCAL_CLI" ]; then | |
if $LOCAL_CLI list-sites >/dev/null 2>&1; then | |
echo "" >/dev/null | |
else | |
LOCAL_CLI="" | |
echo "LocalWP not running" >&2 | |
exit; | |
fi | |
fi | |
STATUS=Running | |
######### | |
## Internals | |
## | |
NEED_RESTART=0 | |
BROWSER= | |
CLOPS= | |
VERBOSE=true | |
SHOWHELP=false | |
SCHEME=http: | |
SQLPRO="$(ls -1d {~,}/Applications/Sequel\ {Ace,Pro}*.app 2>/dev/null | grep Applications | sort | head -n 1)" | |
SQLPRO_IS_ACE=no | |
[ "$(echo $SQLPRO | grep 'Sequel Ace' | wc -l)" -gt 0 ] && SQLPRO_IS_ACE=yes | |
LCLAPP="$(ls -1d {~,}/Applications/Local.app 2>/dev/null | grep Applications | sort | head -n 1)" | |
MSQLWB="$(ls -1d {~,}/Applications/MySQLWorkbench.app 2>/dev/null | grep Applications | sort | head -n 1)" | |
######### | |
## Try to find shell and profile | |
## | |
USESHELL=$SHELL | |
PROFILE_FILE_A=$(basename $SHELL) | |
PROFILE_FILE=no | |
[ "no" = "$PROFILE_FILE" ] && [ -f "${HOME}/.${PROFILE_FILE_A}_profile" ] && PROFILE_FILE="${HOME}/.${PROFILE_FILE_A}_profile" | |
[ "no" = "$PROFILE_FILE" ] && [ -f "${HOME}/.${PROFILE_FILE_A}rc" ] && PROFILE_FILE="${HOME}/.${PROFILE_FILE_A}rc" | |
[ "no" = "$PROFILE_FILE" ] && PROFILE_FILE= | |
########## | |
## Path to the built-in wp-cli implementation | |
## This version has updates disabled, and we need to update because the shipped version is slightly too old | |
## We will use this path to update the WP CLI if this tool is run with cli-update | |
## | |
WPCLI=${LCLAPP}/Contents/Resources/extraResources/site-binaries/wp-cli/bin/wp | |
######### | |
## Parse runtime config flags/parameters | |
## | |
while [ "" != "$1" ]; do | |
case "$1" in | |
--ssl) | |
SCHEME=https: | |
;; | |
--silent) | |
VERBOSE=false | |
;; | |
-h|--help) | |
SHOWHELP=true | |
;; | |
-p|--project|--site) | |
SITE=$2 | |
shift | |
;; | |
-s=*|--site=*) | |
SITE=${1#*=} | |
;; | |
-b|--browser) | |
_BROWSER="$2" | |
shift | |
;; | |
-b=*|--browser=*) | |
_BROWSER=${1#*=} | |
shift | |
;; | |
-ff|--firefox) | |
_BROWSER=Firefox | |
;; | |
-fd|--firefox-dev|--firefox-developer-edition) | |
_BROWSER=Firefox\ Developer\ Edition | |
;; | |
-c|--chrome) | |
_BROWSER=Google\ Chrome | |
;; | |
-cd|--chromium|--chrome-dev) | |
_BROWSER=Chromium | |
;; | |
-o|--opera) | |
_BROWSER=Opera | |
;; | |
-s|--safari) | |
_BROWSER=Safari | |
;; | |
-mse|--edge) | |
_BROWSER=Microsoft\ Edge | |
;; | |
--shell=*) | |
[ -f /bin/${1#*=} ] && USESHELL=/bin/${1#*=} | |
;; | |
--shell) | |
[ -f /bin/${2} ] && USESHELL=/bin/${2} | |
shift | |
;; | |
*) | |
P=$1 | |
[ ">" = "${P}" ] && P="'${P}'" | |
[ ">=" = "${P}" ] && P="'${P}'" | |
[ "<" = "${P}" ] && P="'${P}'" | |
[ "<=" = "${P}" ] && P="'${P}'" | |
[ "|" = "${P}" ] && P="'${P}'" | |
[ "" != "$OP" ] && CLOPS="${CLOPS} ${P}" | |
[ "" = "$OP" ] && OP=$1 | |
;; | |
esac | |
shift; | |
done | |
# Gather Command Line OPtionS | |
CLOPS=${CLOPS## } | |
CLOPS_ARRAY=(${CLOPS}) | |
######### | |
## Find the browser app-bundle for the requested browser. | |
## | |
__local_get_browser() { | |
local BROWSER | |
# resolve browser | |
[ -d "$1" ] && [[ "$1" =~ \.app/?$ ]] && BROWSER="$1" | |
[ -d "/Applications/$1" ] && BROWSER="$1" | |
[ -d "/Applications/$1.app" ] && BROWSER="$1" | |
[ -d ~/"Applications/$1" ] && BROWSER="$1" | |
[ -d ~/"Applications/$1.app" ] && BROWSER="$1" | |
[ "" != "$BROWSER" ] && echo $BROWSER; | |
} | |
BROWSER="$(__local_get_browser "$_BROWSER")" | |
[ "" != "$_BROWSER" ] && [ "" = "$BROWSER" ] && echo "Browser ${_BROWSER} not installed, or not found." && exit 9 | |
######### | |
## Show the help information | |
## | |
[ "true" = "$SHOWHELP" ] && OP= | |
if [ "${OP}" = "" ]; then | |
echo "Local is great, but sometimes you need to use the terminal, so, with this script" | |
echo $0 | |
echo You can | |
echo ' '$(basename "$0") 'list List all sites' | |
echo ' '$(basename "$0") 'raw View all info Local has on this site' | |
echo ' '$(basename "$0") 'info View all info LBL can determine for this site' | |
echo ' '$(basename "$0") 'open Open the site in your default browser' | |
if [ "" != "$LOCAL_CLI" ]; then | |
echo ' '$(basename "$0") 'start Start a halted site' | |
echo ' '$(basename "$0") 'stop|halt Stop a running site' | |
echo ' '$(basename "$0") 'restart Restart a running site' | |
fi | |
echo ' '$(basename "$0") 'mailhog Open the mailhog software for this site in your default browser' | |
echo ' '$(basename "$0") 'db Open Sequel Ace/Sequel Pro with the database of this site' | |
echo ' '$(basename "$0") 'ssh Open a pre-configured shell for this site in the public folder' | |
# echo ' '$(basename "$0") 'ssh commandline Execute commandline in pre-configured shell for this site in the current folder' | |
echo ' '$(basename "$0") 'wp commandline Perform WP-CLI operation on site' | |
echo ' '$(basename "$0") 'php [parameters] Perform PHP operation on site in the current folder' | |
echo ' '$(basename "$0") 'wpdr Perform wp search-replace <current domain> <local domain>' | |
echo ' '$(basename "$0") 'log Show site error-log. If WP_DEBUG_LOG is true, the WordPress debug.log is shown' | |
echo ' '$(basename "$0") 'cli-update Update the WP-CLI included with LocalWP (as it is not possible with wp cli update )' | |
echo "" | |
echo You can use --site, --project or -p to specify a site, either by Name, ID or Path to operate on | |
echo You can use --browser or -b to specify a WebBrowser either by AppName or AppPath to use for \'open\' and \'mailhog\' | |
echo You can use --ssl to use https with operation \'open\' and \'wpdr\' | |
echo Browser shortcuts; | |
echo ' -ff or --firefox Firefox' | |
echo ' -fd or --firefox-dev or --firefox-developer-edition Firefox Developer Edition' | |
echo ' -c or --chrome Google Chrome' | |
echo ' -cd or --chrome-dev or --chromium Chromium' | |
echo ' -o or --opera Opera' | |
echo ' -s or --safari Safari' | |
echo ' -mse or --edge Microsoft Edge' | |
echo "" | |
echo It should come as no surprise you need to be inside the folder structure of your Local site. | |
exit; | |
fi | |
######### | |
## Special case: if we want to run php or wp-cli commands from outside the site-shell, we suppress all other output. | |
[ "wp" = "${OP}" ] && VERBOSE=false | |
[ "php" = "${OP}" ] && VERBOSE=false | |
######### | |
## Find the LocalWP (formerly known as Local Lightning by Flywheel) | |
## | |
FLWL=/Applications/Local.app | |
[ ! -d "$FLWL" ] && FLWL=~/Applications/Local.app | |
[ ! -d "$FLWL" ] && FLWL=$(mdfind Local.app | egrep '\.app$' | head -n 1) | |
[ ! -d "$FLWL" ] && echo "Sorry, looks like Local 5 or higher is not installed." && exit 1; | |
######### | |
## Store the current working directory | |
## | |
CWD=$(pwd); | |
######### | |
## To find the root folder of the current project. This will be a folder in ~/Development | |
## Since this is always called on runtime, we take the opportunity to store the public directory name (public, public_html, web) | |
## | |
PUBLIC_DIR=public | |
__local_find_root () { | |
local DIR=$CWD | |
# we support these three public html folders, also see __local_get_webroot | |
local FOUND=0 | |
[ "" != "$1" ] && DIR="$1" && FOUND=1 | |
[ 0 = $FOUND ] && [ -d "$DIR"/web ] && [ "app" = "$(basename "$DIR")" ] && DIR=$DIR/web && FOUND=1 | |
[ 0 = $FOUND ] && [ -d "$DIR"/public_html ] && [ "app" = "$(basename "$DIR")" ] && DIR=$DIR/public_html && FOUND=1 | |
[ 0 = $FOUND ] && [ -d "$DIR"/public ] && [ "app" = "$(basename "$DIR")" ] && DIR=$DIR/public && FOUND=1 | |
# get site installation path. | |
_DIR=$(echo "$DIR" | awk -F'/app/' '{print $1}') | |
# if successful, we have less work to do. | |
[ "" != "$_DIR" ] && [ "$DIR" != "$_DIR" ] && DIR="$_DIR" | |
# find a folder that contains an 'app' folder | |
while [ "$DIR" != "" ] && [ "$DIR" != '.' ] && [ "$DIR" != "/" ] && [ ! -d "${DIR}/app" ]; do | |
DIR="$( dirname "$DIR" )" | |
echo "DEBUG: $DIR" >&2; | |
done; | |
[ -d "$DIR"/app/web ] && PUBLIC_DIR=web | |
[ -d "$DIR"/app/public_html ] && PUBLIC_DIR=public_html | |
[ -d "$DIR"/app/public ] && PUBLIC_DIR=public | |
echo "$DIR" | |
} | |
__local_find_root >/dev/null 2>&1 | |
######### | |
## Get the current working directory relative to the website public location | |
## | |
PWD_REL=$(php -r 'echo str_replace($argv[1], "", $argv[2]);' "$(__local_find_root)/app/$PUBLIC_DIR/" "$CWD") | |
######### | |
## A list of site IDs | |
## | |
__local_get_ids() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ print "$i "; }' | php | |
} | |
######### | |
## Get site ID by path | |
## $1: a full path to a site (project root) | |
## | |
__local_get_id() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
local DIR="$(realpath "$1")" | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ if (realpath(str_replace("~",$home,$a->path))=="'${DIR}'") { print $i; } }' | php | |
} | |
######### | |
## Get site ID by name | |
## $1: site name (basename of project root) | |
## | |
__local_get_id_by_name() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ if (strtolower($a->name)==strtolower("'${1}'")) { print $i; } }' | php | |
} | |
######### | |
## Given a site ID, reflect it if it exists | |
## $1: SiteID | |
## | |
__local_verify_id() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ if (strtolower($i)==strtolower("'${1}'")) { print $i; } }' | php | |
} | |
######### | |
## Print data by key for a site | |
## $1: SiteID | |
## $2: key | |
## | |
__local_get_data() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $select=explode(" ","'${@}'"); $db=json_decode(file_get_contents("'${DB}'")); foreach($select as $a) { $db=(array)$db; $db=$db[$a]; } print $db;' | php | sed 's^~^'${HOME}'^g' | |
} | |
######### | |
## Fix all sites path by replacing it with its RealPath. | |
## | |
__local_fix_sites() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'")); foreach($db as &$site) { $site->path = realpath($site->path); } file_put_contents("'${DB}'", json_encode($db, 128));' | php | |
} | |
# we run this always | |
__local_fix_sites; | |
######### | |
## Deprecated?? | |
## | |
__local_get_docker() { | |
# $1 = key | |
DB=~/Library/Application\ Support/Local/dockerode-options.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$result=$db->{"'${1}'"}; print $result;' | php | sed 's^~^'${HOME}'^g' | |
} | |
######### | |
## Get raw data for a site | |
## $1: SiteID | |
## | |
__local_get_data_raw() { | |
DB=~/Library/Application\ Support/Local/sites.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$a=$db->{"'${1}'"}; print json_encode($a, JSON_PRETTY_PRINT);' | php | |
} | |
######### | |
## Output filter for nocal-cli output | |
## | |
__local_cli_clean_fucking_output() { | |
cat | php -r '$is=file("php://stdin");foreach($is as $i) { $e=substr(trim($i),-3,3);$o = array_filter(array_map("trim",explode($e, $i))); if (count($o) > 1) print implode("\t", $o) . PHP_EOL; }' | |
} | |
######### | |
## Show status for all sites | |
## | |
__local_cli_site_status() { | |
$LOCAL_CLI list-sites | grep $1 | __local_cli_clean_fucking_output | awk '{print $3}' | |
} | |
######### | |
## Get site status directly from JSON data | |
## TODO: use local-cli | |
## $1: SiteID | |
__local_site_status() { | |
DB=~/Library/Application\ Support/Local/site-statuses.json | |
[ "" != "$LOCAL_CLI" ] && __local_cli_site_status $1 || \ | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$a=$db->{"'${1}'"}; print $a;' | php | |
} | |
######### | |
## Get the webroot for a project | |
## $1: SiteID | |
## | |
__local_get_webroot() { | |
# use predetermined for faster | |
WEBROOT="$(__local_get_data ${1} path)/app/$PUBLIC_DIR" | |
# but backfill when needed | |
[ ! -d "$WEBROOT" ] && WEBROOT="$(__local_get_data ${1} path)/app/web" && PUBLIC_DIR=web | |
[ ! -d "$WEBROOT" ] && WEBROOT="$(__local_get_data ${1} path)"/app/public_html && PUBLIC_DIR=public_html | |
[ ! -d "$WEBROOT" ] && WEBROOT="$(__local_get_data ${1} path)"/app/public && PUBLIC_DIR=public | |
echo "$WEBROOT" | |
} | |
######### | |
## Get the path to the Apache site config file that is in use for this by Apache2 | |
## $1: SiteID | |
## | |
__local_get_apache_site_conf_path() { | |
echo $LOCAL_RUN/${1}/conf/apache/site.conf | |
} | |
######### | |
## Get the path to the Apache site config TEMPLATE file that is used to generate the config file for this site. | |
## $1: SiteID | |
## | |
__local_get_apache_site_conf_template_path() { | |
echo "$(__local_get_data ${1} path)/conf/apache/site.conf.hbs" | |
} | |
######### | |
## Get the path to the Apache modules config TEMPLATE file that is used to generate the config file for this site. | |
## $1: SiteID | |
## | |
__local_get_apache_modules_conf_template_path() { | |
echo "$(__local_get_data ${1} path)/conf/apache/modules.conf.hbs" | |
} | |
######### | |
## Sanitize the Apache configuration | |
## $1: SiteID | |
## | |
__local_ensure_correct_apache() { | |
WEBROOT="$(__local_get_webroot ${1})" | |
CONF_PATH="$(__local_get_apache_site_conf_path ${1})" | |
CONF_TPL="$(__local_get_apache_site_conf_template_path ${1})" | |
MODULES_TPL="$(__local_get_apache_modules_conf_template_path ${1})" | |
# fix the webroot - instead of relying on 'public' by way of LocalWP variable, we inject the actual path. | |
if grep "$WEBROOT" "$CONF_PATH" 2>&1 >/dev/null ; then | |
# all good | |
echo -n '' | |
else | |
OLD_WEBROOT="$(grep DocumentRoot "$CONF_TPL" | awk -F '"' '{print $2}' )" | |
cat "$CONF_TPL" | sed 's@'"${OLD_WEBROOT}"'@'"${WEBROOT}"'@g' > /tmp/$$.conf && mv /tmp/$$.conf "$CONF_TPL" | |
NEED_RESTART=1 | |
fi | |
# make sure the headers module is present. | |
# we currently do not check for present line with a hashmark (disabled) | |
if grep "mod_headers.so" "$MODULES_TPL" 2>&1 >/dev/null ; then | |
# all good | |
echo -n '' | |
else | |
echo 'LoadModule headers_module "{{ modules }}/mod_headers.so"' > "$MODULES_TPL".$$ | |
cat "$MODULES_TPL" >> "$MODULES_TPL".$$ | |
mv "$MODULES_TPL".$$ "$MODULES_TPL" | |
NEED_RESTART=1 | |
fi | |
} | |
######### | |
## Get the path to the PHP INI file that is in use for this by PHP | |
## $1: SiteID | |
## | |
__local_get_php_conf_path() { | |
echo ~/Library/Application\ Support/Local/run/${1}/conf/php/php.ini | |
} | |
######### | |
## Get the path to the PHP INI TEMPLATE file that is used to generate the config file for this site. | |
## $1: SiteID | |
## | |
__local_get_php_conf_template_path() { | |
# $1 = ID | |
echo "$(__local_get_data ${1} path)/conf/php/php.ini.hbs" | |
} | |
######### | |
## Sanitize the PHP configuration | |
## $1: SiteID | |
## | |
__local_ensure_correct_php() { | |
WEBROOT="$(__local_get_webroot ${1})" | |
# try the composer-based installation path first, | |
WORDPRESS="$WEBROOT"/wp/wp-includes/certificates/ca-bundle.crt | |
# revert to the LocalWP default, which could be missing. | |
[ ! -f "$WORDPRESS" ] && WORDPRESS="$WEBROOT"/wp-includes/certificates/ca-bundle.crt | |
CONF_PATH="$(__local_get_php_conf_path ${1})" | |
CONF_TPL="$(__local_get_php_conf_template_path ${1})" | |
# crt file path should be in the ini file | |
if grep "$WORDPRESS" "$CONF_PATH" 2>&1 >/dev/null ; then | |
# all good | |
echo -n '' | |
else | |
OLD_WORDPRESS=$(grep openssl.cafile "$CONF_TPL" | awk -F '"' '{print $2}' ) | |
cat "$CONF_TPL" | sed 's@'${OLD_WORDPRESS}'@'${WORDPRESS}'@g' > /tmp/$$.conf && mv /tmp/$$.conf "$CONF_TPL" | |
NEED_RESTART=1 | |
fi | |
} | |
######### | |
## Experimental: MySQL Workbench support | |
## $1: SiteID | |
## | |
__mysql_workbench_has_connection() { | |
db="~/Library/Application Support/MySQL/Workbench/connections.xml" | |
nm="Local: "$(__local_get_data $1 name) | |
if grep "$nm" "$db"; then | |
# connection exists | |
echo "$nm" | |
else | |
# connection does not exist | |
echo "Please open MySQL Workbench and create a new connection with this exact name:" >&2 | |
echo " $nm" >&2 | |
echo "Use a socket connection to:" >&2 | |
echo " ${LOCAL_RUN}/${1}/mysql/mysqld.sock" >&2 | |
echo "Username: root" >&2 | |
echo "Password: root" >&2 | |
echo "Database: local" >&2 | |
echo "" | |
fi | |
} | |
######### | |
## Generate an spf file for use with Sequel Pro - Yes, this software is old, no longer in development, buggy as hell, but still the best out there. | |
## $1: SiteID | |
## | |
__local_db_spf_generate() { | |
db=$(__local_get_data $1 mysql database); | |
dbu=$(__local_get_data $1 mysql user); | |
pwd=$(__local_get_data $1 mysql password); | |
socket="${LOCAL_RUN}/${1}/mysql/mysqld.sock" | |
socket_shadow_dir="${HOME}/Library/Containers/com.sequel-ace.sequel-ace/Data" | |
socket_shadow_name="mysqld-$1.sock" | |
socket_shadow="$socket_shadow_dir/$socket_shadow_name" | |
# if [ "yes" = "$SQLPRO_IS_ACE" ]; then | |
# [ -f "$socket_shadow" ] && rm "$socket_shadow" | |
# cd "$socket_shadow_dir"; | |
# ln -s "$socket" "socket_shadow_name" | |
# cd - 2>&1 >/dev/null | |
# socket="$socket_shadow" | |
# fi | |
site=$(__local_get_data $1 name); | |
echo '<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>ContentFilters</key> | |
<dict/> | |
<key>auto_connect</key> | |
<true/> | |
<key>data</key> | |
<dict> | |
<key>connection</key> | |
<dict> | |
<key>colorIndex</key> | |
<integer>0</integer> | |
<key>database</key> | |
<string>'$db'</string> | |
<key>host</key> | |
<string>localhost</string> | |
<key>kcid</key> | |
<string>-3334337708084194944</string> | |
<key>name</key> | |
<string>Local - '$site'</string> | |
<key>rdbms_type</key> | |
<string>mysql</string> | |
<key>socket</key> | |
<string>'$socket'</string> | |
<key>sslCACertFileLocation</key> | |
<string></string> | |
<key>sslCACertFileLocationEnabled</key> | |
<integer>0</integer> | |
<key>sslCertificateFileLocation</key> | |
<string></string> | |
<key>sslCertificateFileLocationEnabled</key> | |
<integer>0</integer> | |
<key>sslKeyFileLocation</key> | |
<string></string> | |
<key>sslKeyFileLocationEnabled</key> | |
<integer>0</integer> | |
<key>type</key> | |
<string>SPSocketConnection</string> | |
<key>useSSL</key> | |
<integer>0</integer> | |
<key>user</key> | |
<string>'$dbu'</string> | |
<key>password</key> | |
<string>'$pwd'</string> | |
</dict> | |
<key>session</key> | |
<dict/> | |
</dict> | |
<key>encrypted</key> | |
<false/> | |
<key>format</key> | |
<string>connection</string> | |
<key>queryFavorites</key> | |
<array/> | |
<key>queryHistory</key> | |
<array/> | |
<key>rdbms_type</key> | |
<string>mysql</string> | |
<key>rdbms_version</key> | |
<string>8.0.15</string> | |
<key>version</key> | |
<integer>1</integer> | |
</dict> | |
</plist> | |
' | |
} | |
######### | |
## Find the intelliJ phpStorm .idea folder for this project. | |
## $1: SiteID | |
## | |
__local_find_idea() { | |
SITE_ROOT=$(__local_get_data $1 path) | |
WEB_ROOT=$(__local_get_webroot $1) | |
# allowed in web root | |
if [ -d "$WEB_ROOT/.idea" ]; then | |
echo "$WEB_ROOT/.idea" | |
fi | |
# allowed in app folder | |
if [ -d "$SITE_ROOT/app/.idea" ]; then | |
echo "$SITE_ROOT/app/.idea" | |
fi | |
# allowed in project folder | |
if [ -d "$SITE_ROOT/.idea" ]; then | |
echo "$SITE_ROOT/.idea" | |
fi | |
} | |
######### | |
## Configure phpStorm for the database connection. | |
## $1: SiteID | |
## $2: Path to the .idea folder | |
## | |
__local_db_idea_configure() { | |
db=$(__local_get_data $1 mysql database); | |
dbu=$(__local_get_data $1 mysql user); | |
pwd=$(__local_get_data $1 mysql password); | |
socket="${LOCAL_RUN}/${1}/mysql/mysqld.sock" | |
site=$(__local_get_data $1 name); | |
uuid=$(uuidgen) | |
echo \ | |
'<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> | |
<data-source source="LOCAL" name="LocalWP - '$site'" uuid="'$uuid'"> | |
<driver-ref>mysql.8</driver-ref> | |
<synchronize>true</synchronize> | |
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver> | |
<jdbc-url>jdbc:mysql:///'$db'?junixsocket.file=$USER_HOME$/Library/Application Support/Local/run/'$1'/mysql/mysqld.sock&socketFactory=org.newsclub.net.mysql.AFUNIXDatabaseSocketFactoryCJ</jdbc-url> | |
<working-dir>$ProjectFileDir$</working-dir> | |
</data-source> | |
</component> | |
</project>' > "$2/dataSources.xml" | |
echo \ | |
'<?xml version="1.0" encoding="UTF-8"?> | |
<project version="4"> | |
<component name="dataSourceStorageLocal" created-in="PS-222.3345.135"> | |
<data-source name="local" uuid="'$uuid'"> | |
<database-info product="MySQL" version="8.0.16" jdbc-version="4.2" driver-name="MySQL Connector/J" driver-version="mysql-connector-java-8.0.25 (Revision: 08be9e9b4cba6aa115f9b27b215887af40b159e0)" dbms="MYSQL" exact-version="8.0.16" exact-driver-version="8.0"> | |
<extra-name-characters>#@</extra-name-characters> | |
<identifier-quote-string>\`</identifier-quote-string> | |
</database-info> | |
<case-sensitivity plain-identifiers="mixed" quoted-identifiers="mixed" /> | |
<secret-storage>master_key</secret-storage> | |
<user-name>'$dbu'</user-name> | |
<password>'$pwd'</password> | |
<schema-mapping> | |
<introspection-scope> | |
<node kind="schema" qname="local" /> | |
</introspection-scope> | |
</schema-mapping> | |
</data-source> | |
</component> | |
</project>' > "$2/dataSources.local.xml" | |
} | |
######### | |
## Generate a terminal profile file for use with macOS Terminal | |
## $@: pass-thru | |
## | |
__local_terminal_profile_generate() { | |
echo '<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | |
<plist version="1.0"> | |
<dict> | |
<key>Font</key> | |
<data> | |
YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMS | |
AAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGkCwwVFlUkbnVsbNQNDg8QERIT | |
FFZOU1NpemVYTlNmRmxhZ3NWTlNOYW1lViRjbGFzcyNALAAAAAAAABAQgAKAA18QH0Zp | |
cmFDb2RlTmVyZEZvbnRDb21wbGV0ZS1SZXRpbmHSFxgZGlokY2xhc3NuYW1lWCRjbGFz | |
c2VzVk5TRm9udKIZG1hOU09iamVjdAgRGiQpMjdJTFFTWF5nbnd+hY6QkpS2u8bP1tkA | |
AAAAAAABAQAAAAAAAAAcAAAAAAAAAAAAAAAAAAAA4g== | |
</data> | |
<key>FontAntialias</key> | |
<true/> | |
<key>FontWidthSpacing</key> | |
<real>1.004032258064516</real> | |
<key>ProfileCurrentVersion</key> | |
<real>2.0699999999999998</real> | |
<key>columnCount</key> | |
<integer>160</integer> | |
<key>name</key> | |
<string>Basic</string> | |
<key>rowCount</key> | |
<integer>48</integer> | |
<key>shellExitAction</key> | |
<integer>1</integer> | |
<key>type</key> | |
<string>Window Settings</string> | |
<key>CommandString</key> | |
<string>'$@'</string> | |
<key>RunCommandAsShell</key> | |
<true/> | |
<key>WindowTitle</key> | |
<string>LocalShell</string> | |
</dict> | |
</plist> | |
' | |
} | |
######### | |
## Generate a site-shell bash script to open the site shell for this site. | |
## $1: SiteID | |
## $2: (optional) command-line to pass-thru to the shell | |
## | |
__local_shell_generate() { | |
echo '#!'$SHELL | |
echo 'export DISABLE_AUTO_TITLE="true"' | |
echo 'export WP_ENV=local-by-flywheel' | |
[ "" = "$2" ] && echo 'echo -n -e "\033]0;Local Shell for '$(__local_get_data $1 name)'\007"' | |
echo 'export MYSQL_HOME="'${LOCAL_RUN}'/'${1}'/conf/mysql"' | |
echo 'export PHPRC="'${LOCAL_RUN}'/'${1}'/conf/php"' | |
# TODO: copy the config.yaml file to the site folder and use that, giving the option to customize | |
echo 'export WP_CLI_CONFIG_PATH="'${FLWL}'/Contents/Resources/extraResources/bin/wp-cli/config.yaml"' | |
echo 'export WP_CLI_DISABLE_AUTO_CHECK_UPDATE=1' | |
# Add PHP, MySQL, and WP-CLI to \$PATH | |
if [ "" = "$2" ]; then echo ' | |
echo "Setting Local environment variables..." | |
' | |
fi | |
# Find the applicable runtime library paths | |
ARCHI=darwin | |
[ "" != "$(which arch)" ] && [ "arm64" == "$(arch)" ] && ARCHI=darwin-arm64 | |
MYSQL=$(__local_get_data $SITE services mysql version) | |
PHP=$(__local_get_data $SITE services php version) | |
for i in \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/mysql-${MYSQL}*/bin/${ARCHI}/bin \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/mysql-${MYSQL}*/bin/darwin/bin \ | |
~/Library/Application\ Support/Local/lightning-services/mysql-${MYSQL}*/bin/${ARCHI}/bin \ | |
~/Library/Application\ Support/Local/lightning-services/mysql-${MYSQL}*/bin/darwin/bin \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/mysql-${MYSQL}*/bin/darwin/bin \ | |
; do | |
if [ -d "$i" ]; then | |
pushd $i >/dev/null 2>&1 | |
MYSQL=$(pwd -P) | |
popd >/dev/null 2>&1 | |
break; | |
else | |
MYSQL="" | |
fi | |
done | |
for i in \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/php-${PHP}*/bin/${ARCHI}/bin \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/php-${PHP}*/bin/darwin/bin \ | |
~/Library/Application\ Support/Local/lightning-services/php-${PHP}*/bin/${ARCHI}/bin \ | |
~/Library/Application\ Support/Local/lightning-services/php-${PHP}*/bin/darwin/bin \ | |
${LCLAPP}/Contents/Resources/extraResources/lightning-services/php-${PHP}*/bin/darwin/bin \ | |
; do | |
if [ -d "$i" ]; then | |
pushd "$i" >/dev/null 2>&1 | |
PHP=$(pwd -P) | |
popd >/dev/null 2>&1 | |
break; | |
else | |
PHP="" | |
fi | |
done | |
for i in \ | |
/Applications/Local.app/Contents/Resources/extraResources/lightning-services/php-${PHP}*/bin/darwin/ImageMagick/modules-Q16/coders \ | |
; do | |
if [ -d "$i" ]; then | |
pushd $i >/dev/null 2>&1 | |
MGK=$(pwd -P) | |
popd >/dev/null 2>&1 | |
break; | |
else | |
MGK="" | |
fi | |
done | |
popd >/dev/null 2>&1 | |
[ "" != "$PROFILE_FILE" ] && echo 'source "'$PROFILE_FILE'" >/dev/null 2>&1 | |
' | |
echo ' | |
export PATH="'${MYSQL}':$PATH" | |
export PATH="'${PHP}':$PATH" | |
export PATH="'${FLWL}'/Contents/Resources/extraResources/bin/wp-cli/posix:$PATH" | |
export PATH="'${FLWL}'/Contents/Resources/extraResources/bin/composer/posix:$PATH" | |
' | |
[ "" != "${MGK}" ] && echo ' | |
export MAGICK_CODER_MODULE_PATH="'${MGK}':$PATH" | |
' | |
if [ "" = "$2" ]; then echo ' | |
cd "'$(__local_get_webroot $SITE)'" | |
echo "tell app \"Terminal\" to set current settings of first window to settings set \"'$LBL_SHELL_PROFILE'\""|osascript; | |
echo "tell application \"Terminal\" to delete settings set \"shell-for-'$SITE'\""|osascript | |
clear | |
echo "----" | |
echo "WP-CLI: $(wp --version)" | |
echo "PHP: $(php -r "echo PHP_VERSION;")" | |
echo "MySQL: $(mysql --version)" | |
echo "----" | |
echo "Launching shell: '${USESHELL}' ..." | |
' | |
echo ' | |
'${USESHELL}' | |
' | |
else | |
[ "" != "$PWD_REL" ] && echo ' | |
cd "'${CWD}'"' || echo ' | |
cd "'$(__local_get_webroot $SITE)'/"' | |
echo ' | |
exec '${USESHELL}' -c '$2' | |
' | |
fi | |
} | |
######### | |
## Helper: print a table | |
## | |
printTable() { | |
local -r delimiter="${1}" | |
local -r data="$(__table__removeEmptyLines "${2}")" | |
if [[ "${delimiter}" != '' && "$(__table__isEmptyString "${data}")" = 'false' ]] | |
then | |
local -r numberOfLines="$(wc -l <<< "${data}")" | |
if [[ "${numberOfLines}" -gt '0' ]] | |
then | |
local table='' | |
local i=1 | |
for ((i = 1; i <= "${numberOfLines}"; i = i + 1)) | |
do | |
local line='' | |
line="$(sed "${i}q;d" <<< "${data}")" | |
local numberOfColumns='0' | |
numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")" | |
# Add Line Delimiter | |
if [[ "${i}" -eq '1' ]] | |
then | |
table="${table}$(printf '%s#+' "$(__table__repeatString '#+' "${numberOfColumns}")")" | |
fi | |
# Add Header Or Body | |
table="${table}\n" | |
local j=1 | |
for ((j = 1; j <= "${numberOfColumns}"; j = j + 1)) | |
do | |
table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")" | |
done | |
table="${table}#|\n" | |
# Add Line Delimiter | |
if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]] | |
then | |
table="${table}$(printf '%s#+' "$(__table__repeatString '#+' "${numberOfColumns}")")" | |
fi | |
done | |
if [[ "$(__table__isEmptyString "${table}")" = 'false' ]] | |
then | |
echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1' | |
fi | |
fi | |
fi | |
} | |
## part of printTable | |
__table__removeEmptyLines() { | |
local -r content="${1}" | |
echo -e "${content}" | sed '/^\s*$/d' | |
} | |
## part of printTable | |
__table__repeatString() { | |
local -r string="${1}" | |
local -r numberToRepeat="${2}" | |
if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]] | |
then | |
local -r result="$(printf "%${numberToRepeat}s")" | |
echo -e "${result// /${string}}" | |
fi | |
} | |
## part of printTable | |
__table__isEmptyString() { | |
local -r string="${1}" | |
if [[ "$(__table__trimString "${string}")" = '' ]] | |
then | |
echo 'true' && return 0 | |
fi | |
echo 'false' && return 1 | |
} | |
## part of printTable | |
__table__trimString() { | |
local -r string="${1}" | |
sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,' | |
} | |
#debugging | |
# __local_find_root; exit; | |
# __local_get_id "$(__local_find_root)";exit; | |
######### | |
## Helper: does a string contain another string? Is string $1 in $2? | |
## $1: String to search for | |
## $2: String to search in | |
## | |
stringContain() { | |
[ -z "$1" ] || { [ -z "${2##*$1*}" ] && [ -n "$2" ]; }; | |
} | |
######### | |
## ??? | |
## | |
__lbl_link() { | |
src="$FULL_PATH_TO_SCRIPT" | |
tgd=$1 | |
tgl=lbl | |
cd "$tgd" | |
[ -L $tgl ] && echo "Already linked" && echo "use unlink $tgd if needed" && exit 1; | |
echo "Linking: $tgd/$tgl to $src" | |
ln -s "$src" "$tgl" || echo "Could not create link, maybe try sudo ?" >&2 | |
} | |
######### | |
## ??? | |
## | |
__lbl_unlink() { | |
src="$FULL_PATH_TO_SCRIPT" | |
tgd=$1 | |
tgl=lbl | |
cd "$tgd" | |
[ ! -L $tgl ] && echo "Not linked" && echo "use link $tgd if needed" && exit 1; | |
echo "Unlinking: $tgd/$tgl" | |
rm "$tgl" || echo "Could not remove link, maybe try sudo ?" >&2 | |
} | |
######### | |
## Update the built-in CLI | |
## | |
if [ "cli-update" = "${OP}" ]; then | |
CLI_PATH=$(which wp) | |
if [ "" = "$CLI_PATH" ]; then | |
echo WP CLI not found. sorry. | |
exit 1; | |
fi | |
echo WP CLI Found: $CLI_PATH | |
CLI_PATH=$(realpath "$CLI_PATH") | |
echo Real path: $CLI_PATH | |
if [ "" = "$CLI_PATH" ]; then | |
echo WP CLI not resolved. sorry. | |
exit 1; | |
fi | |
echo Updating ... | |
curl https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 2>/dev/null > "$CLI_PATH" | |
echo Done. Reporting version below: | |
"$CLI_PATH" cli version | |
exit 0; | |
fi | |
######### | |
## Deprecated: install/uninstall | |
## | |
[ "install" = "${OP}" ] && echo install is ambiguous, please use link to link this script in the binaries folder && exit 1; | |
[ "uninstall" = "${OP}" ] && echo uninstall is ambiguous, please use unlink to unlink this script from the binaries folder && exit 1; | |
######### | |
## Unknown how this works, it's been a while since I built it | |
## | |
[ "link" = "${OP}" ] && __lbl_link ${CLOPS_ARRAY[0]} /usr/local/bin && exit 0; | |
[ "unlink" = "${OP}" ] && __lbl_unlink ${CLOPS_ARRAY[0]} /usr/local/bin && exit 0; | |
######### | |
## List all sites | |
## | |
if [ "list" = "${OP}" ]; then | |
printf "working...\r" | |
TABLE='SiteID,Status,Name,Path\n'; | |
for SITE in $(__local_get_ids); do | |
TABLE=${TABLE}$SITE,$(__local_site_status $SITE),$(__local_get_data $SITE name),$(__local_get_data $SITE path)$'\n' | |
done | |
printTable , "$TABLE" | |
exit; | |
fi | |
######### | |
## What is this for? I can't remember ... | |
## | |
if [ "" != "$SITE" ]; then | |
PRESET_SITE="$SITE" | |
SITE=$(__local_verify_id "$PRESET_SITE") | |
[ "" = "$SITE" ] && SITE=$(__local_get_id_by_name "$PRESET_SITE") | |
if [ "" = "$SITE" ] && [ -d "$PRESET_SITE" ]; then | |
PRESET_SITE="`cd "${PRESET_SITE}";pwd`"; | |
SITE=$(__local_get_id "$PRESET_SITE" ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/$PUBLIC_DIR ] && SITE=$(__local_get_id "$PRESET_SITE"/$PUBLIC_DIR ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/app/$PUBLIC_DIR ] && SITE=$(__local_get_id "$PRESET_SITE"/app/$PUBLIC_DIR ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE" ] && SITE=$(__local_get_id "$(__local_find_root "$PRESET_SITE")" ) | |
PRESET_SITE="`cd "${PRESET_SITE}";pwd -P`"; | |
SITE=$(__local_get_id "$PRESET_SITE" ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/$PUBLIC_DIR ] && SITE=$(__local_get_id "$PRESET_SITE"/$PUBLIC_DIR ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/app/$PUBLIC_DIR ] && SITE=$(__local_get_id "$PRESET_SITE"/app/$PUBLIC_DIR ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE" ] && SITE=$(__local_get_id "$(__local_find_root "$PRESET_SITE")" ) | |
fi | |
fi | |
######### | |
## Find the SiteID | |
## | |
[ "" = "$SITE" ] && SITE=$(__local_get_id "$(__local_find_root)" ) | |
######### | |
## Find the Site Name | |
## | |
NAME=$(__local_get_data $SITE name); | |
######### | |
## If either SiteID or Name not found, abort. | |
## | |
[ "" = "$SITE" ] && echo "Not a Local site" && exit 2; | |
[ "" = "$NAME" ] && echo "Not a Local site" && exit 2; | |
######### | |
## Autocorrect the environment | |
__local_ensure_correct_apache $SITE | |
__local_ensure_correct_php $SITE | |
#__local_ensure_correct_xdebug $SITE | |
######### | |
## One of the corrections requires a site restart. | |
## | |
if [ "1" = "$NEED_RESTART" ]; then | |
if [ "" != "$LOCAL_CLI" ]; then | |
"$LOCAL_CLI" stop-site $SITE | |
"$LOCAL_CLI" start-site $SITE | |
else | |
echo "Site needs a restart, could not do it for you." | |
exit | |
fi | |
fi | |
######### | |
## Display a little bit of information about the current site | |
## | |
if [ "true" = "${VERBOSE}" ] && [ "info" != "${OP}" ]; then | |
echo "Root: "$(__local_get_data $SITE path); | |
echo "Name: $NAME"; | |
echo "SiteID: $SITE"; | |
fi | |
######### | |
## If LocalCLI is available, allow start/stop | |
## | |
if [ "" != "$LOCAL_CLI" ]; then | |
[ "running" != "$STATUS" ] && [ "start" = "${OP}" ] && $LOCAL_CLI start-site $SITE && exit 0 | |
[ "running" = "$STATUS" ] && [ "stop" = "${OP}" ] && $LOCAL_CLI stop-site $SITE && exit 0 | |
[ "running" = "$STATUS" ] && [ "halt" = "${OP}" ] && $LOCAL_CLI stop-site $SITE && exit 0 | |
# restart sequence | |
if [ "restart" = "${OP}" ]; then | |
[ "running" = "$STATUS" ] && echo Running, stopping site ... && $LOCAL_CLI stop-site $SITE | |
echo Starting site ... | |
$LOCAL_CLI start-site $SITE | |
exit 0; | |
fi | |
fi | |
######### | |
## Auto-start site | |
## | |
STATUS=$(__local_site_status $SITE) | |
[ "halted" = "$STATUS" ] && [ "" != "$LOCAL_CLI" ] && $LOCAL_CLI start-site $SITE | |
STATUS=$(__local_site_status $SITE) | |
[ "halted" = "$STATUS" ] && echo "Please enable site in Local" && exit 3; | |
######### | |
## Command: raw - Show raw information | |
## | |
[ "raw" = "${OP}" ] && __local_get_data_raw $SITE && exit 0; | |
######### | |
## Command: open - Open the site in the browser | |
## | |
[ "open" = "${OP}" ] && [ "" != "$BROWSER" ] && open -a "$BROWSER" ${SCHEME}//$(__local_get_data $SITE domain) && exit 0; | |
[ "open" = "${OP}" ] && [ "" = "$BROWSER" ] && open ${SCHEME}//$(__local_get_data $SITE domain) && exit 0; | |
######### | |
## Command: mailhog - Open the site MailHog in the browser | |
## | |
[ "mailhog" = "${OP}" ] && [ "" != "$BROWSER" ] && open -a "$BROWSER" http://$(__local_get_data $SITE domain):$(__local_get_data $SITE services mailhog ports WEB 0) && exit 0; | |
[ "mailhog" = "${OP}" ] && [ "" = "$BROWSER" ] && open http://localhost:$(__local_get_data $SITE services mailhog ports WEB 0) && exit 0; | |
######### | |
## Command: db - Open the database manager - SequelPro | |
## Will also configure phpStorm if not already done. | |
## | |
if [ "db" = "${OP}" ]; then | |
IDEA=$(__local_find_idea $SITE) | |
if [ "" != "$IDEA" ] && [ ! -f "$IDEA/dataSources.xml" ]; then | |
__local_db_idea_configure $SITE $IDEA | |
echo "phpStorm configured for Database access" | |
fi | |
fi | |
[ "$SQLPRO" != "" ] && [ "db" = "${OP}" ] && spf="$(__local_get_data $SITE path)"/sequel-pro-lightning.spf && __local_db_spf_generate $SITE > "$spf" && open -a "$SQLPRO" "$spf" && exit 0; | |
# [ "$MSQLWB" != "" ] && [ "db" = "${OP}" ] && [ "" != "$(__mysql_workbench_has_connection $SITE)" ] && { open -a "$MSQLWB" --query "$(__mysql_workbench_has_connection $SITE)" & } && exit 0; | |
######### | |
## Just-in-time revert node to the previous version, if it was changed. | |
## | |
if [ "" != "$NODE_VERSION_SET" ]; then | |
nvm use $NODE_VERSION_SET >/dev/null 2>&1 | |
fi | |
######### | |
## Migrate site back from Secondary location to Primary | |
## | |
if [ "onload" = "${OP}" ]; then | |
[ "$SECONDARY_LOCATION" = "" ] && SECONDARY_LOCATION=$PRIMARY_LOCATION; | |
[ "$SECONDARY_LOCATION" = "" ] && echo "PRIMARY_LOCATION and SECONDARY_LOCATION not declared. Cannot onload." && exit 1; | |
[ "$SECONDARY_LOCATION" = "$PRIMARY_LOCATION" ] && echo "PRIMARY_LOCATION and SECONDARY_LOCATION declared, but identical. Cannot onload." && exit 1; | |
[ ! -d "$PRIMARY_LOCATION" ] && echo PRIMARY_LOCATION is not a valid directory, please reconfigure && exit 1; | |
[ ! -d "$SECONDARY_LOCATION" ] && echo SECONDARY_LOCATION is not a valid directory, please reconfigure && exit 1; | |
# check if not already on PRIMARY | |
THE_PATH=$(__local_get_data $SITE path) | |
if stringContain "$SECONDARY_LOCATION_REAL" "$THE_PATH"; then | |
echo Project is on secondary location, moving to primary location | |
NEW_PATH=$(echo $THE_PATH | sed "s#${SECONDARY_LOCATION_REAL}#${PRIMARY_LOCATION}#") | |
if [ -L "$NEW_PATH" ]; then | |
echo "$NEW_PATH is a symbolic link, removing ..." | |
rm "${NEW_PATH}"; | |
fi | |
if [ -d "$NEW_PATH" ]; then | |
echo "$NEW_PATH already exists, cannot offload" | |
exit 5; | |
fi | |
echo "working ..."; | |
mv "$THE_PATH" "$PRIMARY_LOCATION"/ | |
echo "Done." | |
cd "$NEW_PATH" | |
echo "ATTENTION: Please type cd ~ ; cd - to go away and back in the current directory as the directory is moved." | |
exit; | |
fi | |
echo Project is NOT on secondary location, sorry | |
exit 3; | |
fi | |
######### | |
## Migrate site from Primary location to Secondary | |
## | |
if [ "offload" = "${OP}" ]; then | |
[ "$SECONDARY_LOCATION" = "" ] && SECONDARY_LOCATION=$PRIMARY_LOCATION; | |
[ "$SECONDARY_LOCATION" = "" ] && echo "PRIMARY_LOCATION and SECONDARY_LOCATION not declared. Cannot offload." && exit 1; | |
[ "$SECONDARY_LOCATION" = "$PRIMARY_LOCATION" ] && echo "PRIMARY_LOCATION and SECONDARY_LOCATION declared, but identical. Cannot offload." && exit 1; | |
[ ! -d "$PRIMARY_LOCATION" ] && echo PRIMARY_LOCATION is not a valid directory, please reconfigure && exit 1; | |
[ ! -d "$SECONDARY_LOCATION" ] && echo SECONDARY_LOCATION is not a valid directory, please reconfigure && exit 1; | |
# check if not already on SECONDARY | |
THE_PATH=$(__local_get_data $SITE path) | |
echo $SITE | |
echo $THE_PATH | |
echo $PRIMARY_LOCATION | |
if stringContain "$PRIMARY_LOCATION" "$THE_PATH"; then | |
echo Project is on primary location, moving to secondary location | |
NEW_PATH=$(echo $THE_PATH | sed "s#${PRIMARY_LOCATION}#${SECONDARY_LOCATION}#") | |
if [ -d "$NEW_PATH" ]; then | |
echo "$NEW_PATH already exists, cannot offload" | |
exit 5; | |
fi | |
echo "working ..."; | |
mv "$THE_PATH" "$SECONDARY_LOCATION"/ | |
ln -s "$NEW_PATH" "$THE_PATH" | |
echo "Done." | |
cd "$NEW_PATH" | |
echo "ATTENTION: Please type cd ~ ; cd - to go away and back in the current directory as the directory is moved." | |
exit; | |
fi | |
echo Project is NOT on primary location, sorry | |
exit 3; | |
fi | |
######### | |
## Internal filter: replace the actual secondary location with the safe symlink to allow for use in scripts | |
## | |
__local_replace_secondary_location () { | |
cat | sed 's@'"$SECONDARY_LOCATION"'@'"$PRIMARY_LOCATION"/.secondary_location'@g' | |
} | |
######### | |
## Command: wpdr - shortcut for replacing a domainname with the LocalWP site domainname. Does not work if WP_HOME is defined. | |
## | |
if [ "wpdr" = "${OP}" ]; then | |
D=$(${0} wp option get siteurl | sed -E 's@https?://(www\.)?@@' | cat) | |
N=${SCHEME}//$(__local_get_data $SITE domain) | |
echo Base domain: https?://\(www.\)?$D | |
echo Replace with $N | |
sh="$(__local_get_data $SITE path)"/temp-wp-shell-replace.sh | |
echo 'D=$(wp option get siteurl | sed -E "s@https?://(www\.)?@@")' > "$sh" | |
echo 'N='${SCHEME}'//'$(__local_get_data $SITE domain)'' >> "$sh" | |
echo 'wp search-replace --all-tables http://www.$D $N' >> "$sh" | |
echo 'wp search-replace --all-tables https://www.$D $N' >> "$sh" | |
echo 'wp search-replace --all-tables http://$D $N' >> "$sh" | |
echo 'wp search-replace --all-tables https://$D $N' >> "$sh" | |
chmod 755 "$sh" | |
echo rm "'$sh'" >> "$sh" | |
sh2="$(__local_get_data $SITE path | __local_replace_secondary_location )"/temp-wp-shell.sh | |
__local_shell_generate $SITE "-c '\"$sh\"'" > "$sh2" | |
exec "$sh2" && rm "$sh2" && exit 0; | |
fi | |
######### | |
## Command: wp - run a wp-cli command | |
## | |
if [ "wp" = "${OP}" ]; then | |
sh="$(__local_get_data $SITE path | __local_replace_secondary_location )"/temp-wp-shell.sh | |
__local_shell_generate $SITE "-c 'wp ${CLOPS}'" > "$sh" | |
chmod 755 "$sh" | |
exec "$sh" && rm "$sh" && exit 0; | |
fi | |
######### | |
## Command: env - fix the .env file for use with LocalWP | |
if [ "env" = "${OP}" ]; then | |
envpath="$(__local_get_data $SITE path | __local_replace_secondary_location )/app/.env" | |
envdir="$(dirname "$envpath")" | |
D="$(__local_get_data $SITE domain)" | |
[ ! -f "$envpath" ] && [ -f "$envpath".example ] && cp "$envpath".example "$envpath" | |
[ ! -f "$envpath" ] && [ -f "$envdir"/vendor/acato/acato-wp-core/dist/.env.example ] && cp "$envdir"/vendor/acato/acato-wp-core/dist/.env.example "$envpath" | |
grep WP_ENV "$envpath" >/dev/null && \ | |
sed -i -e 's/WP_ENV=.*$/WP_ENV=local/' "$envpath" || \ | |
echo ' | |
WP_ENV=local' >> "$envpath" | |
sed -i -e 's/DB_NAME=.*$/DB_NAME=local/' "$envpath" | |
sed -i -e 's/DB_USER=.*$/DB_USER=root/' "$envpath" | |
sed -i -e 's/DB_PASSWORD=.*$/DB_PASSWORD=root/' "$envpath" | |
sed -i -e 's/WP_DOMAIN=.*$/WP_DOMAIN='$D'/' "$envpath" | |
[ -f "$envpath"-e ] && rm "$envpath"-e | |
exit 0; | |
fi | |
######### | |
## Command: log - search for a log file and tail it. | |
if [ "log" = "${OP}" ]; then | |
log="$(__local_get_data $SITE path | __local_replace_secondary_location )"/app/$PUBLIC_DIR/wp-content/debug.log | |
[ ! -f "$log" ] && log="$(__local_get_data $SITE path | __local_replace_secondary_location )"/app/$PUBLIC_DIR/wp-content/$(__local_get_data $SITE domain)-debug.log | |
[ ! -f "$log" ] && log="$(__local_get_data $SITE path | __local_replace_secondary_location )"/logs/php/error.log | |
[ ! -f "$log" ] && echo "cannot find error log, sorry." && exit 1; | |
tail -F "$log" | |
exit 0; | |
fi | |
######### | |
## Command: livereload - inject an mu-plugin that loads the livereload javascript. | |
## | |
if [ "livereload" = "${OP}" ]; then | |
E="$(__local_get_data $SITE path | __local_replace_secondary_location )"/app/$PUBLIC_DIR/wp-content/ | |
NE="$(__local_get_data $SITE path | __local_replace_secondary_location )"/app/$PUBLIC_DIR/wp-content/mu-plugins | |
LR="$(__local_get_data $SITE path | __local_replace_secondary_location )"/app/$PUBLIC_DIR/wp-content/mu-plugins/live-reload-injected-by-lbl.php | |
[ ! -d "$E" ] && echo "Could not find wp-content folder. This is a scripting error. sorry." && exit 1; | |
[ ! -d "$NE" ] && echo "Creating mu-plugins folder" && mkdir "$NE" | |
if [ "disable" = "$CLOPS" ]; then | |
rm "$LR" | |
echo "LiveReload disabled" | |
exit 0; | |
fi | |
echo "<?php add_action('wp_footer', function(){ ?><script src='//localhost:35729/livereload.js?snipver=1'></script><?php }, PHP_INT_MAX);" > "$LR" | |
echo "add_action('admin_footer', function(){ ?><script src='//localhost:35729/livereload.js?snipver=1'></script><?php }, PHP_INT_MAX);" >> "$LR" | |
echo "LiveReload enabled. Disable with $0 disable" | |
exit 0; | |
fi | |
######### | |
## Command: php - run a php command | |
## | |
if [ "php" = "${OP}" ]; then | |
sh="$(__local_get_data $SITE path | __local_replace_secondary_location )"/temp-wp-shell.sh | |
__local_shell_generate $SITE "-c 'php ${CLOPS}'" > "$sh" | |
chmod 755 "$sh" | |
exec "$sh" && rm "$sh" && exit 0; | |
fi | |
######### | |
## Command: ssh - open the site shell | |
## | |
if [ "ssh" = "${OP}" ]; then | |
sh="$(__local_get_data $SITE path | __local_replace_secondary_location )"/shell.sh | |
__local_shell_generate $SITE > "$sh" | |
chmod 755 "$sh" | |
prf="$(__local_get_data $SITE path | __local_replace_secondary_location )"/shell-for-$SITE.terminal | |
__local_terminal_profile_generate "$sh" > "$prf" | |
open -a Terminal "$prf" && exit 0; | |
fi | |
######### | |
## Command: info - Show info on the site | |
## | |
if [ "info" = "${OP}" ]; then | |
echo "SiteID: " $SITE | |
ITEM=$(__local_find_root) | |
echo "Site root from current path: " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_get_webroot $SITE) | |
echo "Web root for this site (by disk): " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_find_idea $SITE) | |
echo ".IDEA folder location (by disk): " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_get_apache_site_conf_path $SITE) | |
echo "Apache config path: " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_get_apache_site_conf_template_path $SITE) | |
echo "Apache config template path: " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(grep DocumentRoot "$(__local_get_apache_site_conf_path $SITE)" | head -n1 | awk -F'"' '{print $2}' ) | |
echo "Web root for this ste (Apache): " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_get_php_conf_path $SITE) | |
echo "PHP config path: " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(__local_get_php_conf_template_path $SITE) | |
echo "PHP config template path: " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
ITEM=$(grep openssl.cafile "$(__local_get_php_conf_path $SITE)" | head -n1 | awk -F'"' '{print $2}' ) | |
echo "WordPress SSL CA Cert path (PHP): " $( [ -e "$ITEM" ] && echo √ || echo x ) $ITEM | |
fi | |
#if [ "move-to-primary" = "${OP}"]; then | |
# quit Local | |
# find current project root | |
# move data | |
# rename in json file | |
# restart Local | |
#fi | |
#if [ "move-to-secondary" = "${OP}"]; then | |
# quit Local | |
# find current project root | |
# move data | |
# rename in json file | |
# restart Local | |
#fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment