使用bundler时,如何在Gemfile中使用gem?

时间:2020-11-30 00:19:33

When using bundler with a project in general and Rails specifically, you have access only to gems defined in your Gemfile. While this makes sense, it can be limiting. Mostly I find it limiting when I want to use a certain RSpec formatter that the rest of the team doesn't use. Unless it's in the Gemfile, it isn't accessible.

当一般使用带有项目的bundle和Rails时,你只能访问Gemfile中定义的gem。虽然这是有道理的,但它可能是有限的。当我想使用团队的其他成员不使用的某个RSpec格式化程序时,我发现它主要限制了它。除非它在Gemfile中,否则无法访问。

Any way around it or I have to add it to Gemfile?

任何方式或我必须将其添加到Gemfile?

Update: my problem wasn't Bundler but Spork. When running RSpec without Spork I had no problem of using whatever formatter I wanted.

更新:我的问题不是Bundler而是Spork。在没有Spork的情况下运行RSpec时,我没有使用任何格式化程序的问题。

Update #2: it looks like that using Bundler is still the cause of the problem. The difference between using Spork and not using Spork, is that when running RSpec without Spork, it loads the formatter before loading your project and getting into the Bundler "sandbox".

更新#2:看起来使用Bundler仍然是导致问题的原因。使用Spork和不使用Spork之间的区别在于,在没有Spork的情况下运行RSpec时,它会在加载项目并进入Bundler“sandbox”之前加载格式化程序。

With Bundler:

使用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>'

Without Bundler:

没有Bundler:

$ irb
>> require 'fivemat'
=> true

5 个解决方案

#1


10  

I assume that none of these answers have been chosen as correct because they don't do a great job of solving the problem: having additional gems that you can use that by default don't require any changes to files already in the repository to achieve. That is, you don't have to modify any files, and you don't have to live with remembering not to check in your local changes. Here's how I do it.

我认为这些答案中没有一个被选为正确的,因为它们没有很好地解决问题:拥有额外的宝石,你可以使用它默认情况下不需要对存储库中已有的文件进行任何更改来实现。也就是说,您不必修改任何文件,也不必记住不检查本地更改。我就是这样做的。

The idea is basically inverting the dependencies of Holger's answer, such that there's no need to modify the shared Gemfile. Bundler allows one to specify which file is to be used as the gemfile, but strangely the documented methods do not apparently work with its configuration file and will not be fixed. There is a somewhat obscured feature of Bundler that any of the configuration options can be set in an environment variable or passed on the command line. Running all of your commands as bundle [command] --gemfile [yourgemfile] or BUNDLE_GEMFILE="[yourgemfile]" bundle [command] will cause Bundler to read whatever gemfile you want it to. I highly recommend using the environment variable approach, and either creating an alias or exporting the variable for your current session, particularly as I was unable to use the command line switch with the "exec" command.

这个想法基本上颠倒了Holger的答案的依赖性,因此不需要修改共享的Gemfile。 Bundler允许指定哪个文件用作gemfile,但奇怪的是,记录的方法显然不能使用其配置文件,也不会被修复。 Bundler有一个模糊的功能,任何配置选项都可以在环境变量中设置或在命令行上传递。将所有命令作为bundle [command] --gemfile [yourgemfile]或BUNDLE_GEMFILE =“[yourgemfile]”bundle [command]运行将导致Bundler读取您想要的任何gemfile。我强烈建议使用环境变量方法,并为当前会话创建别名或导出变量,特别是因为我无法使用带有“exec”命令的命令行开关。

Therefore, I run rspec like this: BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename], and I have the first part of this aliased as bem in my bashrc. Works like a charm.

因此,我像这样运行rspec:BUNDLE_GEMFILE =“[mygemfile]”bundle exec rspec [filename],我把这个别名的第一部分作为bem放在我的bashrc中。奇迹般有效。

Then, you should setup your source control to ignore your Gemfile, either in the project's .gitignore or, to keep the project entirely hygienic without changing even its .gitignore, to your personal global ignore file (which is by default in ~/.config/git/ignore and has the same format as a project's gitignore file).

然后,你应该设置你的源代码控制来忽略你的Gemfile,无论是在项目的.gitignore中,还是为了让项目完全卫生而不改变它的.gitignore,你的个人全局忽略文件(默认情况下在〜/ .config中) / git / ignore,其格式与项目的gitignore文件相同。

One other thing to note is that Bundler will create a lockfile based on the Gemfile's name. This is super handy, as it keeps you from overwriting your project's Gemfile.lock if it's checked in, but you need to ignore this new lock file as well. If your gemfile is Foo.bar, look for Foo.bar.lock.

另外需要注意的是Bundler将根据Gemfile的名称创建一个锁文件。这非常方便,因为它可以防止你覆盖你的项目的Gemfile.lock,如果它已经签入,但你也需要忽略这个新的锁文件。如果您的gemfile是Foo.bar,请查找Foo.bar.lock。

Finally, you can do something similar to Holger's suggestion in your custom Gemfile:

最后,您可以在自定义Gemfile中执行与Holger建议类似的操作:

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

and you're good to go, as long as you remember to specify your Gemfile.

并且你很高兴,只要你记得指定你的Gemfile。

#2


14  

In ChiliProject we allow users to create a Gemfile.local which is included into the main Gemfile on load. This allows users to specify additional gems without having to change our Gemfile to ease updates.

在ChiliProject中,我们允许用户创建一个Gemfile.local,它在加载时包含在主Gemfile中。这允许用户指定其他宝石,而无需更改我们的Gemfile以简化更新。

For that, we have included the following code at the bottom of our 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

The Gemfile.local itself is excluded from the repository via .gitignore.

Gemfile.local本身通过.gitignore从存储库中排除。

#3


1  

You can use something like this in your Gemfile:

你可以在你的Gemfile中使用这样的东西:

gem 'foo' if ENV['ENABLE_FOO_GEM']

Then just set ENABLE_FOO_GEM in your environment.

然后在您的环境中设置ENABLE_FOO_GEM。

export ENABLE_FOO_GEM=1

The gem will be disabled by default, but easily turned on (permanently) by anyone who wants to use it.

默认情况下,gem将被禁用,但任何想要使用它的人都可以轻松打开(永久)。

#4


0  

In case you still decide to do this (horrible idea):

如果你仍然决定这样做(可怕的想法):

You can add ruby code to your Gemfile to load a ~/.gemfile (or such) if it exists.

您可以将ruby代码添加到Gemfile中以加载〜/ .gem文件(或类似文件)(如果存在)。

Something like:

就像是:

eval(IO.read('~/.gemfile'), binding) if FileTest.exists?("~/.gemfile")

#5


0  

Add to .gitignore

添加到.gitignore

Gemfile.local
Gemfile.local.lock

Add to the project a Gemfile.local.sample file with the following content:

使用以下内容向项目添加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


10  

I assume that none of these answers have been chosen as correct because they don't do a great job of solving the problem: having additional gems that you can use that by default don't require any changes to files already in the repository to achieve. That is, you don't have to modify any files, and you don't have to live with remembering not to check in your local changes. Here's how I do it.

我认为这些答案中没有一个被选为正确的,因为它们没有很好地解决问题:拥有额外的宝石,你可以使用它默认情况下不需要对存储库中已有的文件进行任何更改来实现。也就是说,您不必修改任何文件,也不必记住不检查本地更改。我就是这样做的。

The idea is basically inverting the dependencies of Holger's answer, such that there's no need to modify the shared Gemfile. Bundler allows one to specify which file is to be used as the gemfile, but strangely the documented methods do not apparently work with its configuration file and will not be fixed. There is a somewhat obscured feature of Bundler that any of the configuration options can be set in an environment variable or passed on the command line. Running all of your commands as bundle [command] --gemfile [yourgemfile] or BUNDLE_GEMFILE="[yourgemfile]" bundle [command] will cause Bundler to read whatever gemfile you want it to. I highly recommend using the environment variable approach, and either creating an alias or exporting the variable for your current session, particularly as I was unable to use the command line switch with the "exec" command.

这个想法基本上颠倒了Holger的答案的依赖性,因此不需要修改共享的Gemfile。 Bundler允许指定哪个文件用作gemfile,但奇怪的是,记录的方法显然不能使用其配置文件,也不会被修复。 Bundler有一个模糊的功能,任何配置选项都可以在环境变量中设置或在命令行上传递。将所有命令作为bundle [command] --gemfile [yourgemfile]或BUNDLE_GEMFILE =“[yourgemfile]”bundle [command]运行将导致Bundler读取您想要的任何gemfile。我强烈建议使用环境变量方法,并为当前会话创建别名或导出变量,特别是因为我无法使用带有“exec”命令的命令行开关。

Therefore, I run rspec like this: BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename], and I have the first part of this aliased as bem in my bashrc. Works like a charm.

因此,我像这样运行rspec:BUNDLE_GEMFILE =“[mygemfile]”bundle exec rspec [filename],我把这个别名的第一部分作为bem放在我的bashrc中。奇迹般有效。

Then, you should setup your source control to ignore your Gemfile, either in the project's .gitignore or, to keep the project entirely hygienic without changing even its .gitignore, to your personal global ignore file (which is by default in ~/.config/git/ignore and has the same format as a project's gitignore file).

然后,你应该设置你的源代码控制来忽略你的Gemfile,无论是在项目的.gitignore中,还是为了让项目完全卫生而不改变它的.gitignore,你的个人全局忽略文件(默认情况下在〜/ .config中) / git / ignore,其格式与项目的gitignore文件相同。

One other thing to note is that Bundler will create a lockfile based on the Gemfile's name. This is super handy, as it keeps you from overwriting your project's Gemfile.lock if it's checked in, but you need to ignore this new lock file as well. If your gemfile is Foo.bar, look for Foo.bar.lock.

另外需要注意的是Bundler将根据Gemfile的名称创建一个锁文件。这非常方便,因为它可以防止你覆盖你的项目的Gemfile.lock,如果它已经签入,但你也需要忽略这个新的锁文件。如果您的gemfile是Foo.bar,请查找Foo.bar.lock。

Finally, you can do something similar to Holger's suggestion in your custom Gemfile:

最后,您可以在自定义Gemfile中执行与Holger建议类似的操作:

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

and you're good to go, as long as you remember to specify your Gemfile.

并且你很高兴,只要你记得指定你的Gemfile。

#2


14  

In ChiliProject we allow users to create a Gemfile.local which is included into the main Gemfile on load. This allows users to specify additional gems without having to change our Gemfile to ease updates.

在ChiliProject中,我们允许用户创建一个Gemfile.local,它在加载时包含在主Gemfile中。这允许用户指定其他宝石,而无需更改我们的Gemfile以简化更新。

For that, we have included the following code at the bottom of our 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

The Gemfile.local itself is excluded from the repository via .gitignore.

Gemfile.local本身通过.gitignore从存储库中排除。

#3


1  

You can use something like this in your Gemfile:

你可以在你的Gemfile中使用这样的东西:

gem 'foo' if ENV['ENABLE_FOO_GEM']

Then just set ENABLE_FOO_GEM in your environment.

然后在您的环境中设置ENABLE_FOO_GEM。

export ENABLE_FOO_GEM=1

The gem will be disabled by default, but easily turned on (permanently) by anyone who wants to use it.

默认情况下,gem将被禁用,但任何想要使用它的人都可以轻松打开(永久)。

#4


0  

In case you still decide to do this (horrible idea):

如果你仍然决定这样做(可怕的想法):

You can add ruby code to your Gemfile to load a ~/.gemfile (or such) if it exists.

您可以将ruby代码添加到Gemfile中以加载〜/ .gem文件(或类似文件)(如果存在)。

Something like:

就像是:

eval(IO.read('~/.gemfile'), binding) if FileTest.exists?("~/.gemfile")

#5


0  

Add to .gitignore

添加到.gitignore

Gemfile.local
Gemfile.local.lock

Add to the project a Gemfile.local.sample file with the following content:

使用以下内容向项目添加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