Jaka jest różnica między Gemfile i Gemfile.lock w Ruby on Rails

Odpowiedzi:

159

To miejsce, w Gemfilektórym określasz, których klejnotów chcesz użyć, i pozwala określić, które wersje.

Gemfile.lockPlik jest gdzie Bundler rejestruje dokładne wersje, które zostały zainstalowane. W ten sposób, gdy ta sama biblioteka / projekt jest ładowana na innym komputerze, uruchomienie bundle installobejrzy Gemfile.locki zainstaluje dokładnie te same wersje, zamiast używać Gemfilei instalować najnowsze wersje. (Uruchamianie różnych wersji na różnych komputerach może prowadzić do zepsutych testów itp.) Nigdy nie powinieneś musieć bezpośrednio edytować pliku blokady.

Zapoznaj się z celem i uzasadnieniem programu Bundler , w szczególności w sekcji Sprawdzanie kodu w kontroli wersji.

Dylan Markow
źródło
2
Tak to powinno działać - ale najwyraźniej Gemfile.lockzawiera wersje „otwarte” w niektórych przypadkach (np. rails (4.0.0)Wymaga bundler (>= 1.3.0, < 2.0)), co powoduje problemy. Masz pomysł, jak uniknąć tych „otwartych” zależności?
Guillermo Grau
158

Zazwyczaj zależności w Gemfile piszemy jako:

gem "nokogiri", "~> 1.4.4"
gem 'bcrypt-ruby', '~> 3.0.0'
gem 'uglifier', '>= 1.2.3'
..

Tutaj w zasadzie mówisz: „ Chcę nokogiri, o ile jest nowszy niż wersja 1.4.4 ”, itd. Teraz przypuśćmy, że skonfigurowałem Gemfile 8 miesięcy temu i pomyślnie skonfigurowałem moją aplikację z tym wymaganiem. 8 miesięcy temu wersja nokogiri była 1.4.4 . Moje aplikacje rails działały doskonale bez żadnych problemów w tej wersji.

Teraz pomyśl, że próbuję zbudować to samo Gemfile. Ale jeśli spojrzymy na wersje nokogiri , zobaczymy, że obecna stabilna wersja zmieniła się na 1.4.9 . Oznacza to, że jeśli spróbujemy zbudować, bundler zainstaluje wersję 1.4.9 nokogiri (załóżmy, że nie mamy Gemfile.lock).

Co to znaczy ?

Jak widać, jeśli ich nie masz Gemfile.locki uruchom:

bundle install

wtedy aktualnie używane klejnoty mogą być inne w dowolnym momencie . Twoja aplikacja korzystała z wersji 1.4.4 i 8 miesięcy temu działa bez żadnych problemów, ale jeśli spróbujesz ją teraz zbudować , otrzymasz wersję 1.4.9 . Może jest zepsuty w najnowszej wersji nokogiri, niesamowitej funkcji, której użyłeś w 1.4.4 nie jest bardziej dostępna itp.

Aby zapobiec tego rodzaju problemom, Gemfile.lockstosuje się. W Gemfile.locktylko dokładne wersje są napisane i dlatego tylko te zostaną zainstalowane. Oznacza to, że jeśli rozpowszechniasz swoją aplikację za pomocą Gemfile.lock, na każdym komputerze będą zainstalowane te same perełki, a co najważniejsze , wszystkie otrzymają tę samą wersję . Zapewni to stabilny i wspólny stos wdrożeniowy.

Jak powstaje Gemfile.lock?

Jest tworzony automatycznie z pierwszym:

bundle install

Komenda. Po tym za każdym razem, gdy uruchomisz bundle install, pakiet najpierw wyszuka Gemfile.locki zainstaluje określone tam klejnoty. Dystrybucja tego pliku między projektami jest nawykiem, aby zapewnić spójność i stabilność.

Jak zaktualizować Gemfile.lock?

Jeśli jesteś zadowolony z najnowszej wersji swoich aplikacji, możesz zaktualizować Gemfile.lock. Po prostu odzwierciedl swoje zmiany w Gemfile. Oznacza to zmianę zależności na nowe dokładne wersje w Gemfile. Po tym biegu:

bundle install

Spowoduje to zaktualizowanie Cię Gemfile.locko najnowszą wersję aplikacji.

Fatih Arslan
źródło
19
Bardzo ładny, jasny opis (zagłosowałem za); ale jeden czubek: nokogiri ~> 1.4.4nie pozwoliłby 1.5.3na instalację; max dozwolone byłoby 1.4.xgdzie x>=4(w przypadku nokogiri byłoby to 1.4.7). Te ~>środki operatorskie tylko ostatnia cyfra w używanych gem może być „większy niż” danej wersji. Np. foo ~> a.b.c.dOznacza , że każda wersja foojest w porządku, o ile nadal jest abc {coś} gdzie {coś} >=d. Zobacz też powiązane pytanie
michael
1
Co mnie gem "nokogiri", "~> 1.4.4"wprawia w zakłopotanie, to fakt, że już określasz konkretne wersje, używając w pliku gem. Dlaczego pakiet nie mógł po prostu użyć tej wersji? Czy to dlatego, że jest przeznaczony do domyślnego celowego instalowania najnowszych wersji klejnotu?
Jonny
@Jonny, zobacz komentarz michael_n. ~> 1.4.4 nie określa dokładnej wersji.
Matthew Flaschen,
2
@Jonny, ~> 1.4.4jest odpowiednikiem >= 1.4.4 and < 1.5. Zobacz bundler.io/v1.5/gemfile.html . Aby uzyskać dokładną wersję, po prostu użyj gem 'foo', '1.4.4'.
Matthew Flaschen
1
Świetna odpowiedź, ale proszę wyjaśnić „ zaktualizuj Gemfile.lock? ”: Czy ta sekcja mówi, że bundle installbędzie sprawdzać, Gemfilenawet jeśli istnieje Gemfile.locki wymusi nowe ograniczenia Gemfile.lock?
JMess
4

Gemfile.lock

Kiedy uruchomisz instalację pakietową, Bundler zachowa pełne nazwy i wersje wszystkich klejnotów, których użyłeś (w tym zależności klejnotów określonych w Gemfile (5)) w pliku o nazwie Gemfile.lock.

Bundler używa tego pliku we wszystkich kolejnych wywołaniach instalacji pakietowej, co gwarantuje, że zawsze używasz tego samego dokładnego kodu, nawet gdy aplikacja jest przenoszona między maszynami.

Ze względu na sposób działania rozwiązywania zależności, nawet pozornie niewielka zmiana (na przykład aktualizacja do punktowego wydania zależności klejnotu w pliku Gemfile (5)) może spowodować, że do spełnienia wszystkich zależności potrzebne będą radykalnie różne klejnoty.

W rezultacie POWINIENEŚ sprawdzić swój plik Gemfile.lock w kontroli wersji. Jeśli tego nie zrobisz, każda maszyna, która sprawdzi Twoje repozytorium (w tym serwer produkcyjny), ponownie rozwiąże wszystkie zależności, co spowoduje użycie różnych wersji kodu stron trzecich, jeśli którykolwiek z klejnotów w Gemfile (5) lub którykolwiek ich zależności zostały zaktualizowane.

Ajey
źródło