programowanieProgramista Go

Jak działają moduły Go i zarządzanie zależnościami w Go? Jakie pułapki mogą się pojawić podczas aktualizacji lub blokowania zależności?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Moduły Go to standardowy mechanizm zarządzania zależnościami, wprowadzony w Go 1.11+. Główne pliki to go.mod (określa minimalne zależności i ich wersje) oraz go.sum (zapewnia integralność za pomocą hashy).

Aby dodać zależność, używa się:

go get github.com/pkg/errors@v0.9.1

Aby zaktualizować zależności —

go get -u ./... go mod tidy # usuń nieużywane

Go wspiera semantyczne wersjonowanie (semver), a zależności są blokowane na sztywno: projekt można powtórzyć, a budowa jest deterministyczna. Należy jednak pamiętać:

  • Przy używaniu ścieżek replace (<replace github.com/pkg/errors = ../errors>) istnieją ryzyka niekompatybilności.
  • Błąd przy ręcznym poprawieniu go.mod może prowadzić do niekompatybilności wersji, konfliktów z zależnościami tranzytywnymi.
  • Niektóre zależności używają innego systemu (dep, vendoring), co powoduje trudności w migracji.

Pytanie z pułapką

Co się stanie, jeśli usuniesz plik go.sum i uruchomisz polecenie go build, oraz jak to jest niebezpieczne?

Wielu myśli, że Go po prostu odbuduje zależności od nowa. Jednak plik go.sum zawiera hashe wszystkich używanych modułów i chroni przed podmianą (atak z łańcuchem dostaw). Jeśli go usuniesz, przy następnym buildzie Go pobierze zależności ponownie, odtworzy plik, ale jeśli repozytorium zależności zostało zmienione przez osobę trzecią — ochrona jest złamana! Może nastąpić podmiana kodu w produkcji.

Przykłady rzeczywistych błędów z powodu nieznajomości niuansów tematu


Historia

W dużym projekcie repozytorium przeszło z vendoringu na moduły Go, zapomniano zablokować wersje. Po miesiącu aktualizacje zewnętrznych pakietów złamały zgodność, stało się niemożliwe zbudowanie starej gałęzi — kod stracił reprodukowalność.


Historia

W innym projekcie programista przypadkowo usunął go.sum. Po ponownym uruchomieniu zespół zauważył, że część zależności się zmieniła, pojawiły się błędy związane z niekompatybilnością wersji minor — z tego powodu nastąpił rollback o kilka dni wstecz.


Historia

Użycie ścieżek replace na lokalnych katalogach (replace ... = ../some/library) nie zostało usunięte przed wdrożeniem — w procesie CI/CD budowa nie powiodła się, ponieważ zewnętrzny system nie miał dostępu do lokalnych plików, a produkcja została "zamrożona" na niepoprawnej wersji.