Was ist der Unterschied zwischen Gemfile und Gemfile.lock in Ruby on Rails?

125

Ich bin ein Anfänger von Ruby on Rails und verwende Rails 3.0.9.

Was ist der Unterschied zwischen Gemfileund Gemfile.lockin Rails?

Shamith c
quelle

Antworten:

159

Das Gemfileist , wo Sie die Edelsteine die Sie verwenden möchten angeben, und können Sie angeben , welche Versionen.

In der Gemfile.lockDatei zeichnet Bundler die genauen Versionen auf, die installiert wurden. Wenn dieselbe Bibliothek / dasselbe Projekt auf einen anderen Computer geladen bundle installwird, werden beim Ausführen auf diese Weise Gemfile.lockgenau dieselben Versionen angezeigt und installiert, anstatt nur Gemfiledie neuesten Versionen zu verwenden und zu installieren. (Das Ausführen verschiedener Versionen auf verschiedenen Computern kann zu fehlerhaften Tests usw. führen.) Sie sollten die Sperrdatei niemals direkt bearbeiten müssen.

Lesen Sie Bundlers Zweck und Begründung , insbesondere den Abschnitt Einchecken Ihres Codes in die Versionskontrolle.

Dylan Markow
quelle
2
So sollte es funktionieren - aber anscheinend Gemfile.lockenthält das in einigen Fällen "offene" Versionen (z. B. rails (4.0.0)erforderlich bundler (>= 1.3.0, < 2.0)), was zu Problemen führt. Irgendeine Idee, wie man diese "offenen" Abhängigkeiten vermeidet?
Guillermo Grau
157

Normalerweise schreiben wir Abhängigkeiten in Gemfile wie folgt:

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

Hier sagen Sie im Grunde: " Ich möchte Nokiaogiri, solange es größer als Version 1.4.4 ist " usw. Nehmen wir nun an, ich habe meine App vor Gemfile 8 Monaten eingerichtet und meine App mit dieser Anforderung erfolgreich eingerichtet. Vor 8 Monaten war die Nokiaogiri-Version 1.4.4 . Meine Rails-Apps liefen mit dieser Version problemlos.

Jetzt denke ich versuche mit dem gleichen zu bauen Gemfile. Wenn wir uns jedoch die Nokia-Versionen ansehen, sehen wir, dass sich die aktuelle stabile Version auf 1.4.9 geändert hat . Das heißt, wenn wir versuchen zu bauen, installiert Bundler Version 1.4.9 von Nokiaogiri (nehmen wir an, wir haben keine Gemfile.lock).

Was heißt das ?

Wie Sie sehen, wenn Sie keine haben Gemfile.lockund laufen:

bundle install

dann können die aktuell verwendeten Edelsteine ​​jederzeit unterschiedlich sein . Ihre App hat die Version 1.4.4 verwendet und funktioniert vor 8 Monaten ohne Probleme. Wenn Sie jedoch versuchen, sie jetzt zu erstellen, erhalten Sie die Version 1.4.9 . Vielleicht ist es mit der neuesten Version von kaputt. nokogiriDie großartige Funktion, die Sie mit 1.4.4 verwendet haben, ist nicht mehr verfügbar.

Um diese Art von Problem zu verhindern, Gemfile.lockwird verwendet. Es werden Gemfile.locknur die genauen Versionen geschrieben und somit werden nur diese installiert. Das heißt, wenn Sie Ihre App mit a verteilen Gemfile.lock, werden auf jedem Computer dieselben Edelsteine ​​installiert, und vor allem erhalten alle dieselbe Version . Dadurch erhalten Sie einen stabilen und gemeinsamen Bereitstellungsstapel.

Wie wird Gemfile.lock erstellt?

Es wird automatisch mit dem ersten erstellt:

bundle install

Befehl. Danach sucht das bundle installBundle bei jeder Ausführung zuerst nach Gemfile.lockden dort angegebenen Edelsteinen und installiert sie. Es ist eine Gewohnheit, diese Datei auf Ihre Projekte zu verteilen, um Konsistenz und Stabilität zu gewährleisten.

Wie aktualisiere ich Gemfile.lock?

Wenn Sie mit der neuesten Version Ihrer Apps zufrieden sind, können Sie diese aktualisieren Gemfile.lock. Reflektieren Sie einfach Ihre Änderungen an Gemfile. Das heißt, ändern Sie die Abhängigkeiten auf die neuen exakten Versionen in Gemfile. Nach diesem Lauf:

bundle install

Dadurch werden Sie Gemfile.lockmit Ihrer neuesten Version von Apps aktualisiert .

Fatih Arslan
quelle
19
Eine sehr schöne, klare Beschreibung (ich habe hochgestimmt); aber ein Trottel: nokogiri ~> 1.4.4würde nicht zulassen 1.5.3, installiert zu werden; maximal erlaubt wäre 1.4.xwo x>=4(für nokogiri wäre das 1.4.7). Der ~>Operator bedeutet, dass nur die letzte Ziffer des verwendeten Edelsteins "größer" als die angegebene Version sein kann. ZB foo ~> a.b.c.dbedeutet , dass jede Version von fooin Ordnung ist, solange es noch abc {etwas} ist, wo {etwas} >=d. Siehe auch verwandte Frage
Michael
1
Was mich verwirrt ist, dass Sie bereits bestimmte Versionen gem "nokogiri", "~> 1.4.4"angeben, indem Sie sie in der Gem-Datei verwenden. Warum konnte der Bundler diese Version nicht einfach verwenden? Liegt es daran, dass die neuesten Versionen des Edelsteins standardmäßig absichtlich installiert werden sollen?
Jonny
@Jonny, siehe den Kommentar von michael_n. ~> 1.4.4 gibt keine genaue Version an.
Matthew Flaschen
2
@Jonny, ~> 1.4.4entspricht >= 1.4.4 and < 1.5. Siehe bundler.io/v1.5/gemfile.html . Für eine genaue Version verwenden Sie einfach gem 'foo', '1.4.4'.
Matthew Flaschen
1
Gute Antwort, aber bitte klären Sie " Update Gemfile.lock? ": Sagt dieser Abschnitt, dass bundle installdas überprüft wird, Gemfileauch wenn es eine gibt, Gemfile.lockund erzwingt neue Einschränkungen für Gemfile.lock?
JMess
4

Das Gemfile.lock

Wenn Sie die Bundle-Installation ausführen, speichert Bundler die vollständigen Namen und Versionen aller von Ihnen verwendeten Gems (einschließlich der Abhängigkeiten der in Gemfile (5) angegebenen Gems) in einer Datei namens Gemfile.lock.

Bundler verwendet diese Datei in allen nachfolgenden Aufrufen, um die Installation zu bündeln. Dies garantiert, dass Sie immer denselben exakten Code verwenden, auch wenn sich Ihre Anwendung über mehrere Computer hinweg bewegt.

Aufgrund der Funktionsweise der Abhängigkeitsauflösung kann selbst eine scheinbar kleine Änderung (z. B. eine Aktualisierung einer Punktfreigabe einer Abhängigkeit eines Edelsteins in Ihrer Gemfile (5)) dazu führen, dass radikal unterschiedliche Edelsteine ​​erforderlich sind, um alle Abhängigkeiten zu erfüllen.

Daher sollten Sie Ihr Gemfile.lock in die Versionskontrolle einchecken. Wenn Sie dies nicht tun, löst jeder Computer, der Ihr Repository auscheckt (einschließlich Ihres Produktionsservers), alle Abhängigkeiten erneut auf, was dazu führt, dass unterschiedliche Versionen von Code von Drittanbietern verwendet werden, wenn eines der Gems in Gemfile (5) oder eines der Gems vorhanden ist ihrer Abhängigkeiten wurden aktualisiert.

Ajey
quelle