Автоматизация сборки проекта на WordPress. WP CLI + AppleScript + MAMP PRO.
Небольшое вступление.
Цель этого поста не изобрести велосипед, ведь вы можете сказать, что в MAMP PRO уже есть функция быстрого создания wp-сайта и будете правы. Цель этого поста - попытка открытия, вероятно, нового для вас мира Apple-скриптов, потому что информации по ним достаточно мало в сети, особенно на русском языке. А в конце повествования я оставлю еще небольшой бонус, в котором покажу как в один клик подготовить ваш мак к работе. Приступим!
Подготовительная работа.
Первое что нам надо сделать - это установить WP CLI, ведь именно его средствами мы будем делать сборку проекта. Для этого проще всего воспользоваться homebrew. Это очень удобный пакетный менеджер. Если он у вас не установлен, то обязательно установите, даже если вы не связаны глубоко с разработкой, уверен, вы оцените возможность установки, к примеру, какого-нибудь whatsapp или дискорда без перетаскивания ярлычков в папку программы… Установить можно так:
Далее пример применительно к нашей задаче, теперь всё, что надо сделать - открыть терминал и выполнить:
brew install wp-cli
Теперь можно проверить, что все установилось
wp --version
Установку и работу с MAMP PRO я не буду рассматривать, потому что это достаточно популярный инструмент и не хочется распыляться на второстепенные вещи.
Подготовка к сборке.
Тут надо понять, что вам надо от вашей сборки и тут потребности у всех разные. Но в этом то и прелесть решения, которое отличает его от всех стандартных - вы можете сделать как вам действительно удобно. Например, мне удобно создать базу, установить несколько любимых плагинов, мою кастомную тему со сборщиком laravel-mix, удалить все лишние темы, активировать стартовую страницу, где имеется набор основных UI-элементов, включить язык сайта - русский.
Часть вещей автоматизирована уже на уровне WP CLI, к примеру, язык сайта, бесплатные плагины… Но как же быть с установкой собственной кастомной темы? Понятно что вариантов множество, но у меня очень простой вариант - программно скопировать тему из файловой системы, где лежит git-репозиторий со всякими хэлперами, которых за годы накопилось достаточно.
Мы с вами разобрались с установкой, теперь давайте подумаем об удалении. Да, это тоже важно, и поверьте, вы поймете это после первой же ошибки, которая потребует ходить везде, где побывал скрипт и вычищать следы вашего проекта.
Apple-скрипты.
Сам по себе язык достаточно простой. Не зная его "от слова совсем", я смог за пару дней худо-бедно научиться выкидывать диалоги, запускать приложения, выполнять консольные команды и постепенно мой эксперимент оброс каким-то смыслом.
Итак, чтобы начать писать на AppleScript вам нужен только мак. Далее просто открываете Spotlight и начинаете писать "Редактор скриптов".
Не буду больше тянуть и приведу скрипт установки проекта
--PROPERTIES
property projectsUrl : "/Users/user_name/Desktop/repo/"
property dbName : "wp_test"
property projectName : "wp.test.loc"
property themePath : "/wp-content/themes/my_mega_theme/"
property themeNameInRepo : "my_mega_theme-lr-mix"
property themeName : "my_mega_theme"
property adminPass : "lUn8wdf4Gx"
property siteTitle : "Site_Name" --no sapaces, please
--VARIABLES
set appStatus to "OK"
--UTILS
on ProcessRunning(processName)
set AppleScript's text item delimiters to "\\|"
set theExpression to processName as string
set AppleScript's text item delimiters to ""
set isRunning to every paragraph of (do shell script "ps -acwx -o command | grep -ix " & quoted form of theExpression & " || echo 'false'")
if isRunning contains "false" then
return false
else
return true
end if
end ProcessRunning
--MAMP PRO running test
if application "MAMP PRO" is not running then
set theDialogText to "А MAMP запустить не забыл?"
display dialog theDialogText
--> Result: {button returned:"OK"}
set appStatus to "FAIL"
else
set apacheRunning to my ProcessRunning("httpd")
set mysqlRunning to my ProcessRunning("mysqld")
if (not apacheRunning and not mysqlRunning) then
set theDialogText to "По ходу MAMP работает, но не запущен сервер. Надо бы запустить"
display dialog theDialogText
--> Result: {button returned:"OK"}
set appStatus to "FAIL"
end if
end if
if appStatus is "OK" then
--TERMINAL'
if application "Terminal" is running then
tell application "Terminal"
quit
end tell
end if
delay 1
tell application "Terminal"
--INIT
activate
set mainID to id of front window
close (every window whose id ≠ mainID)
--CREATE DB
do script "/Applications/MAMP/Library/bin/mysql --host=localhost -uroot -proot;" in window 1
do script "CREATE DATABASE " & dbName & ";" in window 1
do script "QUIT;" in window 1
delay 1
--MAKE PROJECT FOLDER
do script "cd " & projectsUrl in window 1
do script "mkdir -p " & projectName in window 1
do script "cd " & projectName in window 1
--INSTALL WP
do script "wp core download" in window 1
do script "wp config create --dbname=" & dbName & " --dbuser='root' --dbpass='root' --dbhost='localhost' --dbprefix='wp_'" in window 1
do script "wp core install --url='http://" & projectName & ":8899' --title=" & siteTitle & " --admin_user='sb_admin' --admin_password=" & adminPass & " --admin_email='kykyky@bk.ru'" in window 1
do script "wp language core install ru_RU" in window 1
do script "wp site switch-language ru_RU" in window 1
--SET WP THEME
do script "cp -a " & projectsUrl & "_THEMES/" & themeNameInRepo & "/. " & projectsUrl & projectName & themePath in window 1
do script "cd " & projectsUrl & projectName in window 1
do script "wp theme activate " & themeName in window 1
do script "wp theme delete $(wp theme list --status=inactive --field=name)" in window 1
do script "wp plugin delete $(wp plugin list --status=inactive --field=name)" in window 1
--do script "killall Terminal" in window 1
--WAIT FOR COMPLETE
repeat
delay 1
if application "Terminal" is not running then
--SHOW WEB SITE
--tell application "Google Chrome"
-- activate
-- open location "http://" & projectName & ":8899"
--end tell
--DONE NOTIFICATION
display notification "Создал проект " & projectName with title "Я сделял, хозяин!" subtitle "Создание проекта прошло успешно"
quit
exit repeat
end if
end repeat
end tell
end if
Обратите внимание, что в скрипте имеются проверки на возможность выполнения, к примеру, если MAMP PRO не запущен или сервер остановлен, в этом случае мы увидим сообщения.
Если посмотрите внимательнее, то увидите и комментированные блоки, к примеру, блок, который открывает хром по завершению установки и делает переход по нужному урлу. Да, и так тоже можно, далее только все ограничивается вашими потребностями и желанием.
Обращаю ваше внимание, что я передаю вам скрипт 'as is', и если надо что-то поменять, вам придется вчитаться. К примеру, если надо будет также копировать тему, посмотрите внимательно, не все параметризировано, к примеру, в теле кода есть строка '_THEMES', которую вероятно вам надо убрать.
Теперь приложу обратный скрипт по чистке, он будет немного короче
--PROPERTIES
property projectsUrl : "/Users/user_name/Desktop/repo/"
property dbName : "wp_test"
property projectName : "wp.test.loc"
--VARIABLES
set appStatus to "OK"
--UTILS
on ProcessRunning(processName)
set AppleScript's text item delimiters to "\\|"
set theExpression to processName as string
set AppleScript's text item delimiters to ""
set isRunning to every paragraph of (do shell script "ps -acwx -o command | grep -ix " & quoted form of theExpression & " || echo 'false'")
if isRunning contains "false" then
return false
else
return true
end if
end ProcessRunning
--CONFIRM DELETING
set theDialogText to "Точно хочешь удалить проект " & projectName & "?"
display dialog theDialogText buttons {"Нет!", "Удалить"} default button "Удалить" cancel button "Нет!"
--> Result: {button returned:"Нет!"}
--MAMP PRO running test
if application "MAMP PRO" is not running then
set theDialogText to "А MAMP запустить не забыл?"
display dialog theDialogText
--> Result: {button returned:"OK"}
set appStatus to "FAIL"
else
set apacheRunning to my ProcessRunning("httpd")
set mysqlRunning to my ProcessRunning("mysqld")
if (not apacheRunning and not mysqlRunning) then
set theDialogText to "По ходу MAMP работает, но не запущен сервер. Надо бы запустить"
display dialog theDialogText
--> Result: {button returned:"OK"}
set appStatus to "FAIL"
end if
end if
if appStatus is "OK" then
--TERMINAL
if application "Terminal" is running then
tell application "Terminal"
quit
end tell
end if
delay 1
tell application "Terminal"
--INIT
activate
set mainID to id of front window
close (every window whose id ≠ mainID)
--REMOVE DB
do script "/Applications/MAMP/Library/bin/mysql --host=localhost -uroot -proot" in window 1
do script "DROP DATABASE " & dbName & ";" in window 1
do script "QUIT;" in window 1
--MAKE PROJECT FOLDER
do script "rm -rf " & projectsUrl & projectName in window 1
--do script "killall Terminal" in window 1
--WAIT FOR COMPLETE
repeat
delay 1
if application "Terminal" is not running then
--DONE NOTIFICATION
display notification "Удалил проект " & projectName with title "Я сделял, хозяин!" subtitle "Удаление проекта прошло успешно"
quit
exit repeat
end if
end repeat
end tell
end if
Возможные грабли.
Если в пути константы указан '/', то он там не с проста, сверяйте свой вариант с примером внимательно, не удаляйте важные части формирования пути.
Если возникает ошибка команды wp, то проверьте в терменале, что у вас установлен инструмент WP CLI (просто в терминале напишите wp, если получите ответ, что это неизвестная команда, значит и правда ее нет). Если инструмент не установлен, рекомендую установить через homebrew, как это сделать - читайте выше.
Скрипт закрывает терминал если он открыт, имейте это в виду. В определенных случаях прервать процесс может не получиться, а может вы этого и не желаете, поэтому лучше завершить все процессы и закрыть терминал перед использованием скрипта (прям жестко, через command+q)
Если в конфиге вы неверно укажете путь, то файлы запишутся в домашнюю папку вашего пользователя. (cd ~)
Если нет соединения с mysql проверьте пути к установке вашего MAMP и сравните с тем, что указано в Apple-скрипте. Также попробуйте изменить хост для подключения с localhost на 127.0.0.1 или наоборот. Также можно попробовать указать порт 3306 явно (стандартный порт mysql) или посмотреть какой у вас указан в MAMP (там порт можно менять, если что, так что будьте внимательны).
Сверьте версию PHP в консоли и WP CLI, они не должны конфликтовать. То есть если вы счастливый обладатель PHP8.1+ в вашей консоли, скорее всего у вас могут возникнуть проблемы. Проверьте какую версию PHP использует WP CLI с помощью
wp --info
Если ссылка на PHP не та, то добавьте в zsh - профиль вот это (и не забудьте его обновить через source имя_профиля)
К вопросу о том как одной кнопкой запустить все необходимое.
property runVSCode : true
property runChrome : true
property runMAMP : true
property runTelegram : true
property openProjectfolder : true
-- UTILS
on RunApp(appName)
if application appName is not running then
tell application appName
activate
end tell
end if
end RunApp
-- RUN APPLICATIONS
if runVSCode then
RunApp("Visual Studio Code")
end if
delay 1
if runChrome then
RunApp("Google Chrome")
end if
delay 1
if runMAMP then
RunApp("MAMP PRO")
end if
delay 1
if runTelegram then
RunApp("Telegram Desktop")
end if
-- OPEN FOLDERS
if application "Finder" is not running then
tell application "Finder"
activate
end tell
end if
delay 1
tell application "Finder"
open ("/Users/user_name/Desktop/repo/" as POSIX file)
end tell
Комментировать этот скрипт не буду, он совсем не сложный и может стать отправной точкой в ваших собственных скриптах.
Заключение
Еще раз хотелось бы отметить, что основная направленность статьи - это показать возможности AppleScript и, вероятно, кто-то из вас задумается о решении своей рутины именно таким способом. Если у вас получится, получилось или даже не получилось, напишите в комментариях и я буду спокоен, что эта тема оказалась интересной.