capistrano / bundler

Bundler support for Capistrano 3.x
MIT License
219 stars 83 forks source link

How can I set bundle_without option based on role? #117

Closed masa-ekohe closed 4 years ago

masa-ekohe commented 4 years ago

I don't want to install a certain gem in the specific hosts. How could I achieve that?

versions: Ruby 2.5.3 Capistrano 3.7.1 Capistrano-bundler 1.2.0

I tried the code below to specify without option based on role but it seems to be specified for the other hosts too.

Gemfile.rb

group :foo do
  gem 'foo'
end

deploy.rb

role :app, %w(huga.com)

task :without_foo do
  on roles(:app) do
    set :bundle_without, %w{development test foo}.join(' ')
  end
end
before 'bundler:install', :without_foo

results(bundle --without development test foo is executed for the other host too)

...
** Invoke deploy:updated (first_time)
** Invoke bundler:install (first_time)
** Invoke without_foo (first_time)
** Execute without_foo
** Execute bundler:install
00:21 bundler:install
      01 /usr/local/rvm/bin/rvm 2.5.3@my_app_staging do bundle install --path /var/www/staging/my_app/shared/bundle --without development test foo --deployment --quiet
    ✔ 01 me@huga.com 2.071s
    ✔ 01 me@huga2.com 2.007s
...
mattbrictson commented 4 years ago

Hi, good question.

In Capistrano, set is global, so calling it will affect Capistrano regardless of the role context where it is called. To my knowledge there is no way to accomplish per-host or per-role settings in Capistrano.

So the short answer is that Capistrano wasn't really designed to do what you are asking.

Your best bet might be to rewrite the bundler:install task to get the behavior you want.

Alternatively, you could set :bundle_without to nil and manage it via bundle config instead. In other words, on role A run a task that does bundle config without ..., and on role B run a different task that runs bundle config without .... That way you are configuring each role with a different set of Bundler config. When you later run bundle install, it should respect that config.

Here are the Bundler docs on bundle config: https://bundler.io/v2.0/man/bundle-config.1.html

Hope that helps!

masa-ekohe commented 4 years ago

@mattbrictson

Thank you. This is very helpful. I made it work by overriding bundler:install as you suggested.

Alternatively, you could set :bundle_without to nil and manage it via bundle config instead. In other words, on role A run a task that does bundle config without ..., and on role B run a different task that runs bundle config without .... That way you are configuring each role with a different set of Bundler config. When you later run bundle install, it should respect that config.

I never thought about it. This is smart.