Skip to content

Instantly share code, notes, and snippets.

@tompata
Created January 20, 2011 16:33
Show Gist options
  • Save tompata/788136 to your computer and use it in GitHub Desktop.
Save tompata/788136 to your computer and use it in GitHub Desktop.
extended Capistrano Copy strategy with Bundler
# overwrited Copy strategy
# after source.sync it's running bundler with deployment mode, precompiling gems into vendor/bundle
require 'capistrano/recipes/deploy/strategy/copy'
require 'fileutils'
require 'tempfile'
Capistrano::Deploy::Strategy::Copy.class_eval do
def deploy!
if copy_cache
if File.exists?(copy_cache)
logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
system(source.sync(revision, copy_cache))
else
logger.debug "preparing local cache at #{copy_cache}"
system(source.checkout(revision, copy_cache))
end
logger.debug "copying cache to deployment staging area #{destination}"
Dir.chdir(copy_cache) do
FileUtils.mkdir_p(destination)
queue = Dir.glob("*", File::FNM_DOTMATCH)
while queue.any?
item = queue.shift
name = File.basename(item)
next if name == "." || name == ".."
next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }
if File.symlink?(item)
FileUtils.ln_s(File.readlink(File.join(copy_cache, item)), File.join(destination, item))
elsif File.directory?(item)
queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
FileUtils.mkdir(File.join(destination, item))
else
FileUtils.ln(File.join(copy_cache, item), File.join(destination, item))
end
end
end
else
logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
system(command)
if copy_exclude.any?
logger.debug "processing exclusions..."
if copy_exclude.any?
copy_exclude.each do |pattern|
delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
# avoid the /.. trap that deletes the parent directories
delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
FileUtils.rm_rf(delete_list.compact)
end
end
end
end
File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
# bundler extension here...
logger.trace "running bundler in #{destination}"
Dir.chdir(destination) do
# cleaning previous bundled gems
FileUtils.rm_rf( "vendor/bundle" )
# running bundler in deployment mode, without specified environments
bundle_without = fetch( :bundle_without, [:development, :test, :cucumber] )
system( "bundle install --deployment --without #{bundle_without.join(' ')}" )
end
logger.trace "compressing #{destination} to #{filename}"
Dir.chdir(tmpdir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
upload(filename, remote_filename)
run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
ensure
FileUtils.rm filename rescue nil
FileUtils.rm_rf destination rescue nil
end # deploy!
end # class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment