Narazil jsem před časem na diskusi o výhodách a nevýhodách monorepa. Přiznám se, že nesleduji všechny trendy, nestíhám to. Takže je docela dobře možné, že píšu článek o něčem, co už mají ostatní lidé dávno vyřešené. No, ale to téma mě zaujalo, tak jsem zapátral a načetl samozřejmě pár článků.

Pokud nevíte, o čem je řeč, tak řeč je o Git repozitářích. Diskuse se vede o tom, zda je lepší mít všechna repa v jednom, tedy monorepo, nebo zda je lepší je dělit, tedy mít k projektu více repozitářů aka multirepo. V diskusi má každá strana tradičně své zastánce i odpůrce až hejtry.

Monorepo prý razí i takový gigant, jako je Google. Tedy údajně. Kdo ví. Nicméně mi chvíli trvalo, než jsem tu myšlenku vstřebal. Posledních deset let jsem jel na vlně rozbíjení monolitů, byť většinou jen názorově, protože k mé smůle jsem s řadou monolitů musel prostě dělat. Cokoliv, co začíná slovem mono- mi evokuje archaický názorový směr. A to včetně monogamie. Takže adoptovat myšlenku repozitáře, ve kterém je všechno, mi chvilku trvalo.

Jistě. Má to své výhody. Přijde nový zaměstnanec, pošlete mu link na repo, on si ho naklonuje, provede build a může začít programovat. Na druhou stranu jsem zažil firmy, které měly takovéhle monorepo, ve kterém měly doslova všechno - backend, frontend, desktopového klienta, vývojovou databázi i aplikační servery. Každý build strašně trval a IDE s tím vedlo nesmírnou indexační bitvu a vůbec to nebyla zábava.

Plánoval jsem kratší úvod, tak zbytek toho, co jsem chtěl říci, přeskočím a půjdu rovnou na věc.

Při tom pročítání článků jsem narazil i na jeden, který mě nakonec vlastně i inspiroval k sepsání tohohle článku - Mono-repo or multi-repo? Why choose one, when you can have both?

Až ho budete číst, jistě si všimnete, že jsem si část úvodu vypůjčil, tak sorry. Snad z toho nebudou problémy.

Potenciální výhody monorepa jakožto centralizovaného systému tedy tkví v tom, že tam je vše v jednom a má to asi i nižší nároky na správu. Možná ještě něco, co někdo jiný považuje za výhodu a já ne.

Naproti tomu, výhody multirepa z mého pohledu pohledu převažují. Je to distribuovaný systém, jednotlivé moduly lze snadno vyměnit. Ale zase je tam o něco větší administrativní zátěž. Jednotlivé repozitáře musíte vést v patrnosti, změny promítat do dokumentace apod.

Tak jsem vyzkoušel metarepo. Zlatou střední cestu.

Jedná se o utilitku s názvem meta, která v podstatě tvoří git wrapper. Každý příkaz gitu můžete obalit příkazem meta, čímž pádem se daný příkaz vykoná nad všemi submoduly. A to je vlastně vše. Až tak jednoduché to je.

Meta se dá nainstalovat buď s pomocí npm nebo i chocolatey.

Metarepo pak vytvoříte jednoduše.

mkdir meta-project
cd meta-project
meta init
git init
git add -A
git commit -m "Init meta repo"
git remote add origin git@bitbucket.org:you/meta-project.git
git push -u origin master

Výsledkem je git repozitář se soubory .meta a .gitignore. První slouží k samotné konfiguraci meta-repa - drží informace o modulech, druhý pak ty moduly vyloučí z tohoto repozitáře.

Jednotlivé moduly, tedy jednotlivé repozitáře svého multirepo projektu pak přidáte takhle.

# meta project add module-name repository
# Při copy&paste nezapomenout přepsat jak cestu k repository, tak i název modulu!
# Snadno se to přehlédne.

meta project add module-a git@bitbucket.org:you/module-a.git
meta project add module-b git@bitbucket.org:you/module-b.git
meta project add module-c git@bitbucket.org:you/module-c.git
meta project add module-d git@bitbucket.org:you/module-d.git
meta project add module-e git@bitbucket.org:you/module-e.git

To vám:

  • vytvoří adresářovou strukturu s jednotlivými git moduly podle zadaných názvů
  • přidá ty moduly do .gitignore meta-repozitáře
  • vytvoří v souboru .meta konfiguraci meta-repozitáře
{
  "projects": {
    "module-a": "git@bitbucket.org:you/module-a.git",
    "module-b": "git@bitbucket.org:you/module-b.git",
    "module-c": "git@bitbucket.org:you/module-c.git",
    "module-d": "git@bitbucket.org:you/module-d.git",
    "module-e": "git@bitbucket.org:you/module-e.git"
  }
}

No a to je v základu vše. Komitnete a pushnete změny vašeho meta-repozitáře a pak, kdykoliv si někdo bude tohle meta-repo klonovat, tak to udělá přes meta:

meta git clone git@bitbucket.org:you/meta-project.git

Tím se mu postahují všechny moduly a má připravený projekt, který není monorepo, ale ani multirepo. Dají se nad tím dělat samozřejmě i jiné věci - třeba vytvářat hromadně větve, hromadně commitovat, mergovat apod. Každý příkaz gitu se uvede příkazem meta, ten vezme samotný příkaz gitu a v cyklu ho vykoná nad všemi svými moduly. To je celá magie.

Přiznávám, mnoho lidí to nenadchlo. Vlastně z lidí, kterým jsem to ukazoval, to nenadchlo nikoho. Ale mně se to líbí. Často pracuji na víc projektech najednou a rád po sobě uklízím, kdykoliv skončím a jdu na něco jiného. Tedy mažu. Tím ovšem smažu nejen lokální repa, ale i jejich konfigurace. Je to pro mně lepší než mít disk zahnojený starými a dávno neauktuálními projekty, na druhou stranu, když se pak třeba po roce potřebuji k něčemu vrátit, musím si ten projekt znovu nakonfigurovat. Spoustu věcí dělám v IDE - u mně IntelliJ IDEA - takže tam mám spoustu konfigurací, datových konektorů, nastavení inspections, copyrighty nebo třeba i úpravy slovníků.

S meta utilitkou je to všechno mnohem jednodušší. Kromě těch samotných modulů tam tedy mám i konfiguraci IntelliJ - adresář .idea - kromě workspace a lokální cache konektorů, ty dávám do .gitignore. Lokální cache netřeba sdílet a workspace se neustále aktualizuje. A kdo by se s tím chtěl pořád komitovat. Stejně jsou tam jen prkotiny jako naposledy otevřené taby, umístění a velikost panelů apod.

.idea/dataSources.local.xml
.idea/workspace.xml

Když se potřebuji k projektu po roce vrátit, jednoduše si naklonuji meta-repo se všemi moduly v aktuální verzi, konektory k databázím a nastavením IDE a můžu pokračovat. Když přijde nový kolega, pošlu mu link na meta utilitku a meta-repo a do deseti minut je schopen pracovat.

Tak jak? Líbí? Nelíbí? Komentáře tu nemám a ani mít nebudu, takže se váš názor nedozvím. Pokud vás to však zaujalo, tak samozřejmě jedině dobře.