├── .gitignore ├── lib ├── capistrano-bundler.rb └── capistrano │ ├── bundler │ ├── hooks.rb │ └── tasks.rb │ ├── bundler.rb │ └── tasks │ ├── hooks.cap │ └── bundler.cap ├── Rakefile ├── Gemfile ├── capistrano-bundler.gemspec ├── LICENSE ├── CHANGELOG.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | -------------------------------------------------------------------------------- /lib/capistrano-bundler.rb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | -------------------------------------------------------------------------------- /lib/capistrano/bundler/hooks.rb: -------------------------------------------------------------------------------- 1 | load File.expand_path('../../tasks/hooks.cap', __FILE__) 2 | -------------------------------------------------------------------------------- /lib/capistrano/bundler/tasks.rb: -------------------------------------------------------------------------------- 1 | load File.expand_path('../../tasks/bundler.cap', __FILE__) 2 | -------------------------------------------------------------------------------- /lib/capistrano/bundler.rb: -------------------------------------------------------------------------------- 1 | require_relative 'bundler/tasks' 2 | require_relative 'bundler/hooks' 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in capistrano-bundler.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /lib/capistrano/tasks/hooks.cap: -------------------------------------------------------------------------------- 1 | before 'deploy:updated', 'bundler:install' 2 | before 'deploy:reverted', 'bundler:install' 3 | -------------------------------------------------------------------------------- /capistrano-bundler.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = 'capistrano-bundler' 7 | spec.version = '1.1.4' 8 | spec.authors = ['Tom Clements', 'Lee Hambley', 'Kir Shatrov'] 9 | spec.email = ['seenmyfate@gmail.com', 'lee.hambley@gmail.com', 'shatrov@me.com'] 10 | spec.description = %q{Bundler support for Capistrano 3.x} 11 | spec.summary = %q{Bundler support for Capistrano 3.x} 12 | spec.homepage = 'https://github.com/capistrano/bundler' 13 | spec.license = 'MIT' 14 | 15 | spec.files = `git ls-files`.split($/) 16 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 17 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 18 | spec.require_paths = ['lib'] 19 | 20 | spec.add_dependency 'capistrano', '~> 3.1' 21 | spec.add_dependency 'sshkit', '~> 1.2' 22 | 23 | spec.add_development_dependency 'bundler', '~> 1.3' 24 | spec.add_development_dependency 'rake', '~> 0' 25 | end 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Capistrano, your one stop deployment shop. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | (master) 2 | 3 | * Use `bundle check` to check if we can skip `bundle install` 4 | * Run `bundle:install` on rollback (`deploy:reverted`) 5 | 6 | # 1.1.4 (22 Jan 2015) 7 | 8 | * Don’t generate binstubs by default (#61) 9 | 10 | # 1.1.3 (4 Aug 2014) 11 | 12 | * Honor `:no_release` flag by using `release_roles` in Capistrano 3.1 13 | * capistrano-bundler now requires Capistrano 3.1 or higher (~> 3.1) 14 | * Added `:bundle_jobs` option for specifying number of parallel jobs 15 | 16 | # 1.1.2 (8 Feb 2014) 17 | 18 | * Added `bundle_env_variables` option for specifying environment variables that should be set when running `bundle`. 19 | * The `bundle_dir` option is now named `bundle_path` 20 | * Use `bundle install` instead of `bundle` 21 | * All options are now optional and can be excluded from the final bundle command by setting them to `nil` 22 | * Bundler looks for a `Gemfile` by default, so there is no need to specify it. 23 | 24 | # 1.1.1 25 | 26 | * ruby is not prefixed with `bundle exec` anymore by default 27 | * prefix rails with `bundle exec` by default 28 | 29 | # 1.1.0 30 | 31 | * Switching to new command map (https://github.com/capistrano/sshkit/pull/45) 32 | Thanks to new command map, now this integration adds `bundle exec` to global executables (gem, ruby, rake). The list of executable can be tweaked by `bundle_bins`. 33 | 34 | # 1.0.0 35 | 36 | Initial release 37 | -------------------------------------------------------------------------------- /lib/capistrano/tasks/bundler.cap: -------------------------------------------------------------------------------- 1 | namespace :bundler do 2 | desc <<-DESC 3 | Install the current Bundler environment. By default, gems will be \ 4 | installed to the shared/bundle path. Gems in the development and \ 5 | test group will not be installed. The install command is executed \ 6 | with the --deployment and --quiet flags. 7 | 8 | By default, bundler will not be run on servers with no_release: true. 9 | 10 | You can override any of these defaults by setting the variables shown below. 11 | 12 | set :bundle_roles, :all 13 | 14 | set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } 15 | set :bundle_binstubs, -> { shared_path.join('bin') } 16 | set :bundle_gemfile, -> { release_path.join('Gemfile') } 17 | set :bundle_path, -> { shared_path.join('bundle') } 18 | set :bundle_without, %w{development test}.join(' ') 19 | set :bundle_flags, '--deployment --quiet' 20 | set :bundle_jobs, nil 21 | set :bundle_env_variables, {} 22 | DESC 23 | task :install do 24 | on fetch(:bundle_servers) do 25 | within release_path do 26 | with fetch(:bundle_env_variables, {}) do 27 | options = [] 28 | options << "--binstubs #{fetch(:bundle_binstubs)}" if fetch(:bundle_binstubs) 29 | options << "--gemfile #{fetch(:bundle_gemfile)}" if fetch(:bundle_gemfile) 30 | options << "--path #{fetch(:bundle_path)}" if fetch(:bundle_path) 31 | options << "--jobs #{fetch(:bundle_jobs)}" if fetch(:bundle_jobs) 32 | 33 | unless test(:bundle, :check, *options) 34 | options << "--without #{fetch(:bundle_without)}" if fetch(:bundle_without) 35 | options << "#{fetch(:bundle_flags)}" if fetch(:bundle_flags) 36 | execute :bundle, :install, *options 37 | end 38 | end 39 | end 40 | end 41 | end 42 | 43 | desc <<-DESC 44 | Maps all binaries to use `bundle exec` by default. 45 | Add your own binaries to the array with the command shown below. 46 | 47 | set :bundle_bins, fetch(:bundle_bins) + %w(my_new_binary) 48 | DESC 49 | task :map_bins do 50 | fetch(:bundle_bins).each do |command| 51 | SSHKit.config.command_map.prefix[command.to_sym].push("bundle exec") 52 | end 53 | end 54 | end 55 | 56 | Capistrano::DSL.stages.each do |stage| 57 | after stage, 'bundler:map_bins' 58 | end 59 | 60 | namespace :load do 61 | task :defaults do 62 | set :bundle_bins, %w{gem rake rails} 63 | 64 | set :bundle_roles, :all 65 | set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } 66 | set :bundle_path, -> { shared_path.join('vendor/bundle') } 67 | set :bundle_without, %w{development test}.join(' ') 68 | set :bundle_flags, '--deployment --quiet' 69 | 70 | set :linked_dirs, fetch(:linked_dirs, []) << '.bundle' 71 | end 72 | end 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Capistrano::Bundler 2 | 3 | Bundler specific tasks for Capistrano v3: 4 | 5 | ```sh 6 | $ cap production bundler:install 7 | ``` 8 | 9 | It also prefixes certain binaries to use `bundle exec`. 10 | 11 | ## Installation 12 | 13 | Add these lines to your application's Gemfile: 14 | 15 | ```ruby 16 | gem 'capistrano', '~> 3.1' 17 | gem 'capistrano-bundler', '~> 1.1.2' 18 | ``` 19 | 20 | And then execute: 21 | 22 | ```sh 23 | $ bundle 24 | ``` 25 | 26 | Or install it yourself as: 27 | 28 | ```sh 29 | $ gem install capistrano-bundler 30 | ``` 31 | 32 | ## Usage 33 | 34 | Require in `Capfile` to use the default task: 35 | 36 | ```ruby 37 | require 'capistrano/bundler' 38 | ``` 39 | 40 | The task will run before `deploy:updated` as part of Capistrano's default deploy, or can be run in isolation with `cap production bundler:install` 41 | 42 | By default, the plugin adds `bundle exec` prefix to common executables listed in `bundle_bins` option. This currently applies for `gem`, `rake` and `rails`. 43 | 44 | You can add any custom executable to this list: 45 | ```ruby 46 | set :bundle_bins, fetch(:bundle_bins, []).push('my_new_binary') 47 | ``` 48 | 49 | Configurable options: 50 | 51 | ```ruby 52 | set :bundle_roles, :all # this is default 53 | set :bundle_servers, -> { release_roles(fetch(:bundle_roles)) } # this is default 54 | set :bundle_binstubs, -> { shared_path.join('bin') } # default: nil 55 | set :bundle_gemfile, -> { release_path.join('MyGemfile') } # default: nil 56 | set :bundle_path, -> { shared_path.join('bundle') } # this is default 57 | set :bundle_without, %w{development test}.join(' ') # this is default 58 | set :bundle_flags, '--deployment --quiet' # this is default 59 | set :bundle_env_variables, {} # this is default 60 | ``` 61 | 62 | You can parallelize the installation of gems with bundler's jobs feature. 63 | Choose a number less or equal than the number of cores your server. 64 | 65 | ```ruby 66 | set :bundle_jobs, 4 # default: nil, only available for Bundler >= 1.4 67 | ``` 68 | 69 | To generate binstubs on each deploy, set `:bundle_binstubs` path: 70 | 71 | ```ruby 72 | set :bundle_binstubs, -> { shared_path.join('bin') } 73 | ``` 74 | 75 | In the result this would execute the following bundle command on all servers 76 | (actual paths depend on the real deploy directory): 77 | 78 | ```sh 79 | $ bundle install \ 80 | --binstubs /my_app/shared/bin \ 81 | --gemfile /my_app/releases/20130623094732/MyGemfile \ 82 | --path /my_app/shared/bundle \ 83 | --without development test \ 84 | --deployment --quiet 85 | ``` 86 | 87 | If any option is set to `nil` it will be excluded from the final bundle command. 88 | 89 | ### Environment Variables 90 | 91 | The `bundle_env_variables` option can be used to specify any environment variables you want present when running the `bundle` command: 92 | 93 | ```ruby 94 | # This translates to NOKOGIRI_USE_SYSTEM_LIBRARIES=1 when executed 95 | set :bundle_env_variables, { nokogiri_use_system_libraries: 1 } 96 | ``` 97 | 98 | ## Contributing 99 | 100 | 1. Fork it 101 | 2. Create your feature branch (`git checkout -b my-new-feature`) 102 | 3. Commit your changes (`git commit -am 'Add some feature'`) 103 | 4. Push to the branch (`git push origin my-new-feature`) 104 | 5. Create new Pull Request 105 | --------------------------------------------------------------------------------