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 +26 -0
- data/Gemfile +2 -0
- data/lib/capistrano.rb +1 -0
- data/lib/capistrano/cli/help.txt +3 -0
- data/lib/capistrano/configuration/connections.rb +5 -2
- data/lib/capistrano/configuration/servers.rb +21 -3
- data/lib/capistrano/ext/string.rb +5 -0
- data/lib/capistrano/recipes/deploy.rb +2 -1
- data/lib/capistrano/recipes/deploy/scm/base.rb +3 -3
- data/lib/capistrano/recipes/deploy/scm/git.rb +6 -6
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +3 -3
- data/lib/capistrano/version.rb +5 -7
- data/test/configuration/connections_test.rb +18 -0
- data/test/configuration/servers_test.rb +25 -0
- data/test/deploy/scm/git_test.rb +4 -4
- metadata +12 -8
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
data/lib/capistrano.rb
CHANGED
data/lib/capistrano/cli/help.txt
CHANGED
@@ -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
|
-
|
142
|
-
|
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
|
-
|
74
|
-
|
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)
|
@@ -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(' ')}
|
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
|
-
|
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) ?
|
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}
|
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
|
data/lib/capistrano/version.rb
CHANGED
@@ -3,16 +3,14 @@ module Capistrano
|
|
3
3
|
|
4
4
|
class Version
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
STRING = CURRENT.to_s
|
6
|
+
MAJOR = 2
|
7
|
+
MINOR = 6
|
8
|
+
PATCH = 1
|
11
9
|
|
12
10
|
def self.to_s
|
13
|
-
|
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
|
data/test/deploy/scm/git_test.rb
CHANGED
@@ -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
|
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
|
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
|
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:
|
5
|
-
prerelease:
|
4
|
+
hash: 961915984
|
5
|
+
prerelease: 6
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
|
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:
|
261
|
+
hash: 25
|
260
262
|
segments:
|
261
|
-
-
|
262
|
-
|
263
|
+
- 1
|
264
|
+
- 3
|
265
|
+
- 1
|
266
|
+
version: 1.3.1
|
263
267
|
requirements: []
|
264
268
|
|
265
269
|
rubyforge_project:
|