diff --git a/README.md b/README.md index f0d7b678..c0826e06 100644 --- a/README.md +++ b/README.md @@ -72,12 +72,13 @@ Configurable options: ```ruby set :bundle_roles, :all # this is default +set :bundle_config, { deployment: true } # this is default set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } # this is default set :bundle_binstubs, -> { shared_path.join('bin') } # default: nil set :bundle_gemfile, -> { release_path.join('MyGemfile') } # default: nil -set :bundle_path, -> { shared_path.join('bundle') } # this is default. set it to nil for skipping the --path flag. +set :bundle_path, -> { shared_path.join('bundle') } # this is default. set it to nil to use bundler's default path set :bundle_without, %w{development test}.join(' ') # this is default -set :bundle_flags, '--deployment --quiet' # this is default +set :bundle_flags, '--quiet' # this is default set :bundle_env_variables, {} # this is default set :bundle_clean_options, "" # this is default. Use "--dry-run" if you just want to know what gems would be deleted, without actually deleting them set :bundle_check_before_install, true # default: true. Set this to false to bypass running `bundle check` before executing `bundle install` @@ -96,19 +97,18 @@ To generate binstubs on each deploy, set `:bundle_binstubs` path: set :bundle_binstubs, -> { shared_path.join('bin') } ``` -In the result this would execute the following bundle command on all servers +In the result this would execute the following bundle commands on all servers (actual paths depend on the real deploy directory): ```sh -$ bundle install \ - --binstubs /my_app/shared/bin \ - --gemfile /my_app/releases/20130623094732/MyGemfile \ - --path /my_app/shared/bundle \ - --without development test \ - --deployment --quiet +$ bundle config --local deployment true +$ bundle config --local gemfile /my_app/releases/20130623094732/MyGemfile +$ bundle config --local path /my_app/shared/bundle +$ bundle config --local without "development test" +$ bundle install --quiet --binstubs /my_app/shared/bin ``` -If any option is set to `nil` it will be excluded from the final bundle command. +If any option is set to `nil` it will be excluded from the final bundle commands. If you want to clean up gems after a successful deploy, add `after 'deploy:published', 'bundler:clean'` to config/deploy.rb. diff --git a/lib/capistrano/tasks/bundler.cap b/lib/capistrano/tasks/bundler.cap index 3bb7e7f1..48ecf9da 100644 --- a/lib/capistrano/tasks/bundler.cap +++ b/lib/capistrano/tasks/bundler.cap @@ -1,9 +1,39 @@ +require "shellwords" + namespace :bundler do desc <<-DESC - Install the current Bundler environment. By default, gems will be \ - installed to the shared/bundle path. Gems in the development and \ - test group will not be installed. The install command is executed \ - with the --deployment and --quiet flags. + Configure the Bundler environment for the release so that subequent + `bundle check`, `bundle install`, `bundle clean`, and `bundle exec` + commands all behave consistently. The following settings will be + turned into the appropriate `bundle config` executions: + + :bundle_config + :bundle_gemfile + :bundle_path + :bundle_without + DESC + task :config do + on fetch(:bundle_servers) do + within release_path do + with fetch(:bundle_env_variables) do + configuration = fetch(:bundle_config).dup || {} + configuration[:gemfile] = fetch(:bundle_gemfile) + configuration[:path] = fetch(:bundle_path) + configuration[:without] = fetch(:bundle_without) + + configuration.each do |key, value| + execute :bundle, "config", "--local", key, value.to_s.shellescape unless value.nil? + end + end + end + end + end + + desc <<-DESC + Install the current Bundler environment. By default, gems will be + installed to the shared/bundle path. Gems in the development and + test group will not be installed. The install command is executed + with the --quiet and --jobs=4 flags. By default, bundler will not be run on servers with no_release: true. @@ -11,30 +41,27 @@ namespace :bundler do set :bundle_roles, :all + set :bundle_config, { deployment: true } set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } - set :bundle_binstubs, -> { shared_path.join('bin') } + set :bundle_binstubs, nil set :bundle_gemfile, -> { release_path.join('Gemfile') } set :bundle_path, -> { shared_path.join('bundle') } set :bundle_without, %w{development test}.join(' ') - set :bundle_flags, '--deployment --quiet' - set :bundle_jobs, nil + set :bundle_flags, '--quiet' + set :bundle_jobs, 4 set :bundle_env_variables, {} set :bundle_clean_options, "" DESC - task :install do + task install: :config do on fetch(:bundle_servers) do within release_path do with fetch(:bundle_env_variables) do - options = [] - options << "--gemfile #{fetch(:bundle_gemfile)}" if fetch(:bundle_gemfile) - options << "--path #{fetch(:bundle_path)}" if fetch(:bundle_path) - - if fetch(:bundle_check_before_install) && test(:bundle, :check, *options) + if fetch(:bundle_check_before_install) && test(:bundle, :check) info "The Gemfile's dependencies are satisfied, skipping installation" else + options = [] options << "--binstubs #{fetch(:bundle_binstubs)}" if fetch(:bundle_binstubs) options << "--jobs #{fetch(:bundle_jobs)}" if fetch(:bundle_jobs) - options << "--without #{fetch(:bundle_without)}" if fetch(:bundle_without) options << "#{fetch(:bundle_flags)}" if fetch(:bundle_flags) execute :bundle, :install, *options end @@ -56,7 +83,7 @@ namespace :bundler do end desc "Remove unused gems installed by bundler" - task :clean do + task clean: :config do on fetch(:bundle_servers) do within release_path do with fetch(:bundle_env_variables) do @@ -76,12 +103,14 @@ namespace :load do set :bundle_bins, %w{gem rake rails} set :bundle_roles, :all + + set :bundle_config, { deployment: true } set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } set :bundle_binstubs, nil set :bundle_gemfile, nil set :bundle_path, -> { shared_path.join('bundle') } set :bundle_without, %w{development test}.join(' ') - set :bundle_flags, '--deployment --quiet' + set :bundle_flags, '--quiet' set :bundle_jobs, 4 set :bundle_env_variables, {} set :bundle_clean_options, ""