capistrano 2.11.2 → 2.12.0

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/CHANGELOG CHANGED
@@ -1,6 +1,22 @@
1
- ## 2.11.2 / Febuary 22 2012
2
-
3
- Fixes some bugs with the now deprecated `deploy:symlink` fallback option.
1
+ ## 2.12.0 / April 13 2012
2
+
3
+ This release revserts the very verbose logging introduced in the previous version, it also
4
+ enables a handful of power-user features which are largely un-documented, but shouldn't be
5
+ important unless you are looking for them. Undocumented code shouldn't scare you, simply
6
+ read through deploy.rb in the Gem if you want to know how a new feature works!
7
+
8
+ * Update mapped commands to remove symlink deprecation warning. Despo Pentara (despo)
9
+ * Add the "rpm" remote dependency. Nick Hoffman (nickhoffman)
10
+ * Add commented deploy:cleanup task to default recipe. Jean-Philippe Doyle (j15e)
11
+ * Teach deploy:web:enable to fail gracefully. Lee Marlow (lmarlow)
12
+ * Ticket 193 alias task show wrong name when it is not overridden. Rafa García (rgo)
13
+ * Allow configuration of which roles assets are precompiled on. Frederick Cheung (fcheung)
14
+ * Fix transfer action to honor dry-run flag. Serg Podtynnyi (shtirlic)
15
+ * Changed single to double quotes for Windows, fixes a Windows bug in the HG module. Matthew J Morrison (mattjmorrison)
16
+ * Add UnsharedRemoteCache (copied from eycap gem). Ben Symonds (bensymonds)
17
+
18
+ As ever, a sincere thanks to all contributors, and do not hesitate to contact me if this
19
+ release causes problems for you.
4
20
 
5
21
  ## 2.11.0 / Febuary 20 2012
6
22
 
@@ -190,7 +206,7 @@ acceptable)
190
206
  * Various fixes to path handling bugs in the copt strategy. (Philippe Rathé)
191
207
 
192
208
  ## 2.5.21 / April 6 2011
193
-
209
+
194
210
  * Fixed to follow best-practice guidelines from Bundler (Ben Langfeld)
195
211
  * No longer force a gemset for Capistrano development. (Ben Langfeld)
196
212
 
@@ -259,7 +275,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
259
275
 
260
276
  * Fixes Darcs remote repository problem when using the copy strategy [Alex `regularfry` Young]
261
277
  * Documentation improvements for embedding Capistrano [Lee Hambley]
262
- * Fixes ticket #95 -formally deprecating the before_something and after_something methods [Lee Hambley]
278
+ * Fixes ticket #95 -formally deprecating the before_something and after_something methods [Lee Hambley]
263
279
 
264
280
  ## 2.5.9 / 1 August 2009
265
281
 
@@ -274,7 +290,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
274
290
  * #77 - Copy command doesn't work on Solaris due to tar/gtar
275
291
  * #76 - Invalid Subversion URL
276
292
  * Improved web:disable task, now suggests a .htaccess block to use suggested by Rafael García
277
- * Includes more logger options (can now select stdout, stderr of a file) [Rafael García]
293
+ * Includes more logger options (can now select stdout, stderr of a file) [Rafael García]
278
294
 
279
295
  ## 2.5.8 / July 2009
280
296
 
@@ -424,7 +440,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
424
440
  * Added :normalize_asset_timestamps option to deployment, defaulting to true, which allows asset timestamping to be disabled [John Trupiano]
425
441
 
426
442
 
427
- ## 2.4.0 Preview Release #1 (2.3.101) / June 5, 2008
443
+ ## 2.4.0 Preview Release #1 (2.3.101) / June 5, 2008
428
444
 
429
445
  * Only make deploy:start, deploy:stop, and deploy:restart try sudo as :runner. The other sudo-enabled tasks (deploy:setup, deploy:cleanup, etc.) will now use the :admin_runner user (which by default is unset). [Jamis Buck]
430
446
 
@@ -452,7 +468,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
452
468
 
453
469
  * Revert "make sudo helper play nicely with complex command chains", since it broke stuff [Jamis Buck]
454
470
 
455
- * Make set(:default_shell, false) work for not using a shell on a per-command basis [Ryan McGeary]
471
+ * Make set(:default_shell, false) work for not using a shell on a per-command basis [Ryan McGeary]
456
472
 
457
473
  * Improved test coverage [Ryan McGeary]
458
474
 
@@ -660,7 +676,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
660
676
 
661
677
 
662
678
  ## 1.99.2 (2.0 Preview 3) / June 15, 2007
663
-
679
+
664
680
  * CVS SCM module [Brian Phillips]
665
681
 
666
682
  * Fix typo in Perforce SCM module [Chris Bailey]
@@ -870,7 +886,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
870
886
  on_rollback { run "ln -nfs #{previous_release} #{current_path}" }
871
887
  run "ln -nfs #{current_release} #{current_path}"
872
888
  end
873
-
889
+
874
890
  cap symlink # will not run on 192.168.0.3
875
891
 
876
892
  * Deprecate the -r/--recipe switch in favor of -f/--file (for more make/rake-like semantics) [Jamis Buck]
@@ -886,7 +902,7 @@ Fixes a low-value bug, thanks to Chris G for the well submitted patch:
886
902
  task :setup, :roles => [ :app, :web, :db ]
887
903
  # normally this would run every where
888
904
  end
889
-
905
+
890
906
  ROLES=app cap setup # this will only run for the app role, overwritting the default declaration
891
907
 
892
908
  * Added :hosts option to task definition that allows you to specify cross-cutting tasks [DHH]. Example:
data/bin/capify CHANGED
@@ -59,6 +59,9 @@ role :app, "your app-server here" # This may be the sam
59
59
  role :db, "your primary db-server here", :primary => true # This is where Rails migrations will run
60
60
  role :db, "your slave db-server here"
61
61
 
62
+ # if you want to clean up old releases on each deploy uncomment this:
63
+ # after "deploy:restart", "deploy:cleanup"
64
+
62
65
  # if you\'re still using the script/reaper helper you will need
63
66
  # these http://github.com/rails/irs_process_scripts
64
67
 
@@ -219,8 +219,6 @@ module Capistrano
219
219
  command_line = [environment, shell, cmd].compact.join(" ")
220
220
  ch[:command] = command_line
221
221
 
222
- logger.trace command_line, ch[:server] if logger
223
-
224
222
  ch.exec(command_line)
225
223
  ch.send_data(options[:data]) if options[:data]
226
224
  else
@@ -12,7 +12,7 @@ module Capistrano
12
12
  opts = options.dup
13
13
  upload(StringIO.new(data), path, opts)
14
14
  end
15
-
15
+
16
16
  # Get file remote_path from FIRST server targeted by
17
17
  # the current task and transfer it to local machine as path.
18
18
  #
@@ -35,13 +35,12 @@ module Capistrano
35
35
  end
36
36
 
37
37
  def transfer(direction, from, to, options={}, &block)
38
+ if dry_run
39
+ return logger.debug "transfering: #{[direction, from, to] * ', '}"
40
+ end
38
41
  execute_on_servers(options) do |servers|
39
42
  targets = servers.map { |s| sessions[s] }
40
- if dry_run
41
- logger.debug "transfering: #{[direction, from, to, targets, options.merge(:logger => logger).inspect ] * ', '}"
42
- else
43
43
  Transfer.process(direction, from, to, targets, options.merge(:logger => logger), &block)
44
- end
45
44
  end
46
45
  end
47
46
 
@@ -15,7 +15,8 @@ module Capistrano
15
15
  raise ArgumentError, "expected a valid task name"
16
16
  end
17
17
 
18
- task = find_task(old_name) or raise NoSuchTaskError, "the task `#{old_name}' does not exist"
18
+ original_task = find_task(old_name) or raise NoSuchTaskError, "the task `#{old_name}' does not exist"
19
+ task = original_task.dup # Dup. task to avoid modify original task
19
20
  task.name = new_name
20
21
 
21
22
  define_task(task)
@@ -90,7 +90,7 @@ module Capistrano
90
90
  # Usage:
91
91
  #
92
92
  # on :before, "some:hook", "another:hook", :only => "deploy:update"
93
- # on :after, "some:hook", :except => "deploy:symlink"
93
+ # on :after, "some:hook", :except => "deploy:create_symlink"
94
94
  # on :before, "global:hook"
95
95
  # on :after, :only => :deploy do
96
96
  # puts "after deploy here"
@@ -176,6 +176,8 @@ module Capistrano
176
176
  def initialize(name, parent)
177
177
  @parent = parent
178
178
  @name = name
179
+
180
+ explicitly_define_clashing_kernel_methods
179
181
  end
180
182
 
181
183
  def role(*args)
@@ -197,6 +199,17 @@ module Capistrano
197
199
  include Capistrano::Configuration::AliasTask
198
200
  include Capistrano::Configuration::Namespaces
199
201
  undef :desc, :next_description
202
+
203
+ protected
204
+ def explicitly_define_clashing_kernel_methods
205
+ (parent.public_methods & Kernel.methods).each do |m|
206
+ next if self.method(m).owner == self.class
207
+ if parent.method(m).owner == parent.class
208
+ metaclass = class << self; self; end
209
+ metaclass.send(:define_method, m) {|*args, &block| parent.send(m, *args, &block)}
210
+ end
211
+ end
212
+ end
200
213
  end
201
214
  end
202
215
  end
@@ -7,7 +7,7 @@ load 'deploy'
7
7
  map = { "diff_from_last_deploy" => "deploy:pending:diff",
8
8
  "update" => "deploy:update",
9
9
  "update_code" => "deploy:update_code",
10
- "symlink" => "deploy:symlink",
10
+ "symlink" => "deploy:create_symlink",
11
11
  "restart" => "deploy:restart",
12
12
  "rollback" => "deploy:rollback",
13
13
  "cleanup" => "deploy:cleanup",
@@ -29,4 +29,4 @@ task :spinner do
29
29
  warn "[DEPRECATED] `spinner' is deprecated. Use `deploy:start' instead."
30
30
  set :runner, fetch(:spinner_user, "app")
31
31
  deploy.start
32
- end
32
+ end
@@ -265,6 +265,7 @@ namespace :deploy do
265
265
  DESC
266
266
  task :symlink, :except => { :no_release => true } do
267
267
  Kernel.warn "[Deprecation Warning] This API has changed, please hook `deploy:create_symlink` instead of `deploy:symlink`."
268
+ create_symlink
268
269
  end
269
270
 
270
271
  desc <<-DESC
@@ -277,9 +278,6 @@ namespace :deploy do
277
278
  except `restart').
278
279
  DESC
279
280
  task :create_symlink, :except => { :no_release => true } do
280
-
281
- symlink # (Deprecated)
282
-
283
281
  on_rollback do
284
282
  if previous_release
285
283
  run "rm -f #{current_path}; ln -s #{previous_release} #{current_path}; true"
@@ -548,7 +546,7 @@ namespace :deploy do
548
546
  DESC
549
547
  task :disable, :roles => :web, :except => { :no_release => true } do
550
548
  require 'erb'
551
- on_rollback { run "rm #{shared_path}/system/#{maintenance_basename}.html" }
549
+ on_rollback { run "rm -f #{shared_path}/system/#{maintenance_basename}.html" }
552
550
 
553
551
  warn <<-EOHTACCESS
554
552
 
@@ -590,7 +588,7 @@ namespace :deploy do
590
588
  web-accessible again.
591
589
  DESC
592
590
  task :enable, :roles => :web, :except => { :no_release => true } do
593
- run "rm #{shared_path}/system/#{maintenance_basename}.html"
591
+ run "rm -f #{shared_path}/system/#{maintenance_basename}.html"
594
592
  end
595
593
  end
596
594
  end
@@ -2,6 +2,7 @@ load 'deploy' unless defined?(_cset)
2
2
 
3
3
  _cset :asset_env, "RAILS_GROUPS=assets"
4
4
  _cset :assets_prefix, "assets"
5
+ _cset :assets_role, [:web]
5
6
 
6
7
  _cset :normalize_asset_timestamps, false
7
8
 
@@ -18,7 +19,7 @@ namespace :deploy do
18
19
  for efficiency. If you cutomize the assets path prefix, override the \
19
20
  :assets_prefix variable to match.
20
21
  DESC
21
- task :symlink, :roles => :web, :except => { :no_release => true } do
22
+ task :symlink, :roles => assets_role, :except => { :no_release => true } do
22
23
  run <<-CMD
23
24
  rm -rf #{latest_release}/public/#{assets_prefix} &&
24
25
  mkdir -p #{latest_release}/public &&
@@ -37,7 +38,7 @@ namespace :deploy do
37
38
  set :rails_env, "production"
38
39
  set :asset_env, "RAILS_GROUPS=assets"
39
40
  DESC
40
- task :precompile, :roles => :web, :except => { :no_release => true } do
41
+ task :precompile, :roles => assets_role, :except => { :no_release => true } do
41
42
  run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:precompile"
42
43
  end
43
44
 
@@ -52,7 +53,7 @@ namespace :deploy do
52
53
  set :rails_env, "production"
53
54
  set :asset_env, "RAILS_GROUPS=assets"
54
55
  DESC
55
- task :clean, :roles => :web, :except => { :no_release => true } do
56
+ task :clean, :roles => assets_role, :except => { :no_release => true } do
56
57
  run "cd #{latest_release} && #{rake} RAILS_ENV=#{rails_env} #{asset_env} assets:clean"
57
58
  end
58
59
  end
@@ -49,6 +49,12 @@ module Capistrano
49
49
  self
50
50
  end
51
51
 
52
+ def rpm(name, version, options={})
53
+ @message ||= "package `#{name}' #{version} could not be found"
54
+ try("rpm -q #{name} | grep '#{version}'", options)
55
+ self
56
+ end
57
+
52
58
  def match(command, expect, options={})
53
59
  expect = Regexp.new(Regexp.escape(expect.to_s)) unless expect.is_a?(Regexp)
54
60
 
@@ -59,7 +59,7 @@ module Capistrano
59
59
  cmd = scm :log,
60
60
  verbose,
61
61
  "-r #{changeset}",
62
- "--template '{node|short}'"
62
+ '--template "{node|short}"'
63
63
  yield cmd
64
64
  end
65
65
 
@@ -34,7 +34,7 @@ module Capistrano
34
34
  d.remote.writable(configuration[:releases_path]).or("You do not have permissions to write to `#{configuration[:releases_path]}'.")
35
35
  end
36
36
  end
37
-
37
+
38
38
  protected
39
39
 
40
40
  # This is to allow helper methods like "run" and "put" to be more
@@ -52,7 +52,7 @@ module Capistrano
52
52
  cmd = args.join(' ')
53
53
  result = nil
54
54
  if RUBY_PLATFORM =~ /win32/
55
- cmd = cmd.split(/\s+/).collect {|w| w.match(/^[\w+]+:\/\//) ? w : w.gsub('/', '\\') }.join(' ') # Split command by spaces, change / by \\ unless element is a some+thing://
55
+ cmd = cmd.split(/\s+/).collect {|w| w.match(/^[\w+]+:\/\//) ? w : w.gsub('/', '\\') }.join(' ') # Split command by spaces, change / by \\ unless element is a some+thing://
56
56
  cmd.gsub!(/^cd /,'cd /D ') # Replace cd with cd /D
57
57
  cmd.gsub!(/&& cd /,'&& cd /D ') # Replace cd with cd /D
58
58
  logger.trace "executing locally: #{cmd}"
@@ -65,7 +65,7 @@ module Capistrano
65
65
  result = super
66
66
  end
67
67
  end
68
-
68
+
69
69
  logger.trace "command finished in #{(elapsed * 1000).round}ms"
70
70
  result
71
71
  end
@@ -54,83 +54,19 @@ module Capistrano
54
54
  # servers, and uncompresses it on each of them into the deployment
55
55
  # directory.
56
56
  def deploy!
57
- if copy_cache
58
- if File.exists?(copy_cache)
59
- logger.debug "refreshing local cache to revision #{revision} at #{copy_cache}"
60
- system(source.sync(revision, copy_cache))
61
- else
62
- logger.debug "preparing local cache at #{copy_cache}"
63
- system(source.checkout(revision, copy_cache))
64
- end
65
-
66
- # Check the return code of last system command and rollback if not 0
67
- unless $? == 0
68
- raise Capistrano::Error, "shell command failed with return code #{$?}"
69
- end
70
-
71
- build(copy_cache)
72
-
73
- FileUtils.mkdir_p(destination)
74
-
75
- logger.debug "copying cache to deployment staging area #{destination}"
76
- Dir.chdir(copy_cache) do
77
- queue = Dir.glob("*", File::FNM_DOTMATCH)
78
- while queue.any?
79
- item = queue.shift
80
- name = File.basename(item)
81
-
82
- next if name == "." || name == ".."
83
- next if copy_exclude.any? { |pattern| File.fnmatch(pattern, item) }
84
-
85
- if File.symlink?(item)
86
- FileUtils.ln_s(File.readlink(item), File.join(destination, item))
87
- elsif File.directory?(item)
88
- queue += Dir.glob("#{item}/*", File::FNM_DOTMATCH)
89
- FileUtils.mkdir(File.join(destination, item))
90
- else
91
- FileUtils.ln(item, File.join(destination, item))
92
- end
93
- end
94
- end
95
- else
96
- logger.debug "getting (via #{copy_strategy}) revision #{revision} to #{destination}"
97
- system(command)
98
-
99
- build(destination)
100
-
101
- if copy_exclude.any?
102
- logger.debug "processing exclusions..."
103
-
104
- copy_exclude.each do |pattern|
105
- delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
106
- # avoid the /.. trap that deletes the parent directories
107
- delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
108
- FileUtils.rm_rf(delete_list.compact)
109
- end
110
- end
111
- end
112
-
113
- File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
114
-
115
- logger.trace "compressing #{destination} to #{filename}"
116
- Dir.chdir(copy_dir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
57
+ copy_cache ? run_copy_cache_strategy : run_copy_strategy
117
58
 
59
+ create_revision_file
60
+ compress_repository
118
61
  distribute!
119
62
  ensure
120
- FileUtils.rm filename rescue nil
121
- FileUtils.rm_rf destination rescue nil
63
+ rollback_changes
122
64
  end
123
65
 
124
- def build(directory)
125
- return unless configuration[:build_script]
126
-
127
- Dir.chdir(directory) do
128
- self.system(configuration[:build_script])
129
- # Check the return code of last system command and rollback if not 0
130
- unless $? == 0
131
- raise Capistrano::Error, "shell command failed with return code #{$?}"
132
- end
133
- end
66
+ def build directory
67
+ execute "running build script on #{directory}" do
68
+ Dir.chdir(directory) { system(build_script) }
69
+ end if build_script
134
70
  end
135
71
 
136
72
  def check!
@@ -153,6 +89,143 @@ module Capistrano
153
89
 
154
90
  private
155
91
 
92
+ def run_copy_cache_strategy
93
+ copy_repository_to_local_cache
94
+ build copy_cache
95
+ copy_cache_to_staging_area
96
+ end
97
+
98
+ def run_copy_strategy
99
+ copy_repository_to_server
100
+ build destination
101
+ remove_excluded_files if copy_exclude.any?
102
+ end
103
+
104
+ def execute description, &block
105
+ logger.debug description
106
+ handle_system_errors &block
107
+ end
108
+
109
+ def handle_system_errors &block
110
+ block.call
111
+ raise_command_failed if last_command_failed?
112
+ end
113
+
114
+ def refresh_local_cache
115
+ execute "refreshing local cache to revision #{revision} at #{copy_cache}" do
116
+ system(source.sync(revision, copy_cache))
117
+ end
118
+ end
119
+
120
+ def create_local_cache
121
+ execute "preparing local cache at #{copy_cache}" do
122
+ system(source.checkout(revision, copy_cache))
123
+ end
124
+ end
125
+
126
+ def raise_command_failed
127
+ raise Capistrano::Error, "shell command failed with return code #{$?}"
128
+ end
129
+
130
+ def last_command_failed?
131
+ $? != 0
132
+ end
133
+
134
+ def copy_cache_to_staging_area
135
+ execute "copying cache to deployment staging area #{destination}" do
136
+ create_destination
137
+ Dir.chdir(copy_cache) { copy_files(queue_files) }
138
+ end
139
+ end
140
+
141
+ def create_destination
142
+ FileUtils.mkdir_p(destination)
143
+ end
144
+
145
+ def copy_files files
146
+ files.each { |name| process_file(name) }
147
+ end
148
+
149
+ def process_file name
150
+ send "copy_#{filetype(name)}", name
151
+ end
152
+
153
+ def filetype name
154
+ filetype = File.ftype name
155
+ filetype = "file" unless ["link", "directory"].include? filetype
156
+ filetype
157
+ end
158
+
159
+ def copy_link name
160
+ FileUtils.ln_s(File.readlink(name), File.join(destination, name))
161
+ end
162
+
163
+ def copy_directory name
164
+ FileUtils.mkdir(File.join(destination, name))
165
+ copy_files(queue_files(name))
166
+ end
167
+
168
+ def copy_file name
169
+ FileUtils.ln(name, File.join(destination, name))
170
+ end
171
+
172
+ def queue_files directory=nil
173
+ Dir.glob(pattern_for(directory), File::FNM_DOTMATCH).reject! { |file| excluded_files_contain? file }
174
+ end
175
+
176
+ def pattern_for directory
177
+ !directory.nil? ? "#{directory}/*" : "*"
178
+ end
179
+
180
+ def excluded_files_contain? file
181
+ copy_exclude.any? { |p| File.fnmatch(p, file) } or [ ".", ".."].include? File.basename(file)
182
+ end
183
+
184
+ def copy_repository_to_server
185
+ execute "getting (via #{copy_strategy}) revision #{revision} to #{destination}" do
186
+ copy_repository_via_strategy
187
+ end
188
+ end
189
+
190
+ def copy_repository_via_strategy
191
+ system(command)
192
+ end
193
+
194
+ def remove_excluded_files
195
+ logger.debug "processing exclusions..."
196
+
197
+ copy_exclude.each do |pattern|
198
+ delete_list = Dir.glob(File.join(destination, pattern), File::FNM_DOTMATCH)
199
+ # avoid the /.. trap that deletes the parent directories
200
+ delete_list.delete_if { |dir| dir =~ /\/\.\.$/ }
201
+ FileUtils.rm_rf(delete_list.compact)
202
+ end
203
+ end
204
+
205
+ def create_revision_file
206
+ File.open(File.join(destination, "REVISION"), "w") { |f| f.puts(revision) }
207
+ end
208
+
209
+ def compress_repository
210
+ execute "Compressing #{destination} to #{filename}" do
211
+ Dir.chdir(copy_dir) { system(compress(File.basename(destination), File.basename(filename)).join(" ")) }
212
+ end
213
+ end
214
+
215
+ def rollback_changes
216
+ FileUtils.rm filename rescue nil
217
+ FileUtils.rm_rf destination rescue nil
218
+ end
219
+
220
+ def copy_repository_to_local_cache
221
+ return refresh_local_cache if File.exists?(copy_cache)
222
+ create_local_cache
223
+ end
224
+
225
+ def build_script
226
+ configuration[:build_script]
227
+ end
228
+
156
229
  # Specify patterns to exclude from the copy. This is only valid
157
230
  # when using a local cache.
158
231
  def copy_exclude
@@ -237,10 +310,14 @@ module Capistrano
237
310
  compression.decompress_command + [file]
238
311
  end
239
312
 
313
+ def decompress_remote_file
314
+ run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
315
+ end
316
+
240
317
  # Distributes the file to the remote servers
241
318
  def distribute!
242
319
  upload(filename, remote_filename)
243
- run "cd #{configuration[:releases_path]} && #{decompress(remote_filename).join(" ")} && rm #{remote_filename}"
320
+ decompress_remote_file
244
321
  end
245
322
  end
246
323
 
@@ -0,0 +1,21 @@
1
+ require 'capistrano/recipes/deploy/strategy/remote_cache'
2
+
3
+ module Capistrano
4
+ module Deploy
5
+ module Strategy
6
+ class UnsharedRemoteCache < RemoteCache
7
+ def check!
8
+ super.check do |d|
9
+ d.remote.writable(repository_cache)
10
+ end
11
+ end
12
+
13
+ private
14
+
15
+ def repository_cache
16
+ configuration[:repository_cache]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -117,7 +117,7 @@ module Capistrano
117
117
 
118
118
  def prepare_scp_transfer(from, to, session)
119
119
  real_callback = callback || Proc.new do |channel, name, sent, total|
120
- logger.trace "#{transport} #{operation} #{from} -> #{to}", channel[:host] if logger && sent == 0
120
+ logger.trace "[#{channel[:host]}] #{name}" if logger && sent == 0
121
121
  end
122
122
 
123
123
  channel = case direction
@@ -167,9 +167,9 @@ module Capistrano
167
167
  if callback
168
168
  callback.call(event, op, *args)
169
169
  elsif event == :open
170
- logger.trace "#{transport} #{operation} #{from} -> #{to}", op[:host]
170
+ logger.trace "[#{op[:host]}] #{args[0].remote}"
171
171
  elsif event == :finish
172
- logger.trace "#{transport} #{operation} #{from} -> #{to} done", op[:host]
172
+ logger.trace "[#{op[:host]}] done"
173
173
  end
174
174
  end
175
175
 
@@ -4,8 +4,8 @@ module Capistrano
4
4
  class Version
5
5
 
6
6
  MAJOR = 2
7
- MINOR = 11
8
- PATCH = 2
7
+ MINOR = 12
8
+ PATCH = 0
9
9
 
10
10
  def self.to_s
11
11
  "#{MAJOR}.#{MINOR}.#{PATCH}"
@@ -59,7 +59,7 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
59
59
  config = make_config
60
60
  config.dry_run = true
61
61
  config.servers = %w[ foo ]
62
- config.expects(:sessions).returns({ 'foo-server' => 'bar' })
62
+ config.expects(:execute_on_servers).never
63
63
  ::Capistrano::Transfer.expects(:process).never
64
64
  config.put "foo", "bar", :mode => 0644
65
65
  end
@@ -203,7 +203,7 @@ class ConfigurationActionsInvocationTest < Test::Unit::TestCase
203
203
  a = mock("channel", :called => true)
204
204
  b = mock("stream", :called => true)
205
205
  c = mock("data", :called => true)
206
-
206
+
207
207
  callback[a, b, c]
208
208
  end
209
209
 
@@ -30,6 +30,14 @@ class AliasTaskTest < Test::Unit::TestCase
30
30
  assert @config.tasks.key?(:new_foo)
31
31
  end
32
32
 
33
+ def test_original_task_remain_with_same_name
34
+ @config.task(:foo) { 42 }
35
+ @config.alias_task 'new_foo', 'foo'
36
+
37
+ assert_equal :foo, @config.tasks[:foo].name
38
+ assert_equal :new_foo, @config.tasks[:new_foo].name
39
+ end
40
+
33
41
  def test_aliased_task_do_the_same
34
42
  @config.task(:foo) { 42 }
35
43
  @config.alias_task 'new_foo', 'foo'
@@ -308,4 +308,25 @@ class ConfigurationNamespacesDSLTest < Test::Unit::TestCase
308
308
  end
309
309
  assert_nil @config.find_task("outer::inner")
310
310
  end
311
+
312
+ def test_kernel_method_clashing_should_not_affect_method_delegation_to_parent
313
+ @config.class.class_eval do
314
+ def some_weird_method() 'config' end
315
+ end
316
+
317
+ @config.namespace(:clash) {}
318
+ namespace = @config.namespaces[:clash]
319
+ assert_equal 'config', namespace.some_weird_method
320
+
321
+ Kernel.module_eval do
322
+ def some_weird_method() 'kernel' end
323
+ end
324
+
325
+ @config.namespace(:clash2) {}
326
+ namespace = @config.namespaces[:clash2]
327
+ assert_equal 'config', namespace.some_weird_method
328
+
329
+ Kernel.send :remove_method, :some_weird_method
330
+ @config.class.send :remove_method, :some_weird_method
331
+ end
311
332
  end
@@ -43,6 +43,12 @@ class RemoteDependencyTest < Test::Unit::TestCase
43
43
  assert_equal "package `dpkg' 1.15 could not be found (host)", @dependency.message
44
44
  end
45
45
 
46
+ def test_should_use_standard_error_message_for_rpm
47
+ setup_for_a_configuration_rpm_run("rpm", "4.8", false)
48
+ @dependency.rpm("rpm", "4.8")
49
+ assert_equal "package `rpm' 4.8 could not be found (host)", @dependency.message
50
+ end
51
+
46
52
  def test_should_fail_if_directory_not_found
47
53
  setup_for_a_configuration_run("test -d /data", false)
48
54
  assert !@dependency.directory("/data").pass?
@@ -132,4 +138,9 @@ class RemoteDependencyTest < Test::Unit::TestCase
132
138
  find_deb_cmd = "dpkg -s #{name} | grep '^Version: #{version}'"
133
139
  setup_for_a_configuration_run(find_deb_cmd, passing)
134
140
  end
141
+
142
+ def setup_for_a_configuration_rpm_run(name, version, passing)
143
+ find_rpm_cmd = "rpm -q #{name} | grep '#{version}'"
144
+ setup_for_a_configuration_run(find_rpm_cmd, passing)
145
+ end
135
146
  end
@@ -39,7 +39,7 @@ class DeploySCMMercurialTest < Test::Unit::TestCase
39
39
  end
40
40
 
41
41
  def test_query_revision
42
- assert_equal "hg log -r 8a8e00b8f11b --template '{node|short}'", @source.query_revision('8a8e00b8f11b') { |o| o }
42
+ assert_equal "hg log -r 8a8e00b8f11b --template \"{node|short}\"", @source.query_revision('8a8e00b8f11b') { |o| o }
43
43
  end
44
44
 
45
45
  def test_username_should_be_backwards_compatible
@@ -306,15 +306,15 @@ class DeployStrategyCopyTest < Test::Unit::TestCase
306
306
 
307
307
  def prepare_directory_tree!(cache, exclude=false)
308
308
  Dir.expects(:glob).with("*", File::FNM_DOTMATCH).returns([".", "..", "app", "foo.txt"])
309
- File.expects(:directory?).with("app").returns(true)
309
+ File.expects(:ftype).with("app").returns("directory")
310
310
  FileUtils.expects(:mkdir).with("/temp/dir/1234567890/app")
311
- File.expects(:directory?).with("foo.txt").returns(false)
311
+ File.expects(:ftype).with("foo.txt").returns("file")
312
312
  FileUtils.expects(:ln).with("foo.txt", "/temp/dir/1234567890/foo.txt")
313
313
 
314
314
  Dir.expects(:glob).with("app/*", File::FNM_DOTMATCH).returns(["app/.", "app/..", "app/bar.txt"])
315
315
 
316
316
  unless exclude
317
- File.expects(:directory?).with("app/bar.txt").returns(false)
317
+ File.expects(:ftype).with("app/bar.txt").returns("file")
318
318
  FileUtils.expects(:ln).with("app/bar.txt", "/temp/dir/1234567890/app/bar.txt")
319
319
  end
320
320
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.2
4
+ version: 2.12.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2012-02-22 00:00:00.000000000Z
13
+ date: 2012-04-13 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: highline
17
- requirement: &70157295072440 !ruby/object:Gem::Requirement
17
+ requirement: &70100200770260 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ! '>='
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '0'
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *70157295072440
25
+ version_requirements: *70100200770260
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: net-ssh
28
- requirement: &70157295071180 !ruby/object:Gem::Requirement
28
+ requirement: &70100200769760 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ! '>='
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 2.0.14
34
34
  type: :runtime
35
35
  prerelease: false
36
- version_requirements: *70157295071180
36
+ version_requirements: *70100200769760
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: net-sftp
39
- requirement: &70157295069420 !ruby/object:Gem::Requirement
39
+ requirement: &70100200769280 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ! '>='
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 2.0.0
45
45
  type: :runtime
46
46
  prerelease: false
47
- version_requirements: *70157295069420
47
+ version_requirements: *70100200769280
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: net-scp
50
- requirement: &70157295068700 !ruby/object:Gem::Requirement
50
+ requirement: &70100200768800 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: 1.0.0
56
56
  type: :runtime
57
57
  prerelease: false
58
- version_requirements: *70157295068700
58
+ version_requirements: *70100200768800
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: net-ssh-gateway
61
- requirement: &70157295058440 !ruby/object:Gem::Requirement
61
+ requirement: &70100200768320 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: 1.1.0
67
67
  type: :runtime
68
68
  prerelease: false
69
- version_requirements: *70157295058440
69
+ version_requirements: *70100200768320
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: mocha
72
- requirement: &70157295056280 !ruby/object:Gem::Requirement
72
+ requirement: &70100200767840 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '0'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *70157295056280
80
+ version_requirements: *70100200767840
81
81
  description: Capistrano is a utility and framework for executing commands in parallel
82
82
  on multiple remote machines, via SSH.
83
83
  email:
@@ -152,6 +152,7 @@ files:
152
152
  - lib/capistrano/recipes/deploy/strategy/export.rb
153
153
  - lib/capistrano/recipes/deploy/strategy/remote.rb
154
154
  - lib/capistrano/recipes/deploy/strategy/remote_cache.rb
155
+ - lib/capistrano/recipes/deploy/strategy/unshared_remote_cache.rb
155
156
  - lib/capistrano/recipes/deploy/templates/maintenance.rhtml
156
157
  - lib/capistrano/recipes/standard.rb
157
158
  - lib/capistrano/recipes/templates/maintenance.rhtml
@@ -226,7 +227,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
226
227
  version: '0'
227
228
  requirements: []
228
229
  rubyforge_project:
229
- rubygems_version: 1.8.10
230
+ rubygems_version: 1.8.11
230
231
  signing_key:
231
232
  specification_version: 3
232
233
  summary: Capistrano - Welcome to easy deployment with Ruby over SSH