Go modules: Správa závislostí

Thursday, Mar 4, 2021 by Lenka
Správa závislosti od výberu balíka, jeho stiahnutie a importovanie, až po spravovanie závislostí väčších projektov.

Ako sa starať o závislosti (Dependency management)

Keď kód používa externé balíky - balíky tretích strán, tieto balíky (distribuované ako moduly) sa stávajú závislosťami. Aby bol kód stále aktuálny, treba sa starať aj o tieto závislosti. Go poskytuje nástroje na správu závislostí, ktoré pomáhajú zaistiť bezpečnosť aplikácií pri začleňovaní externých závislostí.

Závislosti, ako moduly, obsahujú importované balíky. Vývojari po celom svete robia svoje moduly dostupné a zdieľajú ich pre ostatných vývojarov. Ide o tzv. decentralizovaný systém zdieľania. Teda nie je to presne organizované, ale predsa len nejaké pravidlá platia. Pozrime sa, ako postupovať pri práci so závislosťami.

Výber vhodného balíka

Pre vyhľadanie balíkov a ich dokumentácie je možné použiť nástroj pkg.go.dev, ktorý poskytuje centralizované informácie pre Go balíky a moduly zdieľané na index.golang.org a ďalšie užitočné rady. Dáta pre go.dev sú sťahované z proxy.golang.org. Ak by ste chceli pridať svoj balík na pkg.go.dev, treba si podať žiadosť, buď cez pkg.go.dev alebo cez vyššie spomínaný proxy protocol.

Každý modul obsahuje aj číslo verzie. Go sa riadi klasickými konvenciami pre verziovanie. Číslo verzie daného modulu signalizuje stabilitu a spätnú kompatibilitu. Každé číslo špecificky odráža o aké zmeny v module ide v porovnaní s prechádzajúcou verziou.

Číslo verzie sa skladá z nasledujúcich častí:

Prvé číslo určuje, či sa jedná o modul vo vývoji alebo o hlavnú verziu. Modul vo vývoji má tvar v0.x.x, ide o nestabilnú verziu a nezaručuje spätnú kompatibilitu. Modul v hlavnej (plnej) verzii má tvar v1.x.x a tiež nezaručuje spätnú kompatibilitu. Ide však o stabilný modul.

Vývojári modulu by mali byť opatrní a zvýšiť toto číslo z v1 iba v prípade potreby. Aktualizácia verzie predstavuje významné narušenie pre vývojárov, ktorých kód používa funkciu v inovovanom module. Toto narušenie zahŕňa spätne nekompatibilné zmeny, ako aj potrebu aktualizovať cestu k balíku všade, kde je tento balík importovaný. Hlavná aktualizácia verzie na číslo vyššie ako v1 bude mať aj novú cestu k modulu - v ceste k modulu bude pripojené hlavné číslo verzie.

module example.com/mymodule/v2 v2.0.0

Ďalšie čísla verzie sa už správajú tak, ako sme zvyknutí. Viac info tu.

Importovanie balíka

Balík sme si už vybrali, na jeho stiahnutie a importovanie máme viacero možností.

Môžeme si balíky správne importovať do kódu import "example.com/somemodule"a až neskôr všetky importy naraz stiahnuť pomocou go get .. Ak chceme stiahnuť špecifický balík použijeme:

go get example.com/somemodule

Tiež je možné získať špecifickú verziu modulu, napríklad keď chceme vyskúšať beta verziu projektu alebo nám nefunguje súčasná verzia a chceme použiť predchádzajúcu (downgrade). Verziu modulu pripíšeme do get príkazu za názov modulu spolu s znakom @. Pre najnovšiu verziu použijeme @latest. Môžeme tiež inštalovať vetvu - branch (@master) či commit pomocou hashu (@08c92af).

go get example.com/somemodule@1.2.3
go get example.com/somemodule@latest
go get example.com/somemodule@master
go get example.com/somemodule@08c92af

Ďalej môžeme skontrolovať, či existujú novšie verzie závislostí, ktoré už vo svojom projekte používame. Príkazom go list zobrazíme zoznam závislostí nášho modulu spolu s najnovšou dostupnou verziou. Po nájdení dostupných aktualizácií ich môžeme vyskúšať pomocou svojho kódu a rozhodnúť sa, či ich chceme použiť.

  • Zoznam všetkých modulov použitých v projekte spolu s najnovšou verziou dostupnou pre každý z nich:
    go list -m -u all
    
  • Zobraziť najnovšiu verziu dostupnú pre konkrétny modul:
    go list -m -u example.com/somemodule
    

Príkazy go get -u a go get -u=patch môžeme použiť na aktualizáciu závislostí na najnovšie alebo opravné aktualizácie. Pre hlavné verzie (minor) to však nemôžeme urobiť.

Synchronizácia závislostí

Pre veľké projekty je pracné starať sa o každý import a jeho aktuálnosť samostatne.

Go urobilo v správe závislostí výrazné pokroky. Od verzie 1.11 predstavilo funkciu s názvom Go Modules, ktorá umožňuje efektívnu a bezproblémovú správu balíkov. Je to v súčasnosti predvolený spôsob správy závislostí v Go - podobne ako npm v Node.js alebo pip v Pythone.

Moduly označujú zoskupenie súvisiacich balíkov, ktoré sú navzájom verzované ako jedna jednotka. S modulmi môžeme definovať presné požiadavky na závislosť (napr. presnú verziu) a navrhnúť reprodukovateľné zostavenia pre rôzne prostredia.

Ak chceme v projekte začať používať moduly, jednoducho zadáme nasledujúci príkaz na inicializáciu modulu, prípadne môžeme aj manuálne pridať cestu importu modulu. Cesta môže byť názov modulu, názov projektu alebo adresa URL, ktorá hostí kód úložiska.

go mod init
go mod init example.com/mymodule

Po spustení príkazu, Go moduly vygeneruje konfiguračný súbor go.mod v koreňovom adresári projektu. Súbor bude obsahovať informácie o module a verzii Go.

module example.com/mymodule

go 1.16

Súbor stanovuje požiadavky na projekt a uvádza všetky potrebné závislosti - je to podobné, ako súbor package.json používaný v správe závislostí Node.js.

Tento príkaz funguje aj keď už projekt používa iný nástroj na správu závislostí. Napríklad veľmi známy dep alebo obľúbený glide. Go moduly automaticky importuje závislosti rôznych formátov.

Po inicializácii projektu, môžeme do projektu nainštalovať nové závislosti. Na inštaláciu závislostí môžeme použiť spomínaný príkaz go get, ktorý tiež automaticky aktualizuje súbor go.mod. Po spustení príkazu by mal súbor go.mod vyzerať asi takto:

module example.com/mymodule

go 1.16
require go get example.com/somemodule v1.2.3 // indirect

Pretože sa balík momentálne v projekte nikde nepoužíva, je označený ako nepriamy (indirect). Tento komentár sa môže objaviť aj v balíku nepriamej závislosti, teda závislosť inej závislosti.

Inštalácia závislosti ďalej vygeneruje súbor go.sum v koreňovom adresári projektu. Aj keď nejde o lock súbor (ako napríklad package-lock.json v Node.js), tento súbor obsahuje očakávané kryptografické hashe obsahu jednotlivých verzií modulov.

Súbor go.sum slúži ako kontrola závislosti, ktorá overuje moduly pred neočakávanými alebo škodlivými zmenami, ktoré môžu narušiť celý projekt. A tiež, ak prestaneme používať modul, zaznamenané informácie o kontrolnom súčte nám v budúcnosti umožnia pokračovať v jeho použití tak, ako je.

Pre upratanie závislostí používame príkaz tidy. Okrem toho, že odstráni nepoužívané závislosti, jeho účelom je tiež pridať akékoľvek závislosti potrebné pre ďalšie kombinácie operačného systému, architektúry a building tags.

go mod tidy

Nezabudnite to spustiť pred každým vydaním novej verzie (release).

Príkazy, ako go build alebo go test automaticky stiahnu všetky chýbajúce závislosti, aj keď to môžeme urobiť explicitne pomocou go mod download.

Štandardne sú všetky balíky zo všetkých projektov stiahnuté do adresára $GOPATH/pkg/mod.

Za povšimnutie tiež stojí príkaz edit -replace, ktorým požadovaný modul nasmerujeme na vlastný fork alebo dokonca na cestu k miestnemu súboru. Vieme to potom odstrániť manuálne alebo pomocou edit -dropreplace.

Viac info na medium.com alebo na golangu blogu.

Referencie

  1. https://pkg.go.dev
  2. https://index.golang.org
  3. https://proxy.golang.org
  4. https://golang.org/doc/modules/version-numbers
  5. https://github.com/golang/dep
  6. https://github.com/Masterminds/glide
  7. https://go.googlesource.com/go/+/362625209b6cd2bc059b6b0a67712ddebab312d9/src/cmd/go/internal/modconv/modconv.go#9
  8. https://medium.com/@adiach3nko/package-management-with-go-modules-the-pragmatic-guide-c831b4eaaf31
  9. https://blog.golang.org/using-go-modules

Vaše otázky, návrhy a komentáre

Verím, že vás tento návod inšpiroval a budem vďačný ak dáte spätnú väzbu a pomôžete mi zamerať sa na to čo by vás zaujímalo.

TAK ČO HOVORÍŠ ?

Kontaktuj nás ak potrebuješ pomoc, veľmi radi pomôžeme.

Kontaktuj nás