Make makefiles
У меня две простые просьбы:
- пишите make-файлы;
- не приставайте к тем, кто их пишет.
Тогда все будет хорошо.
Теперь длинно. Когда мы садимся за проект, то запускаем в терминале команды. Сбилдить uberjar, образ докера, переколбасить какие-то файлы. Например:
docker build --no-cache -t super:image .
pip install -r requirements.txt
virtualenv -p /usr/bin/python3 venv
curl 'http://localhost:8083/connectors/' \
-X POST -d @/path/to/http-config.json \
-H 'Content-Type: application/json' \
| jq
Момент истины: тут же откройте заветный Makefile
и перенесите туда эту
команду. Назначьте ей понятный алиас и никогда больше — никогда — не вбивайте ее
вручную. Только через мейк. Вот так:
make docker-build
make venv-install
make connect-add-config
Зачем? Потому что через неделю вы забудете команду, а история баша потрётся. Коллеги тоже будут страдать и гуглить, хотя способ решение на поверхности – всего-то записать команду.
Скажем, я работаю над сложным образом докера, и после сборки надо проверить его
в баше. Раньше я бы методом проб и ошибок набрал команду, а затем тыкал
стрелочки вверх и вниз для поиска в истории. Сегодня я сразу сделаю Makefile
такого содержания:
PROJECT = registry.internal.exoscale.ch/exoscale/connect
TAG = 2.7.0
docker-build:
docker build --no-cache -t ${PROJECT}:${TAG} .
docker-bash:
docker run -it --rm ${PROJECT}:${TAG} /bin/bash
И отныне:
make docker-build docker-bash
Каждый раз, когда кто-то спрашивает, зачем мейкфайл, я сперва теряюсь. Первое,
что хочется ответить — да чтобы, так тебя и разтак, не набивать эту хрень руками
в следующий раз, когда что-то сломается. Не все сверхчеловеки, как
ты. Утнерменши вроде меня не помнят аргументы docker build
наизусть, вот в чем
дело.
Починил образ, теперь надо проверить его с локальной Кафкой. Это вообще прелесть. Вот что надо выполнить, чтобы привести систему в нужное состояние:
bin/zookeeper-server-start.sh config/zookeeper.properties
bin/kafka-server-start.sh config/server.properties
bin/kafka-topics.sh --create --topic=httptest \
--partitions=1 --replication-factor=1 \
--zookeeper=localhost:2181
curl 'http://localhost:8083/connectors/exo-http' -X DELETE | jq
curl 'http://localhost:8083/connectors/' -X POST \
-d @/path/to/config.docker.json \
-H 'Content-Type: application/json' \
| jq
curl 'http://localhost:8083/connectors/exo-http' -X GET | jq
bin/kafka-console-producer.sh \
--topic httptest \
--bootstrap-server localhost:9092
Хочется спросить — ребята, вы серьезно полагаете, что это полотно я наберу руками? Утверждаете, что сами тоже вбиваете? Не верю. Вы однажды набрали её (с грехом пополам и с Гуглом) и теперь просто ищете истории баша. Я тоже так делал, но баш не различает историю разных вкладок. Вбейте команду в одной вкладке, переключитесь во вторую, нажмите вверх — появится команда из первой вкладки. А во второй совсем другой проект и окружение.
Поражает, что каждый раз в ревью приходит тело и говорит — это твоя локальная мулька, проекту она не нужна. Неправда — проекту нужно всё, что экономит время, даже если речь только обо мне. Файл на десять строк никому не помешает, а мне сэкономит десять минут гуглежа.
Того человека я отмечаю. Либо и правда не понимает пользы, но тогда можно объяснить. Либо самодовольный идиот, и иметь дело с ним не стоит.
Мейкфайл — база знаний. Это набор действий, которые можно выполнить в проекте. В
нём работают комментарии, можно ставить ссылки на доки, задачи и артефакты. В
Zsh и других продвинутых шеллах работает автокомплит. Набрал make do<TAB>
—
вывалился автокомплит. Что еще нужно для счастья!
Мейкфайл — это записная книжка проекта. С той же целью люди ведут заметки, ежедневники и дневники: чтобы не забыть. Кто-то скажет: используй баш-скрипт. Но зачем, если уже есть механизм с метками и пакетными операциями?
Да, я в курсе, что Make создан для других целей. Это корявая система сборки сишных проектов, где основная единица — файл. Но дело в том, что ничего лучше не придумали. Точнее, придумали, но оно вынуждает читать доки и ставить софт, а мейк стоит на каждом утюге. Как реестр доступных команд он незаменим.
Поражаюсь проектам, где в корне лежат всякие package.json
, Dockerfile
,
requirements.txt
и прочая требуха без мейк-файла. Я что, должен гуглить
параметры каждый тулзы — npm
, docker
, pip
? Почему никто не создал Makefile
с командами:
python-deps:
pip --bla-bla
js-deps:
npm --bla-bla
docker-build:
docker --bla-bla
Это будет первое, чем я займусь в проекте, неважно, что там горит. Гигиена важнее пожара.
Пишите в мейкфайлы всё, что длиннее одного аргумента. Сами же обрадуетесь, когда откроете проект через год. Не насилуйте мозг тем, кто вносит в мейк новые команды, в том числе для личных нужд. Тот человек святой, а вы, весь такой хранитель проекта, поступаете отстойно.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter
Roman Tataurov, 2nd Feb 2021, link
А почему именно make? Зачем плодить зависимости если достаточно shell скрипта(ов). Это же в разы гибче.
Ivan Grishaev, 2nd Feb 2021, link , parent
Потому что в шапке Make удобно задать глобальные переменные и ссылаться на них во всех таргетах. Например, имя проекта и версия. Кроме того, цели можно группировать. Скажем, у меня есть операции foo, bar, baz, и в одном случае я хочу только первые два, а во втором все три. То, что make не такой гибкий, как шелл, что я лично рассматриваю как благо. Шелл-скрипт быстро становится лапшой.
Roman Tataurov, 2nd Feb 2021, link , parent
Ну к слову и в шелле ничто не мешает переменные определить да и в функции всё позаворачивать как угодно.
Ну с этим отчасти можно согласиться
Да лааадно, а огромных make файлов где чорт ногу сломит не бывает?
Ivan Grishaev, 2nd Feb 2021, link , parent
Шелл-скрипт это, как правило, отсебятина, а мейк задает структуру. К тому же неясно, как организовать вызов шелл-скриптов. Это набор разных файлов? Если это функции в одном файле, должна быть какая-то точка входа с параметрами. Будет ли с ней работать автокомплит zsh? Вопросов больше, чем ответов.