just — минималистичный запускатор команд, который часто называют «Makefile без магии». Он читает файл justfile, находит рецепт по имени и выполняет его команды. В отличие от make, just не сравнивает даты файлов и не строит файловый граф: это осознанно не система сборки, а удобный способ хранить повторяющиеся команды проекта. Ниже — установка, синтаксис, параметры, модули, работа с .env и типичные ошибки.
Зачем нужен just, если есть make
Make хорош для компиляции C, где важны временные метки. Для задач вроде «прогнать тесты», «собрать Docker-образ» или «запустить линтер» его модель только мешает: приходится объявлять .PHONY, следить за табами и помнить о странностях переменных. just выполняет рецепт всегда, если явно не указано иное, и делает это предсказуемо. Рецепты не зависят от файлов, ошибки разбираются до запуска, а список задач выводится командой just —list.
Ещё преимущества: именованные аргументы со значениями по умолчанию, загрузка .env, собственный shell для рецепта, рецепты-скрипты на Python или bash, модули и импорт общих файлов. just отлично работает в CI и на Windows, если установлен подходящий shell. Но если нужна инкрементальная сборка по зависимостям, оставляйте её make, CMake или cargo.
Установка
Пакет есть в Debian, Ubuntu, Fedora, Arch и Homebrew. Если в репозитории версия старая, поставьте бинарник с GitHub Releases или соберите через cargo. Для команд ниже достаточно любого способа; проверьте версию, потому что синтаксис атрибутов и модулей развивался постепенно.
sudo apt install just
sudo dnf install just
cargo install just
just --version
В Arch и openSUSE пакет тоже называется just. Для проекта полезно зафиксировать минимальную версию через set minimum-version, чтобы у коллег не ломался парсинг justfile. Это особенно важно, если вы используете модули, атрибуты [parallel] или новые функции работы с аргументами.
Первый justfile
Файл называется justfile или Justfile и лежит в корне проекта. Рецепт — имя, двоеточие и команды с отступом. Строка, начинающаяся с #, становится описанием в списке задач. Символ @ перед командой отключает её эхо, а команда без @ печатается перед выполнением.
set shell := ["bash", "-uc"]
# Собрать проект
build:
cargo build --release
# Тесты после сборки
test: build
cargo test
# Форматирование
fmt:
cargo fmt --all
Запуск: just build, just test, just fmt. Если вызвать just без аргументов, выполнится первый рецепт в файле. Зависимость test: build означает, что build отработает до тестов. Это не проверка свежести, а именно порядок: build выполнится каждый раз. Для параллельного запуска зависимостей используется атрибут [parallel].
Переменные, аргументы и рецепты-скрипты
Переменные объявляются через := и подставляются в двойных фигурных скобках. Аргументы задаются после имени рецепта; значение по умолчанию отделяется знаком равенства. Вариативный аргумент с плюсом принимает одно или несколько значений, с звёздочкой — ноль или несколько.
version := "0.9.0"
env := "staging"
deploy target=env:
@echo "deploy {{version}} -> {{target}}"
backup +dirs:
tar -czf backup-{{version}}.tar.gz {{dirs}}
Вызовы: just deploy production и just backup src docs. Если команда должна выполняться в другом каталоге, используйте атрибут [working-directory: ‘path’] или [no-cd]. Для сложной логики удобен shebang-рецепт: тело превращается в отдельный скрипт, а не в набор строк shell. В нём работает set -euo pipefail, и ошибка на любом шаге останавливает выполнение.
[confirm]
migrate:
#!/usr/bin/env bash
set -euo pipefail
./manage.py migrate
./manage.py check
[confirm] попросит подтверждение перед запуском — полезно для опасных операций. [private] скрывает служебный рецепт из —list, [group(‘db’)] группирует задачи в выводе, [linux] включает рецепт только на Linux. Атрибуты можно комбинировать в одной строке через запятую.
.env, секреты и модули
just умеет читать .env автоматически, если включить set dotenv-load. Это удобно для локальных параметров вроде DATABASE_URL, но .env нельзя коммитить. Секреты лучше передавать через переменные окружения из менеджера секретов, а в justfile держать только имена.
set dotenv-load
set dotenv-required
db:
@psql "$DATABASE_URL" -c 'select 1'
[private]
_check-env:
test -n "$DATABASE_URL"
Не забывайте, что just по умолчанию печатает команды перед выполнением. Если в команде есть токен, он попадёт в терминал и логи CI. Ставьте @ перед такой командой, не используйте echo с секретом и проверяйте, что .env исключён через .gitignore. Права на файл должны быть 600.
Большой проект удобно делить на модули. Строка mod infra подключает infra.just или infra/mod.just; вызывать задачи можно как just infra deploy или just infra::deploy. Команда import ‘scripts/common.just’ подключает общие рецепты в текущий файл. Так корневой justfile остаётся коротким меню, а детали лежат рядом с кодом.
Ежедневные команды и CI
Полезные флаги стоит запомнить. —list показывает рецепты с описаниями, —show build печатает тело рецепта, —dry-run выполняет разбор и показывает команды без запуска, —evaluate выводит значения переменных, —summary перечисляет имена. Для выбора рецепта есть just —choose, но нужен fzf. —fmt приводит файл к единому стилю, а —fmt —check проверяет его в CI.
just --list
just --show build
just --dry-run deploy production
just --fmt --check
В конвейере достаточно двух шагов: проверить форматирование justfile и запустить основной рецепт. Не вызывайте интерактивные рецепты с [confirm] в автоматическом режиме. Если just установлен через cargo в CI, кэшируйте ~/.cargo/bin и target, иначе установка будет занимать больше времени, чем сама проверка.
Типичные ошибки
- Отступы табами и пробелами в одном рецепте: just требует единообразия, иначе выдаёт ошибку парсинга.
- Рецепт с тем же именем объявлен дважды: по умолчанию это ошибка, а не переопределение.
- Зависимость указана после двоеточия, но рецепта нет: just сообщит об этом до выполнения.
- Секрет попал в команду без @ и оказался в логах.
- Сложная логика свалена в одну строку вместо shebang-рецепта.
Проверяйте файл через just —fmt —check и just —list в чистом окружении. Если рецепт работает у вас, но не у коллеги, сравните версии just и оболочку: set shell с bash -uc требует bash, которого может не быть в минимальном контейнере.
Итог
just закрывает нишу между длинными shell-скриптами и тяжёлыми системами сборки. Он даёт читаемый список задач, аргументы, зависимости, .env и модули, оставаясь маленьким и предсказуемым. Начните с одного justfile на пять рецептов, затем вынесите инфраструктуру в модуль. Для настоящей сборки по временным меткам оставьте make или cargo, а just пусть отвечает за удобный вход в проект.