Привет! Сегодня разберемся как не напрягаться и сохранить свое время избежав рутины.
Представим соревнование поваров - финал, очень сложное задание. Требуется приготовить 100 порций яичницы. Один повар знает где у него лежит каждый ингредиент, всё его рабочее пространство структурировано и везде царит порядок. Другой же повар - полная противоположность, у него хаос и разруха, сковородки лежат в разных местах, он каждый раз ищет подходящую тару и это постоянно отнимает у него ценные минуты.
Первый повар греет масло на сковороде нужного размера, а второй все ещё ищет яйца. Первый начинает разбивать яйца, а второй только сейчас понял, что ему нужна другая сковорода. Итог очевиден - первый победит. Также и у нас - мелкие вещи поглощают наше ценное время.
При работе часто требуется выполнять разные команды, например:
- запустить тесты
- удалить или создать базу данных
- накатить миграции
Что делает разработчик? Варианта у него три:
- копирует откуда-то команду и вставляет в консоль
- жмет в консоли стрелочку вверх до посинения, и надеется найти требуемую команду
- вводит команду вручную по памяти
Хитрый и ленивый разработчик заведет файлик с командами и будет заглядывать в него, а если команда выполняется часто - будет еще и жать стрелочку вверх в консоли. Умный разработчик заведет Makefile, данный файл сможет использовать вся команда.
Что такое makefile и утилита Make? #
По своей сути данный файл - это набор инструкций для утилиты Make. Makefile хранится в корне проекта и является сразу как документацией, так и исполняемыми командами.
Изначально утилита Make использовалась для сборки программ и библиотек из исходного кода, она стала поставляться по умолчанию в большинстве Linux дистрибутивов и поэтому стала такой популярной. В итоге люди начали использовать make не только для сборки программ, но и для автоматизации различных процессов. Поэтому теперь мы можем встретить makefile в большом количестве проектов.
Структура Makefile-а #
Сам make-файл состоит из целей, которые содержат в себе команды:
засунуть_жирафа_в_холодильник:
команда_открытия_холодильника
команда_засовывания_жирафа
команда_закрытия_холодильника
Команды будут выполняться в строгой последовательности: одна за другой. В случае если первая команда не выполнится - последующие не будут запущены. Важным замечанием является, что makefile чувствителен к табам, перед командой обязательно должен быть таб, а не четыре пробела (питонистам привет)!
Если нам понадобится засовывать в холодильник не только жирафа, но и других животных - мы можем не устоять перед желанием засунуть все команды в одну цель. В таком случае наш makefile будет представлять из себя одну бесполезную гору команд, которая не даст нам никаких плюсов. Чтобы этого избежать - мы можем накидать файл такого вида:
засунуть_всех_зверей: открытие_холодильника засовывание_жирафа засовывание_кукушки засовывание_дятла закрытие_холодильника
засунуть_птиц: открытие_холодильника засовывание_кукушки засовывание_дятла закрытие_холодильника
открытие_холодильника:
команда_открытия_холодильника
закрытие_холодильника:
команда_закрытия_холодильника
засовывание_жирафа:
команда_засовывания_жирафа
засовывание_кукушки:
команда_засовывания_кукушки
засовывание_дятла:
команда_засовывания_дятла
Таким образом мы можем комбинировать и запускать цели одну в другой. Наш файл теперь помогает другим разработчикам видеть список доступных целей. Если подходящая цель не найдена - можно добавить собственную!
Запуск целей #
Тут все просто, устанавливаем утилиту Make (как это сделать - легко гуглится), создаем файл с именем Makefile, заполняем его и в консоли выполняем команду **make** *имя_цели*
.
Подводные камни #
У make и makefile есть много подводных камней, но самый популярный - это ошибка: make: <имя-цели> is up to date.
Она может возникнуть в случае если имя цели совпадает с наименованием файла или каталога имеющегося в данной директории. Да, штука неприятная, но решается добавлением ключевого слова .PHONY
:
.PHONY: имя_цели1
имя_цели1:
команда
Переменные #
Makefile позволяет определять переменные - это очень удобный функционал. Рассмотрим реальный пример запуска миграций:
pg_host = ${PG_HOST}
pg_user_name = ${PG_USER_NAME}
pg_password = ${PG_PASSWORD}
pg_database = ${PG_DATABASE}
host_port = ${HOST_PORT}
postgres_url="postgres://$(pg_user_name):$(pg_password)@$(pg_host):5432/$(pg_database)?sslmode=disable"
dbmate_migrations_folder="./Migrations"
dbmate_schema_folder="./schema.sql"
dbmate_options= -d $(dbmate_migrations_folder) -s $(dbmate_schema_folder) -u $(postgres_url)
.PHONY: db_up
db_up:
dbmate $(dbmate_options) --no-dump-schema up
В самом начале у нас объявляется пачка переменных, которые хранят в себе данные для подключения к Postgres. Их значения берутся из переменных окружения - это позволяет каждому разработчику локально изменять конфигурацию и запускать цели индивидуально!
Также можно заметить, что переменная postgres_url использует в себе значения переменных, объявленных ранее, сама же postgres_url используется в команде db_up.
Применение #
Makefile может пригодиться в самых разных задачах:
- запуск тестов
- запуск линтеров
- запуск форматтеров
- работа с миграциями
- публикация
- работа с docker-ом
- работа с git-ом
- многое другое
А что еще? #
Я описал не все возможности и тонкости make-файла, за рамками статьи остались условные операторы, дополнительные функции и многое другое, но то, что мы сегодня рассмотрели может очень сильно облегчить жизнь! Подробнее про make можно почитать тут: GNU Make.
Итоги #
Думаю, что итог можно подвести нехитрыми вычислениями. Представим, что мы не пользуемся make-файлом и постоянно открываем файл с командами, ищем требуемую, копируем, вставляем, выполняем - все это занимает у нас ~30 секунд времени на команду (да, мы черепахи). В день мы выполняем 20 команд, 20 команд по 30 секунд = 600 секунд = 10 минут. 20 рабочих дней * 12 месяцев * 10 минут = 2400 минут = 40 часов! Сорок часов уходят на рутину. И это только для одного человека, а если над проектом работает большая команда?
Конечно, все это вычислено с ОЧЕНЬ большой натяжкой, но все же поиск и выполнение команд очень бесит и напрягает, с makefile-ом головной боли теперь будет меньше! Внедри его у себя и команда скажет: “Спасибо!”.
🙏🙏🙏
Поскольку ты зашел так далеко, я буду очень признателен, если ты поделишься этой статьей в своей любимой социальной сети 💖! Для обратной связи, пожалуйста, напиши в Telegram.
Опубликовано