vulp

Terminalowe narzędzie do zarządzania wieloma repozytoriami naraz. Z jednego miejsca pokazuje stan całego workspace'u, robi batch-sync, prowadzi PR-y, issues i statystyki kontrybucji. Ma powierzchnię TUI dla ludzi i bezpromptowe CLI z JSON dla skryptów i automatyzacji.

vulp
TL;DR

vulp to jeden interfejs do całego warsztatu repozytoriów: kilkadziesiąt repo, ten sam stan i te same operacje wsadowo. Pod spodem siedzi jeden rdzeń, a na wierzchu dwa wejścia - bezpromptowe CLI z wyjściem JSON dla skryptów i pełnoekranowe TUI dla człowieka. Guardrale pilnują, żebyś nie wypchnął czegoś nie tam, a wykrywanie rozjazdu porównuje każde repo z jego lustrem na serwerze.

Wprowadzenie

vulp wyrósł z naszego własnego warsztatu, a nie z pomysłu na produkt. Prowadzimy kilkadziesiąt repozytoriów naraz - marki, panele, boty, narzędzia - i w pewnym momencie samo trzymanie w głowie, co gdzie czeka na commit, a co na push, zaczęło kosztować więcej niż sama robota. Standardowy git jest świetny do jednego repo i kompletnie bezradny wobec trzydziestu naraz.

Zbudowaliśmy więc narzędzie, które traktuje cały workspace jak jedną całość: skanuje wszystkie repo jednym przebiegiem, składa ich stan w jedną tabelę i pozwala zrobić tę samą operację na wielu naraz. Jeden twardy warunek postawiliśmy od początku - to samo narzędzie ma służyć i człowiekowi przy klawiaturze, i skryptowi w CI, bez dwóch osobnych kodów do utrzymania.

Trzydzieści repo, jedna pętla klikania

Kiedy prowadzisz jedno repo, sam git wystarcza w zupełności. Przy trzydziestu zaczyna się rytuał: wejdź do katalogu, sprawdź branch, zobacz czy drzewo czyste, sprawdź czy jesteś przed remote, wróć, następny. Zanim ogarniesz stan całości, mija kwadrans, a i tak łatwo przeoczyć to jedno repo, w którym siedzą niewypchnięte zmiany sprzed dwóch dni.

Najgorsze jest to, że ten koszt rośnie liniowo z liczbą repo, a uwaga człowieka nie. Im więcej katalogów do obejścia, tym większa szansa, że któryś zostanie pominięty - i to zwykle akurat ten, w którym coś wisi. Pętla po katalogach w bashu trochę pomaga, ale każda taka pętla to kolejny skrypt do napisania i utrzymania, pisany na nowo za każdym razem, gdy potrzebna jest inna operacja.

vulp zbiera ten stan w jedno miejsce i pozwala zrobić tę samą rzecz na wielu repo jednym poleceniem. Zamiast trzydziestu wywołań git status dostajesz jedną tabelę, a zamiast pętli po katalogach - jedną komendę z jasnym zakresem.

1
Skan workspace'u

jeden przebieg po wszystkich repo zbiera branch, czystość drzewa i ile commitów jesteś przed lub za remote.

2
Widok zbiorczy

stan całości ląduje w jednej tabeli, posortowany tak, że to, co wymaga uwagi, jest na górze.

3
Operacja wsadowa

commit i push lecą przez wybrane repo jednym poleceniem, nie katalog po katalogu.

4
Weryfikacja

po operacji vulp porównuje stan lokalny z lustrem na serwerze i pokazuje rozjazd deployu.

Jeden rdzeń, dwa wejścia

Najważniejsza decyzja architektoniczna zapadła na samym początku: cała logika żyje w rdzeniu, a CLI i TUI to tylko dwie skórki na to samo. CLI jest bezpromptowe i zwraca JSON, więc wpina się w skrypty i CI bez parsowania tekstu pisanego dla ludzi. TUI daje tę samą wiedzę człowiekowi, który woli patrzeć na tabelę niż pamiętać flagi.

Dzięki temu nowa operacja pojawia się od razu w obu miejscach. Dopisujesz ją raz, w rdzeniu, a i skrypt w cronie, i człowiek klawiszem dostają dokładnie to samo zachowanie - z tymi samymi zabezpieczeniami. Znika cała klasa rozjazdów w stylu "z ręki działa inaczej niż z pipeline'u".

sync-all.sh · bash
vulp status --json > state.json

vulp sync --push --only-ahead --require-clean

Guardrale, które wolą odmówić

Flaga wymagająca czystego drzewa to nie kaprys. Bez niej batch-push potrafi wypchnąć połowę niedokończonej roboty razem z tą gotową - i to na trzydziestu repo naraz, więc błędu nie cofniesz jednym ruchem. Guardrale w vulp są domyślnie zachowawcze: wolimy, żeby narzędzie odmówiło i kazało dopowiedzieć, niż żeby po cichu zrobiło coś nieodwracalnego.

Ta sama zasada działa przy operacjach masowych. Push na branch chroniony, wypchnięcie do repo, które wyprzedza lokalny stan, commit z brudnym drzewem tam, gdzie nie powinno go być - to wszystko są rzeczy, na których narzędzie ma się zatrzymać i zapytać, a nie zgadywać intencje. Automatyzacja bez hamulców jest szybsza dokładnie do pierwszej pomyłki.

!
Ostrzeżenie

Batch-operacja na dziesiątkach repo jest tak samo szybka w robieniu dobra, jak i zła. Jeden zły push mnoży się przez liczbę repo, więc guardrale nie są tu ostrożnością na wyrost - są warunkiem, na jakim w ogóle dopuszczamy operacje wsadowe. Domyślnie blokuj, wymagaj jawnej flagi na odstępstwo.

Rozjazd z lustrem na serwerze

Sam push to nie koniec historii - liczy się to, co realnie stoi na serwerze. Trzymamy tam lustro repozytoriów, a vulp po operacji porównuje stan lokalny z tym lustrem i pokazuje, gdzie kod w repo rozjechał się z tym, co faktycznie wdrożone. To wychwytuje klasyczną pułapkę: zmiana zacommitowana i wypchnięta, ale nigdy nie wdrożona, więc żyje tylko w gicie.

Do tego dochodzi codzienna robota wokół repo, która też idzie przez to samo narzędzie: przegląd PR-ów, issues i statystyk kontrybucji. Zamiast otwierać przeglądarkę do każdego repo z osobna, widzisz to zbiorczo, tam gdzie i tak już patrzysz na stan workspace'u.

Ręcznie kontra vulp

CzynnośćRęcznie, repo po repoPrzez vulp
Sprawdzenie stanutrzydzieści wejść i git statusjeden przebieg, jedna tabela
Push tego, co gotowepętla po katalogachjedno polecenie z zakresem
Ochrona przed złym pushempamięć i uwagaguardrale w rdzeniu
Rozjazd deployuwykrywasz, gdy coś padnieporównanie z lustrem po operacji

Co z tego zostaje

Efekt jest nudny w najlepszym sensie tego słowa: sprawdzenie stanu workspace'u i wypchnięcie tego, co gotowe, przestało być porannym rytuałem klikania. Zostało jedno polecenie, które można odpalić z ręki albo zaplanować i zapomnieć - z tymi samymi zabezpieczeniami w obu przypadkach.

Głębszy zysk jest w tym, że narzędzie skaluje się razem z liczbą repo, a nie przeciwko niej. Dwudzieste repo nie dokłada rytuału, bo cały warsztat i tak jest obchodzony jednym przebiegiem. Nowa operacja to poprawka w rdzeniu, którą dostaje i CLI, i TUI, i skrypt w CI - jednym commitem, bez rozjazdu wersji.

30+
repozytoriów pod jedną komendą
1
rdzeń, dwa wejścia zamiast dwóch kodów
0
promptów w trybie CI

Najważniejsze jest jednak to, że vulp nie jest osobnym gadżetem obok naszej pracy - jest tą samą warstwą, przez którą idzie i ręka, i automat. Człowiek klika, cron odpala, a robią dokładnie to samo, tak samo bezpiecznie. To jest różnica między skryptem, który działa u autora, a narzędziem, na którym da się polegać codziennie.

Więcej projektów

Inne realizacje z tej samej kategorii - zobacz, jak podchodzimy do podobnych wyzwań.

Masz podobny projekt?

Napisz do nas - wycena jest bezpłatna i wraca w godzinę.