web-dev-qa-db-de.com

Soll ich in meinem Gemfile genaue Versionen angeben?

Ich habe festgestellt, dass auf rubygems.org viele Edelsteine ​​darauf hindeuten, dass Sie sie nach Hauptversion und nicht nach genauer Version angeben. Beispielsweise...

Der Haml-Rails Edelstein ...

gem "haml-Rails", "~> 0.3.4"  # "$ bundle install" will acquire the 
                              # latest version before 1.0.

Basierend auf den Bundler docs kam es mir jedoch so vor, als ob es besser wäre, die genaue Version wie diese festzunageln ...

gem "haml-Rails", "0.3.4"

Es gibt also dein Haml-Rails-Juwel und all seine Abhängigkeiten werden nicht vorwärts driften. Wenn Sie das Projekt einige Wochen später auf einem anderen Computer auschecken und $ bundle install Sie haben genau die gleichen Versionen von allem, was Sie angegeben haben.

Ich habe Punktveröffentlichungen gesehen und dachte, ein Teil der ganzen Idee von Bundler war es, "Bundle.lock "alle deine Edelsteinversionen.

Aber auf rubygems.org wird viel "~>" verwendet, also fehlt mir vielleicht etwas?

Jede Klarstellung wäre für mich sehr hilfreich, um Bundler- und Edelsteinmanagement zu verstehen.

62
Ethan

Dies ist der Zweck der Gemfile.lock-Datei - Ausführen von bundle install mit einem Gemfile.lock installiert sich nur mit den dort aufgeführten Abhängigkeiten; Das Gemfile wird nicht erneut aufgelöst. Um Abhängigkeiten zu aktualisieren/Gem-Versionen zu aktualisieren, müssen Sie dann explizit ein bundle update, wodurch Ihre Gemfile.lock-Datei aktualisiert wird.

Wenn es kein Gemfile.lock gäbe, wäre die Bereitstellung von Code für die Produktion ein großes Problem, da sich, wie Sie bereits erwähnt haben, die Abhängigkeiten und Gem-Versionen ändern könnten.

Kurz gesagt, Sie sollten im Allgemeinen sicher sein, wenn Sie den pessimistischen Versionsbeschränkungsoperator (~>) wie rubygems.org rät. Stelle nur sicher, dass du deine Tests erneut durchführst, nachdem du ein bundle update um sicherzustellen, dass nichts kaputt geht.

Es gibt ein Netter Artikel von Yehuda Katz, das ein wenig mehr Informationen über Gemfile.lock enthält.

55
Abe Voelker

Ich würde definitiv sagen, verwenden Sie die genauen Versionsnummern. Sie können es wahrscheinlich immer nur auf eine Hauptversion beschränken oder nie eine Version angeben und sind in Ordnung, aber wenn Sie wirklich eine fein abgestimmte Steuerung wünschen und 100% iges Vertrauen in Ihr Programm haben möchten, wenn es auf anderen Computern ausgeführt wird, Verwenden Sie die genauen Versionsnummern.

Ich war in Situationen, in denen die genaue Versionsnummer nicht angegeben wurde und als ich oder jemand anderes ein bundle install, das Projekt ist gescheitert, weil es auf eine neuere Version umgestellt wurde. Dies kann insbesondere bei der Bereitstellung in der Produktion von Nachteil sein.

Bundler funktioniert sperrt Ihre Edelsteinspezifikationen, aber wenn Sie sagen, dass Sie nur eine Hauptversion verwenden sollen, sperrt es diese. Es ist also nur bekannt, dass "Oh, die Version ist auf> 0.1 gesperrt". oder was auch immer, aber nicht "Oh, die Version ist speziell bei 0.1.2.3 gesperrt".

6
MrDanA

TL; DR

Ja, benutze pessimistische Sperre (~>) und spezifiziere eine semantische Version bis zum Patch (Major.minor.patch) auf all deinen Edelsteinen!

Diskussion

Ich bin überrascht über die Unklarheit in dieser Frage, selbst "Branchenexperten" sagten mir neulich, dass Gemfile.lock ist da, um Edelsteinversionen zu pflegen. Falsch!

Sie möchten Ihr Gemfile so organisieren, dass Sie bundle update jederzeit ohne das Risiko, alles zu zerbrechen. Um dies zu erreichen:

  1. Geben Sie eine Patch-Level-Version für alle Ihre Edelsteine ​​mit pessimistischer Sperre an. Dies ermöglicht bundle update, um Ihnen Fehler zu beheben, aber Änderungen nicht zu verwerfen.

  2. Geben Sie ein ref für Edelsteine ​​aus Git an

Der einzige Nachteil dieses Setups ist, dass Sie die Version manuell erhöhen müssen, wenn eine süße neue Moll-/Dur-Version für einen Edelstein herauskommt.

Warnszenario

Überlegen Sie, was passiert, wenn Sie Ihre Edelsteine ​​nicht sperren.
Sie haben einen freigeschalteten gem "Rails" in deinem Gemfile und die Version in Gemfile.lock ist 4.1.16. Du programmierst mit und machst irgendwann ein bundle update. Jetzt springt Ihre Rails Version zu 5.2.0 (vorausgesetzt, ein anderer Edelstein verhindert dies nicht) und alles zerbricht.
Tu dir selbst einen Gefallen und erlaube dies keinem Edelstein!

Ein Beispiel Gemfile

# lock that bundler
if (version = Gem::Version.new(Bundler::VERSION)) < Gem::Version.new('1.16.3')
  abort "Bundler version >= 1.16.3 is required. You are running #{version}"
end

source "http://rubygems.org"

# specify explicit ref for git repos
gem "entity_validator",
  git: "https://github.com/plataformatec/devise",
  ref: "acc45c5a44c45b252ccba65fd169a45af73ff369" # "2018-08-02"

# consider hard-lock on gems you do not want to change one bit
gem "Rails", "5.1.5"

# pessimistic lock on your common gems
gem "newrelic_rpm", "~> 4.8.0"
gem "puma", "~> 3.12.0"

group :test do
  gem "simplecov", "~> 0.16.1", require: false
end

Eine Konzession
Wenn Sie sicher sind, dass Ihre Tests Fehler erkennen, die durch Versionsänderungen von Edelsteinen hervorgerufen wurden, können Sie versuchen, Edelsteine ​​mit pessimistischer Sperrung in einer Nebenversion zu verwenden, nicht zu patchen.
Dadurch kann die Gem-Version innerhalb der angegebenen Hauptversion erhöht werden, jedoch nie in die nächste.

gem "puma", "~> 3.12"
4
Epigene