capistrano-db-tasks.senya 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0f34055a123659fdc31c7b0c7454f2f6b1d055db
4
+ data.tar.gz: f999701b00c2ceb38258df098c23c34762a34f1c
5
+ SHA512:
6
+ metadata.gz: 49fa1a30921b945a3cf6ea1152a16ce6c9b3b715ac488a14c67dcfac036869fc16f4d4c54c54b4bc849d2d68f70e9747ae65f812ea819c0873c5b9bab6a0a6a3
7
+ data.tar.gz: 661f622abede36dc0e2ea10bcaeb489e319dd046d8e7ccc1fbe42155b2d4411b0e7eb64dc530367a2065aa6b8b3fb477ada8b86f9c646a2d0b7883fb89a48868
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2009 Sébastien Gruhier - Xilinus/Maptimize
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16
+ SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,103 @@
1
+ CapistranoDbTasks
2
+ =================
3
+
4
+ Add database AND assets tasks to capistrano to a Rails project.
5
+ It only works with capistrano 3. Older versions until 0.3 works with capistrano 2.
6
+
7
+ Currently
8
+
9
+ * It only supports mysql and postgresql (both side remote and local)
10
+ * Synchronize assets remote to local and local to remote
11
+
12
+ Commands mysql, mysqldump (or pg\_dump, psql), bzip2 and unbzip2 (or gzip) must be in your PATH
13
+
14
+ Feel free to fork and to add more database support or new tasks.
15
+
16
+ Install
17
+ =======
18
+
19
+ Add it as a gem:
20
+
21
+ ```ruby
22
+ gem "capistrano-db-tasks", require: false
23
+ ```
24
+
25
+ Add to config/deploy.rb:
26
+
27
+ ```ruby
28
+ require 'capistrano-db-tasks'
29
+
30
+ # if you haven't already specified
31
+ set :rails_env, "production"
32
+
33
+ # if you want to remove the local dump file after loading
34
+ set :db_local_clean, true
35
+
36
+ # if you want to remove the dump file from the server after downloading
37
+ set :db_remote_clean, true
38
+
39
+ # if you want to exclude table from dump
40
+ set :db_ignore_tables, []
41
+
42
+ # if you want to exclude table data (but not table schema) from dump
43
+ set :db_ignore_data_tables, []
44
+
45
+ # If you want to import assets, you can change default asset dir (default = system)
46
+ # This directory must be in your shared directory on the server
47
+ set :assets_dir, %w(public/assets public/att)
48
+ set :local_assets_dir, %w(public/assets public/att)
49
+
50
+ # if you want to work on a specific local environment (default = ENV['RAILS_ENV'] || 'development')
51
+ set :locals_rails_env, "production"
52
+
53
+ # if you are highly paranoid and want to prevent any push operation to the server
54
+ set :disallow_pushing, true
55
+
56
+ # if you prefer bzip2/unbzip2 instead of gzip
57
+ set :compressor, :bzip2
58
+
59
+ ```
60
+
61
+ Add to .gitignore
62
+ ```yml
63
+ /db/*.sql
64
+ ```
65
+
66
+
67
+ [How to install bzip2 on Windows](http://stackoverflow.com/a/25625988/3324219)
68
+
69
+ Available tasks
70
+ ===============
71
+
72
+ app:local:sync || app:pull # Synchronize your local assets AND database using remote assets and database
73
+ app:remote:sync || app:push # Synchronize your remote assets AND database using local assets and database
74
+
75
+ assets:local:sync || assets:pull # Synchronize your local assets using remote assets
76
+ assets:remote:sync || assets:push # Synchronize your remote assets using local assets
77
+
78
+ db:local:sync || db:pull # Synchronize your local database using remote database data
79
+ db:remote:sync || db:push # Synchronize your remote database using local database data
80
+ db:remote:backup # Dumps database to db folder after that we can take it from there
81
+
82
+ Example
83
+ =======
84
+
85
+ cap db:pull
86
+ cap production db:pull # if you are using capistrano-ext to have multistages
87
+
88
+
89
+ Contributors
90
+ ============
91
+
92
+ * tilsammans (http://github.com/tilsammansee)
93
+ * bigfive (http://github.com/bigfive)
94
+ * jakemauer (http://github.com/jakemauer)
95
+ * tjoneseng (http://github.com/tjoneseng)
96
+
97
+ TODO
98
+ ====
99
+
100
+ * May be change project's name as it's not only database tasks now :)
101
+ * Add tests
102
+
103
+ Copyright (c) 2009 [Sébastien Gruhier - XILINUS], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+ require 'bundler'
5
+ require 'bundler/gem_tasks'
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the capistrano_db_tasks plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the capistrano_db_tasks plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'CapistranoDbTasks'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "capistrano-db-tasks/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "capistrano-db-tasks.senya"
7
+ s.version = CapistranoDbTasks::VERSION
8
+ s.authors = ["Sebastien Gruhier"]
9
+ s.email = ["sebastien.gruhier@xilinus.com"]
10
+ s.homepage = "https://github.com/cmrd-senya/capistrano-db-tasks/tree/dump_task.2"
11
+ s.summary = "A collection of capistrano tasks for syncing assets and databases (a modification from Senya)"
12
+ s.description = "A collection of capistrano tasks for syncing assets and databases"
13
+
14
+ s.rubyforge_project = "capistrano-db-tasks"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "capistrano", ">= 3.0.0"
22
+ end
@@ -0,0 +1,2 @@
1
+ require "capistrano"
2
+ require File.expand_path("#{File.dirname(__FILE__)}/capistrano-db-tasks/dbtasks")
@@ -0,0 +1,27 @@
1
+ module Asset
2
+ extend self
3
+
4
+ def remote_to_local(cap)
5
+ servers = Capistrano::Configuration.env.send(:servers)
6
+ server = servers.detect { |s| s.roles.include?(:app) }
7
+ port = server.netssh_options[:port] || 22
8
+ user = server.netssh_options[:user] || server.properties.fetch(:user)
9
+ [cap.fetch(:assets_dir)].flatten.each do |dir|
10
+ system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' #{user}@#{server}:#{cap.current_path}/#{dir} #{cap.fetch(:local_assets_dir)}")
11
+ end
12
+ end
13
+
14
+ def local_to_remote(cap)
15
+ servers = Capistrano::Configuration.env.send(:servers)
16
+ server = servers.detect { |s| s.roles.include?(:app) }
17
+ port = server.netssh_options[:port] || 22
18
+ user = server.netssh_options[:user] || server.properties.fetch(:user)
19
+ [cap.fetch(:assets_dir)].flatten.each do |dir|
20
+ system("rsync -a --del -L -K -vv --progress --rsh='ssh -p #{port}' ./#{dir} #{user}@#{server}:#{cap.current_path}/#{cap.fetch(:local_assets_dir)}")
21
+ end
22
+ end
23
+
24
+ def to_string(cap)
25
+ [cap.fetch(:assets_dir)].flatten.join(" ")
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ module Compressors
2
+ class Base
3
+
4
+ end
5
+ end
@@ -0,0 +1,40 @@
1
+ module Compressors
2
+ class Bzip2 < Base
3
+
4
+ class << self
5
+
6
+ def file_extension
7
+ "bz2"
8
+ end
9
+
10
+ def compress(from, to = nil)
11
+ to = case to
12
+ when "-"
13
+ "-c --stdout"
14
+ when nil
15
+ ""
16
+ else
17
+ "-c --stdout > #{to}"
18
+ end
19
+
20
+ "bzip2 #{from} #{to}"
21
+ end
22
+
23
+ def decompress(from, to = nil)
24
+ from = "-f #{from}" unless from == "-"
25
+
26
+ to = case to
27
+ when "-"
28
+ "-c --stdout"
29
+ when nil
30
+ ""
31
+ else
32
+ "-c --stdout > #{to}"
33
+ end
34
+
35
+ "bunzip2 -k -f #{from} #{to}"
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ module Compressors
2
+ class Gzip < Base
3
+
4
+ class << self
5
+
6
+ def file_extension
7
+ "gz"
8
+ end
9
+
10
+ def compress(from, to = nil)
11
+ from = from == :stdin ? "-" : from
12
+ to = case to
13
+ when '-'
14
+ "-c --stdout"
15
+ when nil
16
+ ""
17
+ else
18
+ "-c --stdout > #{to}"
19
+ end
20
+
21
+ "gzip #{from} #{to}"
22
+ end
23
+
24
+ def decompress(from, to = nil)
25
+ from = from == :stdin ? "-" : from
26
+ to = case to
27
+ when :stdout
28
+ "-c --stdout"
29
+ when nil
30
+ ""
31
+ else
32
+ "-c --stdout > #{to}"
33
+ end
34
+
35
+ "gzip -d #{from} #{to}"
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,245 @@
1
+ module Database
2
+ class Base
3
+ DBCONFIG_BEGIN_FLAG = "__CAPISTRANODB_CONFIG_BEGIN_FLAG__".freeze
4
+ DBCONFIG_END_FLAG = "__CAPISTRANODB_CONFIG_END_FLAG__".freeze
5
+
6
+ attr_accessor :config, :output_file
7
+
8
+ def initialize(cap_instance)
9
+ @cap = cap_instance
10
+ end
11
+
12
+ def mysql?
13
+ @config['adapter'] =~ /^mysql/
14
+ end
15
+
16
+ def postgresql?
17
+ %w(postgresql pg postgis).include? @config['adapter']
18
+ end
19
+
20
+ def credentials
21
+ credential_params = ""
22
+ username = @config['username'] || @config['user']
23
+
24
+ if mysql?
25
+ credential_params << " -u #{username} " if username
26
+ credential_params << " -p'#{@config['password']}' " if @config['password']
27
+ credential_params << " -h #{@config['host']} " if @config['host']
28
+ credential_params << " -S #{@config['socket']} " if @config['socket']
29
+ credential_params << " -P #{@config['port']} " if @config['port']
30
+ elsif postgresql?
31
+ credential_params << " -U #{username} " if username
32
+ credential_params << " -h #{@config['host']} " if @config['host']
33
+ credential_params << " -p #{@config['port']} " if @config['port']
34
+ end
35
+
36
+ credential_params
37
+ end
38
+
39
+ def database
40
+ @config['database']
41
+ end
42
+
43
+ def current_time
44
+ Time.now.strftime("%Y-%m-%d-%H%M%S")
45
+ end
46
+
47
+ def output_file
48
+ @output_file ||= "db/#{database}_#{current_time}.sql.#{compressor.file_extension}"
49
+ end
50
+
51
+ def compressor
52
+ @compressor ||= begin
53
+ compressor_klass = @cap.fetch(:compressor).to_s.split('_').collect(&:capitalize).join
54
+ klass = Object.module_eval("::Compressors::#{compressor_klass}", __FILE__, __LINE__)
55
+ klass
56
+ end
57
+ end
58
+
59
+ private
60
+
61
+ def pgpass
62
+ @config['password'] ? "PGPASSWORD='#{@config['password']}'" : ""
63
+ end
64
+
65
+ def dump_cmd
66
+ if mysql?
67
+ "mysqldump #{credentials} #{database} #{dump_cmd_opts}"
68
+ elsif postgresql?
69
+ "#{pgpass} pg_dump #{credentials} #{database} #{dump_cmd_opts}"
70
+ end
71
+ end
72
+
73
+ def import_cmd(file)
74
+ if mysql?
75
+ "mysql #{credentials} -D #{database} < #{file}"
76
+ elsif postgresql?
77
+ terminate_connection_sql = "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '#{database}' AND pid <> pg_backend_pid();"
78
+ "#{pgpass} psql -c \"#{terminate_connection_sql};\" #{credentials} #{database}; #{pgpass} dropdb #{credentials} #{database}; #{pgpass} createdb #{credentials} #{database}; #{pgpass} psql #{credentials} -d #{database} < #{file}"
79
+ end
80
+ end
81
+
82
+ def dump_cmd_opts
83
+ if mysql?
84
+ "--lock-tables=false #{dump_cmd_ignore_tables_opts} #{dump_cmd_ignore_data_tables_opts}"
85
+ elsif postgresql?
86
+ "--no-acl --no-owner #{dump_cmd_ignore_tables_opts} #{dump_cmd_ignore_data_tables_opts}"
87
+ end
88
+ end
89
+
90
+ def dump_cmd_ignore_tables_opts
91
+ ignore_tables = @cap.fetch(:db_ignore_tables, [])
92
+ if mysql?
93
+ ignore_tables.map{ |t| "--ignore-table=#{database}.#{t}" }.join(" ")
94
+ elsif postgresql?
95
+ ignore_tables.map{ |t| "--exclude-table=#{t}" }.join(" ")
96
+ end
97
+ end
98
+
99
+ def dump_cmd_ignore_data_tables_opts
100
+ ignore_tables = @cap.fetch(:db_ignore_data_tables, [])
101
+ if postgresql?
102
+ ignore_tables.map{ |t| "--exclude-table-data=#{t}" }.join(" ")
103
+ end
104
+ end
105
+
106
+ end
107
+
108
+ class Remote < Base
109
+ def initialize(cap_instance)
110
+ super(cap_instance)
111
+ @cap.info "Loading remote database config"
112
+ @cap.within @cap.current_path do
113
+ @cap.with rails_env: @cap.fetch(:rails_env) do
114
+ dirty_config_content = @cap.capture(:rails, "runner \"puts '#{DBCONFIG_BEGIN_FLAG}' + ActiveRecord::Base.connection.instance_variable_get(:@config).to_yaml + '#{DBCONFIG_END_FLAG}'\"", '2>/dev/null')
115
+ # Remove all warnings, errors and artefacts produced by bunlder, rails and other useful tools
116
+ config_content = dirty_config_content.match(/#{DBCONFIG_BEGIN_FLAG}(.*?)#{DBCONFIG_END_FLAG}/m)[1]
117
+ @config = YAML.load(config_content).inject({}) { |h, (k, v)| h[k.to_s] = v; h }
118
+ end
119
+ end
120
+ end
121
+
122
+ def dump
123
+ @cap.execute "cd #{@cap.current_path} && #{dump_cmd} | #{compressor.compress('-', output_file)}"
124
+ @cap.execute("ln -fs #{@cap.current_path}/#{output_file} #{@cap.current_path}/db/latest.sql.#{compressor.file_extension}")
125
+ self
126
+ end
127
+
128
+ def download(local_file = "#{output_file}")
129
+ @cap.download! dump_file_path, local_file
130
+ end
131
+
132
+ def clean_dump_if_needed
133
+ if @cap.fetch(:db_remote_clean)
134
+ @cap.execute "rm -f #{dump_file_path}"
135
+ else
136
+ @cap.info "leaving #{dump_file_path} on the server (add \"set :db_remote_clean, true\" to deploy.rb to remove)"
137
+ end
138
+ end
139
+
140
+ # cleanup = true removes the mysqldump file after loading, false leaves it in db/
141
+ def load(file, cleanup)
142
+ unzip_file = File.join(File.dirname(file), File.basename(file, ".#{compressor.file_extension}"))
143
+ # @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)}"
144
+ @cap.execute "cd #{@cap.current_path} && #{compressor.decompress(file)} && RAILS_ENV=#{@cap.fetch(:rails_env)} && #{import_cmd(unzip_file)}"
145
+ @cap.execute("cd #{@cap.current_path} && rm #{unzip_file}") if cleanup
146
+ end
147
+
148
+ private
149
+
150
+ def dump_file_path
151
+ "#{@cap.current_path}/#{output_file}"
152
+ end
153
+ end
154
+
155
+ class Local < Base
156
+ def initialize(cap_instance)
157
+ super(cap_instance)
158
+ @cap.info "Loading local database config"
159
+ dirty_config_content = @cap.run_locally do
160
+ capture(:rails, "runner \"puts '#{DBCONFIG_BEGIN_FLAG}' + ActiveRecord::Base.connection.instance_variable_get(:@config).to_yaml + '#{DBCONFIG_END_FLAG}'\"")
161
+ end
162
+ # Remove all warnings, errors and artefacts produced by bunlder, rails and other useful tools
163
+ config_content = dirty_config_content.match(/#{DBCONFIG_BEGIN_FLAG}(.*?)#{DBCONFIG_END_FLAG}/m)[1]
164
+ @config = YAML.load(config_content).inject({}) { |h, (k, v)| h[k.to_s] = v; h }
165
+ end
166
+
167
+ # cleanup = true removes the mysqldump file after loading, false leaves it in db/
168
+ def load(file, cleanup)
169
+ unzip_file = File.join(File.dirname(file), File.basename(file, ".#{compressor.file_extension}"))
170
+ # execute("bunzip2 -f #{file} && bundle exec rake db:drop db:create && #{import_cmd(unzip_file)} && bundle exec rake db:migrate")
171
+ @cap.info "executing local: #{compressor.decompress(file)}" && #{import_cmd(unzip_file)}"
172
+ execute("#{compressor.decompress(file)} && #{import_cmd(unzip_file)}")
173
+ if cleanup
174
+ @cap.info "removing #{unzip_file}"
175
+ File.unlink(unzip_file)
176
+ else
177
+ @cap.info "leaving #{unzip_file} (specify :db_local_clean in deploy.rb to remove)"
178
+ end
179
+ @cap.info "Completed database import"
180
+ end
181
+
182
+ def dump
183
+ execute "#{dump_cmd} | #{compressor.compress('-', output_file)}"
184
+ self
185
+ end
186
+
187
+ def upload
188
+ remote_file = "#{@cap.current_path}/#{output_file}"
189
+ @cap.upload! output_file, remote_file
190
+ end
191
+
192
+ private
193
+
194
+ def execute(cmd)
195
+ result = system cmd
196
+ @cap.error "Failed to execute the local command: #{cmd}" unless result
197
+ result
198
+ end
199
+ end
200
+
201
+
202
+ class << self
203
+ def check(local_db, remote_db)
204
+ unless (local_db.mysql? && remote_db.mysql?) || (local_db.postgresql? && remote_db.postgresql?)
205
+ raise 'Only mysql or postgresql on remote and local server is supported'
206
+ end
207
+ end
208
+
209
+ def remote_to_local(instance)
210
+ local_db = Database::Local.new(instance)
211
+ remote_db = Database::Remote.new(instance)
212
+
213
+ check(local_db, remote_db)
214
+
215
+ begin
216
+ remote_db.dump.download
217
+ ensure
218
+ remote_db.clean_dump_if_needed
219
+ end
220
+ local_db.load(remote_db.output_file, instance.fetch(:db_local_clean))
221
+ end
222
+
223
+ def local_to_remote(instance)
224
+ local_db = Database::Local.new(instance)
225
+ remote_db = Database::Remote.new(instance)
226
+
227
+ check(local_db, remote_db)
228
+
229
+ local_db.dump.upload
230
+ remote_db.load(local_db.output_file, instance.fetch(:db_local_clean))
231
+ File.unlink(local_db.output_file) if instance.fetch(:db_local_clean)
232
+ end
233
+
234
+ def backup(instance)
235
+ remote_db = Database::Remote.new(instance)
236
+ remote_db.dump
237
+ remote_db.download
238
+ end
239
+
240
+ def restore_latest(instance)
241
+ remote_db = Database::Remote.new(instance)
242
+ remote_db.load("#{instance.current_path}/db/latest.sql.#{remote_db.compressor.file_extension}", true)
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/util")
2
+ require File.expand_path("#{File.dirname(__FILE__)}/database")
3
+ require File.expand_path("#{File.dirname(__FILE__)}/asset")
4
+ require File.expand_path("#{File.dirname(__FILE__)}/compressors/base")
5
+ require File.expand_path("#{File.dirname(__FILE__)}/compressors/bzip2")
6
+ require File.expand_path("#{File.dirname(__FILE__)}/compressors/gzip")
7
+
8
+ set :local_rails_env, ENV['RAILS_ENV'] || 'development' unless fetch(:local_rails_env)
9
+ set :rails_env, fetch(:stage) || 'production' unless fetch(:rails_env)
10
+ set :db_local_clean, false unless fetch(:db_local_clean)
11
+ set :assets_dir, 'system' unless fetch(:assets_dir)
12
+ set :local_assets_dir, 'public' unless fetch(:local_assets_dir)
13
+ set :skip_data_sync_confirm, (ENV['SKIP_DATA_SYNC_CONFIRM'].to_s.downcase == 'true')
14
+ set :disallow_pushing, false unless fetch(:disallow_pushing)
15
+ set :compressor, :gzip unless fetch(:compressor)
16
+
17
+ namespace :capistrano_db_tasks do
18
+ task :check_can_push do
19
+ raise "pushing is disabled, set disallow_pushing to false to carry out this operation" if fetch(:disallow_pushing)
20
+ end
21
+ end
22
+
23
+ namespace :db do
24
+ namespace :remote do
25
+ desc 'Synchronize your remote database using local database data'
26
+ task :sync => 'capistrano_db_tasks:check_can_push' do
27
+ on roles(:db) do
28
+ if fetch(:skip_data_sync_confirm) || Util.prompt('Are you sure you want to REPLACE THE REMOTE DATABASE with local database')
29
+ Database.local_to_remote(self)
30
+ end
31
+ end
32
+ end
33
+
34
+ desc 'Dumps database to db folder after that we can take it from there'
35
+ task :backup do
36
+ on roles(:db) do
37
+ Database.backup(self)
38
+ end
39
+ end
40
+
41
+ desc 'Restores the latest database dump from the remote folder (pairs with db:remote:backup)'
42
+ task :restore_latest do
43
+ on roles(:db) do
44
+ Database.restore_latest(self)
45
+ end
46
+ end
47
+ end
48
+
49
+ namespace :local do
50
+ desc 'Synchronize your local database using remote database data'
51
+ task :sync do
52
+ on roles(:db) do
53
+ puts "Local database: #{Database::Local.new(self).database}"
54
+ if fetch(:skip_data_sync_confirm) || Util.prompt('Are you sure you want to erase your local database with server database')
55
+ Database.remote_to_local(self)
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ desc 'Synchronize your local database using remote database data'
62
+ task :pull => "db:local:sync"
63
+
64
+ desc 'Synchronize your remote database using local database data'
65
+ task :push => "db:remote:sync"
66
+ end
67
+
68
+ namespace :assets do
69
+ namespace :remote do
70
+ desc 'Synchronize your remote assets using local assets'
71
+ task :sync => 'capistrano_db_tasks:check_can_push' do
72
+ on roles(:app) do
73
+ puts "Assets directories: #{fetch(:assets_dir)}"
74
+ if fetch(:skip_data_sync_confirm) || Util.prompt("Are you sure you want to erase your server assets with local assets")
75
+ Asset.local_to_remote(self)
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ namespace :local do
82
+ desc 'Synchronize your local assets using remote assets'
83
+ task :sync do
84
+ on roles(:app) do
85
+ puts "Assets directories: #{fetch(:local_assets_dir)}"
86
+ if fetch(:skip_data_sync_confirm) || Util.prompt("Are you sure you want to erase your local assets with server assets")
87
+ Asset.remote_to_local(self)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ desc 'Synchronize your local assets using remote assets'
94
+ task :pull => "assets:local:sync"
95
+
96
+ desc 'Synchronize your remote assets using local assets'
97
+ task :push => "assets:remote:sync"
98
+ end
99
+
100
+ namespace :app do
101
+ namespace :remote do
102
+ desc 'Synchronize your remote assets AND database using local assets and database'
103
+ task :sync => 'capistrano_db_tasks:check_can_push' do
104
+ if fetch(:skip_data_sync_confirm) || Util.prompt("Are you sure you want to REPLACE THE REMOTE DATABASE AND your remote assets with local database and assets(#{fetch(:assets_dir)})")
105
+ on roles(:db) do
106
+ Database.local_to_remote(self)
107
+ end
108
+
109
+ on roles(:app) do
110
+ Asset.local_to_remote(self)
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ namespace :local do
117
+ desc 'Synchronize your local assets AND database using remote assets and database'
118
+ task :sync do
119
+ puts "Local database : #{Database::Local.new(self).database}"
120
+ puts "Assets directories : #{fetch(:local_assets_dir)}"
121
+ if fetch(:skip_data_sync_confirm) || Util.prompt("Are you sure you want to erase your local database AND your local assets with server database and assets(#{fetch(:assets_dir)})")
122
+ on roles(:db) do
123
+ Database.remote_to_local(self)
124
+ end
125
+
126
+ on roles(:app) do
127
+ Asset.remote_to_local(self)
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ desc 'Synchronize your local assets AND database using remote assets and database'
134
+ task :pull => "app:local:sync"
135
+
136
+ desc 'Synchronize your remote assets AND database using local assets and database'
137
+ task :push => "app:remote:sync"
138
+ end
@@ -0,0 +1,6 @@
1
+ module Util
2
+ def self.prompt(msg, prompt = "(y)es, (n)o ")
3
+ ask(:answer, "#{msg} #{prompt} ? ")
4
+ (fetch(:answer) =~ /^y$|^yes$/i) == 0
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ module CapistranoDbTasks
2
+ VERSION = "0.4.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'test_helper'
2
+
3
+ class CapistranoDbTasksTest < ActiveSupport::TestCase
4
+ # Replace this with your real tests.
5
+ test "the truth" do
6
+ assert true
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-db-tasks.senya
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.1
5
+ platform: ruby
6
+ authors:
7
+ - Sebastien Gruhier
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-11-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.0
27
+ description: A collection of capistrano tasks for syncing assets and databases
28
+ email:
29
+ - sebastien.gruhier@xilinus.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.markdown
37
+ - Rakefile
38
+ - capistrano-db-tasks.gemspec
39
+ - lib/capistrano-db-tasks.rb
40
+ - lib/capistrano-db-tasks/asset.rb
41
+ - lib/capistrano-db-tasks/compressors/base.rb
42
+ - lib/capistrano-db-tasks/compressors/bzip2.rb
43
+ - lib/capistrano-db-tasks/compressors/gzip.rb
44
+ - lib/capistrano-db-tasks/database.rb
45
+ - lib/capistrano-db-tasks/dbtasks.rb
46
+ - lib/capistrano-db-tasks/util.rb
47
+ - lib/capistrano-db-tasks/version.rb
48
+ - test/capistrano_db_tasks_test.rb
49
+ - test/test_helper.rb
50
+ homepage: https://github.com/cmrd-senya/capistrano-db-tasks/tree/dump_task.2
51
+ licenses: []
52
+ metadata: {}
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project: capistrano-db-tasks
69
+ rubygems_version: 2.5.1
70
+ signing_key:
71
+ specification_version: 4
72
+ summary: A collection of capistrano tasks for syncing assets and databases (a modification
73
+ from Senya)
74
+ test_files: []
75
+ has_rdoc: