vulp
Терминальный инструмент для управления многими репозиториями сразу. Из одного места показывает состояние всего workspace, делает batch-sync, ведет PR, issue и статистику вкладов. Имеет TUI-поверхность для людей и беспромптовый JSON CLI для скриптов и автоматизации.
vulp - это единый интерфейс ко всей мастерской репозиториев: десятки репозиториев, одно и то же состояние и одни и те же операции пакетно. Внизу лежит единое ядро, а сверху два входа - CLI без промптов с выводом JSON для скриптов и полноэкранный TUI для человека. Guardrails следят за тем, чтобы вы не запушили что-то не туда, а обнаружение расхождений сравнивает каждый репозиторий с его зеркалом на сервере.
Введение
vulp вырос из нашей собственной мастерской, а не из идеи продукта. Мы ведём десятки репозиториев одновременно - бренды, панели, боты, инструменты - и в какой-то момент одно только удержание в голове того, какой репозиторий ждёт коммита, а какой пуша, стало стоить дороже самой работы. Обычный git прекрасен для одного репозитория и совершенно беспомощен против тридцати сразу.
Поэтому мы построили инструмент, который относится ко всему рабочему пространству как к единому целому: он сканирует каждый репозиторий за один проход, сводит их состояние в одну таблицу и позволяет выполнить одну и ту же операцию сразу над многими. Одно жёсткое условие мы поставили с самого начала - тот же инструмент должен служить и человеку за клавиатурой, и скрипту в CI, без двух отдельных кодовых баз для сопровождения.
Тридцать репозиториев, один цикл кликов
Когда вы ведёте один репозиторий, обычного git вполне достаточно. При тридцати начинается ритуал: зайти в каталог, проверить ветку, посмотреть, чист ли рабочий каталог, проверить, опережаете ли вы удалённый, назад, следующий. Пока охватите состояние всего, проходит четверть часа, и всё равно легко упустить тот единственный репозиторий, в котором лежат незапушенные изменения двухдневной давности.
Хуже всего то, что эти затраты растут линейно с числом репозиториев, а человеческое внимание - нет. Чем больше каталогов обходить, тем выше шанс, что один пропустите - и обычно именно тот, в котором что-то висит. Цикл в shell по каталогам немного помогает, но каждый такой цикл - это ещё один скрипт, который надо написать и сопровождать, переписываемый заново каждый раз, когда нужна другая операция.
vulp собирает это состояние в одно место и позволяет сделать одно и то же над многими репозиториями одной командой. Вместо тридцати вызовов git status вы получаете одну таблицу, а вместо цикла по каталогам - одну команду с ясной областью действия.
один проход по каждому репозиторию собирает ветку, чистоту рабочего каталога и на сколько коммитов вы опережаете удалённый или отстаёте от него.
состояние всего попадает в одну таблицу, отсортированную так, что требующее внимания оказывается наверху.
коммит и пуш проходят по выбранным репозиториям одной командой, а не каталог за каталогом.
после операции vulp сравнивает локальное состояние с зеркалом на сервере и показывает расхождение деплоя.
Одно ядро, два входа
Самое важное архитектурное решение было принято в самом начале: вся логика живёт в ядре, а CLI и TUI - лишь две оболочки над одним и тем же. CLI без промптов и возвращает JSON, поэтому встраивается в скрипты и CI без разбора текста, написанного для людей. TUI даёт то же знание человеку, который предпочитает смотреть на таблицу, а не помнить флаги.
Благодаря этому новая операция появляется сразу в обоих местах. Вы пишете её один раз, в ядре, и скрипт в cron, и человек по нажатию клавиши получают ровно одно и то же поведение - с теми же предохранителями. Исчезает целый класс расхождений в духе "из-под руки работает иначе, чем из пайплайна".
Guardrails, которые предпочитают отказать
Флаг, требующий чистого рабочего каталога, - не каприз. Без него пакетный пуш может отправить половину недоделанной работы вместе с готовой - и на тридцати репозиториях сразу, так что ошибку не откатить одним движением. Guardrails в vulp по умолчанию консервативны: нам лучше, чтобы инструмент отказал и потребовал явности, чем чтобы он молча сделал что-то необратимое.
Тот же принцип действует при массовых операциях. Пуш в защищённую ветку, пуш в репозиторий, опережающий локальное состояние, коммит с грязным рабочим каталогом там, где его быть не должно - всё это вещи, на которых инструмент должен остановиться и спросить, а не угадывать намерение. Автоматизация без тормозов быстрее ровно до первой ошибки.
Пакетная операция над десятками репозиториев так же быстра в добре, как и во зле. Один плохой пуш умножается на число репозиториев, поэтому guardrails здесь - не чрезмерная осторожность, а условие, при котором мы вообще допускаем пакетные операции. По умолчанию блокировать, для исключения требовать явный флаг.
Расхождение с зеркалом на сервере
Сам пуш - ещё не конец истории; важно то, что реально стоит на сервере. Мы держим там зеркало репозиториев, и после операции vulp сравнивает локальное состояние с этим зеркалом и показывает, где код в репозитории разошёлся с тем, что на самом деле развёрнуто. Это ловит классическую ловушку: изменение закоммичено и запушено, но никогда не развёрнуто, поэтому живёт только в git.
К этому добавляется ежедневная работа вокруг репозиториев, которая тоже идёт через тот же инструмент: просмотр PR, issue и статистики вклада. Вместо того чтобы открывать браузер для каждого репозитория по отдельности, вы видите всё сводно, там же, где и так смотрите на состояние рабочего пространства.
Вручную против vulp
| Действие | Вручную, репозиторий за репозиторием | Через vulp |
|---|---|---|
| Проверка состояния | тридцать заходов и git status | один проход, одна таблица |
| Пуш готового | цикл по каталогам | одна команда с областью действия |
| Защита от плохого пуша | память и внимание | guardrails в ядре |
| Расхождение деплоя | узнаёте, когда что-то падает | сравнение с зеркалом после операции |
Что от этого остаётся
Эффект скучен в лучшем смысле слова: проверка состояния рабочего пространства и пуш готового перестали быть утренним ритуалом кликов. Осталась одна команда, которую можно запустить из-под руки или запланировать и забыть - с теми же предохранителями в обоих случаях.
Более глубокий выигрыш в том, что инструмент масштабируется вместе с числом репозиториев, а не против него. Двадцатый репозиторий не добавляет ритуала, потому что вся мастерская всё равно обходится за один проход. Новая операция - это правка в ядре, которую получают и CLI, и TUI, и скрипт CI - одним коммитом, без расхождения версий.
Но самое важное - vulp не отдельный гаджет рядом с нашей работой, а тот же слой, через который проходят и рука, и автомат. Человек кликает, cron срабатывает, и они делают ровно одно и то же, столь же безопасно. В этом и разница между скриптом, который работает у автора, и инструментом, на который можно полагаться каждый день.
Больше проектов
Другие работы из той же категории - посмотрите, как мы решаем похожие задачи.
Есть похожий проект?
Напишите нам - смета бесплатна и приходит в течение часа.



