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

После запуска команды 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!

Что описывают "PATH", "GEM", "PLATFORMS" и "DEPENDENCIES"? Все они требуются?

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

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

Ответ 1

Более подробную информацию об этом можно найти на веб-сайте поставщика (см. ниже для удобства):

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

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

Ответ 2

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

gem "foo", :git => "[email protected]:company/foo.git"

Ответ 3

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

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

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

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

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

GIT (необязательно)

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

  • remote: Git Remote. Например, [email protected]: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/

Ответ 4

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

В плагине 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, но и под DEPENDENCIES, но только в разработке. В производстве его вообще не будет. Однако, когда вы используете (2), вы увидите "июль" только в PATH, а не в DEPENDENCIES, но он будет отображаться, когда вы bundle install из производственной среды (то есть в каком-то другом драгоценном камне, который включает ваши в качестве зависимости), а не только развитие.

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

Ответ 5

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

Gemfile и Gemfile.lock - это первичные продукты, данные из драгоценных камней Bundler (сам Bundler - жемчужина).

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

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

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

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

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

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

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

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

Также можно обновить gem в Gemfile.lock, используя пакетное обновление.

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

Ответ 6

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

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

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

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

И PLATFORM из здесь.

Для DEPENDENCIES это снимок зависимостей, разрешенных в связке.

Ответ 7

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

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