capistrano 2.6.0 → 2.6.1.pre

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