Bundler просто великолепен, поэтому он стал де-факто менеджером пакетов и зависимостей для приложений на Ruby. Я использовал npm и golang vendoring и другие менеджеры языковых зависимостей, но ни один из них даже не может удержать свечу от той простоты, которую предлагает Bundler.
Как я уверен, вы знаете, в основе доброты Бундлера лежит Gemfile . Gemfile содержит список драгоценных камней, которые необходимы нашему приложению для выполнения своей работы. Если вы похожи на меня, я научился использовать Gemfile и Bundler из различных руководств по Rails (и другим). Я видел, как люди печатали
gem "a_gem"
Затем запустите bundle install
Эти два шага настолько очевидны, что мне никогда не удавалось исследовать намного больше. Не говоря уже о том, что Бандлер был такой находкой после многих лет продаж зависимостей и других крайне неприятных подходов. разглагольствовать о старых днях и о том, как легко вы, бунтовщики, имеете это сейчас
После первоначальных руководств по Bundler для слепого следования пошаговым инструкциям я выбрал другие параметры Gemfile, такие как group
path
github
Однако на днях я решил прочитать документы Bundler, в частности, о Gemfile, и был поражен всеми вариантами, которые я не использовал. Я научился нескольким вещам, поэтому решил, что другие тоже могут.
В сегодняшнем посте я собираюсь найти варианты в Gemfile. Здесь действительно нет ничего, что вы не могли бы увидеть в превосходной документации Bundler, но вы этого не читали, не так ли ??? разглагольствовать о том, почему мы не можем иметь хорошие вещи
Основы
Всегда хорошее место для начала, это то, что вы, вероятно, уже знаете.
Источник
В верхней части всех Gemfiles есть строка вроде этой:
source "https://rubygems.org"
Эта строка указывает Bundler использовать сайт Rubygems в качестве единственного источника для всех драгоценных камней, перечисленных здесь. Вот что вы можете не знать:
- Вы можете иметь несколько строк
source
обратном порядке, в котором они перечислены. Мне это не очень нравится, но оно есть. - Если вы используете частный гем-сервер, вам нужно установить имя пользователя и пароль, используя
source
Не кладите его в GEMFILE, потому что он окажется на Github, и тогда ваши личные жемчужины станут открытыми, и наступит хаос. - Хорошо, вы можете поместить пользователя и пароль в сам URL (
bundle config
В любом случае, ты собираешься это сделать? разглагольствовать о том, что молодые люди никогда не слушают
Драгоценные камни
Правильно. Мы все знаем, как указать драгоценный камень в Gemfile, верно?
https://user:[email protected]
Эта линия будет тянуть в последней версии драгоценного камня. Очевидно, вы должны заблокировать свои зависимости для версий, которые, как вы знаете, работают с вашим приложением. Есть несколько способов указать версии гемов:
- Используйте конкретную версию:
gem "name-of-gem"
Вы можете найти конкретные версии на Rubygems.org (при условии, что это
gem "name-of-gem", "1.0"
выполнив поиск вашего драгоценного камня и просмотрев перечисленные «Версии». - Используйте оператор версии:
source
Это тянет в любой драгоценный камень, который после 1.0. - Используйте этот странный оператор squiggly-stabby:
gem "name-of-gem", ">1.0"
Этот оператор, который некоторые называют «тиддл-чёрт», в основном говорит «любая версия больше этой, но меньше следующей незначительной ревизии». Поскольку я уверен, что вы знаете, что такое семантическое управление версиями , мне не нужно объяснять, что второстепенная версия — это второе число. В этом примере это означает «любая версия больше или равна 1,3, но меньше 1,4». Он также работает с основными версиями, поэтомуgem "name-of-gem", "~>1.3"
~>1
2
~>1.0.rc.1
- Используйте составное требование:
1.0.rc
Здесь мы хотим конкретную версию, но все в порядке с более новыми незначительными выпусками Никто не делает это.
группы
Bundler позволяет вам распределить ваши зависимости в разные группы. Это чаще всего используется для установки в среду разработки других драгоценных камней, чем те, которые установлены в производственной среде. Вы можете указать группы для драгоценного камня в той же строке, что и драгоценный камень, или поместив драгоценный камень в gem "name-of-gem", "~>2.2", ">=2.2.1"
group
Затем вы можете избежать установки определенной группы (или групп) в определенную среду, используя gem "my-dev-tool", group: :development
group :development, :test do
gem "my-test-tool"
end
--without
bundle install
Редкие Находки
Давайте поговорим о других вариантах указания драгоценных камней, которые вы могли видеть или не видеть, но, вероятно, не совсем понятны. По крайней мере, я так к ним отношусь.
платформы
Платформы позволяют сообщать Bundler об установке гема для конкретной версии Ruby. Платформы в основном являются группами, но Bundler выполняет установку (или не установку) гемов на основе вашей текущей версии Ruby. Доступные платформы перечислены здесь. Вот как вы используете это:
gem "my-java-gem", platform: jruby
Если я bundle
my-java-gem
install_if
Другой способ контролировать установку гема — это install_if
Передача proc или лямбда-выражения с логическим значением (что означает «правдивый» или «ложный») будет контролировать установку драгоценных камней в блоке. Из документов:
install_if -> { RUBY_PLATFORM =~ /darwin/ } do
gem "pasteboard"
end
Возможно, у вас есть другая переменная окружения, которая определяет, устанавливаете ли вы какой-нибудь драгоценный камень или драгоценные камни. Я не могу говорить разумно о том, почему вы делаете вещи, все, что я могу сделать, это показать вам инструменты.
требовать
Если вы когда-либо видели ключевое слово require
gem "rspec", require: "spec"
Это означает, что имя драгоценного камня и имя, по которому вам требуется драгоценный камень, различны. Видите ли, когда что-то вызывает Bundler.require
Итак, в примере вы хотите, чтобы он require "spec"
require "rspec"
Также иногда мы видим такую строку:
gem 'rspec', require: false
Это говорит Bundler не требовать rspec
Bundler.require
Например, Rails вызовет Bundler.require
Bundler по умолчанию установит все гемы в Gemfile и загрузит их в память. Если мы не хотим загружать определенный гем (возможно, потому что мы будем делать это динамически из нашего кода), мы можем установить для ключевого слова require значение false.
Переопределить источник
Я упомянул ключевое слово source
source
Это может быть сделано на основе одного драгоценного камня или для нескольких драгоценных камней в блоке:
gem "a-gem", source: "https://my-private-gem-server.com"
source "https://my-private-gem-server.com" do
gem "a-gem"
gem "b-gem"
end
Гит
Другой, более распространенный способ переопределить источник гемов — использовать параметры git
github
path
Когда вы извлекаете гем непосредственно из git, нужно просто указать путь к хранилищу:
gem "my-git-gem", git: "https://github.com/me/my-git-gem.git"
У вас должен быть доступ к репо, поэтому он должен быть общедоступным, в вашей сети и т. Д. Синтаксис блока также работает, если ваш репозиторий git имеет более одной gemspec:
git "http://github.com/me/many_gems.git" do
gem "a-gem"
gem "b-gem"
end
Кстати, эти репозитории должны иметь файлы .gemspec
В противном случае вы должны предоставить версию:
gem "my-git-gem-with-on-spec", "0.1", git: "https://github.com/me/my-git-gem-with-no-spec.git"
Что если вы хотите добавить ветку, тег или конкретный коммит? Bundler позволяет вам использовать параметры branch
tag
ref
gem "my-git-gem", git: "https://github.com/me/my-git-gem.git", branch: "the_new_stuff"
gem "my-git-gem", git: "https://github.com/me/my-git-gem.git", tag: "1.0.rc2"
gem "my-git-gem", git: "https://github.com/me/my-git-gem.git", ref: "5acdb"
Кстати, опция ref
Наконец, если вы используете git-репозиторий, в котором есть множество субмодулей (люди так делают?), Существует логическая опция submodule
gem "my-gem-of-submodules", git: "https://github.com/me/my-gem-of-submodules.git", submodules: true
Пользовательские источники Git
Как выяснилось, вы можете определить собственные источники git. Bundler предоставляет 3 исходных git-источника: github
bitbucket
gist
Это обеспечивает довольно классное сокращение:
gem "my-git-gem", github: "me/my-git-gem.git"
Просто укажите путь к репо на Github (или Bitbucket). Что если владелец (или организация) имеет то же имя, что и хранилище git? Это становится еще меньше:
gem "rails", github: "rails" # Works b/c the repo is https://github.com/rails/rails.git
Все параметры, которые работают для исходного кода git
Кстати, опция github
git
Если ваши репозитории на Github являются частными, вы можете создать токен личного доступа и использовать его в Gemfile:
gem "my-private-gem", git: "https://<the_token>:[email protected]/me/my-private-gem.git"
Это облегчает использование частных git-репозиториев, но размещение вашего токена в Gemfile — это путь к катастрофе. Чтобы обеспечить безопасность вашего токена, установите переменную окружения ( GITHUB_TOKEN
git
gem "my-private-gem", git: "https://#{ENV['GITHUB_TOKEN']}:[email protected]/me/my-private-gem.git"
bundle config
С большой любовью к этой сути, для того, чтобы сначала показать это мне. К сожалению, все еще существует проблема с этим подходом, так как он запишет токен в файл Gemfile.lock , который, вероятно, находится под контролем исходного кода. Так что мы можем сделать?
Существует также способ использовать gem "my-private-gem", git: "https://github.com/me/my-private-gem.git"
Если вы измените строку в вашем Gemfile на:
bundle config github.com <the_token>
а потом беги
~/.bundle/config
Bundler будет использовать токен для доступа к github от вашего имени. Итак, все ваши личные репо будут доступны. Кстати, это записывает значения в gem "gist-gem", gist: "e0bef10af2e0f9bb2ed703c721ca9d29"
Хммм … может быть, мне нужно сделать еще одну статью, которая погружается в CLI Bundler. разглагольствовать о том, что моя работа никогда не делается
Суть
Я никогда не использовал Gist в качестве источника драгоценных камней, поэтому я не был полностью уверен, как он работает. Я сделал один, чтобы понять это:
git_source(:stash){ |repo_name| "https://stash.corp.acme.pl/#{repo_name}.git" }
gem "rails", :stash => "forks/rails"
Это работает. Пока это. Я понятия не имею, почему кто-то сделал бы это. Но я тоже не получаю MySpace.
Наконец, вы можете создавать собственные источники git для других git-серверов, таких как Github Enterprise Server, Bitbucket Server (формально Stash) или других источников. Вот пример из документации:
path
Путь
Если у вас есть гем, который вы разрабатываете локально, вы можете добавить его в свой пакет с помощью опции gem "mine-mine-all-mine", path: "~/my-gems/mine-mine-all-mine"
path "~/my-gems" do
gem "mine-mine-all-mine"
gem "acts-as-myspace"
end
Конечно, есть опция блока:
ruby "~>2.1"
Версия Ruby
Можно указать версию Ruby и интерпретатор (или движок), которые требуются вашему приложению. Например, если вы связаны с Ruby 2.1 или выше, но не хотите предполагать, что 2.2 в порядке, поместите это в верхнюю часть вашего Gemfile:
ruby "~>2.1", engine: "jruby", engine_version: "9.0.3.0"
Эта версия, очевидно, относится к МРТ по умолчанию. Что делать, если вы хотите захватить JRuby?
ruby
Это означает, что вам нужен JRuby 9000. Ключевое слово patchlevel
Кстати, если я когда-нибудь отправлю патч, это будет nicotine
adams
eye
Некоторые менеджеры версий, такие как RVM, также читают директиву Ruby и устанавливают соответствующую версию Ruby, чтобы Bundler никогда не жаловался, что мы используем другую версию Ruby.
Все сделано
Итак, это все. Bundler Gemfile дистиллированный. Кто знал, что в Gemfile так много вариантов установки гемов? Я этого не сделал, поэтому эти усилия научили меня новым вещам и подтвердили мою любовь к Бандлеру, лучшему менеджеру по зависимостям в мире. Я надеюсь, вы тоже чему-то научились.
Вот вам вопрос: я что-то пропустил? Любые другие уловки, которые мы должны включить сюда? Что молодые люди делают с Bundler в эти дни?
Я хотел бы искренне поблагодарить Энрике Гонсалеса и Фреда Хита за рецензирование этой статьи. Несмотря на молодость, они очень полезные члены общества.