Я пытаюсь написать makefile для упаковки некоторых PHP-скриптов. Мне также хотелось бы проверить наличие синтаксических ошибок (используя встроенный инструмент php lint) перед созданием окончательного zip-файла, чтобы предотвратить случайные ошибки.
До сих пор
all: dist clean: rm -f output.zip dist: clean for i in `find . -name "*.php"`; do php -l $$i; done zip -r output.zip src -x "*/.*" "*/tests*"
Это работает, но если есть ошибка PHP, я бы хотел ее сломать и не продолжить создание zip-файла (по понятным причинам). В настоящее время они могут просто потеряться на страницах вывода успешных прогонов пробега и zip-файла.
Правильно ли я это делаю? Должен ли я использовать цикл make, а не цикл оболочки? Как вам получить make, чтобы прервать ошибки командной оболочки?
Вы можете сделать что-то вроде этого:
for i in `find . -name "*.php"`; do \ php -l $$i; \ if [ $$? -ne 0 ] ; then exit 42 ; fi \ done
Оболочка for
цикла в вашем рецепте dist
скрывает статус выхода php -l
из make, поэтому он не знает, чтобы выйти. Ответ Мата показывает, как исправить это, если команда shell выйдет с ошибкой.
Контур оболочки можно было бы полностью исключить:
all: dist clean: rm -f output.zip LINT_TARGETS := $(addprefix lint-,$(shell find . -name "*.php")) .PHONY: $(LINT_TARGETS) $(LINT_TARGETS):lint-%:% php -l $< dist: clean $(LINT_TARGETS) zip -r output.zip src -x "*/.*" "*/tests*"
Теперь есть фальшивая цель со статическим шаблоном для запуска каждой из команд php -l
. Если какой-либо из них терпит неудачу, рецепт dist
не будет запущен. Это, возможно, труднее читать, чем цикл оболочки, но это означает, что: а) сообщение об ошибке, сделанное самим, будет касаться проблемного файла для вас, и б) с make -j
вы можете иметь многопоточные чеки: