Skip to content

Commit

Permalink
Capistrano 3 support PR #23 from @sauliusgrigaitis
Browse files Browse the repository at this point in the history
  • Loading branch information
Sébastien Gruhier committed Feb 9, 2014
1 parent e7775db commit fe8749e
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 123 deletions.
2 changes: 1 addition & 1 deletion README.markdown
Expand Up @@ -2,7 +2,7 @@ CapistranoDbTasks
=================

Add database AND assets tasks to capistrano to a Rails project.
It only works with capistrano 2. Any pull requests for capistrano 3 support are welcome :)
It only works with capistrano 3. Older versions until 0.3 works with capistrano 2.

Currently

Expand Down
2 changes: 1 addition & 1 deletion capistrano-db-tasks.gemspec
Expand Up @@ -18,5 +18,5 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]

s.add_development_dependency "capistrano", "> 2.0.0"
s.add_runtime_dependency "capistrano", ">= 3.0.0"
end
22 changes: 13 additions & 9 deletions lib/capistrano-db-tasks/asset.rb
Expand Up @@ -2,22 +2,26 @@ module Asset
extend self

def remote_to_local(cap)
servers = cap.find_servers :roles => :app
port = cap.port rescue 22
[cap.assets_dir].flatten.each do |dir|
system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' #{cap.user}@#{servers.first}:#{cap.current_path}/#{dir} #{cap.local_assets_dir}")
servers = Capistrano::Configuration.env.send(:servers)
server = servers.detect { |s| s.roles.include?(:app) }
port = server.netssh_options[:port] || 22
user = server.netssh_options[:user]
[cap.fetch(:assets_dir)].flatten.each do |dir|
system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' #{user}@#{server}:#{cap.current_path}/#{dir} #{cap.fetch(:local_assets_dir)}")
end
end

def local_to_remote(cap)
servers = cap.find_servers :roles => :app
port = cap.port rescue 22
[cap.assets_dir].flatten.each do |dir|
system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' ./#{dir} #{cap.user}@#{servers.first}:#{cap.current_path}/#{cap.local_assets_dir}")
servers = Capistrano::Configuration.env.send(:servers)
server = servers.detect { |s| s.roles.include?(:app) }
port = server.netssh_options[:port] || 22
user = server.netssh_options[:user]
[cap.fetch(:assets_dir)].flatten.each do |dir|
system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' ./#{dir} #{user}@#{server}:#{cap.current_path}/#{cap.fetch(:local_assets_dir)}")
end
end

def to_string(cap)
[cap.assets_dir].flatten.join(" ")
[cap.fetch(:assets_dir)].flatten.join(" ")
end
end
27 changes: 12 additions & 15 deletions lib/capistrano-db-tasks/database.rb
Expand Up @@ -61,52 +61,49 @@ def import_cmd(file)
class Remote < Base
def initialize(cap_instance)
super(cap_instance)
@config = ""
@cap.run("cat #{@cap.current_path}/config/database.yml") do |c, s, d|
@config += d
end
@config = YAML.load(ERB.new(@config).result)[@cap.rails_env.to_s]
@config = @cap.capture("cat #{@cap.current_path}/config/database.yml")
@config = YAML.load(ERB.new(@config).result)[@cap.fetch(:rails_env).to_s]
end

def dump
@cap.run "cd #{@cap.current_path} && #{dump_cmd} | bzip2 - - > #{output_file}"
@cap.execute "cd #{@cap.current_path} && #{dump_cmd} | bzip2 - - > #{output_file}"
self
end

def download(local_file = "#{output_file}")
remote_file = "#{@cap.current_path}/#{output_file}"
@cap.get remote_file, local_file
@cap.download! remote_file, local_file
end

# cleanup = true removes the mysqldump file after loading, false leaves it in db/
def load(file, cleanup)
unzip_file = File.join(File.dirname(file), File.basename(file, '.bz2'))
# @cap.run "cd #{@cap.current_path} && bunzip2 -f #{file} && RAILS_ENV=#{@cap.rails_env} bundle exec rake db:drop db:create && #{import_cmd(unzip_file)}"
@cap.run "cd #{@cap.current_path} && bunzip2 -f #{file} && RAILS_ENV=#{@cap.rails_env} && #{import_cmd(unzip_file)}"
@cap.run("cd #{@cap.current_path} && rm #{unzip_file}") if cleanup
@cap.execute "cd #{@cap.current_path} && bunzip2 -f #{file} && RAILS_ENV=#{@cap.fetch(:rails_env)} && #{import_cmd(unzip_file)}"
@cap.execute("cd #{@cap.current_path} && rm #{unzip_file}") if cleanup
end
end

class Local < Base
def initialize(cap_instance)
super(cap_instance)
@config = YAML.load(ERB.new(File.read(File.join('config', 'database.yml'))).result)[@cap.local_rails_env.to_s]
@config = YAML.load(ERB.new(File.read(File.join('config', 'database.yml'))).result)[fetch(:local_rails_env).to_s]
puts "local #{@config}"
end

# cleanup = true removes the mysqldump file after loading, false leaves it in db/
def load(file, cleanup)
unzip_file = File.join(File.dirname(file), File.basename(file, '.bz2'))
# system("bunzip2 -f #{file} && bundle exec rake db:drop db:create && #{import_cmd(unzip_file)} && bundle exec rake db:migrate")
@cap.logger.info("executing local: bunzip2 -f #{file} && #{import_cmd(unzip_file)}")
@cap.info "executing local: bunzip2 -f #{file} && #{import_cmd(unzip_file)}"
system("bunzip2 -f #{file} && #{import_cmd(unzip_file)}")
if cleanup
@cap.logger.info("removing #{unzip_file}")
@cap.info "removing #{unzip_file}"
File.unlink(unzip_file)
else
@cap.logger.info("leaving #{unzip_file} (specify :db_local_clean in deploy.rb to remove)")
@cap.info "leaving #{unzip_file} (specify :db_local_clean in deploy.rb to remove)"
end
@cap.logger.info("Completed database import")
@cap.info "Completed database import"
end

def dump
Expand All @@ -116,7 +113,7 @@ def dump

def upload
remote_file = "#{@cap.current_path}/#{output_file}"
@cap.upload output_file, remote_file
@cap.upload! output_file, remote_file
end
end

Expand Down
168 changes: 78 additions & 90 deletions lib/capistrano-db-tasks/dbtasks.rb
@@ -1,114 +1,102 @@
if Capistrano::Configuration.instance(false)

Capistrano::Configuration.instance(true).load do |instance|

require File.expand_path("#{File.dirname(__FILE__)}/util")
require File.expand_path("#{File.dirname(__FILE__)}/database")
require File.expand_path("#{File.dirname(__FILE__)}/asset")

instance.set :local_rails_env, ENV['RAILS_ENV'] || 'development' unless exists?(:local_rails_env)
instance.set :rails_env, 'production' unless exists?(:rails_env)
instance.set :db_local_clean, false unless exists?(:db_local_clean)
instance.set :assets_dir, 'system' unless exists?(:assets_dir)
instance.set :local_assets_dir, 'public' unless exists?(:local_assets_dir)

namespace :db do
namespace :remote do
desc 'Synchronize your remote database using local database data'
task :sync, :roles => :db do
if Util.prompt 'Are you sure you want to REPLACE THE REMOTE DATABASE with local database'
Database.local_to_remote(instance)
end
require File.expand_path("#{File.dirname(__FILE__)}/util")
require File.expand_path("#{File.dirname(__FILE__)}/database")
require File.expand_path("#{File.dirname(__FILE__)}/asset")

set :local_rails_env, ENV['RAILS_ENV'] || 'development' unless fetch(:local_rails_env)
set :rails_env, 'production' unless fetch(:rails_env)
set :db_local_clean, false unless fetch(:db_local_clean)
set :assets_dir, 'system' unless fetch(:assets_dir)
set :local_assets_dir, 'public' unless fetch(:local_assets_dir)

namespace :db do
namespace :remote do
desc 'Synchronize your remote database using local database data'
task :sync do
on roles(:db) do
if Util.prompt 'Are you sure you want to REPLACE THE REMOTE DATABASE with local database'
Database.local_to_remote(self)
end
end
end
end

namespace :local do
desc 'Synchronize your local database using remote database data'
task :sync, :roles => :db do
puts "Local database: #{Database::Local.new(instance).database}"
if Util.prompt 'Are you sure you want to erase your local database with server database'
Database.remote_to_local(instance)
end
namespace :local do
desc 'Synchronize your local database using remote database data'
task :sync do
on roles(:db) do
puts "Local database: #{Database::Local.new(self).database}"
if Util.prompt 'Are you sure you want to erase your local database with server database'
Database.remote_to_local(self)
end
end
end
end

desc 'Synchronize your local database using remote database data'
task :pull do
db.local.sync
end
desc 'Synchronize your local database using remote database data'
task :pull => "db:local:sync"

desc 'Synchronize your remote database using local database data'
task :push do
db.remote.sync
end
end
desc 'Synchronize your remote database using local database data'
task :push => "db:remote:sync"
end

namespace :assets do
namespace :remote do
desc 'Synchronize your remote assets using local assets'
task :sync, :roles => :app do
puts "Assets directories: #{assets_dir}"
if Util.prompt "Are you sure you want to erase your server assets with local assets"
Asset.local_to_remote(instance)
end
namespace :assets do
namespace :remote do
desc 'Synchronize your remote assets using local assets'
task :sync do
on roles(:app) do
puts "Assets directories: #{fetch(:assets_dir)}"
if Util.prompt "Are you sure you want to erase your server assets with local assets"
Asset.local_to_remote(self)
end
end
end
end

namespace :local do
desc 'Synchronize your local assets using remote assets'
task :sync, :roles => :app do
puts "Assets directories: #{local_assets_dir}"
if Util.prompt "Are you sure you want to erase your local assets with server assets"
Asset.remote_to_local(instance)
end
namespace :local do
desc 'Synchronize your local assets using remote assets'
task :sync do
on roles(:app) do
puts "Assets directories: #{fetch(:local_assets_dir)}"
if Util.prompt "Are you sure you want to erase your local assets with server assets"
Asset.remote_to_local(self)
end
end

desc 'Synchronize your local assets using remote assets'
task :pull do
assets.local.sync
end

desc 'Synchronize your remote assets using local assets'
task :push do
assets.remote.sync
end
end
end

namespace :app do
namespace :remote do
desc 'Synchronize your remote assets AND database using local assets and database'
task :sync do
if Util.prompt "Are you sure you want to REPLACE THE REMOTE DATABASE AND your remote assets with local database and assets(#{assets_dir})"
Database.local_to_remote(instance)
Asset.local_to_remote(instance)
end
end
end
desc 'Synchronize your local assets using remote assets'
task :pull => "assets:local:sync"

namespace :local do
desc 'Synchronize your local assets AND database using remote assets and database'
task :sync do
puts "Local database : #{Database::Local.new(instance).database}"
puts "Assets directories : #{local_assets_dir}"
if Util.prompt "Are you sure you want to erase your local database AND your local assets with server database and assets(#{assets_dir})"
Database.remote_to_local(instance)
Asset.remote_to_local(instance)
end
end
end
desc 'Synchronize your remote assets using local assets'
task :push => "assets:remote:sync"
end

desc 'Synchronize your local assets AND database using remote assets and database'
task :pull do
app.local.sync
namespace :app do
namespace :remote do
desc 'Synchronize your remote assets AND database using local assets and database'
task :sync do
if Util.prompt "Are you sure you want to REPLACE THE REMOTE DATABASE AND your remote assets with local database and assets(#{assets_dir})"
Database.local_to_remote(self)
Asset.local_to_remote(self)
end
end
end

desc 'Synchronize your remote assets AND database using local assets and database'
task :push do
app.remote.sync
namespace :local do
desc 'Synchronize your local assets AND database using remote assets and database'
task :sync do
puts "Local database : #{Database::Local.new(self).database}"
puts "Assets directories : #{fetch(:local_assets_dir)}"
if Util.prompt "Are you sure you want to erase your local database AND your local assets with server database and assets(#{assets_dir})"
Database.remote_to_local(self)
Asset.remote_to_local(self)
end

end
end

desc 'Synchronize your local assets AND database using remote assets and database'
task :pull => "app:local:sync"

desc 'Synchronize your remote assets AND database using local assets and database'
task :push => "app:remote:sync"
end
8 changes: 2 additions & 6 deletions lib/capistrano-db-tasks/util.rb
@@ -1,10 +1,6 @@
module Util
def self.prompt(msg, prompt = "(y)es, (n)o ")
answer = Capistrano::CLI.ui.ask("#{msg} #{prompt} ? ") do |q|
q.overwrite = false
q.validate = /^y$|^yes$|^n$|^no$/i
q.responses[:not_valid] = prompt
end
(answer =~ /^y$|^yes$/i) == 0
ask(:answer, "#{msg} #{prompt} ? ")
(fetch(:answer) =~ /^y$|^yes$/i) == 0
end
end
2 changes: 1 addition & 1 deletion lib/capistrano-db-tasks/version.rb
@@ -1,3 +1,3 @@
module CapistranoDbTasks
VERSION = "0.2.1"
VERSION = "0.3"
end

0 comments on commit fe8749e

Please sign in to comment.