В чем разница между Gemfile и Gemfile.lock в Ruby on Rails

Ответы:

159

Здесь Gemfileвы указываете, какие драгоценные камни хотите использовать, и позволяет указать, какие версии.

В этом Gemfile.lockфайле Bundler записывает точные версии, которые были установлены. Таким образом, когда та же библиотека / проект загружается на другой компьютер, при запуске bundle installбудут просматриваться Gemfile.lockи устанавливаться точно такие же версии, а не просто использовать Gemfileи устанавливать самые последние версии. (Запуск разных версий на разных машинах может привести к сбоям в тестах и ​​т. Д.) Вам никогда не придется напрямую редактировать файл блокировки.

Ознакомьтесь с целью и обоснованием Bundler , особенно с разделом «Проверка кода в системе контроля версий».

Дилан Маркоу
источник
2
Вот как это должно работать - но, видимо, Gemfile.lockв некоторых случаях (например, rails (4.0.0)требует bundler (>= 1.3.0, < 2.0)) включаются «открытые» версии , что вызывает проблемы. Есть идеи, как избежать этих «открытых» зависимостей?
Гильермо Грау
158

Обычно мы пишем зависимости в Gemfile как:

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

Здесь вы в основном говорите: « Я хочу nokogiri, если он выше версии 1.4.4 » и т. Д. Теперь предположим, что я настроил свое Gemfile 8 месяцев назад и успешно настроил свое приложение с этим требованием. 8 месяцев назад версия nokogiri была 1.4.4 . Мои приложения rails работали отлично, без проблем с этой версией.

Теперь подумайте, что я пытаюсь построить то же самое Gemfile. Но если мы посмотрим на версии nokogiri, то увидим, что текущая стабильная версия изменилась на 1.4.9 . Это означает, что если мы попытаемся собрать, сборщик установит версию 1.4.9 nokogiri (предположим, что у нас ее нет Gemfile.lock).

Что это означает ?

Как видите, если у вас их нет, Gemfile.lockзапустите:

bundle install

тогда используемые в настоящее время драгоценные камни могут быть разными в любое время . Ваше приложение использовало версию 1.4.4 и работает 8 месяцев назад без каких-либо проблем, но если вы попытаетесь собрать его сейчас, вы получите версию 1.4.9 . Возможно, он не работает в последней версии nokogiri, замечательная функция, которую вы использовали с 1.4.4, больше недоступна и т. Д.

Для предотвращения такого рода проблем Gemfile.lockиспользуется. В написаны Gemfile.lockтолько точные версии и поэтому будут установлены только они. Это означает, что если вы распространяете свое приложение с помощью Gemfile.lock, на каждой машине будут установлены одни и те же драгоценные камни, и, что наиболее важно, все они получат одну и ту же версию . Это даст вам стабильный и общий стек развертывания.

Как создается Gemfile.lock?

Он автоматически создается с первым:

bundle install

команда. После этого каждый раз при запуске bundle installпакет сначала ищет Gemfile.lockи устанавливает указанные там драгоценные камни. Распространять этот файл среди своих проектов - это привычка, чтобы обеспечить стабильность и стабильность.

Как обновить Gemfile.lock?

Если вас устраивает последняя версия ваших приложений, вы можете обновить ее Gemfile.lock. Просто отразите свои изменения в Gemfile. Это означает изменение зависимостей на новые точные версии в Gemfile. После этого запустите:

bundle install

Это обновит вас до Gemfile.lockпоследней версии приложений.

Фатих Арслан
источник
19
Очень красивое, четкое описание (я проголосовал за); но одна придирка, однако: nokogiri ~> 1.4.4не позволяет 1.5.3установить; максимально допустимый будет 1.4.xгде x>=4(для нокогири это будет 1.4.7). В ~>оператор означает только последняя цифра в использованную драгоценный камень может быть «больше» данной версии. Например, foo ~> a.b.c.dозначает , что подойдет любая версия, fooесли она все еще abc {something} where {something} >=d. См. Также связанный вопрос
Майкл
1
Что меня сбивает с толку, так это то, что вы уже указываете конкретные версии, используя их gem "nokogiri", "~> 1.4.4"в gemfile. Почему сборщик не мог просто использовать эту версию? Это потому, что он предназначен для намеренной установки последних версий гема по умолчанию?
Джонни
@Jonny, см. Комментарий michael_n. ~> 1.4.4 не указывает точную версию.
Мэтью Флашен
2
@Jonny ~> 1.4.4эквивалентно >= 1.4.4 and < 1.5. См. Bundler.io/v1.5/gemfile.html . Для точной версии просто используйте gem 'foo', '1.4.4'.
Мэтью Флашен
1
Отличный ответ, но уточните, пожалуйста, « обновить Gemfile.lock? »: В этом разделе говорится, что bundle installбудет проверяться, Gemfileдаже если есть, Gemfile.lockи вводиться новые ограничения Gemfile.lock?
JMess
4

Gemfile.lock

Когда вы запускаете установку пакета, Bundler сохранит полные имена и версии всех используемых гемов (включая зависимости гемов, указанных в Gemfile (5)) в файле с именем Gemfile.lock.

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

Из-за того, как работает разрешение зависимостей, даже кажущееся небольшое изменение (например, обновление до момента выпуска зависимости гема в вашем Gemfile (5)) может привести к тому, что для удовлетворения всех зависимостей потребуются радикально разные драгоценные камни.

В результате вам СЛЕДУЕТ проверить свой Gemfile.lock в системе контроля версий. Если вы этого не сделаете, каждая машина, которая проверяет ваш репозиторий (включая ваш производственный сервер), снова разрешит все зависимости, что приведет к использованию разных версий стороннего кода, если какой-либо из драгоценных камней в Gemfile (5) или любой другой их зависимости были обновлены.

Ajey
источник