Bundle deployment only for selected gems

2019-09-09 16:54发布

问题:

I would like to run bundle --deployment only for one group of gems that are not provided by the system. I've tried using --with=group but it started doing for all gems in the Gemfile

回答1:

Bundler's --with option works a bit different than what you're expecting. Let's first look at the bundle install man page for --without and --with options:

--without=<list>

A space-separated list of groups referencing gems to skip during installation. If a group is given that is in the remembered list of groups given to --with, it is removed from that list. This is a remembered option.

--with=<list>

A space-separated list of groups referencing gems to install. If an optional group is given it is installed. If a group is given that is in the remembered list of groups given to --without, it is removed from that list. This is a remembered option.

It is important to note that --with is not just the inverse of --without (although a --with group does cancel out a previously-remembered --without group and vice versa), it supports an entirely different feature (one implemented more recently, around mid-2015), the (backwards-compatible) concept of an "optional group", which only applies to groups explicitly marked with the optional => true parameter.

Importantly, the --with implementation does not exclude gems from either the default group or any other group not specified by --without.

So you have two options for restricting your installation to just a single group of gems:

  1. Whitelist using --with by marking all groups as "optional groups" (using :optional => true parameter) and passing the group(s) you wish to install to --with, leaving all other optional groups excluded.
  2. Blacklist using --without by passing all groups you do not wish to install to --without.

Unfortunately, neither option is able to prevent gems in the "default group" (gems not assigned to a group explicitly) from being installed, so you must place all gems you ever want to potentially exclude in some group.

The following Gemfile example should help clarify:

gem "rack" # Always installed; impossible to exclude

group :group, :optional => true do
  gem "thin" # Not installed by default; install using --with=group
end
group :another_group, :optional => true do
  gem "wirble" # Not installed by default; install using --with=another_group
end
group :third_group do
  gem "activesupport", "2.3.5" # Installed by default; exclude using --without=third_group
end