diff --git a/README.md b/README.md index 38ba43c..0bab189 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,12 @@ require "capistrano/rsync" Set some `rsync_options` to your liking: ```ruby -set :rsync_options, %w[--recursive --delete --delete-excluded --exclude .git*] +set :rsync_options, %w[--recursive --delete --delete-excluded --exclude=.git*] +``` + +Ensure to set `scm` to :rsync in your deploy.rb: +```ruby +set :scm, :rsync ``` And after setting regular Capistrano options, deploy as usual! @@ -60,16 +65,23 @@ After that, Capistrano takes over and runs its usual tasks and symlinking. ### Exclude files from being deployed If you don't want to deploy everything you've committed to your repository, pass -some `--exclude` options to Rsync: +some `--exclude` options to Rsync (note the equals signs): ```ruby set :rsync_options, %w[ --recursive --delete --delete-excluded - --exclude .git* - --exclude /config/database.yml - --exclude /test/*** + --exclude=.git* + --exclude=/config/database.yml + --exclude=/test/*** + --include=/etc/folder + --exclude=/etc/* ] ``` +The `=` is required in order for patterns to be properly read. Note the order of the +`--include` and `--exclude` params; if you wish to exclude an entire directory except +a certain folder, because of an Rsync quirk you must specify the include first. + + ### Precompile assets before deploy Capistrano::Rsync runs `rsync:stage` before rsyncing. Hook to that like this: ```ruby diff --git a/lib/capistrano/rsync.rb b/lib/capistrano/rsync.rb index 758d96b..94c8fbb 100644 --- a/lib/capistrano/rsync.rb +++ b/lib/capistrano/rsync.rb @@ -5,48 +5,56 @@ # private API and internals of Capistrano::Rsync. If you think something should # be public for extending and hooking, please let me know! -set :rsync_options, [] -set :rsync_copy, "rsync --archive --acls --xattrs" - -# Stage is used on your local machine for rsyncing from. -set :rsync_stage, "tmp/deploy" - -# Cache is used on the server to copy files to from to the release directory. -# Saves you rsyncing your whole app folder each time. If you nil rsync_cache, -# Capistrano::Rsync will sync straight to the release path. -set :rsync_cache, "shared/deploy" - rsync_cache = lambda do cache = fetch(:rsync_cache) cache = deploy_to + "/" + cache if cache && cache !~ /^\// cache end +# Use cap3's load:defaults to set default vars so that they can be overridden. +namespace :load do + task :defaults do + set :rsync_options, [] + set :rsync_copy, "rsync --archive --acls --xattrs" + + # Stage is used on your local machine for rsyncing from. + set :rsync_stage, "tmp/deploy" + + # Cache is used on the server to copy files to from to the release directory. + # Saves you rsyncing your whole app folder each time. If you nil rsync_cache, + # Capistrano::Rsync will sync straight to the release path. + set :rsync_cache, "shared/deploy" + end +end + Rake::Task["deploy:check"].enhance ["rsync:hook_scm"] Rake::Task["deploy:updating"].enhance ["rsync:hook_scm"] desc "Stage and rsync to the server (or its cache)." task :rsync => %w[rsync:stage] do - roles(:all).each do |role| - user = role.user + "@" if !role.user.nil? - - rsync = %w[rsync] - rsync.concat fetch(:rsync_options) - rsync << fetch(:rsync_stage) + "/" - rsync << "#{user}#{role.hostname}:#{rsync_cache.call || release_path}" - - Kernel.system *rsync + on roles(:all), in: :parallel do |host| + user = host.user + "@" if !host.user.nil? + port = host.port + + run_locally do + rsynccmd = [] + rsynccmd.concat(fetch(:rsync_options)) + rsynccmd << fetch(:rsync_stage) + "/" + rsynccmd << "-e \'ssh -p #{port}\'" if port + rsynccmd << "#{user}#{host.hostname}:#{rsync_cache.call || release_path}" + execute :rsync, rsynccmd.join(" ") + end end end namespace :rsync do task :hook_scm do Rake::Task.define_task("#{scm}:check") do - invoke "rsync:check" + invoke "rsync:check" end Rake::Task.define_task("#{scm}:create_release") do - invoke "rsync:release" + invoke "rsync:release" end end @@ -57,20 +65,18 @@ task :create_stage do next if File.directory?(fetch(:rsync_stage)) - clone = %W[git clone] - clone << fetch(:repo_url, ".") - clone << fetch(:rsync_stage) - Kernel.system *clone + run_locally do + execute :git, "clone #{fetch(:repo_url, '.')} #{fetch(:rsync_stage)}"; + end end desc "Stage the repository in a local directory." task :stage => %w[create_stage] do - Dir.chdir fetch(:rsync_stage) do - update = %W[git fetch --quiet --all --prune] - Kernel.system *update - - checkout = %W[git reset --hard origin/#{fetch(:branch)}] - Kernel.system *checkout + run_locally do + within fetch(:rsync_stage) do + execute :git, "fetch --quiet --all --prune" + execute :git, "reset --hard origin/#{fetch(:branch)}" + end end end @@ -86,4 +92,14 @@ # Matches the naming scheme of git tasks. # Plus was part of the public API in Capistrano::Rsync <= v0.2.1. task :create_release => %w[release] + + desc "Set the current revision" + task :set_current_revision do + run_locally do + within fetch(:rsync_stage) do + rev = capture(:git, 'rev-parse', '--short', 'HEAD') + set :current_revision, rev + end + end + end end