Понимание файла Gemfile.lock


181

После выполнения bundle installкоманды в рабочем каталоге создается Gemfile.lock . Что означают директивы внутри этого файла?

Например, давайте возьмем следующий файл:

PATH
  remote: .
  specs:
    gem_one (0.0.1)

GEM
  remote: http://example.org/
  specs:
    gem_two (0.0.2)
    gem_three (0.0.3)
      gem_four (0.0.4)

PLATFORMS
  platform

DEPENDENCIES
  gem_two
  gem_one!

Что описывают « ПУТЬ », « GEM », « ПЛАТФОРМЫ » и « ЗАВИСИМОСТЬ »? Все ли они необходимы?

Что должно содержать поддирективы « remote » и « specs »?

Что означает восклицательный знак после названия драгоценного камня в группе « ЗАВИСИМОСТЬ »?

Ответы:


71

Вы можете найти больше об этом на веб-сайте комплектующих (для вашего удобства добавлен ниже):

После некоторой разработки приложения проверьте приложение вместе со снимком Gemfile и Gemfile.lock . Теперь в вашем хранилище есть запись точных версий всех драгоценных камней, которые вы использовали в последний раз, когда вы точно знали, что приложение работало ...

Это важно: Gemfile.lock делает ваше приложение единым пакетом как вашего собственного кода, так и стороннего кода, который он запускал в прошлый раз, когда вы точно знали, что все работает. Указание точных версий стороннего кода, от которого вы зависите, в вашем Gemfile не даст такой же гарантии, потому что гемы обычно объявляют диапазон версий для своих зависимостей.


65
Это не ответило ни на один из его вопросов, он спрашивает о формате Gemfile.lock, но это просто описывает, что он делает.
Джошуа Чик

38

Что касается восклицательного знака, я только что узнал, что это на драгоценных камнях, полученных через :git, например,

gem "foo", :git => "git@github.com:company/foo.git"

Вау, отличная работа, я тоже удивляюсь. Спасибо.
JP Silvashy

5
Это также происходит при загрузке локальных драгоценных камней через pathопцию. Я предполагаю, что это как-то связано с загрузкой не скомпилированного гема?
zykadelic

Да, это причина. Но это не единственная причина, по которой камень должен быть помечен восклицательным знаком. В настоящее время я вижу любой драгоценный камень, объявленный внутри исходного блока как помеченный восклицательным знаком.
Шон Мубри

35

Последние несколько месяцев я много возился с Gemfiles и Gemfile.locks, создавая инструмент автоматического обновления зависимостей 1 . Ниже далеко не все, но это хорошая отправная точка для понимания формата Gemfile.lock. Возможно, вы также захотите проверить исходный код парсера файла блокировки Bundler .

Вы найдете следующие заголовки в файле блокировки, сгенерированном Bundler 1.x:

GEM (необязательно, но очень часто)

Это зависимости, полученные из сервера Rubygems. Это может быть основной индекс Rubygems на Rubygems.org или пользовательский индекс, например, доступный в Gemfury и других. В этом разделе вы увидите:

  • remote: одна или несколько строк, указывающих расположение индекса (ов) Rubygems
  • specs: список зависимостей, с их номером версии и ограничениями на любые подчиненные зависимости

GIT (опционально)

Это зависимости, полученные из данного git remote. Вы увидите разные разделы для каждого git remote, а внутри каждого раздела вы увидите:

  • remote:Git Remote. Например,git@github.com:rails/rails
  • revision: ссылка коммита, к которой заблокирован Gemfile.lock
  • tag: (необязательно) тег, указанный в Gemfile
  • specs: git-зависимость, найденная на этом удаленном компьютере, с номером версии и ограничениями на любые подзависимости

ПУТЬ (необязательно)

Это зависимости, полученные из заданного pathв Gemfile. Вы увидите различный из этих разделов для каждой зависимости пути, и в каждом разделе вы увидите:

  • remote:тропинка. Например,plugins/vendored-dependency
  • specs: git-зависимость, найденная на этом удаленном компьютере, с номером версии и ограничениями на любые подзависимости

ПЛАТФОРМЫ

Платформа Ruby, против которой был создан Gemfile.lock. Если какие-либо зависимости в Gemfile указывают платформу, они будут включены в Gemfile.lock только при создании файла блокировки на этой платформе (например, посредством установки).

ЗАВИСИМОСТИ

Список зависимостей, указанных в Gemfile, вместе с указанным там ограничением версии.

Зависимости, указанные с источником, отличным от основного индекса Rubygems (например, git-зависимости, основанные на пути, зависимости), имеют значение, !которое означает, что они «прикреплены» к этому источнику 2 (хотя иногда нужно искать в Gemfile, чтобы определить его).

РУБИНОВАЯ ВЕРСИЯ (опционально)

Версия Ruby, указанная в Gemfile, когда был создан этот Gemfile.lock. Если .ruby_versionвместо этого в файле указана версия Ruby, этот раздел не будет представлен (так как Bundler будет рассматривать Gemfile / Gemfile.lock независимо от версии Ruby установщика).

ОБЯЗАН С (Bundler> = v1.10.x)

Версия Bundler, использованная для создания Gemfile.lock. Используется для напоминания установщикам обновить свою версию Bundler, если она старше, чем версия, создавшая файл.

ИСТОЧНИК ПЛАГИНА (необязательно и очень редко)

Теоретически, Gemfile может указывать плагины Bundler, а также гемы 3 , которые затем будут перечислены здесь. На практике я не знаю ни о каких доступных плагинах по состоянию на июль 2017 года. Эта часть Bundler все еще находится в активной разработке!


  1. https://dependabot.com
  2. https://github.com/bundler/bundler/issues/4631
  3. http://andre.arko.net/2012/07/23/towards-a-bundler-plugin-system/

2
кажется, лучший ответ
daslicious

9

Bundler - менеджер Gem, который обеспечивает согласованную среду для проектов Ruby, отслеживая и устанавливая точные гемы и версии, которые необходимы.

Gemfile и Gemfile.lock являются основными продуктами, предоставляемыми Bundler gem (сам Bundler является самоцветом).

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

Gemfile.lock содержит полный снимок всех драгоценных камней в Gemfile и связанных с ними зависимостей.

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

То же самое происходит, когда вы делитесь своим кодом на разных машинах

Вы делитесь своим Gemfile.lock вместе с Gemfile, когда вы запускаете bundle install на другом компьютере, он ссылается на ваш Gemfile.lock и пропускает шаг разрешения зависимостей, вместо этого он установит все те же самые зависимые гемы, которые вы использовали на оригинальная машина, которая поддерживает согласованность на нескольких машинах

Почему нам нужно поддерживать согласованность на нескольких машинах?

  • Запуск разных версий на разных машинах может привести к повреждению кода

  • Предположим, ваше приложение использовало версию 1.5.3, и оно работает
    без проблем 14 месяцев назад , и вы пытаетесь установить его на другой компьютер
    без Gemfile.lock, теперь вы получаете версию 1.5.8. Может быть, он сломан с последней версией некоторых гемов, и ваше приложение
    потерпит неудачу. Поддержание последовательности имеет первостепенное значение (предпочтительная
    практика).

Также возможно обновить gem (ы) в Gemfile.lock с помощью обновления пакета .

Это основано на концепции консервативного обновления


8

Мне кажется, что PATH перечисляет зависимости первого поколения непосредственно из вашей gemspec, тогда как GEM перечисляет зависимости второго поколения (то есть от чего зависят ваши зависимости) и те из вашего Gemfile. PATH :: remote - .потому что он полагался на локальную gemspec в текущем каталоге, чтобы выяснить, что принадлежит в PATH :: spec, тогда как GEM :: remote есть rubygems.org, поскольку именно туда он должен был пойти, чтобы выяснить, что принадлежит в GEM :: спекуляция

В плагине Rails вы увидите раздел PATH, но не в приложении Rails. Поскольку в приложении нет файла gemspec, нечего было бы вставлять в PATH.

Что касается ЗАВИСИМОСТИ, gembundler.com заявляет:

Runtime dependencies in your gemspec are treated like base dependencies, 
and development dependencies are added by default to the group, :development

Сгенерированный Gemfile rails plugin new my_pluginговорит что-то похожее:

# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.

Это означает, что разница между

s.add_development_dependency "july" # (1)

и

s.add_dependency "july" # (2)

является то, что (1) будет включать «июль» только в Gemfile.lock (и, следовательно, в приложении) в среде разработки. Поэтому, когда вы запустите bundle install, вы увидите «июль» не только в PATH, но и в ЗАВИСИМОСТИ, но только в разработке. В производстве его не будет вообще. Однако, когда вы используете (2), вы увидите «июль» только в PATH, а не в ЗАВИСИМОСТИ, но он будет отображаться, когда вы bundle installиз производственной среды (то есть в каком-то другом геме, который включает в себя ваш в качестве зависимости), только разработка.

Это всего лишь мои наблюдения, и я не могу полностью объяснить, почему так происходит, но я приветствую дальнейшие комментарии.


3

Кажется, нет четкого документа, говорящего о Gemfile.lockформате. Может быть, это потому Gemfile.lock, что используется внутри пакета.

Однако, поскольку Gemfile.lockэто снимок Gemfile, это означает, что вся его информация должна поступить Gemfile(или из значения по умолчанию, если оно не указано в Gemfile).

Для GEMнего перечислены все зависимости, которые вы прямо или косвенно вводите в Gemfile. remoteunder GEMсообщает, где взять драгоценные камни, которые указаны источником в Gemfile.

Если драгоценный камень не получен remote, PATHсообщает местоположение, чтобы найти его. PATHИнформация поступает от пути в Gemfileпри объявлении зависимости.

И PLATFORMот сюда .

Ведь DEPENDENCIESэто снимок зависимостей, разрешенных с помощью пакета.


0

Что означает восклицательный знак после названия драгоценного камня в группе «ЗАВИСИМОСТЬ»?

Восклицательный знак появляется, когда камень был установлен с использованием источника, отличного от « https://rubygems.org ».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.