Понимание файла 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!
Что описывают "ПУТЬ", "ДЖЕМ", "ПЛАТФОРМЫ" и "ЗАВИСИМОСТЬ"? Все ли они необходимы?
Что должно содержать поддирективы "remote" и "specs"?
Что означает восклицательный знак после названия драгоценного камня в группе "ЗАВИСИМОСТЬ"?
7 ответов
Вы можете узнать больше об этом на веб-сайте комплектующих (для вашего удобства добавлен ниже):
После некоторой разработки приложения проверьте приложение вместе со снимком Gemfile и Gemfile.lock. Теперь в вашем репозитории есть запись точных версий всех драгоценных камней, которые вы использовали в последний раз, когда вы точно знали, что приложение работало...
Это важно: Gemfile.lock делает ваше приложение единым пакетом как вашего собственного кода, так и стороннего кода, который он запускал в последний раз, когда вы точно знали, что все работает. Указание точных версий стороннего кода, от которого вы зависите, в вашем Gemfile не даст такой же гарантии, потому что гемы обычно объявляют диапазон версий для своих зависимостей.
Последние несколько месяцев я много возился с Gemfiles и Gemfile.locks, создавая инструмент автоматического обновления зависимостей 1. Ниже далеко не все, но это хорошая отправная точка для понимания формата Gemfile.lock. Вы также можете проверить исходный код парсера файла блокировки Bundler.
Вы найдете следующие заголовки в файле блокировки, сгенерированном Bundler 1.x:
GEM (необязательно, но очень часто)
Это зависимости, полученные из сервера Rubygems. Это может быть основной индекс Rubygems на Rubygems.org или пользовательский индекс, например, доступный в Gemfury и других. В этом разделе вы увидите:
remote:
одна или несколько строк, указывающих расположение индекса (ов) Rubygemsspecs:
список зависимостей с указанием номера версии и ограничений на любые подчиненные зависимости
GIT (необязательно)
Это зависимости, полученные из данного git remote. Вы увидите разные разделы для каждого удаленного git, и внутри каждого раздела вы увидите:
remote:
Git Remote. Например,git@github.com:rails/rails
revision:
ссылка коммита, к которой заблокирован Gemfile.locktag:
(необязательно) тег, указанный в Gemfilespecs:
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 указана в .ruby_version
файл, вместо этого этот раздел не будет представлен (так как Bundler будет рассматривать Gemfile / Gemfile.lock независимо от версии Ruby установщика).
ОБЪЕДИНЕНО (Bundler >= v1.10.x)
Версия Bundler, использованная для создания Gemfile.lock. Используется для напоминания установщикам обновить их версию Bundler, если она старше, чем версия, создавшая файл.
ИСТОЧНИК ПЛАГИНА (необязательно и очень редко)
Теоретически, Gemfile может указывать плагины Bundler, а также гемы 3, которые затем будут перечислены здесь. На практике я не знаю ни о каких доступных плагинах, по состоянию на июль 2017 года. Эта часть Bundler все еще находится в активной разработке!
Что касается восклицательного знака, я только что узнал, что это на драгоценных камнях, полученных через :git
например,
gem "foo", :git => "git@github.com:company/foo.git"
Bundler - менеджер Gem, который обеспечивает согласованную среду для проектов Ruby, отслеживая и устанавливая точные гемы и версии, которые необходимы.
Gemfile и Gemfile.lock являются основными продуктами, предоставляемыми Bundler gem (сам Bundler является самоцветом).
Gemfile содержит зависимость вашего проекта от драгоценных камней, которые вы упоминаете вручную с указанными версиями, но эти экземпляры этих драгоценных камней зависят от других драгоценных камней, которые автоматически разрешаются компоновщиком.
Gemfile.lock содержит полный снимок всех драгоценных камней в Gemfile и связанных с ними зависимостей.
Когда вы в первый раз вызываете пакетную установку, он создает этот Gemfile.lock и использует этот файл во всех последующих вызовах для пакетной установки, что гарантирует, что у вас установлены все зависимости, и пропустит установку зависимостей.
То же самое происходит, когда вы делитесь своим кодом на разных машинах
Вы делитесь своим Gemfile.lock вместе с Gemfile. Когда вы запускаете bundle install на другом компьютере, он ссылается на ваш Gemfile.lock и пропускает шаг разрешения зависимостей, вместо этого он установит все те же самые зависимые гемы, которые вы использовали на оригинальная машина, которая поддерживает согласованность на нескольких машинах
Почему мы должны поддерживать согласованность на нескольких машинах?
Запуск разных версий на разных машинах может привести к повреждению кода
Предположим, ваше приложение использовало версию 1.5.3 и оно работает 14 месяцев назад.
без проблем, и вы пытаетесь установить на другую машину
без Gemfile.lock теперь вы получаете версию 1.5.8. Может быть, это сломано с последней версией некоторых драгоценных камней, и ваше приложение будет
потерпеть поражение. Поддержание согласованности имеет первостепенное значение (предпочтительно
практика).
Также возможно обновить gem в Gemfile.lock с помощью обновления пакета.
Это основано на концепции консервативного обновления
Мне кажется, что PATH перечисляет зависимости первого поколения непосредственно из вашей gemspec, тогда как GEM перечисляет зависимости второго поколения (то есть от чего зависят ваши зависимости) и те из вашего Gemfile. PATH::remote is .
потому что он полагался на локальную 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, но и в ЗАВИСИМОСТИ, но только в развитии. В производстве его не будет вообще. Однако, когда вы используете (2), вы увидите "июль" только в PATH, а не в ЗАВИСИМОСТИ, но оно будет отображаться, когда вы bundle install
из производственной среды (то есть в какой-то другой драгоценный камень, который включает в себя ваш в качестве зависимости), а не только разработки.
Это всего лишь мои наблюдения, и я не могу полностью объяснить, почему так происходит, но я приветствую дальнейшие комментарии.
Кажется, нет четкого документа, говорящего о Gemfile.lock
формат. Может это потому что Gemfile.lock
просто используется внутри пакета.
Тем не менее, так как Gemfile.lock
это снимок Gemfile
Это означает, что вся информация должна поступать Gemfile
(или из значения по умолчанию, если не указано в Gemfile
).
За GEM
, в нем перечислены все зависимости, которые вы вводите прямо или косвенно в Gemfile
, remote
под GEM
говорит, где взять драгоценные камни, которые указаны источником в Gemfile
,
Если драгоценный камень не получен из remote
, PATH
говорит местоположение, чтобы найти его. PATH
Информация приходит с пути в Gemfile
когда вы объявляете зависимость.
А также PLATFORM
отсюда
За DEPENDENCIES
, это снимок зависимостей, разрешенных с помощью пакета.
Что означает восклицательный знак после названия драгоценного камня в группе "ЗАВИСИМОСТЬ"?
Восклицательный знак появляется, когда камень был установлен с использованием источника, отличного от " https://rubygems.org/".