Вопрос по ruby, bundler, rubygems – Как использовать гемы не в Gemfile при работе с bundler?

21

При использовании bundler с проектом в целом и Rails в частности, вы имеете доступ только к гемам, определенным в вашем Gemfile. Хотя это имеет смысл, оно может быть ограничивающим. В основном я нахожу это ограничивающим, когда я хочу использовать определенный форматер RSpec, который не использует остальная часть команды. Если он не находится в Gemfile, он недоступен.

Любой способ обойти это, или я должен добавить его в Gemfile?

Обновление: моя проблема была не в Bundler, а в Spork. Когда я запускал RSpec без Spork, у меня не было проблем с использованием любого желаемого форматера.

Обновление № 2: похоже, что использование Bundler все еще является причиной проблемы. Разница между использованием Spork и отсутствием Spork заключается в том, что при запуске RSpec без Spork он загружает средство форматирования перед загрузкой проекта и попаданием в Bundler & quot; песочницу & quot ;.

С Bundler:

$ bundle exec irb
>> require 'fivemat'
LoadError: cannot load such file -- fivemat

from (irb):1:in `require'
from (irb):1
from /Users/arikfr/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'

Без Бандлера:

$ irb
>> require 'fivemat'
=> true
Проблема с OS X / Linux может быть решена в Gemfile путем проверки платформы Rubygithub.com/carlhuda/bundler/issues/663#issuecomment-2849045 Peter Brown
Почему вы не добавляете FiveMat в свой gemfile? Peter Brown
"В основном я нахожу это ограничивающим, когда я хочу использовать определенный форматер RSpec, который остальная часть команды не использует". вот почему. Также иногда я хочу использовать гемы, которые поддерживаются в OS / X, но не поддерживаются в Ubuntu (и наоборот). arikfr
@ Beerlington, но это только позволит избежать этого. Я вообще не хочу его устанавливать. И вообще, я не хочу загрязнять Gemfile вещами, которыеI Нужна в разработке, а остальная часть команды нет. arikfr

Ваш Ответ

5   ответов
15

ВChiliProject мы позволяем пользователям создаватьGemfile.local который входит в основнойGemfile в процессе. Это позволяет пользователям указывать дополнительные драгоценные камни без необходимости менять нашиGemfile чтобы облегчить обновления.

Для этого мы включили следующий кодв нижней части нашего Gemfile.

gemfile_local = File.expand_path('Gemfile.local', __dir__)
if File.readable?(gemfile_local)
  puts "Loading #{gemfile_local}..." if $DEBUG
  instance_eval(File.read(gemfile_local))
end

Gemfile.local сам исключен из хранилища через.gitignore.

хорошее, элегантное решение!
Это отлично сработало для меня! Это должен быть принятый ответ. :)
Мне интересно узнать о возможных последствиях такого подхода, когдаGemfile.lock отслеживается системой контроля версий. Один заканчивается спецификациями вGemfile.lock это не обязательно относится к другим разработчикам "Gemfiles. Я догадываюсь, что Бандлер может разумно устранить эти несоответствия, не вызывая каких-либо реальных проблем, но меня беспокоит, чтоGemfile/.lock потенциально может быть не синхронизирован друг с другом.
В этом решенииGemfile.lock зависит отGemfile.localтак что это не будет работать хорошо для проектов, гдеGemfile.lock отслеживается VCS.
0

На случай, если вы все-таки решите сделать это (ужасная идея):

Вы можете добавить код ruby в свой Gemfile, чтобы загрузить ~ / .gemfile (или такой), если он существует.

Что-то вроде:

eval(IO.read('~/.gemfile'), binding) if FileTest.exists?("~/.gemfile")
У меня тоже были похожие мысли, я не могу просто: require_relative & apos; ~ / .gemfile & apos; вместо eval? arikfr
0

добавить в.gitignore

Gemfile.local
Gemfile.local.lock

Добавить в проектGemfile.local.sample файл со следующим содержанием:

# Include gems that are note meant to be part of the project but for development purposes
# That's why Gemfile.local and Gemfile.local.lock must be git-ignored

# To use these gems:
#   1. Create a "Gemfile.local" file (at same level of "Gemfile")
#   2. Prepend "BUNDLE_GEMFILE=Gemfile.local" before "bundle install" or "bundle exec rails c" and so forth.

eval_gemfile "./Gemfile"

group :development, :test do
  # Suggested gems
  gem "awesome_print", require:"ap"
  gem "hirb"
  gem "pry"
  gem "pry-byebug"
  gem "pry-rails"
  gem "meta_request"

  # My gems
  gem "fivemat"
end
1

Вы можете использовать что-то вроде этого в вашем Gemfile:

gem 'foo' if ENV['ENABLE_FOO_GEM']

Затем просто установите ENABLE_FOO_GEM в вашей среде.

export ENABLE_FOO_GEM=1

Драгоценный камень будет отключен по умолчанию, но легко включается (постоянно) любым, кто захочет его использовать.

10

Я предполагаю, что ни один из этих ответов не был выбран как правильный, потому что они не делают большую работу по решению проблемы: наличие дополнительных драгоценных камней, которые вы можете использовать,by default не требовать внесения каких-либо изменений в файлы, уже находящиеся в хранилище. То есть вам не нужно изменять какие-либо файлы, и вам не нужно мириться с тем, чтобы не регистрировать свои локальные изменения. Вот как я это делаю.

Идея в основном заключается в инверсии зависимостей ответа Хольгера, так что нет необходимости изменять общий Gemfile. Bundler позволяет указатькакой файл будет использоваться в качестве gemfile, но странно документированные методывидимо не работает с его конфигурационным файлом и не будет исправлен, В Bundler есть несколько скрытая особенность, заключающаяся в том, что любой из параметров конфигурации может быть установлен в переменной среды или передан в командной строке. Выполнение всех ваших команд какbundle [command] --gemfile [yourgemfile] или жеBUNDLE_GEMFILE="[yourgemfile]" bundle [command] заставит Bundler читать любой гемфайл, который вы хотите. Я настоятельно рекомендую использовать подход с использованием переменных среды и либо создать псевдоним, либо экспортировать переменную для текущего сеанса, особенно потому, что я не смог использовать переключатель командной строки с параметром & quot; exec & quot; команда.

Поэтому я запускаю rspec так:BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename]и у меня есть первая часть этого псевдонима какbem в моем башрч. Работает как шарм.

Затем вы должны настроить свой исходный элемент управления так, чтобы он игнорировал ваш Gemfile, либо в .gitignore проекта, либо чтобы проект оставался полностью гигиеничным, даже не заменяя его .gitignore, на ваш личный файл глобального игнорирования (который по умолчанию находится в~/.config/git/ignore и имеет тот же формат, что и файл gitignore проекта).

Следует также отметить, что Bundler создаст файл блокировки на основе имени Gemfile. Это очень удобно, так как не позволяет перезаписывать Gemfile.lock вашего проекта, если он зарегистрирован, но вам также нужно игнорировать этот новый файл блокировки. Если ваш гемфайлFoo.bar, ИщуFoo.bar.lock.

Наконец, вы можете сделать что-то похожее на предложение Хольгера в своем пользовательском Gemfile:

source "http://rubygems.org"
gem "fivemat"
instance_eval(File.read(File.dirname(__FILE__) + "/Gemfile"))

и вы готовы идти вперед, если не забыли указать свой Gemfile.

Я создалthis repo который вы можете раскошелиться и клонировать в каталогwithin ваше приложение, чтобы получить большую часть этой функциональности.
Вы можете обновить Gemfile.lock (в отличие от Foo.bar.lock) сbundle --gemfile Gemfile
Я также хотел бы указать вам на мерзавцаexclusions, которые похожи на игнорируемые файлы, за исключением того, что они не записывают, что игнорируют их. Чтобы исключить файл, специфичный для репозитория, укажите путь к нему в<repo>/.git/info/excludeтак же, как вы бы в.gitignore файл.
Этот подход является наилучшим из известных мне, но, к сожалению, не сохраняет версии gem во включенном Gemfile's Gemfile.lock. Я хотел бы видеть решение, которое сделало.

Похожие вопросы