Должен ли я указать точные версии в моем Gemfile? - PullRequest
62 голосов
/ 13 февраля 2012

Я заметил, что на rubygems.org многие гемы предлагают указывать их по основной, а не по точной версии. Например ...

Камень Хамл-рельсов ...

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

Однако, основываясь на Документах Bundler , мне показалось, что было бы лучше записать точную версию, как эта ...

gem "haml-rails", "0.3.4"

Итак, ваш драгоценный камень haml-rails и все его зависимости не будут перемещаться вперед. Если вы проверите проект на другом компьютере через несколько недель и запустите $ bundle install, у вас будут точно такие же версии всего, что вы указали.

Я видел, как точечные релизы ломали вещи, и я думал, что частью всей идеи Bundler было "Bundle.lock" всех ваших версий гемов.

Но на rubygems.org они часто используют "~>", так что, может быть, я что-то упустил?

Любое разъяснение было бы очень полезно для понимания Bundler и управления драгоценными камнями.

Ответы [ 3 ]

55 голосов
/ 13 февраля 2012

Это цель файла Gemfile.lock - запуск bundle install с присутствующим Gemfile.lock устанавливается только с использованием зависимостей, перечисленных там;это не повторно разрешает Gemfile.Чтобы обновить зависимости / обновить версии gem, вам нужно явно сделать bundle update, который обновит ваш файл Gemfile.lock.

Если не было Gemfile.lock, развертывание кода в рабочей среде будетглавная проблема, потому что, как вы упоминаете, зависимости и версии гемов могут измениться.

Короче говоря, вы должны быть в безопасности, используя пессимистический оператор ограничения версии (~>), как советует rubygems.org.Просто обязательно перезапустите свои тесты после того, как вы выполните bundle update, чтобы убедиться, что ничего не сломалось.

Есть хорошая статья Иегуды Каца, в которой есть немного больше информации о Gemfile.блокировка.

6 голосов
/ 13 февраля 2012

Я бы определенно сказал, использовать точные номера версий.Вы, вероятно, всегда можете просто заблокировать его для основной версии или никогда не указывать какую-либо версию, и все будет в порядке, но если вы действительно хотите этот детальный уровень контроля и иметь 100% уверенность в своей программе при запуске на других машинах,используйте точные номера версий.

Я был в ситуациях, когда точный номер версии не был указан, и когда я или кто-то другой сделал bundle install, проект прервался, потому что он перешел на более новую версию,Это может быть особенно плохо при развертывании в производство.

Bundler делает блокировку в ваших спецификациях гемов, но если вы говорите ему просто использовать основной выпуск, то он фиксирует это.Так что он просто знает «О, версия заблокирована на уровне> 0.1» или что-то еще, но не «О, версия заблокирована специально на уровне 0.1.2.3».

4 голосов
/ 10 августа 2018

TL; DR

Да, используйте пессимистическую блокировку (~>) и укажите семантическую версию вплоть до исправления (Major.minor.patch) на всех ваших драгоценных камнях!

Обсуждение

Я удивлен отсутствием ясности в этом вопросе, даже «отраслевые эксперты» сказали мне на днях, что Gemfile.lock существует для поддержки версий гемов. Неправильно!

Вы хотите организовать Gemfile таким образом, чтобы вы могли запустить bundle update в любое время, не рискуя сломать все. Чтобы достичь этого:

  1. Укажите версию уровня патча для всех ваших драгоценных камней с пессимистической блокировкой. Это позволит bundle update исправлять, но не вносить изменения.

  2. Укажите ref для драгоценных камней из git

Единственным недостатком этой настройки является то, что, когда выходит новая милая / основная версия для драгоценного камня, вы должны увеличить версию вручную.

Сценарий предупреждения

Подумайте, что произойдет, если вы не заблокируете свои драгоценные камни.
У вас есть разблокированный gem "rails" в вашем гемфайле, а версия в Gemfile.lock равна 4.1.16. Вы пишете код, и в какой-то момент вы делаете bundle update. Теперь ваша версия Rails переходит на 5.2.0 (при условии, что некоторые другие гемы не мешают этому) и все ломается.
Сделайте себе одолжение и не допускайте этого ни для какого драгоценного камня!

Пример 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

Концессия
Если вы уверены, что ваши тесты обнаружат ошибки, вызванные изменениями версии гема, вы можете попробовать гемы с пессимистической блокировкой в ​​минорной версии, а не в патче.
Это позволит увеличить версию гема в пределах указанной основной версии, но не до следующей.

gem "puma", "~> 3.12"
...