capistrano 2.11.2 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
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