Zrozumienie pliku Gemfile.lock

181

Po uruchomieniu bundle installpolecenia w katalogu roboczym tworzony jest plikGemfile.lock ”. Co oznaczają dyrektywy w tym pliku?

Na przykład weźmy następujący plik:

PATH
  remote: .
  specs:
    gem_one (0.0.1)

GEM
  remote: http://example.org/
  specs:
    gem_two (0.0.2)
    gem_three (0.0.3)
      gem_four (0.0.4)

PLATFORMS
  platform

DEPENDENCIES
  gem_two
  gem_one!

Co opisują „ ŚCIEŻKA ”, „ GEM ”, „ PLATFORMY ” i „ ZALEŻNOŚCI ”? Czy wszystkie są wymagane?

Co powinno zawierać podkatalogi „ remote ” i „ specs ”?

Co oznacza wykrzyknik po nazwie klejnotu w grupie „ ZALEŻNOŚCI ”?

Shamaoke
źródło

Odpowiedzi:

71

Więcej informacji na ten temat można znaleźć na stronie internetowej producenta pakietu (podkreślenie zostało dodane poniżej dla Twojej wygody):

Po chwilowym opracowaniu aplikacji sprawdź ją wraz z migawką Gemfile i Gemfile.lock . Teraz Twoje repozytorium zawiera dokładną wersję wszystkich klejnotów, których użyłeś ostatnim razem, na pewno wiesz, że aplikacja działała ...

Jest to ważne: Gemfile.lock sprawia, że ​​aplikacja jest pojedynczym pakietem zarówno własnego kodu, jak i kodu innej firmy, który uruchomił przy ostatnim uruchomieniu, na pewno wiesz, że wszystko działało. Określenie dokładnych wersji kodu innej firmy, na którym zależysz w swoim pliku Gemfile, nie dałoby tej samej gwarancji, ponieważ klejnoty zwykle deklarują zakres wersji dla ich zależności.

Filipe Miguel Fonseca
źródło
65
To nie odpowiedziało na żadne z jego pytań, pyta o format Gemfile.lock, ale to po prostu opisuje, co robi.
Joshua Cheek
38

jeśli chodzi o wykrzyknik, właśnie się dowiedziałem, że dotyczy klejnotów pobranych :gitnp

gem "foo", :git => "[email protected]:company/foo.git"
agenteo
źródło
Wow, fajna robota, wymyślenie tego, też się nad tym zastanawiałem. Dzięki.
JP Silvashy
5
Występuje również podczas ładowania lokalnych klejnotów poprzez pathopcję. Zgaduję, że ma to coś wspólnego z ładowaniem nieskompilowanego klejnotu?
zykadelic
Tak, to jest powód. Ale to NIE jest jedyny powód, dla którego klejnot jest oznaczany wykrzyknikiem. Obecnie widzę dowolny klejnot zadeklarowany w bloku źródłowym jako oznaczony wykrzyknikiem.
Sean Moubry
35

Ostatnie kilka miesięcy spędziłem na zabawie z Gemfiles i Gemfile.locks podczas tworzenia automatycznego narzędzia do aktualizacji zależności 1 . Poniżej znajduje się daleka od ostateczności, ale jest to dobry punkt wyjścia do zrozumienia formatu Gemfile.lock. Możesz także sprawdzić kod źródłowy analizatora plików blokujących Bundlera .

W pliku blokującym wygenerowanym przez Bundler 1.x znajdują się następujące nagłówki:

GEM (opcjonalnie, ale bardzo często)

Są to zależności pochodzące z serwera Rubygems. Może to być główny indeks Rubygems, na stronie Rubygems.org, lub może to być indeks niestandardowy, taki jak te dostępne w Gemfury i innych. W tej sekcji zobaczysz:

  • remote: jeden lub więcej wierszy określających położenie indeksu (-ów) Rubygems
  • specs: lista zależności wraz z ich numerem wersji i ograniczeniami wszelkich zależności zależnych

GIT (opcjonalnie)

Są to zależności pochodzące od danego zdalnego git. Zobaczysz inną z tych sekcji dla każdego pilota git, aw każdej sekcji zobaczysz:

  • remote:pilot git. Na przykład,[email protected]:rails/rails
  • revision: referencja zatwierdzenia, w której znajduje się Gemfile.lock
  • tag: (opcjonalnie) znacznik określony w pliku Gemfile
  • specs: zależność git znaleziona na tym pilocie, wraz z jej numerem wersji i ograniczeniami wszelkich zależności zależnych

ŚCIEŻKA (opcjonalnie)

Są to zależności pochodzące od danego path, podane w Gemfile. Zobaczysz inną z tych sekcji dla każdej zależności ścieżki, aw każdej sekcji zobaczysz:

  • remote:ścieżka. Na przykład,plugins/vendored-dependency
  • specs: zależność git znaleziona na tym pilocie, wraz z jej numerem wersji i ograniczeniami wszelkich zależności zależnych

PLATFORMY

Platforma Ruby, przeciwko której wygenerowano Gemfile.lock. Jeśli jakiekolwiek zależności w pliku Gemfile określają platformę, zostaną one uwzględnione w pliku Gemfile.lock tylko wtedy, gdy plik blokady zostanie wygenerowany na tej platformie (np. Podczas instalacji).

ZALEŻNOŚCI

Lista zależności, które są określone w Gemfile, wraz z ograniczeniem wersji tam określonym.

Zależności określone w źródle innym niż główny indeks Rubygems (np. Zależności git, zależne od ścieżki, zależności) mają !co oznacza, że ​​są „przypięte” do tego źródła 2 (chociaż czasami trzeba zajrzeć do pliku Gemfile, aby określić in).

WERSJA RUBY (opcjonalnie)

Wersja Ruby określona w Gemfile, kiedy ten Gemfile.lock został utworzony. Jeśli .ruby_versionzamiast tego w pliku podano wersję Ruby, ta sekcja nie będzie obecna (ponieważ Bundler uzna Gemfile / Gemfile.lock za agnostyczny wobec wersji Ruby instalatora).

ZWIĄZANE Z (Bundler> = v1.10.x)

Wersja Bundlera użyta do utworzenia Gemfile.lock. Służy do przypominania instalatorom o aktualizacji ich wersji Bundlera, jeśli jest on starszy niż wersja, która utworzyła plik.

ŹRÓDŁO WTYKU (opcjonalne i bardzo rzadkie)

Teoretycznie Gemfile może określać wtyczki Bundlera, a także klejnoty 3 , które zostałyby tutaj wymienione. W praktyce od lipca 2017 r. Nie znam żadnych dostępnych wtyczek. Ta część pakietu jest wciąż w fazie rozwoju!


  1. https://dependabot.com
  2. https://github.com/bundler/bundler/issues/4631
  3. http://andre.arko.net/2012/07/23/towards-a-bundler-plugin-system/
greysteil
źródło
2
wydaje się być najlepszą odpowiedzią
trudne
9

Bundler to menedżer klejnotów, który zapewnia spójne środowisko dla projektów Ruby, śledząc i instalując potrzebne klejnoty i wersje.

Gemfile i Gemfile.lock to podstawowe produkty oferowane przez klejnot Bundlera (sam Bundler jest klejnotem).

Gemfile zawiera zależność twojego projektu od klejnotów, o których wspominasz ręcznie w określonych wersjach, ale zamiana tych klejnotów zależy od innych klejnotów, które są automatycznie rozstrzygane przez pakiet.

Gemfile.lock zawiera pełną migawkę wszystkich klejnotów w Gemfile wraz z powiązaną zależnością.

Kiedy po raz pierwszy wywołasz instalację pakietu , utworzy ten plik Gemfile.lock i użyje tego pliku we wszystkich kolejnych wywołaniach instalacji pakietu, co zagwarantuje, że masz zainstalowane wszystkie zależności i pominiesz instalację zależności.

To samo dzieje się, gdy dzielisz swój kod z różnymi komputerami

Udostępniasz swój Gemfile.lock razem z Gemfile, kiedy uruchomisz instalację pakietu na innym komputerze, będzie on odnosił się do twojego Gemfile.lock i pominie krok rozwiązywania zależności, zamiast tego zainstaluje wszystkie te same zależne klejnoty, których użyłeś na oryginalna maszyna, która zachowuje spójność na wielu maszynach

Dlaczego musimy zachować spójność na wielu komputerach?

  • Uruchamianie różnych wersji na różnych komputerach może prowadzić do uszkodzenia kodu

  • Załóżmy, że Twoja aplikacja używała wersji 1.5.3 i działa 14 miesięcy temu
    bez żadnych problemów, a ty próbujesz zainstalować na innym komputerze
    bez Gemfile.lock, teraz otrzymujesz wersję 1.5.8. Być może jest zepsuty w najnowszej wersji niektórych klejnotów i aplikacja się
    nie powiedzie. Utrzymanie spójności ma ogromne znaczenie (preferowana
    praktyka).

Możliwe jest również zaktualizowanie klejnotów w Gemfile.lock przy użyciu aktualizacji pakietu .

Jest to oparte na koncepcji konserwatywnej aktualizacji

Keshav
źródło
8

Wydaje mi się, że PATH wyświetla zależności pierwszej generacji bezpośrednio z twojego gemspec, podczas gdy GEM wyświetla zależności drugiej generacji (tj. Od czego zależą twoje zależności) i te z twojego Gemfile. PATH :: remote polega na .tym, że polegał na lokalnym gemspec w bieżącym katalogu, aby dowiedzieć się, co należy do PATH :: spec, podczas gdy GEM :: remote rubygems.org, ponieważ tam musiał się dowiedzieć, co należy do GEM :: spec.

We wtyczce Rails zobaczysz sekcję ŚCIEŻKA, ale nie w aplikacji Rails. Ponieważ aplikacja nie ma pliku gemspec, w PATH nie byłoby nic do dodania.

Jeśli chodzi o ZALEŻNOŚCI , gembundler.com stwierdza:

Runtime dependencies in your gemspec are treated like base dependencies, 
and development dependencies are added by default to the group, :development

Plik Gem wygenerowany przez rails plugin new my_pluginmówi coś podobnego:

# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.

Oznacza to, że różnica między nimi

s.add_development_dependency "july" # (1)

i

s.add_dependency "july" # (2)

jest to, że (1) będzie zawierać tylko „lipiec” w Gemfile.lock (a zatem w aplikacji) w środowisku programistycznym. Kiedy więc biegniesz bundle install, zobaczysz „lipiec” nie tylko w polu ŚCIEŻKA, ale także w ZALEŻNOŚCIACH, ale tylko w fazie rozwoju. W produkcji nie będzie go wcale. Jednakże, gdy użyjesz (2), zobaczysz „lipiec” tylko w ŚCIEŻCE, a nie W ZALEŻNOŚCIACH, ale pojawi się, gdy będziesz bundle installze środowiska produkcyjnego (tj. W jakimś innym klejnocie, który zawiera twój jako zależność), a nie tylko rozwój.

To tylko moje spostrzeżenia i nie mogę w pełni wyjaśnić, dlaczego tak jest, ale z zadowoleniem przyjmuję dalsze komentarze.

Izaak Betesh
źródło
3

Wydaje się, że nie ma wyraźnego dokumentu mówiącego o Gemfile.lockformacie. Może to dlatego, że Gemfile.lockjest po prostu używany wewnętrznie przez pakiet.

Jednakże, ponieważ Gemfile.lockjest migawką Gemfile, co oznacza, że ​​wszystkie jego informacje powinny pochodzić Gemfile(lub od wartości domyślnej, jeśli nie określono w Gemfile).

Za GEMto listę wszystkich zależności Państwo wprowadzić bezpośrednio lub pośrednio w Gemfile. remoteunder GEMmówi, gdzie zdobyć klejnoty, które są określone przez źródło w Gemfile.

Jeśli klej nie jest pobierany remote, PATHinformuje lokalizację, aby go znaleźć. PATH„s informacji pochodzi ze ścieżki w Gemfilekiedy zadeklarować zależność.

I PLATFORMjest stąd .

Na DEPENDENCIES, jest to migawka zależności rozwiązane przez wiązkę.

Hong
źródło
0

Co oznacza wykrzyknik po nazwie klejnotu w grupie „DEPENDECIES”?

Wykrzyknik pojawia się, gdy klejnot został zainstalowany przy użyciu źródła innego niż „ https://rubygems.org ”.

SWiggels
źródło