Урок 11. Makefile: финальный проект — сборка конфига из частей
Primary tabs
Финальный урок — большой проект, в котором встретится всё пройденное: цели-файлы, зависимости, переменные, параметры и цвета. Соберём конфиг приложения, который склеивается из двух частей: общей базы и «оверлея» окружения — dev для разработки, prod для «боя». Так устроены конфиги настоящих систем, и make для этого подходит идеально.
Шаг 1: исходные файлы
Создайте в папке урока три файла. Общая база — config/base.conf:
# базовые настройки (общие для всех окружений) app_name = my-app port = 8080 log_level = info
Оверлей разработки — config/dev.conf:
# оверлей окружения dev debug = true log_level = debug
И «боевой» оверлей — config/prod.conf:
# оверлей окружения prod debug = false log_level = error
Идея: оверлей приклеивается после базы, и его ключи перебивают базовые — в ini-подобных конфигах при повторе ключа действует последнее значение.
Шаг 2: шапка Makefile
Сначала всё знакомое: параметры с умолчаниями из урока про параметры, пути и цвета из урока про export:
APP_ENV ?= dev CONFIG_DIR = config OUT = out/app.conf export cyan = `tput setaf 6` export green = `tput setaf 2` export reset = `tput sgr0`
Шаг 3: .PHONY
В этом проекте будут и цели-файлы, и цели-команды. Чтобы make никогда не путал вторые с файлами (грабли из урока про цель-файл), перечислим команды в директиве .PHONY:
.PHONY: help build show rebuild clean
Шаг 4: правило сборки
Сердце проекта — правило «файл из файлов»:
$(OUT): $(CONFIG_DIR)/base.conf $(CONFIG_DIR)/$(APP_ENV).conf
@mkdir -p out
@cat $^ > $@
@echo "Собрано: ${green}$@${reset} (APP_ENV=$(APP_ENV))"
Новинка — $^: все исходники сразу, в порядке перечисления. Именно поэтому cat $^ клеит базу первой, а оверлей (имя которого зависит от $(APP_ENV)) — следом.
Шаг 5: цели-команды и справка
Вокруг правила — обвязка из привычных целей:
build: $(OUT) show: build @cat $(OUT) rebuild: clean build clean: @rm -f $(OUT) @echo "Удалён файл $(OUT)"
Обратите внимание на пустую цель build: у неё нет своего рецепта — это просто «обёртка», заставляющая собраться файл out/app.conf.
И справка с цветами — как в уроке про цель по умолчанию, но многострочная: обратный слэш в конце строки продолжает команду, а \n даёт перенос в выводе:
help:
@echo "${cyan}Сборка конфига${reset}, доступные команды: \
\n ${green}build${reset} - собрать конфиг (APP_ENV=prod) \
\n ${green}show${reset} - показать собранный конфиг \
\n ${green}rebuild${reset} - пересобрать с нуля \
\n ${green}clean${reset} - удалить собранное \
"
Прогон
make build Собрано: out/app.conf (APP_ENV=dev) make build make: Nothing to be done for 'build'. make show # базовые настройки (общие для всех окружений) app_name = my-app port = 8080 log_level = info # оверлей окружения dev debug = true log_level = debug
Второй make build ничего не собирает — отслеживание из урока про цель-файл в действии. В собранном конфиге log_level встречается дважды: базовое info перебито оверлейным debug. Теперь «боевая» сборка — тем же механизмом пересборки из урока про зависимости:
APP_ENV=prod make rebuild Удалён файл out/app.conf Собрано: out/app.conf (APP_ENV=prod)
Задание
- Добавьте оверлей
staging.conf(предрелизное окружение:debug = false, свойlog_level) и соберите конфиг для него. - Запустите
make build APP_ENV=test— файлаtest.confнет. Посмотрите, как make объясняет отсутствие исходника. - Сделайте
helpпервой целью файла — чтобыmakeбез аргументов сразу показывал справку.
Это был последний урок курса: теперь любой Makefile — включая те, что встречаются в рабочих проектах с docker и деплоем, — читается как набор знакомых приёмов. Загляните в список уроков, если хотите что-то повторить, а полный код финального проекта лежит в репозитории: lesson11-project.
- Log in to post comments
- 6 reads