capistrano 2.6.0 → 2.6.1.pre

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,3 +1,29 @@
1
+ ## 2.6.1 / June 25 2011
2
+
3
+ A short maintenance release, Some fixes to the verbose flag inside the Git SCM
4
+ as well as another argument for the (internal) `variable()` command, offering
5
+ a default. The Git SCM is now verbose by default, but can be disabled by
6
+ setting `:scm_verbose` to false.
7
+
8
+ There has been an additional method added to string, within the context of the
9
+ test suite, I'm always sketchy about adding additional methods to core
10
+ classes, but it's a short term fix until I make the time to patch the test
11
+ suite not to compare strings literally. The method is `String#compact`, and is
12
+ implemented simply as `self.gsub(/\s+/, ' ')`.
13
+
14
+ Here's the run-down of changes, and their committers, as always - a huge thank
15
+ you to the community that continues to drive Capistrano's development.
16
+
17
+ * `deploy:setup` now respects `:group_writable` (Mathew Davies)
18
+ * Fixes to `:scm_verbose` for the Git module (defaults to On.) (Daniel Duvall)
19
+ * Will now copy hidden files in the project's root into the release
20
+ directory (Mark Jaquith)
21
+ * Now handles closing already-dead connections in a sane way (does not raise
22
+ an exception) (Will Bryant)
23
+ * Renamed `Capistrano::VERSION::TINY` to `Capistrano::VERSION::PATCH` (Lee
24
+ Hambley)
25
+ * Removed the `VERSION` file (Lee Hambley)
26
+
1
27
  ## 2.6.0 / May 3 2011
2
28
 
3
29
  A rather large release, feature-version bump because of the new
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source "http://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in capistrano.gemspec
4
4
  gemspec
5
+
6
+ gem "rake"
@@ -1,2 +1,3 @@
1
1
  require 'capistrano/configuration'
2
2
  require 'capistrano/extensions'
3
+ require 'capistrano/ext/string'
@@ -74,5 +74,8 @@ The following options are understood:
74
74
  <%= color 'HOSTFILTER', :bold %>
75
75
  Execute tasks against this comma-separated list of host, but only if the host has the proper role for the task.
76
76
 
77
+ <%= color 'HOSTROLEFILTER', :bold %>
78
+ Execute tasks against the hosts in this comma-separated list of roles, but only if the host has the proper role for the task.
79
+
77
80
  <%= color 'ROLES', :bold %>
78
81
  Execute tasks against this comma-separated list of roles. Hosts which do not have the right roles will be skipped.
@@ -138,8 +138,11 @@ module Capistrano
138
138
  # Destroys sessions for each server in the list.
139
139
  def teardown_connections_to(servers)
140
140
  servers.each do |server|
141
- sessions[server].close
142
- sessions.delete(server)
141
+ begin
142
+ sessions.delete(server).close
143
+ rescue IOError
144
+ # the TCP connection is already dead
145
+ end
143
146
  end
144
147
  end
145
148
 
@@ -26,6 +26,9 @@ module Capistrano
26
26
  # Yet additionally, if the HOSTFILTER environment variable is set, it
27
27
  # will limit the result to hosts found in that (comma-separated) list.
28
28
  #
29
+ # If the HOSTROLEFILTER environment variable is set, it will limit the
30
+ # result to hosts found in that (comma-separated) list of roles
31
+ #
29
32
  # Usage:
30
33
  #
31
34
  # # return all known servers
@@ -39,6 +42,9 @@ module Capistrano
39
42
  # # returns the given hosts, translated to ServerDefinition objects
40
43
  # servers = find_servers :hosts => "jamis@example.host.com"
41
44
  def find_servers(options={})
45
+ return [] if options.key?(:hosts) && (options[:hosts].nil? || [] == options[:hosts])
46
+ return [] if options.key?(:roles) && (options[:roles].nil? || [] == options[:roles])
47
+
42
48
  hosts = server_list_from(ENV['HOSTS'] || options[:hosts])
43
49
 
44
50
  if hosts.any?
@@ -69,9 +75,21 @@ module Capistrano
69
75
  protected
70
76
 
71
77
  def filter_server_list(servers)
72
- return servers unless ENV['HOSTFILTER']
73
- filters = ENV['HOSTFILTER'].split(/,/)
74
- servers.select { |server| filters.include?(server.host) }
78
+ return servers unless ENV['HOSTFILTER'] or ENV['HOSTROLEFILTER']
79
+ if ENV['HOSTFILTER']
80
+ filters = ENV['HOSTFILTER'].split(/,/)
81
+ servers.select { |server| filters.include?(server.host) }
82
+ elsif ENV['HOSTROLEFILTER']
83
+ filters = ENV['HOSTROLEFILTER'].split(/,/).map do |role|
84
+ local_roles = roles[role.to_sym]
85
+ if local_roles.is_a? Array
86
+ roles[role.to_sym]
87
+ else
88
+ roles[role.to_sym].servers
89
+ end
90
+ end.flatten
91
+ servers.select { |server| filters.include?(server) }
92
+ end
75
93
  end
76
94
 
77
95
  def server_list_from(hosts)
@@ -0,0 +1,5 @@
1
+ class String
2
+ def compact
3
+ self.gsub(/\s+/, ' ')
4
+ end
5
+ end
@@ -183,7 +183,8 @@ namespace :deploy do
183
183
  task :setup, :except => { :no_release => true } do
184
184
  dirs = [deploy_to, releases_path, shared_path]
185
185
  dirs += shared_children.map { |d| File.join(shared_path, d) }
186
- run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
186
+ run "#{try_sudo} mkdir -p #{dirs.join(' ')}"
187
+ run "#{try_sudo} chmod g+w #{dirs.join(' ')}" if fetch(:group_writable, true)
187
188
  end
188
189
 
189
190
  desc <<-DESC
@@ -161,11 +161,11 @@ module Capistrano
161
161
 
162
162
  # A helper for accessing variable values, which takes into
163
163
  # consideration the current mode ("normal" vs. "local").
164
- def variable(name)
164
+ def variable(name, default = nil)
165
165
  if local? && configuration.exists?("local_#{name}".to_sym)
166
- return configuration["local_#{name}".to_sym]
166
+ return configuration["local_#{name}".to_sym] || default
167
167
  else
168
- configuration[name]
168
+ configuration[name] || default
169
169
  end
170
170
  end
171
171
 
@@ -144,16 +144,16 @@ module Capistrano
144
144
 
145
145
  # checkout into a local branch rather than a detached HEAD
146
146
  execute << "cd #{destination} && #{git} checkout #{verbose} -b deploy #{revision}"
147
-
147
+
148
148
  if variable(:git_enable_submodules)
149
149
  execute << "#{git} submodule #{verbose} init"
150
150
  execute << "#{git} submodule #{verbose} sync"
151
151
  execute << "#{git} submodule #{verbose} update --init --recursive"
152
152
  end
153
153
 
154
- execute.join(" && ")
154
+ execute.join(" && ").compact
155
155
  end
156
-
156
+
157
157
  # An expensive export. Performs a checkout as above, then
158
158
  # removes the repo.
159
159
  def export(revision, destination)
@@ -199,8 +199,8 @@ module Capistrano
199
199
 
200
200
  # Returns a string of diffs between two revisions
201
201
  def diff(from, to=nil)
202
- from << "..#{to}" if to
203
- scm :diff, from
202
+ return scm :diff, from unless to
203
+ scm :diff, "#{from}..#{to}"
204
204
  end
205
205
 
206
206
  # Returns a log of changes between the two revisions (inclusive).
@@ -266,7 +266,7 @@ module Capistrano
266
266
  # If verbose output is requested, return nil, otherwise return the
267
267
  # command-line switch for "quiet" ("-q").
268
268
  def verbose
269
- variable(:scm_verbose) ? nil : "-q"
269
+ variable(:scm_verbose, true) ? "-q" : nil
270
270
  end
271
271
  end
272
272
  end
@@ -39,14 +39,14 @@ module Capistrano
39
39
 
40
40
  def copy_repository_cache
41
41
  logger.trace "copying the cached version to #{configuration[:release_path]}"
42
- if copy_exclude.empty?
42
+ if copy_exclude.empty?
43
43
  run "cp -RPp #{repository_cache} #{configuration[:release_path]} && #{mark}"
44
44
  else
45
45
  exclusions = copy_exclude.map { |e| "--exclude=\"#{e}\"" }.join(' ')
46
- run "rsync -lrpt #{exclusions} #{repository_cache}/* #{configuration[:release_path]} && #{mark}"
46
+ run "rsync -lrpt #{exclusions} #{repository_cache}/ #{configuration[:release_path]} && #{mark}"
47
47
  end
48
48
  end
49
-
49
+
50
50
  def copy_exclude
51
51
  @copy_exclude ||= Array(configuration.fetch(:copy_exclude, []))
52
52
  end
@@ -3,16 +3,14 @@ module Capistrano
3
3
 
4
4
  class Version
5
5
 
6
- CURRENT = File.read(File.dirname(__FILE__) + '/../../VERSION')
7
-
8
- MAJOR, MINOR, TINY = CURRENT.scanf('%d.%d.%d')
9
-
10
- STRING = CURRENT.to_s
6
+ MAJOR = 2
7
+ MINOR = 6
8
+ PATCH = 1
11
9
 
12
10
  def self.to_s
13
- CURRENT
11
+ "#{MAJOR}.#{MINOR}.#{PATCH}.pre"
14
12
  end
15
-
13
+
16
14
  end
17
15
 
18
16
  end
@@ -355,6 +355,24 @@ class ConfigurationConnectionsTest < Test::Unit::TestCase
355
355
  assert_equal 2, block_called
356
356
  end
357
357
 
358
+ def test_execute_on_servers_should_cope_with_already_dropped_connections_when_attempting_to_close_them
359
+ cap1 = server("cap1")
360
+ cap2 = server("cap2")
361
+ connection1 = mock()
362
+ connection2 = mock()
363
+ connection3 = mock()
364
+ connection4 = mock()
365
+ connection1.expects(:close).raises(IOError)
366
+ connection2.expects(:close)
367
+ connection3.expects(:close)
368
+ connection4.expects(:close)
369
+ @config.current_task = mock_task(:max_hosts => 1)
370
+ @config.expects(:find_servers_for_task).times(2).with(@config.current_task, {}).returns([cap1, cap2])
371
+ Capistrano::SSH.expects(:connect).times(4).returns(connection1).then.returns(connection2).then.returns(connection3).then.returns(connection4)
372
+ @config.execute_on_servers {}
373
+ @config.execute_on_servers {}
374
+ end
375
+
358
376
  def test_connect_should_honor_once_option
359
377
  assert @config.sessions.empty?
360
378
  @config.current_task = mock_task
@@ -131,6 +131,14 @@ class ConfigurationServersTest < Test::Unit::TestCase
131
131
  ENV.delete('HOSTFILTER')
132
132
  end
133
133
 
134
+ def test_task_with_hostrolefilter_environment_variable_should_apply_only_to_those_hosts
135
+ ENV['HOSTROLEFILTER'] = "web"
136
+ task = new_task(:testing)
137
+ assert_equal %w(web1 web2).sort, @config.find_servers_for_task(task).map { |s| s.host }.sort
138
+ ensure
139
+ ENV.delete('HOSTROLEFILTER')
140
+ end
141
+
134
142
  def test_task_with_only_should_apply_only_to_matching_tasks
135
143
  task = new_task(:testing, @config, :roles => :app, :only => { :primary => true })
136
144
  assert_equal %w(app1), @config.find_servers_for_task(task).map { |s| s.host }
@@ -155,4 +163,21 @@ class ConfigurationServersTest < Test::Unit::TestCase
155
163
  assert_equal %w(app1 app2 app3), @config.find_servers(:roles => lambda { :app }).map { |s| s.host }.sort
156
164
  assert_equal %w(app2 file), @config.find_servers(:roles => lambda { [:report, :file] }).map { |s| s.host }.sort
157
165
  end
166
+
167
+ def test_find_servers_with_hosts_nil_or_empty
168
+ assert_equal [], @config.find_servers(:hosts => nil)
169
+ assert_equal [], @config.find_servers(:hosts => [])
170
+ result = @config.find_servers(:hosts => @config.find_servers(:roles => :report)[0])
171
+ assert_equal 1, result.size
172
+ result = @config.find_servers(:hosts => "app1")
173
+ assert_equal 1, result.size
174
+ end
175
+
176
+ def test_find_servers_with_rolees_nil_or_empty
177
+ assert_equal [], @config.find_servers(:roles => nil)
178
+ assert_equal [], @config.find_servers(:roles => [])
179
+ result = @config.find_servers(:roles => :report)
180
+ assert_equal 1, result.size
181
+ end
182
+
158
183
  end
@@ -31,7 +31,7 @@ class DeploySCMGitTest < Test::Unit::TestCase
31
31
  @config[:repository] = "git@somehost.com:project.git"
32
32
  dest = "/var/www"
33
33
  rev = 'c2d9e79'
34
- assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
34
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
35
35
 
36
36
  # With :scm_command
37
37
  git = "/opt/local/bin/git"
@@ -43,12 +43,12 @@ class DeploySCMGitTest < Test::Unit::TestCase
43
43
  assert_equal "#{git} clone -q git@somehost.com:project.git /var/www && cd /var/www && #{git} checkout -q -b deploy #{rev} && #{git} submodule -q init && #{git} submodule -q sync && #{git} submodule -q update --init --recursive", @source.checkout(rev, dest).gsub(/\s+/, ' ')
44
44
  end
45
45
 
46
- def test_checkout_with_verbose_should_not_use_q_switch
46
+ def test_checkout_with_verbose_should_use_q_switch
47
47
  @config[:repository] = "git@somehost.com:project.git"
48
48
  @config[:scm_verbose] = true
49
49
  dest = "/var/www"
50
50
  rev = 'c2d9e79'
51
- assert_equal "git clone git@somehost.com:project.git /var/www && cd /var/www && git checkout -b deploy #{rev}", @source.checkout(rev, dest)
51
+ assert_equal "git clone -q git@somehost.com:project.git /var/www && cd /var/www && git checkout -q -b deploy #{rev}", @source.checkout(rev, dest)
52
52
  end
53
53
 
54
54
  def test_diff
@@ -68,7 +68,7 @@ class DeploySCMGitTest < Test::Unit::TestCase
68
68
  end
69
69
  assert_equal "d11006102c07c94e5d54dd0ee63dca825c93ed61", revision
70
70
  end
71
-
71
+
72
72
  def test_query_revision_has_whitespace
73
73
  revision = @source.query_revision('HEAD') do |o|
74
74
  assert_equal "git ls-remote . HEAD", o
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capistrano
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease:
4
+ hash: 961915984
5
+ prerelease: 6
6
6
  segments:
7
7
  - 2
8
8
  - 6
9
- - 0
10
- version: 2.6.0
9
+ - 1
10
+ - pre
11
+ version: 2.6.1.pre
11
12
  platform: ruby
12
13
  authors:
13
14
  - Jamis Buck
@@ -155,6 +156,7 @@ files:
155
156
  - lib/capistrano/configuration/servers.rb
156
157
  - lib/capistrano/configuration/variables.rb
157
158
  - lib/capistrano/errors.rb
159
+ - lib/capistrano/ext/string.rb
158
160
  - lib/capistrano/extensions.rb
159
161
  - lib/capistrano/logger.rb
160
162
  - lib/capistrano/processable.rb
@@ -254,12 +256,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
254
256
  required_rubygems_version: !ruby/object:Gem::Requirement
255
257
  none: false
256
258
  requirements:
257
- - - ">="
259
+ - - ">"
258
260
  - !ruby/object:Gem::Version
259
- hash: 3
261
+ hash: 25
260
262
  segments:
261
- - 0
262
- version: "0"
263
+ - 1
264
+ - 3
265
+ - 1
266
+ version: 1.3.1
263
267
  requirements: []
264
268
 
265
269
  rubyforge_project: