capistrano-db-tasks.senya 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: