Должен ли я указывать точные версии в моем Gemfile?
Я заметил, что на 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"
Таким образом, ваш драгоценный камень и все его зависимости не будут перемещаться вперед. Если вы проверите проект на другом компьютере несколько недель спустя и запустите $ bundle install
вас будут точно такие же версии всего, что вы указали.
Я видел, как точечные выпуски ломали вещи, и я думал, что частью всей идеи Bundler было " Bundle.lock
" всех ваших версий Bundle.lock
.
Но на rubygems.org они часто используют "~>", так что, может быть, я что-то упустил?
Любое разъяснение было бы очень полезно для понимания Bundler и управления драгоценными камнями.
Ответы
Ответ 1
Это цель файла Gemfile.lock - запуск bundle install
с присутствием Gemfile.lock только с использованием зависимостей, перечисленных там; он не перенаправляет Gemfile. Чтобы обновить зависимости/обновить версии gem, вам необходимо явно сделать bundle update
, который обновит ваш файл Gemfile.lock.
Если бы не был Gemfile.lock, развертывание кода для производства было бы серьезной проблемой, потому что, как вы упомянули, изменения в зависимости и версии gem могут измениться.
Короче говоря, вы должны быть в целом безопасны с помощью оператора ограничения пессимистической версии (~>
), как советует rubygems.org. Просто не забудьте повторно запустить свои тесты после того, как сделаете bundle update
, чтобы убедиться, что ничего не сломалось.
Там есть хорошая статья от Yehuda Katz, у которой есть немного больше информации о Gemfile.lock.
Ответ 2
Я определенно скажу, что использую точные номера версий. Вероятно, вы всегда можете просто заблокировать его до основной версии или никогда не указывать какую-либо версию, и все в порядке, но если вы действительно хотите, чтобы этот тонкий уровень контроля и был на 100% уверен в вашей программе при запуске на других машинах, используйте точные номера версий.
Я был в ситуациях, когда точный номер версии не был указан, а когда я или кто-то другой сделал bundle install
, проект сломался, потому что он перешел к более новой версии. Это может быть особенно плохо при развертывании в производство.
Bundler блокирует ваши характеристики драгоценных камней, но если вы говорите ему просто использовать основной выпуск, тогда он блокирует это. Так что просто знает: "О, версия заблокирована нa > 0,1" или что-то еще, но а не "О, версия заблокирована, в частности, на 0,1.2.3".
Ответ 3
TL; DR
Да, используйте пессимистическую блокировку (~>
) и укажите семантическую версию для исправления (Major.minor.patch
) для всех ваших драгоценных камней!
обсуждение
Я удивлен отсутствием ясности в этом вопросе, даже "отраслевые эксперты" сказали мне на днях, что Gemfile.lock
существует для поддержки версий gem. Неправильно!
Вы хотите организовать свой Gemfile
таким образом, чтобы вы могли в любое время запустить bundle update
не рискуя нарушить все. Чтобы достичь этого:
-
Укажите версию уровня патча для всех ваших драгоценных камней с пессимистической блокировкой. Это позволит bundle update
предоставлять вам исправления, но не вносить изменения.
-
Укажите ref
для драгоценных камней из Git
Единственным недостатком этой настройки является то, что, когда выходит новая милая/основная версия для драгоценного камня, вы должны увеличить версию вручную.
Сценарий предупреждения
Подумайте, что произойдет, если вы не заблокируете свои драгоценные камни.
В вашем файле gemfile есть разблокированные 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"