capistrano-extensions 0.1.5 → 0.1.8
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.
- data/ISSUES.txt +10 -0
- data/Manifest.txt +4 -0
- data/README.rdoc +32 -0
- data/VERSION.yml +4 -0
- data/lib/capistrano-extensions/deploy.rb +107 -191
- data/lib/capistrano-extensions/recipes/content_sync.rb +103 -0
- data/lib/capistrano-extensions/recipes/db_sync.rb +136 -0
- metadata +15 -24
- data/README.txt +0 -53
- data/Rakefile +0 -35
- data/capistrano-extensions.gemspec +0 -39
- data/lib/capistrano-extensions/version.rb +0 -20
data/ISSUES.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
Known Bugs and Shortcomings
|
2
|
+
|
3
|
+
(this one is specific to passenger-recipes, which really should be merged into capistrano-extensions...)
|
4
|
+
* When introducing a new shared content directory, a bug can manifest itself when trying to sync production data back to your staging server. Consider the following scenario:
|
5
|
+
1) Add a new upload field to your app (e.g. using file_column)
|
6
|
+
2) Update the deploy script to reference this new shared directory (via either :shared_content or :content_directories)
|
7
|
+
3) Try cap remote:sync FROM=production TO=staging --> It will fail when it tries to tarball up the shared content on production.
|
8
|
+
|
9
|
+
Currently, the best workaround is to log onto your production server and created the shared content directory, e.g. #{shared_path}/content/model_that_you_added_file_column_to
|
10
|
+
|
data/Manifest.txt
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
History.txt
|
2
|
+
ISSUES.txt
|
2
3
|
Manifest.txt
|
3
4
|
README.txt
|
4
5
|
Rakefile
|
6
|
+
TODO
|
5
7
|
bin/capistrano-extensions-sync-content
|
6
8
|
bin/capistrano-extensions-sync-db
|
7
9
|
capistrano-extensions.gemspec
|
8
10
|
lib/capistrano-extensions.rb
|
9
11
|
lib/capistrano-extensions/deploy.rb
|
10
12
|
lib/capistrano-extensions/geminstaller_dependency.rb
|
13
|
+
lib/capistrano-extensions/recipes/content_sync.rb
|
14
|
+
lib/capistrano-extensions/recipes/db_sync.rb
|
11
15
|
lib/capistrano-extensions/version.rb
|
data/README.rdoc
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
= capistrano-extensions
|
2
|
+
|
3
|
+
* Stable API: http://johntrupiano.rubyforge.org/capistrano-extensions
|
4
|
+
* Source: http://github.com/jtrupiano/capistrano-extensions
|
5
|
+
|
6
|
+
== DESCRIPTION/FEATURES:
|
7
|
+
|
8
|
+
This gem provides a base set of {Capistrano}[http://www.capify.org/] extensions including the following:
|
9
|
+
* a new :gemfile RemoteDependency type
|
10
|
+
* tasks/helpers for handling public and private asset folders (e.g. created by the file_column plugin)
|
11
|
+
* tasks/helpers for auto-syncing server gems (via integration with the {GemInstaller}[http://geminstaller.rubyforge.org/] gem)
|
12
|
+
* helpers for dealing with multiple deployable environments (e.g. staging, prodtest, production)
|
13
|
+
* tasks for working with remote logfiles
|
14
|
+
* tasks for database/asset synchronization from production back to local environments
|
15
|
+
* integration with {environmentalist}[http://johntrupiano.rubyforge.org/environmentalist]
|
16
|
+
|
17
|
+
For a detailed exploration of these features, check out the wiki: http://github.com/jtrupiano/capistrano-extensions/wikis/home
|
18
|
+
|
19
|
+
== SYNOPSIS:
|
20
|
+
|
21
|
+
FIX (code sample of usage)
|
22
|
+
|
23
|
+
== REQUIREMENTS:
|
24
|
+
|
25
|
+
* Capistrano ~> 2.5.5
|
26
|
+
* GemInstaller ~> 0.5.1
|
27
|
+
|
28
|
+
== INSTALL:
|
29
|
+
|
30
|
+
* sudo gem install capistrano-extensions (stable from rubyforge)
|
31
|
+
* sudo gem install jtrupiano-capistrano-extensions (HEAD of repo from github)
|
32
|
+
|
data/VERSION.yml
ADDED
@@ -1,9 +1,8 @@
|
|
1
1
|
require 'capistrano-extensions/geminstaller_dependency'
|
2
|
-
require 'capistrano/server_definition'
|
3
2
|
|
4
3
|
# Overrides the majority of recipes from Capistrano's deploy recipe set.
|
5
4
|
Capistrano::Configuration.instance(:must_exist).load do
|
6
|
-
# Add
|
5
|
+
# Add us to the load path
|
7
6
|
@load_paths << File.expand_path(File.dirname(__FILE__))
|
8
7
|
|
9
8
|
# ========================================================================
|
@@ -27,10 +26,10 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
27
26
|
# changes if you do decide to muck with these!
|
28
27
|
# =========================================================================
|
29
28
|
|
30
|
-
set(:use_sudo, false)
|
31
|
-
set(:deploy_via, :
|
32
|
-
_cset(:deploy_to) { "/var/
|
33
|
-
_cset(:deployable_environments, [:
|
29
|
+
set(:use_sudo, false) # we don't want to use sudo-- we don't have to!
|
30
|
+
set(:deploy_via, :copy) # no need to have subversion on the production server
|
31
|
+
_cset(:deploy_to) { "/var/vhosts/#{application}" }
|
32
|
+
_cset(:deployable_environments, [:staging])
|
34
33
|
|
35
34
|
_cset(:rails_config_path) { File.join(latest_release, 'config') }
|
36
35
|
_cset(:db_conf) {
|
@@ -45,11 +44,36 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
45
44
|
_cset(:public_path) { File.join(latest_release, 'public') }
|
46
45
|
_cset(:log_path) { "/var/log/#{application}" }
|
47
46
|
|
47
|
+
# Local Properties
|
48
|
+
_cset(:tmp_dir, "tmp/cap")
|
49
|
+
# when local:syncing, should we keep backups just in case of failure?
|
50
|
+
_cset(:store_dev_backups, false)
|
51
|
+
# how long to allow remote backups to be valid (at both cache levels)
|
52
|
+
_cset(:remote_backup_expires, 172800) # 2 days in seconds.
|
53
|
+
# when remote:syncing, should we keep backups just in case of failure?
|
54
|
+
_cset(:store_remote_backups, true)
|
55
|
+
# paths to exclude during deployment
|
56
|
+
_cset(:exclude_paths, [])
|
57
|
+
|
58
|
+
_cset(:copy_cache) { File.expand_path("~/.capistrano/#{application}") }
|
59
|
+
set(:copy_exclude) {
|
60
|
+
# don't deploy the other environment directories
|
61
|
+
envs = fetch(:deployable_environments).dup
|
62
|
+
envs.delete_if { |env| rails_env.to_sym == env.to_sym }
|
63
|
+
envs.map! { |env| File.join("config", "#{env}") }
|
64
|
+
|
65
|
+
envs + fetch(:exclude_paths)
|
66
|
+
}
|
67
|
+
|
68
|
+
_cset(:zip, "gzip")
|
69
|
+
_cset(:unzip, "gunzip")
|
70
|
+
_cset(:zip_ext, "gz")
|
71
|
+
|
48
72
|
# Allow recipes to ask for a certain local environment
|
49
73
|
def local_db_conf(env = nil)
|
50
74
|
env ||= fetch(:rails_env)
|
51
75
|
fetch(:config_structure, :rails).to_sym == :sls ?
|
52
|
-
File.join('config', env, 'database.yml') :
|
76
|
+
File.join('config', env.to_s, 'database.yml') :
|
53
77
|
File.join('config', 'database.yml')
|
54
78
|
end
|
55
79
|
|
@@ -79,17 +103,16 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
79
103
|
# Now, let's actually include our common recipes!
|
80
104
|
namespace :deploy do
|
81
105
|
desc <<-DESC
|
82
|
-
[capistrano-extensions] Creates shared directories and symbolic links to them by the
|
83
|
-
:content_directories and :shared_content properties. See the README for
|
84
|
-
further explanation.
|
106
|
+
[capistrano-extensions] Creates shared directories and symbolic links to them by reading the
|
107
|
+
:content_directories and :shared_content properties. See the README for further explanation.
|
85
108
|
DESC
|
86
109
|
task :create_shared_file_column_dirs, :roles => :app, :except => { :no_release => true } do
|
87
110
|
mappings = content_directories.inject(shared_content) { |hsh, dir| hsh.merge({"content/#{dir}" => "public/#{dir}"}) }
|
88
111
|
mappings.each_pair do |remote, local|
|
89
112
|
run <<-CMD
|
113
|
+
umask 0022 &&
|
90
114
|
mkdir -p #{shared_path}/#{remote} &&
|
91
|
-
ln -sf #{shared_path}/#{remote} #{latest_release}/#{local}
|
92
|
-
chmod 755 -R #{shared_path}/#{remote}
|
115
|
+
ln -sf #{shared_path}/#{remote} #{latest_release}/#{local}
|
93
116
|
CMD
|
94
117
|
end
|
95
118
|
end
|
@@ -115,88 +138,17 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
115
138
|
filesystem
|
116
139
|
DESC
|
117
140
|
task :pull do
|
118
|
-
tmp_location = "#{shared_path}/#{rails_env}.log
|
119
|
-
run "cp #{log_path}/#{rails_env}.log #{shared_path}/ &&
|
120
|
-
get "#{tmp_location}", "#{application}-#{rails_env}.log
|
141
|
+
tmp_location = "#{shared_path}/#{rails_env}.log.#{zip_ext}"
|
142
|
+
run "cp #{log_path}/#{rails_env}.log #{shared_path}/ && #{zip} #{shared_path}/#{rails_env}.log"
|
143
|
+
get "#{tmp_location}", "#{application}-#{rails_env}.log.#{zip_ext}"
|
121
144
|
run "rm #{tmp_location}"
|
122
145
|
end
|
123
146
|
end
|
124
147
|
|
148
|
+
load 'recipes/db_sync'
|
149
|
+
load 'recipes/content_sync'
|
150
|
+
|
125
151
|
namespace :remote do
|
126
|
-
desc <<-DESC
|
127
|
-
[capistrano-extensions] Uploads the backup file downloaded from local:backup_db (specified via the FROM env variable),
|
128
|
-
copies it to the remove environment specified by RAILS_ENV, and imports (via mysql command line tool) it back into the
|
129
|
-
remote database.
|
130
|
-
DESC
|
131
|
-
task :restore_db, :roles => :db do
|
132
|
-
env = ENV['FROM'] || 'production'
|
133
|
-
|
134
|
-
puts "\033[1;41m Restoring database backup to #{rails_env} environment \033[0m"
|
135
|
-
if deployable_environments.include?(rails_env.to_sym)
|
136
|
-
# remote environment
|
137
|
-
local_backup_file = "#{application}-#{env}-db.sql.gz"
|
138
|
-
remote_file = "#{shared_path}/restore_db.sql"
|
139
|
-
if !File.exists?(local_backup_file)
|
140
|
-
puts "Could not find backup file: #{local_backup_file}"
|
141
|
-
exit 1
|
142
|
-
end
|
143
|
-
upload(local_backup_file, "#{remote_file}.gz")
|
144
|
-
|
145
|
-
pass_str = pluck_pass_str(db)
|
146
|
-
run "gunzip -f #{remote_file}.gz"
|
147
|
-
run "mysql -u#{db['username']} #{pass_str} #{db['database']} < #{remote_file}"
|
148
|
-
run "rm -f #{remote_file}"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
desc <<-DESC
|
153
|
-
[capistrano-extensions]: Backs up target deployable environment's database (identified
|
154
|
-
by the FROM environment variable, which defaults to 'production') and restores it to
|
155
|
-
the remote database identified by the TO environment variable, which defaults to "staging."
|
156
|
-
DESC
|
157
|
-
task :sync_db do
|
158
|
-
system("capistrano-extensions-sync-db #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
|
159
|
-
end
|
160
|
-
|
161
|
-
desc <<-DESC
|
162
|
-
[capistrano-extensions]: Uploads the backup file downloaded from local:backup_content (specified via the
|
163
|
-
FROM env variable), copies it to the remote environment specified by RAILS_ENV, and unpacks it into the
|
164
|
-
shared/ directory.
|
165
|
-
DESC
|
166
|
-
task :restore_content do
|
167
|
-
from = ENV['FROM'] || 'production'
|
168
|
-
|
169
|
-
if deployable_environments.include?(rails_env.to_sym)
|
170
|
-
local_backup_file = "#{application}-#{from}-content_backup.tar.gz"
|
171
|
-
remote_file = "#{shared_path}/content_backup.tar.gz"
|
172
|
-
|
173
|
-
if !File.exists?(local_backup_file)
|
174
|
-
puts "Could not find backup file: #{local_backup_file}"
|
175
|
-
exit 1
|
176
|
-
end
|
177
|
-
|
178
|
-
upload(local_backup_file, "#{remote_file}")
|
179
|
-
remote_dirs = ["content"] + shared_content.keys
|
180
|
-
|
181
|
-
run("cd #{shared_path} && rm -rf #{remote_dirs.join(' ')} && tar xzf #{remote_file} -C #{shared_path}/")
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
desc <<-DESC
|
186
|
-
[capistrano-extensions]: Backs up target deployable environment's shared content (identified by the FROM environment
|
187
|
-
variable, which defaults to 'production') and restores it to the remote environment identified
|
188
|
-
by the TO envrionment variable, which defaults to "staging."
|
189
|
-
|
190
|
-
Because multiple capistrano configurations must be loaded, an external executable
|
191
|
-
(capistrano-extensions-sync_content) is invoked, which independently calls capistrano. See the
|
192
|
-
executable at $GEM_HOME/capistrano-extensions-0.1.2/bin/capistrano-extensions-sync_content
|
193
|
-
|
194
|
-
$> cap remote:sync_content FROM=production TO=staging
|
195
|
-
DESC
|
196
|
-
task :sync_content do
|
197
|
-
system("capistrano-extensions-sync-content #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
|
198
|
-
end
|
199
|
-
|
200
152
|
desc <<-DESC
|
201
153
|
[capistrano-extensions]: Wrapper fro remote:sync_db and remote:sync_content.
|
202
154
|
$> cap remote:sync FROM=production TO=staging
|
@@ -209,116 +161,42 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
209
161
|
|
210
162
|
namespace :local do
|
211
163
|
desc <<-DESC
|
212
|
-
[capistrano-extensions]:
|
213
|
-
|
214
|
-
DESC
|
215
|
-
task :backup_db, :roles => :db do
|
216
|
-
pass_str = pluck_pass_str(db)
|
217
|
-
|
218
|
-
run "mysqldump -u#{db['username']} #{pass_str} #{db['database']} > #{shared_path}/db_backup.sql"
|
219
|
-
run "gzip #{shared_path}/db_backup.sql"
|
220
|
-
get "#{shared_path}/db_backup.sql.gz", "#{application}-#{rails_env}-db.sql.gz"
|
221
|
-
run "rm -f #{shared_path}/db_backup.sql.gz #{shared_path}/db_backup.sql"
|
222
|
-
end
|
223
|
-
|
224
|
-
desc <<-DESC
|
225
|
-
[capistrano-extensions] Untars the backup file downloaded from local:backup_db (specified via the FROM env
|
226
|
-
variable, which defalts to RAILS_ENV), and imports (via mysql command line tool) it back into the database
|
227
|
-
defined in the RAILS_ENV env variable.
|
228
|
-
|
229
|
-
ToDo: implement proper rollback: currently, if the mysql import succeeds, but the rm fails,
|
230
|
-
the database won't be rolled back. Not sure this is even all that important or necessary, since
|
231
|
-
it's a local database that doesn't demand integrity (in other words, you're still going to have to
|
232
|
-
fix it, but it's not mission critical).
|
233
|
-
DESC
|
234
|
-
task :restore_db, :roles => :db do
|
235
|
-
on_rollback { "gzip #{application}-#{from}-db.sql"}
|
236
|
-
|
237
|
-
from = ENV['FROM'] || rails_env
|
238
|
-
|
239
|
-
env = ENV['RESTORE_ENV'] || 'development'
|
240
|
-
y = YAML.load_file(local_db_conf(env))[env]
|
241
|
-
db, user = y['database'], (y['username'] || 'root') # update me!
|
242
|
-
|
243
|
-
pass_str = pluck_pass_str(y)
|
244
|
-
|
245
|
-
puts "\033[1;41m Restoring database backup to #{env} environment \033[0m"
|
246
|
-
# local
|
247
|
-
system <<-CMD
|
248
|
-
gunzip #{application}-#{from}-db.sql.gz &&
|
249
|
-
mysql -u#{user} #{pass_str} #{db} < #{application}-#{from}-db.sql
|
250
|
-
CMD
|
251
|
-
end
|
252
|
-
|
253
|
-
desc <<-DESC
|
254
|
-
[capistrano-extensions]: Downloads a tarball of uploaded content (that lives in public/
|
255
|
-
directory, as specified by the :content_directories property) from the production site
|
256
|
-
back to the local filesystem
|
164
|
+
[capistrano-extensions]: Wrapper for local:sync_db and local:sync_content
|
165
|
+
$> cap local:sync RAILS_ENV=production RESTORE_ENV=development
|
257
166
|
DESC
|
258
|
-
task :
|
259
|
-
|
260
|
-
|
261
|
-
run "cd #{shared_path} && tar czf #{shared_path}/content_backup.tar.gz #{folders.join(' ')}"
|
262
|
-
|
263
|
-
#run "cd #{content_path} && tar czf #{shared_path}/content_backup.tar.gz *"
|
264
|
-
download("#{shared_path}/content_backup.tar.gz", "#{application}-#{rails_env}-content_backup.tar.gz")
|
265
|
-
run "rm -f #{shared_path}/content_backup.tar.gz"
|
167
|
+
task :sync do
|
168
|
+
sync_db
|
169
|
+
sync_content
|
266
170
|
end
|
171
|
+
end
|
172
|
+
|
173
|
+
namespace :util do
|
267
174
|
|
268
|
-
|
269
|
-
[capistrano-extensions]:
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
system "mkdir -p tmp/content-#{from}"
|
276
|
-
system "tar xzf #{application}-#{from}-content_backup.tar.gz -C tmp/content-#{from}"
|
277
|
-
system "rm -f #{application}-#{from}-content_backup.tar.gz"
|
278
|
-
|
279
|
-
shared_content.each_pair do |remote, local|
|
280
|
-
system "rm -rf #{local} && mv tmp/content-#{from}/#{remote} #{local}"
|
175
|
+
namespace :tmp do
|
176
|
+
desc "[capistrano-extensions]: Displays warning if :tmp_dir has more than 10 files or is greater than 50MB"
|
177
|
+
task :check do
|
178
|
+
#[ 5 -le "`ls -1 tmp/cap | wc -l`" ] && echo "Display Me"
|
179
|
+
cmd = %Q{ [ 10 -le "`ls -1 #{tmp_dir} | wc -l`" ] || [ 50 -le "`du -sh #{tmp_dir} | awk '{print int($1)}'`" ] && printf "\033[1;41m Clean up #{tmp_dir} directory \033[0m\n" && du -sh #{tmp_dir}/* }
|
180
|
+
system(cmd)
|
281
181
|
end
|
282
182
|
|
283
|
-
|
284
|
-
|
285
|
-
system
|
286
|
-
end
|
287
|
-
|
288
|
-
end
|
289
|
-
|
290
|
-
desc <<-DESC
|
291
|
-
[capistrano-extensions]: Wrapper for local:backup_db and local:restore_db.
|
292
|
-
$> cap local:sync_db RAILS_ENV=production RESTORE_ENV=development
|
293
|
-
DESC
|
294
|
-
task :sync_db do
|
295
|
-
transaction do
|
296
|
-
backup_db
|
297
|
-
ENV['FROM'] = rails_env
|
298
|
-
restore_db
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
desc <<-DESC
|
303
|
-
[capistrano-extensions]: Wrapper for local:backup_content and local:restore_content
|
304
|
-
$> cap local:sync_content RAILS_ENV=production RESTORE_ENV=development
|
305
|
-
DESC
|
306
|
-
task :sync_content do
|
307
|
-
transaction do
|
308
|
-
backup_content
|
309
|
-
restore_content
|
183
|
+
desc "[capistrano-extensions]: Remove the current remote env's backups from :tmp_dir"
|
184
|
+
task :clean_remote do
|
185
|
+
system("rm -f #{tmp_dir}/#{application}-#{rails_env}*")
|
310
186
|
end
|
311
|
-
end
|
312
187
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
188
|
+
# desc "Removes all but a single backup from :tmp_dir"
|
189
|
+
# task :clean do
|
190
|
+
#
|
191
|
+
# end
|
192
|
+
#
|
193
|
+
# desc "Removes all tmp files from :tmp_dir"
|
194
|
+
# task :remove do
|
195
|
+
#
|
196
|
+
# end
|
320
197
|
end
|
321
198
|
end
|
199
|
+
|
322
200
|
end
|
323
201
|
|
324
202
|
def pluck_pass_str(db_config)
|
@@ -327,4 +205,42 @@ def pluck_pass_str(db_config)
|
|
327
205
|
pass_str = "-p#{pass_str.gsub('$', '\$')}"
|
328
206
|
end
|
329
207
|
pass_str || ''
|
330
|
-
end
|
208
|
+
end
|
209
|
+
|
210
|
+
module LocalUtils
|
211
|
+
def current_timestamp
|
212
|
+
@current_timestamp ||= Time.now.to_i
|
213
|
+
end
|
214
|
+
|
215
|
+
def local_db_backup_file(args = {})
|
216
|
+
env = args[:env] || rails_env
|
217
|
+
timestamp = args[:timestamp] || current_timestamp
|
218
|
+
"#{tmp_dir}/#{application}-#{env}-db-#{timestamp}.sql"
|
219
|
+
end
|
220
|
+
|
221
|
+
def local_content_backup_dir(args={})
|
222
|
+
env = args[:env] || rails_env
|
223
|
+
timestamp = args[:timestamp] || current_timestamp
|
224
|
+
"#{tmp_dir}/#{application}-#{env}-content-#{timestamp}"
|
225
|
+
end
|
226
|
+
|
227
|
+
def retrieve_local_files(env, type)
|
228
|
+
`ls -r #{tmp_dir} | awk -F"-" '{ if ($2 ~ /#{env}/ && $3 ~ /#{type}/) { print $4; } }'`.split(' ')
|
229
|
+
end
|
230
|
+
|
231
|
+
def most_recent_local_backup(env, type)
|
232
|
+
retrieve_local_files(env, type).first.to_i
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
module RemoteUtils
|
237
|
+
def last_mod_time(path)
|
238
|
+
capture("stat -c%Y #{path}").to_i
|
239
|
+
end
|
240
|
+
|
241
|
+
def server_cache_valid?(path)
|
242
|
+
capture("[ -f #{path} ] || echo '1'").empty? && ((Time.now.to_i - last_mod_time(path)) <= remote_backup_expires) # two days in seconds
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
include LocalUtils, RemoteUtils
|
@@ -0,0 +1,103 @@
|
|
1
|
+
namespace :remote do
|
2
|
+
desc <<-DESC
|
3
|
+
[capistrano-extensions]: Uploads the backup file downloaded from local:backup_content (specified via the
|
4
|
+
FROM env variable), copies it to the remote environment specified by RAILS_ENV, and unpacks it into the
|
5
|
+
shared/ directory.
|
6
|
+
DESC
|
7
|
+
task :restore_content do
|
8
|
+
from = ENV['FROM'] || 'production'
|
9
|
+
|
10
|
+
if deployable_environments.include?(rails_env.to_sym)
|
11
|
+
generate_remote_content_backup if store_remote_backups
|
12
|
+
|
13
|
+
local_backup_file = local_content_backup_dir(:timestamp => most_recent_local_backup(from, 'content'), :env => from) + ".tar.#{zip_ext}"
|
14
|
+
remote_dir = "#{shared_path}/restore_#{from}_content"
|
15
|
+
remote_file = "#{remote_dir}.tar.#{zip_ext}"
|
16
|
+
|
17
|
+
if !File.exists?(local_backup_file)
|
18
|
+
puts "Could not find backup file: #{local_backup_file}"
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
upload(local_backup_file, "#{remote_file}")
|
23
|
+
remote_dirs = [content_dir] + shared_content.keys
|
24
|
+
|
25
|
+
run("cd #{shared_path} && rm -rf #{remote_dirs.join(' ')} && tar xzf #{remote_file} -C #{shared_path}/")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
desc <<-DESC
|
30
|
+
[capistrano-extensions]: Backs up remote server's shared content and restores it to a separate remote server.
|
31
|
+
$> cap remote:sync_content FROM=production TO=staging
|
32
|
+
DESC
|
33
|
+
task :sync_content do
|
34
|
+
system("capistrano-extensions-sync-content #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
namespace :local do
|
39
|
+
desc <<-DESC
|
40
|
+
[capistrano-extensions]: Downloads a tarball of shared content (identified by the :shared_content and
|
41
|
+
:content_directories properties) from a deployable environment (RAILS_ENV) to the local filesystem.
|
42
|
+
DESC
|
43
|
+
task :backup_content do
|
44
|
+
# sort by last alphabetically (forcing the most recent timestamp to the top)
|
45
|
+
files = retrieve_local_files(rails_env, 'content')
|
46
|
+
|
47
|
+
if files.empty?
|
48
|
+
# pull it from the server
|
49
|
+
generate_remote_content_backup unless server_cache_valid?(content_backup_file)
|
50
|
+
system("mkdir -p #{tmp_dir}")
|
51
|
+
download(content_backup_file, "#{local_content_backup_dir}.tar.#{zip_ext}")
|
52
|
+
else
|
53
|
+
# set us up to use our local cache
|
54
|
+
@current_timestamp = files.first.to_i # actually has the extension hanging off of it, but shouldn't be a problem
|
55
|
+
end
|
56
|
+
# Notify user if :tmp_dir is too large
|
57
|
+
util::tmp::check
|
58
|
+
end
|
59
|
+
|
60
|
+
desc <<-DESC
|
61
|
+
[capistrano-extensions]: Restores the backed up content (env var FROM specifies which environment
|
62
|
+
was backed up, defaults to RAILS_ENV) to the local development environment app
|
63
|
+
DESC
|
64
|
+
task :restore_content do
|
65
|
+
from = ENV['FROM'] || rails_env
|
66
|
+
|
67
|
+
local_dir = local_content_backup_dir(:env => from)
|
68
|
+
system "mkdir -p #{local_dir}"
|
69
|
+
system "tar xzf #{local_dir}.tar.#{zip_ext} -C #{local_dir}"
|
70
|
+
|
71
|
+
shared_content.each_pair do |remote, local|
|
72
|
+
system "rm -rf #{local} && mv #{local_dir}/#{remote} #{local}"
|
73
|
+
end
|
74
|
+
|
75
|
+
content_directories.each do |public_dir|
|
76
|
+
system "rm -rf public/#{public_dir}"
|
77
|
+
system "mv #{local_dir}/content/#{public_dir} public/"
|
78
|
+
end
|
79
|
+
|
80
|
+
system "rm -rf #{local_dir}"
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
desc <<-DESC
|
85
|
+
[capistrano-extensions]: Wrapper for local:backup_content and local:restore_content
|
86
|
+
$> cap local:sync_content RAILS_ENV=production RESTORE_ENV=development
|
87
|
+
DESC
|
88
|
+
task :sync_content do
|
89
|
+
transaction do
|
90
|
+
backup_content
|
91
|
+
restore_content
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def content_backup_file
|
97
|
+
"#{shared_path}/backup_#{rails_env}_content.tar.#{zip_ext}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def generate_remote_content_backup
|
101
|
+
folders = [content_dir] + shared_content.keys
|
102
|
+
run "cd #{shared_path} && tar czf #{content_backup_file} #{folders.join(' ')}"
|
103
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
namespace :remote do
|
2
|
+
desc <<-DESC
|
3
|
+
[capistrano-extensions] Uploads the backup file downloaded from local:backup_db (specified via the FROM env variable),
|
4
|
+
copies it to the remote environment specified by RAILS_ENV, and imports (via mysql command line tool) it back into the
|
5
|
+
remote database.
|
6
|
+
DESC
|
7
|
+
task :restore_db, :roles => :db do
|
8
|
+
env = ENV['FROM'] || 'production'
|
9
|
+
|
10
|
+
puts "\033[1;41m Restoring database backup to #{rails_env} environment \033[0m"
|
11
|
+
if deployable_environments.include?(rails_env.to_sym)
|
12
|
+
generate_remote_db_backup if store_remote_backups
|
13
|
+
|
14
|
+
# remote environment
|
15
|
+
local_backup_file = local_db_backup_file(:timestamp => most_recent_local_backup(env, 'db'), :env => env) + ".#{zip_ext}"
|
16
|
+
remote_file = "#{shared_path}/restore_#{env}_db.sql"
|
17
|
+
|
18
|
+
if !File.exists?(local_backup_file)
|
19
|
+
puts "Could not find backup file: #{local_backup_file}"
|
20
|
+
exit 1
|
21
|
+
end
|
22
|
+
upload(local_backup_file, "#{remote_file}.#{zip_ext}")
|
23
|
+
|
24
|
+
pass_str = pluck_pass_str(db)
|
25
|
+
run "#{unzip} -c #{remote_file}.#{zip_ext} > #{remote_file}"
|
26
|
+
run "mysql -u#{db['username']} #{pass_str} #{db['database']} < #{remote_file}"
|
27
|
+
run "rm -f #{remote_file}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc <<-DESC
|
32
|
+
[capistrano-extensions]: Backs up target deployable environment's database (identified
|
33
|
+
by the FROM environment variable, which defaults to 'production') and restores it to
|
34
|
+
the remote database identified by the TO environment variable, which defaults to "staging."
|
35
|
+
DESC
|
36
|
+
task :sync_db do
|
37
|
+
system("capistrano-extensions-sync-db #{ENV['FROM'] || 'production'} #{ENV['TO'] || 'staging'}")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
namespace :local do
|
42
|
+
desc <<-DESC
|
43
|
+
[capistrano-extensions]: Backs up deployable environment's database (identified by the
|
44
|
+
RAILS_ENV environment variable, which defaults to 'production') and copies it to the local machine
|
45
|
+
DESC
|
46
|
+
task :backup_db, :roles => :db do
|
47
|
+
|
48
|
+
# sort by last alphabetically (forcing the most recent timestamp to the top)
|
49
|
+
files = retrieve_local_files(rails_env, 'db')
|
50
|
+
|
51
|
+
if files.empty?
|
52
|
+
# pull it from the server
|
53
|
+
generate_remote_db_backup unless server_cache_valid?(db_backup_zip_file)
|
54
|
+
system "mkdir -p #{tmp_dir}"
|
55
|
+
download(db_backup_zip_file, "#{local_db_backup_file}.#{zip_ext}")
|
56
|
+
else
|
57
|
+
# set us up to use our local cache
|
58
|
+
@current_timestamp = files.first.to_i # actually has the extension hanging off of it, but shouldn't be a problem
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
desc <<-DESC
|
63
|
+
[capistrano-extensions] Untars the backup file downloaded from local:backup_db (specified via the FROM env
|
64
|
+
variable, which defalts to RAILS_ENV), and imports (via mysql command line tool) it back into the database
|
65
|
+
defined in the RESTORE_ENV env variable (defaults to development).
|
66
|
+
DESC
|
67
|
+
task :restore_db, :roles => :db do
|
68
|
+
from = ENV['FROM'] || rails_env
|
69
|
+
env = ENV['RESTORE_ENV'] || 'development'
|
70
|
+
|
71
|
+
y = YAML.load_file(local_db_conf(env))[env]
|
72
|
+
db, user = y['database'], (y['username'] || 'root') # update me!
|
73
|
+
|
74
|
+
pass_str = pluck_pass_str(y)
|
75
|
+
mysql_str = "mysql -u#{user} #{pass_str} #{db}"
|
76
|
+
mysql_dump = "mysqldump --add-drop-database -u#{user} #{pass_str} #{db}"
|
77
|
+
|
78
|
+
local_backup_file = local_db_backup_file(:env => env)
|
79
|
+
remote_backup_file = local_db_backup_file(:env => from)
|
80
|
+
|
81
|
+
puts "\033[1;41m Restoring database backup to #{env} environment \033[0m"
|
82
|
+
|
83
|
+
# local
|
84
|
+
cmd = ""
|
85
|
+
if store_dev_backups
|
86
|
+
cmd << <<-CMD
|
87
|
+
mkdir -p #{tmp_dir} &&
|
88
|
+
#{mysql_dump} | #{zip} > #{local_backup_file}.#{zip_ext} &&
|
89
|
+
CMD
|
90
|
+
end
|
91
|
+
cmd << <<-CMD
|
92
|
+
#{unzip} -c #{remote_backup_file}.#{zip_ext} > #{remote_backup_file} &&
|
93
|
+
#{mysql_str} < #{remote_backup_file} &&
|
94
|
+
rm -f #{remote_backup_file}
|
95
|
+
CMD
|
96
|
+
system(cmd.strip)
|
97
|
+
|
98
|
+
# Notify user if :tmp_dir is too large
|
99
|
+
util::tmp::check
|
100
|
+
end
|
101
|
+
|
102
|
+
desc <<-DESC
|
103
|
+
[capistrano-extensions]: Wrapper for local:backup_db and local:restore_db.
|
104
|
+
$> cap local:sync_db RAILS_ENV=production RESTORE_ENV=development
|
105
|
+
DESC
|
106
|
+
task :sync_db do
|
107
|
+
transaction do
|
108
|
+
backup_db
|
109
|
+
ENV['FROM'] = rails_env
|
110
|
+
restore_db
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
desc <<-DESC
|
115
|
+
[capistrano-extensions]: Ensure that a fresh remote data dump is retrieved before syncing to the local environment.
|
116
|
+
DESC
|
117
|
+
task :resync_db do
|
118
|
+
util::tmp::clean_remote
|
119
|
+
sync_db
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
def db_backup_file
|
125
|
+
"#{shared_path}/backup_#{rails_env}_db.sql"
|
126
|
+
end
|
127
|
+
|
128
|
+
def db_backup_zip_file
|
129
|
+
"#{db_backup_file}.#{zip_ext}"
|
130
|
+
end
|
131
|
+
|
132
|
+
def generate_remote_db_backup
|
133
|
+
pass_str = pluck_pass_str(db)
|
134
|
+
run "mysqldump --add-drop-database -u#{db['username']} #{pass_str} #{db['database']} > #{db_backup_file}"
|
135
|
+
run "rm -f #{db_backup_zip_file} && #{zip} #{db_backup_file} && rm -f #{db_backup_file}"
|
136
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano-extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Trupiano
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-04-27 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -20,7 +20,7 @@ dependencies:
|
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
22
22
|
- !ruby/object:Gem::Version
|
23
|
-
version: 2.5.
|
23
|
+
version: 2.5.5
|
24
24
|
version:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: geminstaller
|
@@ -30,17 +30,7 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.5.
|
34
|
-
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: hoe
|
37
|
-
type: :development
|
38
|
-
version_requirement:
|
39
|
-
version_requirements: !ruby/object:Gem::Requirement
|
40
|
-
requirements:
|
41
|
-
- - ">="
|
42
|
-
- !ruby/object:Gem::Version
|
43
|
-
version: 1.8.2
|
33
|
+
version: 0.5.1
|
44
34
|
version:
|
45
35
|
description: A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment
|
46
36
|
email: jtrupiano@gmail.com
|
@@ -50,27 +40,28 @@ executables:
|
|
50
40
|
extensions: []
|
51
41
|
|
52
42
|
extra_rdoc_files:
|
53
|
-
-
|
54
|
-
- Manifest.txt
|
55
|
-
- README.txt
|
43
|
+
- README.rdoc
|
56
44
|
files:
|
57
45
|
- History.txt
|
46
|
+
- ISSUES.txt
|
58
47
|
- Manifest.txt
|
59
|
-
- README.
|
60
|
-
-
|
48
|
+
- README.rdoc
|
49
|
+
- VERSION.yml
|
61
50
|
- bin/capistrano-extensions-sync-content
|
62
51
|
- bin/capistrano-extensions-sync-db
|
63
|
-
- capistrano-extensions
|
64
|
-
- lib/capistrano-extensions.rb
|
52
|
+
- lib/capistrano-extensions
|
65
53
|
- lib/capistrano-extensions/deploy.rb
|
66
54
|
- lib/capistrano-extensions/geminstaller_dependency.rb
|
67
|
-
- lib/capistrano-extensions/
|
55
|
+
- lib/capistrano-extensions/recipes
|
56
|
+
- lib/capistrano-extensions/recipes/content_sync.rb
|
57
|
+
- lib/capistrano-extensions/recipes/db_sync.rb
|
58
|
+
- lib/capistrano-extensions.rb
|
68
59
|
has_rdoc: true
|
69
60
|
homepage: http://github.com/jtrupiano/capistrano-extensions
|
70
61
|
post_install_message:
|
71
62
|
rdoc_options:
|
72
|
-
- --
|
73
|
-
-
|
63
|
+
- --inline-source
|
64
|
+
- --charset=UTF-8
|
74
65
|
require_paths:
|
75
66
|
- lib
|
76
67
|
required_ruby_version: !ruby/object:Gem::Requirement
|
data/README.txt
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
= capistrano-extensions
|
2
|
-
|
3
|
-
* http://github.com/jtrupiano/capistrano-extensions
|
4
|
-
|
5
|
-
== DESCRIPTION/FEATURES:
|
6
|
-
|
7
|
-
This gem provides a base set of Capistrano extensions including the following:
|
8
|
-
* a new :gemfile RemoteDependency type
|
9
|
-
* tasks/helpers for handling public and private asset folders (e.g. created by the file_column plugin)
|
10
|
-
* tasks/helpers for auto-syncing server gems (via integration with Chad Wooley's GemInstaller gem)
|
11
|
-
* helpers for dealing with multiple deployable environments (e.g. staging, prodtest, production)
|
12
|
-
* tasks for working with remote logfiles
|
13
|
-
* tasks for database/asset synchronization from production back to local environments
|
14
|
-
|
15
|
-
For a detailed exploration of these features, check out the wiki: http://github.com/jtrupiano/capistrano-extensions/wikis/home
|
16
|
-
|
17
|
-
== SYNOPSIS:
|
18
|
-
|
19
|
-
FIX (code sample of usage)
|
20
|
-
|
21
|
-
== REQUIREMENTS:
|
22
|
-
|
23
|
-
* Capistrano ~> 2.5.4
|
24
|
-
* GemInstaller ~> 0.5.0
|
25
|
-
|
26
|
-
== INSTALL:
|
27
|
-
|
28
|
-
* sudo gem install capistrano-extensions
|
29
|
-
|
30
|
-
== LICENSE:
|
31
|
-
|
32
|
-
(The MIT License)
|
33
|
-
|
34
|
-
Copyright (c) 2008 FIX
|
35
|
-
|
36
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
37
|
-
a copy of this software and associated documentation files (the
|
38
|
-
'Software'), to deal in the Software without restriction, including
|
39
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
40
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
41
|
-
permit persons to whom the Software is furnished to do so, subject to
|
42
|
-
the following conditions:
|
43
|
-
|
44
|
-
The above copyright notice and this permission notice shall be
|
45
|
-
included in all copies or substantial portions of the Software.
|
46
|
-
|
47
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
48
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
49
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
50
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
51
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
52
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
53
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
# -*- ruby -*-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'hoe'
|
5
|
-
require './lib/capistrano-extensions.rb'
|
6
|
-
require "./lib/capistrano-extensions/version"
|
7
|
-
|
8
|
-
PKG_NAME = "capistrano-extensions"
|
9
|
-
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
|
-
version = CapistranoExtensions::Version::STRING.dup
|
11
|
-
if ENV['SNAPSHOT'].to_i == 1
|
12
|
-
version << "." << Time.now.utc.strftime("%Y%m%d%H%M%S")
|
13
|
-
end
|
14
|
-
PKG_VERSION = version
|
15
|
-
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
16
|
-
|
17
|
-
Hoe.new(PKG_NAME, PKG_VERSION) do |p|
|
18
|
-
p.rubyforge_name = 'johntrupiano' # if different than lowercase project name
|
19
|
-
p.developer('John Trupiano', 'jtrupiano@gmail.com')
|
20
|
-
p.name = PKG_NAME
|
21
|
-
p.version = PKG_VERSION
|
22
|
-
#p.platform = Gem::Platform::RUBY
|
23
|
-
p.author = "John Trupiano"
|
24
|
-
p.email = "jtrupiano@gmail.com"
|
25
|
-
p.description = %q(A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment)
|
26
|
-
p.summary = p.description # More details later??
|
27
|
-
p.remote_rdoc_dir = PKG_NAME # Release to /PKG_NAME
|
28
|
-
# p.changes = p.paragraphs_of('CHANGELOG', 0..1).join("\n\n")
|
29
|
-
p.extra_deps << ["capistrano", "~> 2.5.4"]
|
30
|
-
p.extra_deps << ["geminstaller", "~> 0.5.0"]
|
31
|
-
p.need_zip = true
|
32
|
-
p.need_tar = false
|
33
|
-
end
|
34
|
-
|
35
|
-
# vim: syntax=Ruby
|
@@ -1,39 +0,0 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = %q{capistrano-extensions}
|
3
|
-
s.version = "0.1.4"
|
4
|
-
|
5
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
-
s.authors = ["John Trupiano"]
|
7
|
-
s.date = %q{2008-09-12}
|
8
|
-
s.description = %q{A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment}
|
9
|
-
s.email = %q{jtrupiano@gmail.com}
|
10
|
-
s.executables = ["capistrano-extensions-sync-content", "capistrano-extensions-sync-db"]
|
11
|
-
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
12
|
-
s.files = ["History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/capistrano-extensions-sync-content", "bin/capistrano-extensions-sync-db", "lib/capistrano-extensions.rb", "lib/capistrano-extensions/deploy.rb", "lib/capistrano-extensions/geminstaller_dependency.rb", "lib/capistrano-extensions/version.rb"]
|
13
|
-
s.has_rdoc = true
|
14
|
-
s.homepage = %q{http://github.com/jtrupiano/capistrano-extensions}
|
15
|
-
s.rdoc_options = ["--main", "README.txt"]
|
16
|
-
s.require_paths = ["lib"]
|
17
|
-
s.rubyforge_project = %q{johntrupiano}
|
18
|
-
s.rubygems_version = %q{1.2.0}
|
19
|
-
s.summary = %q{A base set of Capistrano extensions-- aids with the file_column plugin, the GemInstaller gem, multiple deployable environments, logfile helpers, and database/asset synchronization from production to local environment}
|
20
|
-
|
21
|
-
if s.respond_to? :specification_version then
|
22
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
23
|
-
s.specification_version = 2
|
24
|
-
|
25
|
-
if current_version >= 3 then
|
26
|
-
s.add_runtime_dependency(%q<capistrano>, [">= 2.4.3"])
|
27
|
-
s.add_runtime_dependency(%q<geminstaller>, [">= 0.4.3"])
|
28
|
-
s.add_development_dependency(%q<hoe>, [">= 1.7.0"])
|
29
|
-
else
|
30
|
-
s.add_dependency(%q<capistrano>, [">= 2.4.3"])
|
31
|
-
s.add_dependency(%q<geminstaller>, [">= 0.4.3"])
|
32
|
-
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
33
|
-
end
|
34
|
-
else
|
35
|
-
s.add_dependency(%q<capistrano>, [">= 2.4.3"])
|
36
|
-
s.add_dependency(%q<geminstaller>, [">= 0.4.3"])
|
37
|
-
s.add_dependency(%q<hoe>, [">= 1.7.0"])
|
38
|
-
end
|
39
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module CapistranoExtensions
|
2
|
-
module Version #:nodoc:
|
3
|
-
# A method for comparing versions of required modules. It expects two
|
4
|
-
# arrays of integers as parameters, the first being the minimum version
|
5
|
-
# required, and the second being the actual version available. It returns
|
6
|
-
# true if the actual version is at least equal to the required version.
|
7
|
-
def self.check(required, actual) #:nodoc:
|
8
|
-
required = required.map { |v| "%06d" % v }.join(".")
|
9
|
-
actual = actual.map { |v| "%06d" % v }.join(".")
|
10
|
-
return actual >= required
|
11
|
-
end
|
12
|
-
|
13
|
-
MAJOR = 0
|
14
|
-
MINOR = 1
|
15
|
-
TINY = 5
|
16
|
-
|
17
|
-
STRING = [MAJOR, MINOR, TINY].join(".")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|