Last active
July 9, 2020 22:18
-
-
Save rmpel/ec500221be9f6e6969991cee1fac1e6a to your computer and use it in GitHub Desktop.
Local By Flywheel (unofficial) CLI for MacOS
This file contains hidden or 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 | |
PRIMARY_LOCATION=~/Development | |
SECONDARY_LOCATION=/Volumes/Macintosh\ HD/Development | |
BROWSER= | |
CLOPS= | |
VERBOSE=true | |
SHOWHELP=false | |
SCHEME=http: | |
SQLPRO="$(ls -1d {~,}/Applications/Sequel\ Pro*.app 2>/dev/null | grep Applications | sort | head -n 1)" | |
LCLAPP="$(ls -1d {~,}/Applications/Local\ by\ Flywheel*.app 2>/dev/null | grep Applications | sort | head -n 1)" | |
DOCMAC="${LCLAPP}"/Contents/Resources/extraResources/virtual-machine/vendor/docker/osx/docker-machine | |
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 | |
;; | |
*) | |
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 | |
CLOPS=${CLOPS## } | |
__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 | |
[ "true" = "$SHOWHELP" ] && OP= | |
if [ "${OP}" = "" ]; then | |
echo "Local By Flywheel 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") 'open Open the site in your default browser' | |
echo ' '$(basename "$0") 'mailhog Open the mailhog software for this site in your default browser' | |
echo ' '$(basename "$0") 'db Open Sequel Pro with the database of this site' | |
echo ' '$(basename "$0") 'ssh Open the docker shell of this site' | |
echo ' '$(basename "$0") 'ssh commandline Execute commandline in shell of this site' | |
echo ' '$(basename "$0") 'wp commandline Perform WP-CLI operation on site' | |
echo ' '$(basename "$0") 'wpdr Perform wp search-replace <current domain> <local domain>' | |
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 "" | |
echo It should come as no surprise you need to be inside the folder structure of your Local site. | |
exit; | |
fi | |
[ "wp" = "${OP}" ] && VERBOSE=false | |
FLWL=/Applications/Local\ by\ Flywheel.app | |
[ ! -d "$FLWL" ] && FLWL=~/Applications/Local\ by\ Flywheel.app | |
[ ! -d "$FLWL" ] && FLWL=$(mdfind Local\ by\ Flywheel.app | egrep '\.app$' | head -n 1) | |
[ ! -d "$FLWL" ] && echo "Sorry, looks like Local by Flywheel is not installed." && exit 1; | |
CWD=$(pwd -P); | |
STATUS=$("${DOCMAC}" status local-by-flywheel) | |
if [ "vm" = "${OP}" ]; then | |
case "$CLOPS" in | |
start|restart) | |
[ "Running" != "$STATUS" ] && "${DOCMAC}" start local-by-flywheel || "${DOCMAC}" restart local-by-flywheel | |
;; | |
stop) | |
[ "Running" = "$STATUS" ] && "${DOCMAC}" stop local-by-flywheel | |
;; | |
esac | |
exit; | |
fi | |
[ "Running" != "$STATUS" ] && echo "Local Machine not running, attempting to wake it up" && "${DOCMAC}" start local-by-flywheel | |
__local_find_root () { | |
local DIR=$CWD | |
[ "" != "$1" ] && DIR="$1" | |
_DIR=$(echo "$DIR" | awk -F'/app/' '{print $1}') | |
[ "" != "$_DIR" ] && [ "$DIR" != "$_DIR" ] && DIR="$_DIR" | |
while [ "$DIR" != "" ] && [ "$DIR" != '.' ] && [ "$DIR" != "/" ] && [ ! -d "${DIR}/app" ]; do | |
DIR="$( dirname "$DIR" )" | |
echo "DEBUG: $DIR"; | |
done; | |
echo "$DIR" | |
} | |
__local_get_ids() { | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/sites.json | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ print "$i "; }' | php | |
} | |
__local_get_id() { | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/sites.json | |
echo '<?php $home=getenv("HOME"); $db=json_decode(file_get_contents("'${DB}'"));foreach($db as $i => $a){ if (str_replace("~",$home,$a->path)=="'${1}'") { print $i; } }' | php | |
} | |
__local_get_id_by_name() { | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/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 | |
} | |
__local_verify_id() { | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/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 | |
} | |
__local_get_data() { | |
# $1 = ID, #2 = key | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/sites.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$a=$db->{"'${1}'"}; $result = $a->{"'${2}'"}; if (is_object($result)) {$result = $result->{"'${3}'"};} print $result;' | php | sed 's^~^'${HOME}'^g' | |
} | |
__local_fix_sites() { | |
# $1 = ID, #2 = key | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/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 | |
} | |
__local_fix_sites; | |
__local_get_docker() { | |
# $1 = key | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/dockerode-options.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$result=$db->{"'${1}'"}; print $result;' | php | sed 's^~^'${HOME}'^g' | |
} | |
__local_get_data_raw() { | |
# $1 = ID, #2 = key | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/sites.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$a=$db->{"'${1}'"}; print json_encode($a, JSON_PRETTY_PRINT);' | php | |
} | |
__local_site_status() { | |
# $1 = ID | |
DB=~/Library/Application\ Support/Local\ By\ Flywheel/site-statuses.json | |
echo '<?php $db=json_decode(file_get_contents("'${DB}'"));$a=$db->{"'${1}'"}; print $a;' | php | |
} | |
# $1: $SITE | |
__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); | |
prt=$(__local_get_data $1 ports MYSQL); | |
ip=$(__local_get_docker host); | |
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>database</key> | |
<string>'$db'</string> | |
<key>host</key> | |
<string>'$ip'</string> | |
<key>name</key> | |
<string>Local by Flywheel - '$site'</string> | |
<key>password</key> | |
<string>'$pwd'</string> | |
<key>port</key> | |
<integer>'$prt'</integer> | |
<key>rdbms_type</key> | |
<string>mysql</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>SPTCPIPConnection</string> | |
<key>useSSL</key> | |
<integer>0</integer> | |
<key>user</key> | |
<string>'$dbu'</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>version</key> | |
<integer>1</integer> | |
</dict> | |
</plist> | |
' | |
} | |
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 | |
} | |
__table__removeEmptyLines() { | |
local -r content="${1}" | |
echo -e "${content}" | sed '/^\s*$/d' | |
} | |
__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 | |
} | |
__table__isEmptyString() { | |
local -r string="${1}" | |
if [[ "$(__table__trimString "${string}")" = '' ]] | |
then | |
echo 'true' && return 0 | |
fi | |
echo 'false' && return 1 | |
} | |
__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; | |
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 | |
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 ] && SITE=$(__local_get_id "$PRESET_SITE"/public ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/app/public ] && SITE=$(__local_get_id "$PRESET_SITE"/app/public ) | |
[ "" = "$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 ] && SITE=$(__local_get_id "$PRESET_SITE"/public ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE"/app/public ] && SITE=$(__local_get_id "$PRESET_SITE"/app/public ) | |
[ "" = "$SITE" ] && [ -d "$PRESET_SITE" ] && SITE=$(__local_get_id "$(__local_find_root "$PRESET_SITE")" ) | |
fi | |
fi | |
[ "" = "$SITE" ] && SITE=$(__local_get_id "$(__local_find_root)" ) | |
#debugging | |
# __local_get_data $SITE name;exit; | |
NAME=$(__local_get_data $SITE name); | |
[ "" = "$SITE" ] && echo "Not a Local site" && exit 2; | |
[ "" = "$NAME" ] && echo "Not a Local site" && exit 2; | |
STATUS=$(__local_site_status $SITE); | |
if [ "true" = "${VERBOSE}" ]; then | |
echo "Root: "$(__local_get_data $SITE path); | |
echo "Name: $NAME"; | |
echo "SiteID: $SITE"; | |
echo "Status: $STATUS" | |
fi | |
[ "halted" = "$STATUS" ] && echo "Please enable site in Local by Flywheel" && exit 3; | |
[ "raw" = "${OP}" ] && __local_get_data_raw $SITE && exit 0; | |
[ "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; | |
[ "ngrok" = "${OP}" ] && echo "ngrok not yet available" && exit 4; | |
[ "mailhog" = "${OP}" ] && [ "" != "$BROWSER" ] && open -a "$BROWSER" http://$(__local_get_data $SITE domain):$(__local_get_data $SITE ports MAILCATCHER) && exit 0; | |
[ "mailhog" = "${OP}" ] && [ "" = "$BROWSER" ] && open http://$(__local_get_data $SITE domain):$(__local_get_data $SITE ports MAILCATCHER) && exit 0; | |
[ "db" = "${OP}" ] && spf="$(__local_get_data $SITE path)"/sequel-pro.spf && __local_db_spf_generate $SITE > "$spf" && open -a "$SQLPRO" "$spf" && exit 0; | |
CONTAINER=$(__local_get_data $SITE container); | |
if [ "wpdr" = "${OP}" ]; then | |
OP=ssh | |
N=${SCHEME}//$(__local_get_data $SITE domain) | |
CLOPS="cd app/public" | |
CLOPS=" $CLOPS; D=\$(WP_ENV=local-by-flywheel wp --allow-root option get siteurl | sed -E 's@https?://(www\.)?@@') ; echo Base domain: https?://\(www.\)?\$D ; echo Replace with $N" | |
CLOPS=" $CLOPS; WP_ENV=local-by-flywheel wp --allow-root search-replace http://www.\$D '$N'" | |
CLOPS=" $CLOPS; WP_ENV=local-by-flywheel wp --allow-root search-replace https://www.\$D '$N'" | |
CLOPS=" $CLOPS; WP_ENV=local-by-flywheel wp --allow-root search-replace http://\$D '$N'" | |
CLOPS=" $CLOPS; WP_ENV=local-by-flywheel wp --allow-root search-replace https://\$D '$N'" | |
fi | |
if [ "wp" = "${OP}" ]; then | |
OP=ssh | |
CLOPS="cd app/public; WP_ENV=local-by-flywheel wp --allow-root $CLOPS" | |
fi | |
if [ "ssh" = "${OP}" ]; then | |
export DOCKER_TLS_VERIFY="1" | |
export DOCKER_HOST="tcp://"$(__local_get_docker host)":"$(__local_get_docker port) | |
export DOCKER_CERT_PATH="$(dirname "$(__local_get_docker ca)")" | |
export DOCKER_MACHINE_NAME="$(basename "$(dirname "$(__local_get_docker ca)")")" | |
LINES=$(tput lines) | |
COLUMNS=$(tput cols) | |
echo -n -e "\033]0;Local: ${NAME}\007" | |
[ "" = "$CLOPS" ] && "${FLWL}/Contents/Resources/extraResources/virtual-machine/vendor/docker/osx/docker" exec -it -e LINES=$LINES -e COLUMNS=$COLUMNS $CONTAINER /bin/bash; | |
[ "" != "$CLOPS" ] && "${FLWL}/Contents/Resources/extraResources/virtual-machine/vendor/docker/osx/docker" exec -it -e LINES=$LINES -e COLUMNS=$COLUMNS $CONTAINER /bin/bash -c "$CLOPS"; | |
echo -n -e "\033]0;\007" | |
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