Должен ли я указать точные версии в моем Gemfile?


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

драгоценный камень haml-rails...

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

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

gem "haml-rails", "0.3.4"

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

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

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

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

3 57

3 ответа:

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

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

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

здесь хорошая статья по Yehuda Katz, который имеет немного больше информации о Gemfile.замок.

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

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

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

TL; DR

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

Обсуждение

я удивлен отсутствием ясности по этому вопросу, даже "отраслевые эксперты" сказали мне на днях, что Gemfile.lock есть ли для поддержания версии gem. Неправильно!

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

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

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

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

предупреждение сценарий

подумайте, что произойдет, если вы не заблокируете свои драгоценные камни.
У вас есть разблокированный gem "rails" в вашем gemfile и версии в 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, вы можете попробовать пессимистические блокировки драгоценных камней в минорной версии, а не патч.
Это позволит версии gem увеличиваться в пределах указанной основной версии, но никогда в следующую.

gem "puma", "~> 3.12"