capistrano 3.0.0.pre2 → 3.0.0.pre3
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/README.md +108 -4
- data/lib/capistrano/application.rb +16 -1
- data/lib/capistrano/configuration.rb +12 -17
- data/lib/capistrano/configuration/server.rb +68 -3
- data/lib/capistrano/configuration/servers.rb +71 -28
- data/lib/capistrano/dsl.rb +2 -0
- data/lib/capistrano/dsl/env.rb +7 -4
- data/lib/capistrano/i18n.rb +2 -1
- data/lib/capistrano/tasks/deploy.rake +3 -6
- data/lib/capistrano/templates/Capfile +4 -0
- data/lib/capistrano/version.rb +1 -1
- data/spec/integration/deploy_finalize_spec.rb +34 -0
- data/spec/integration/deploy_finished_spec.rb +36 -0
- data/spec/integration/deploy_started_spec.rb +74 -0
- data/spec/integration/deploy_update_spec.rb +45 -0
- data/spec/integration/dsl_spec.rb +254 -0
- data/spec/integration/installation_spec.rb +76 -0
- data/spec/integration_spec_helper.rb +7 -0
- data/spec/lib/capistrano/application_spec.rb +61 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +91 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +79 -11
- data/spec/lib/capistrano/configuration_spec.rb +12 -2
- data/spec/lib/capistrano/dsl/env_spec.rb +0 -73
- data/spec/spec_helper.rb +2 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/support/test_app.rb +89 -0
- metadata +24 -2
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'integration_spec_helper'
|
2
|
+
|
3
|
+
describe 'cap install', slow: true do
|
4
|
+
|
5
|
+
context 'with defaults' do
|
6
|
+
before :all do
|
7
|
+
create_test_app
|
8
|
+
Dir.chdir(test_app_path) do
|
9
|
+
%x[bundle exec cap install]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe 'installation' do
|
14
|
+
|
15
|
+
it 'creates config/deploy' do
|
16
|
+
path = test_app_path.join('config/deploy')
|
17
|
+
expect(Dir.exists?(path)).to be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'creates lib/capistrano/tasks' do
|
21
|
+
path = test_app_path.join('lib/capistrano/tasks')
|
22
|
+
expect(Dir.exists?(path)).to be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'creates the deploy file' do
|
26
|
+
file = test_app_path.join('config/deploy.rb')
|
27
|
+
expect(File.exists?(file)).to be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'creates the stage files' do
|
31
|
+
staging = test_app_path.join('config/deploy/staging.rb')
|
32
|
+
production = test_app_path.join('config/deploy/production.rb')
|
33
|
+
expect(File.exists?(staging)).to be_true
|
34
|
+
expect(File.exists?(production)).to be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with STAGES' do
|
41
|
+
before :all do
|
42
|
+
create_test_app
|
43
|
+
Dir.chdir(test_app_path) do
|
44
|
+
%x[bundle exec cap install STAGES=qa,production]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'installation' do
|
49
|
+
|
50
|
+
it 'creates config/deploy' do
|
51
|
+
path = test_app_path.join('config/deploy')
|
52
|
+
expect(Dir.exists?(path)).to be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'creates lib/capistrano/tasks' do
|
56
|
+
path = test_app_path.join('lib/capistrano/tasks')
|
57
|
+
expect(Dir.exists?(path)).to be_true
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'creates the deploy file' do
|
61
|
+
file = test_app_path.join('config/deploy.rb')
|
62
|
+
expect(File.exists?(file)).to be_true
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'creates the stage files specified, not the defaults' do
|
66
|
+
qa = test_app_path.join('config/deploy/qa.rb')
|
67
|
+
production = test_app_path.join('config/deploy/production.rb')
|
68
|
+
staging = test_app_path.join('config/deploy/staging.rb')
|
69
|
+
expect(File.exists?(qa)).to be_true
|
70
|
+
expect(File.exists?(production)).to be_true
|
71
|
+
expect(File.exists?(staging)).to be_false
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Capistrano::Application do
|
4
|
+
|
5
|
+
it "provides a --trace option which enables SSHKit/NetSSH trace output"
|
6
|
+
|
7
|
+
it "provides a --format option which enables the choice of output formatting"
|
8
|
+
|
9
|
+
it "identifies itself as cap and not rake" do
|
10
|
+
pending "Waiting for: https://github.com/jimweirich/rake/pull/204"
|
11
|
+
out, _ = capture_io do
|
12
|
+
flags '--help', '-h'
|
13
|
+
end
|
14
|
+
out.should match(/\bcap [ -f capfile ]\b/)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "overrides the rake method, but still prints the rake version" do
|
18
|
+
out, _ = capture_io do
|
19
|
+
flags '--version', '-V'
|
20
|
+
end
|
21
|
+
out.should match(/\bCapistrano Version\b/)
|
22
|
+
out.should match(/\b#{Capistrano::VERSION}\b/)
|
23
|
+
out.should match(/\bRake Version\b/)
|
24
|
+
out.should match(/\b#{RAKEVERSION}\b/)
|
25
|
+
end
|
26
|
+
|
27
|
+
def flags(*sets)
|
28
|
+
sets.each do |set|
|
29
|
+
ARGV.clear
|
30
|
+
@exit = catch(:system_exit) { command_line(*set) }
|
31
|
+
end
|
32
|
+
yield(subject.options) if block_given?
|
33
|
+
end
|
34
|
+
|
35
|
+
def command_line(*options)
|
36
|
+
options.each { |opt| ARGV << opt }
|
37
|
+
def subject.exit(*args)
|
38
|
+
throw(:system_exit, :exit)
|
39
|
+
end
|
40
|
+
subject.instance_eval do
|
41
|
+
handle_options
|
42
|
+
end
|
43
|
+
subject.options
|
44
|
+
end
|
45
|
+
|
46
|
+
def capture_io
|
47
|
+
require 'stringio'
|
48
|
+
|
49
|
+
orig_stdout, orig_stderr = $stdout, $stderr
|
50
|
+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
51
|
+
$stdout, $stderr = captured_stdout, captured_stderr
|
52
|
+
|
53
|
+
yield
|
54
|
+
|
55
|
+
return captured_stdout.string, captured_stderr.string
|
56
|
+
ensure
|
57
|
+
$stdout = orig_stdout
|
58
|
+
$stderr = orig_stderr
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -12,6 +12,14 @@ module Capistrano
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
+
describe 'adding roles' do
|
16
|
+
subject { server.add_roles([:things, :stuff]) }
|
17
|
+
it 'adds the roles' do
|
18
|
+
expect{subject}.to change{server.roles.size}.from(0).to(2)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
15
23
|
describe 'checking roles' do
|
16
24
|
subject { server.has_role?(:test) }
|
17
25
|
|
@@ -43,6 +51,89 @@ module Capistrano
|
|
43
51
|
end
|
44
52
|
end
|
45
53
|
|
54
|
+
describe 'identifying as primary' do
|
55
|
+
subject { server.primary }
|
56
|
+
context 'server is primary' do
|
57
|
+
before do
|
58
|
+
server.set(:primary, true)
|
59
|
+
end
|
60
|
+
it 'returns self' do
|
61
|
+
expect(subject).to eq server
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'server is not primary' do
|
66
|
+
it 'is falesy' do
|
67
|
+
expect(subject).to be_false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe 'assigning properties' do
|
73
|
+
|
74
|
+
before do
|
75
|
+
server.with(properties)
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'properties contains roles' do
|
79
|
+
let(:properties) { {roles: [:clouds]} }
|
80
|
+
|
81
|
+
it 'adds the roles' do
|
82
|
+
expect(server.roles.first).to eq :clouds
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'properties contains user' do
|
87
|
+
let(:properties) { {user: 'tomc'} }
|
88
|
+
|
89
|
+
it 'sets the user' do
|
90
|
+
expect(server.user).to eq 'tomc'
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'properties contains port' do
|
95
|
+
let(:properties) { {port: 2222} }
|
96
|
+
|
97
|
+
it 'sets the port' do
|
98
|
+
expect(server.port).to eq 2222
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'properties contains key' do
|
103
|
+
let(:properties) { {key: '/key'} }
|
104
|
+
|
105
|
+
it 'adds the key' do
|
106
|
+
expect(server.keys).to include '/key'
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'properties contains password' do
|
111
|
+
let(:properties) { {password: 'supersecret'} }
|
112
|
+
|
113
|
+
it 'adds the key' do
|
114
|
+
expect(server.password).to eq 'supersecret'
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'new properties' do
|
119
|
+
let(:properties) { { webscales: 5 } }
|
120
|
+
|
121
|
+
it 'adds the properties' do
|
122
|
+
expect(server.properties.webscales).to eq 5
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'existing properties' do
|
127
|
+
let(:properties) { { webscales: 6 } }
|
128
|
+
|
129
|
+
it 'keeps the existing properties' do
|
130
|
+
expect(server.properties.webscales).to eq 6
|
131
|
+
server.properties.webscales = 5
|
132
|
+
expect(server.properties.webscales).to eq 5
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
46
137
|
end
|
47
138
|
end
|
48
139
|
end
|
@@ -6,11 +6,28 @@ module Capistrano
|
|
6
6
|
let(:servers) { Servers.new }
|
7
7
|
|
8
8
|
describe 'adding a role' do
|
9
|
-
subject { servers.add_role(:app, %w{1 2}) }
|
10
9
|
|
11
10
|
it 'adds two new server instances' do
|
12
|
-
expect{
|
11
|
+
expect{servers.add_role(:app, %w{1 2})}.
|
12
|
+
to change{servers.count}.from(0).to(2)
|
13
13
|
end
|
14
|
+
|
15
|
+
it 'handles de-duplification within roles' do
|
16
|
+
servers.add_role(:app, %w{1})
|
17
|
+
servers.add_role(:app, %w{1})
|
18
|
+
expect(servers.count).to eq 1
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'accepts instances of server objects' do
|
22
|
+
servers.add_role(:app, [Capistrano::Configuration::Server.new('example.net'), 'example.com'])
|
23
|
+
expect(servers.roles_for([:app]).length).to eq 2
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'accepts non-enumerable types' do
|
27
|
+
servers.add_role(:app, '1')
|
28
|
+
expect(servers.roles_for([:app]).count).to eq 1
|
29
|
+
end
|
30
|
+
|
14
31
|
end
|
15
32
|
|
16
33
|
describe 'adding a role to an existing server' do
|
@@ -22,6 +39,7 @@ module Capistrano
|
|
22
39
|
it 'adds new roles to existing servers' do
|
23
40
|
expect(servers.count).to eq 2
|
24
41
|
end
|
42
|
+
|
25
43
|
end
|
26
44
|
|
27
45
|
describe 'collecting server roles' do
|
@@ -35,20 +53,21 @@ module Capistrano
|
|
35
53
|
end
|
36
54
|
|
37
55
|
it 'returns an array of the roles' do
|
38
|
-
expect(servers.
|
39
|
-
expect(servers.
|
56
|
+
expect(servers.roles_for([:app]).collect(&:roles)).to eq [app, web_app, web_app]
|
57
|
+
expect(servers.roles_for([:web]).collect(&:roles)).to eq [web_app, web_app, web]
|
40
58
|
end
|
41
59
|
end
|
42
60
|
|
43
61
|
describe 'finding the primary server' do
|
44
|
-
it 'takes the first server
|
62
|
+
it 'takes the first server if none have the primary property' do
|
45
63
|
servers.add_role(:app, %w{1 2})
|
46
|
-
servers.fetch_primary(:app).hostname.should ==
|
64
|
+
servers.fetch_primary(:app).hostname.should == '1'
|
47
65
|
end
|
66
|
+
|
48
67
|
it 'takes the first server with the primary have the primary flag' do
|
49
68
|
servers.add_role(:app, %w{1 2})
|
50
69
|
servers.add_host('2', primary: true)
|
51
|
-
servers.fetch_primary(:app).hostname.should ==
|
70
|
+
servers.fetch_primary(:app).hostname.should == '2'
|
52
71
|
end
|
53
72
|
end
|
54
73
|
|
@@ -59,21 +78,70 @@ module Capistrano
|
|
59
78
|
end
|
60
79
|
|
61
80
|
it 'returns the correct app servers' do
|
62
|
-
expect(servers.
|
81
|
+
expect(servers.roles_for([:app]).map(&:hostname)).to eq %w{1 2}
|
63
82
|
end
|
64
83
|
|
65
84
|
it 'returns the correct web servers' do
|
66
|
-
expect(servers.
|
85
|
+
expect(servers.roles_for([:web]).map(&:hostname)).to eq %w{2 3}
|
67
86
|
end
|
68
87
|
|
69
88
|
it 'returns the correct app and web servers' do
|
70
|
-
expect(servers.
|
89
|
+
expect(servers.roles_for([:app, :web]).map(&:hostname)).to eq %w{1 2 3}
|
71
90
|
end
|
72
91
|
|
73
92
|
it 'returns all servers' do
|
74
|
-
expect(servers.
|
93
|
+
expect(servers.roles_for([:all]).map(&:hostname)).to eq %w{1 2 3}
|
75
94
|
end
|
76
95
|
end
|
96
|
+
|
97
|
+
describe 'adding a server' do
|
98
|
+
|
99
|
+
before do
|
100
|
+
servers.add_host('1', roles: [:app, 'web'], test: :value)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'can create a server with properties' do
|
104
|
+
expect(servers.roles_for([:app]).first.hostname).to eq '1'
|
105
|
+
expect(servers.roles_for([:web]).first.hostname).to eq '1'
|
106
|
+
expect(servers.roles_for([:all]).first.properties.test).to eq :value
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#roles' do
|
112
|
+
|
113
|
+
before do
|
114
|
+
servers.add_host('1', roles: :app, active: true)
|
115
|
+
servers.add_host('2', roles: :app)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'raises if the filter would remove all matching hosts' do
|
119
|
+
I18n.expects(:t)
|
120
|
+
expect { servers.roles_for([:app, select: :inactive]) }.to raise_error
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'can filter hosts by properties on the host object using symbol as shorthand' do
|
124
|
+
expect(servers.roles_for([:app, filter: :active]).length).to eq 1
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'can select hosts by properties on the host object using symbol as shorthand' do
|
128
|
+
expect(servers.roles_for([:app, select: :active]).length).to eq 1
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'can filter hosts by properties on the host using a regular proc' do
|
132
|
+
expect(servers.roles_for([:app, filter: lambda { |h| h.properties.active }]).length).to eq 1
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'can select hosts by properties on the host using a regular proc' do
|
136
|
+
expect(servers.roles_for([:app, select: lambda { |h| h.properties.active }]).length).to eq 1
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'raises if the regular proc filter would remove all matching hosts' do
|
140
|
+
I18n.expects(:t)
|
141
|
+
expect { servers.roles_for([:app, select: lambda { |h| h.properties.inactive }])}.to raise_error
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
77
145
|
end
|
78
146
|
end
|
79
147
|
end
|
@@ -18,7 +18,7 @@ module Capistrano
|
|
18
18
|
|
19
19
|
before do
|
20
20
|
Configuration::Servers.expects(:new).returns(servers)
|
21
|
-
servers.expects(:add_role).with(:app, %w{server1 server2})
|
21
|
+
servers.expects(:add_role).with(:app, %w{server1 server2}, {})
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'adds the role' do
|
@@ -75,6 +75,16 @@ module Capistrano
|
|
75
75
|
expect(config.fetch(:branch)).to eq question
|
76
76
|
end
|
77
77
|
end
|
78
|
-
end
|
79
78
|
|
79
|
+
describe 'setting the backend' do
|
80
|
+
it 'by default, is SSHKit' do
|
81
|
+
expect(config.backend).to eq SSHKit
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'can be set to another class' do
|
85
|
+
config.backend = :test
|
86
|
+
expect(config.backend).to eq :test
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
80
90
|
end
|
@@ -5,79 +5,6 @@ module Capistrano
|
|
5
5
|
|
6
6
|
describe Env do
|
7
7
|
|
8
|
-
let(:env) { Configuration.new }
|
9
|
-
|
10
|
-
describe '#role' do
|
11
|
-
|
12
|
-
it 'can add a role, with hosts' do
|
13
|
-
env.role(:app, %w{example.com})
|
14
|
-
env.roles_for(:app).first.hostname.should == "example.com"
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'handles de-duplification within roles' do
|
18
|
-
env.role(:app, %w{example.com})
|
19
|
-
env.role(:app, %w{example.com})
|
20
|
-
env.roles_for(:app).length.should == 1
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'accepts instances of server objects' do
|
24
|
-
pending
|
25
|
-
env.role(:app, [Capistrano::Configuration::Server.new('example.net'), 'example.com'])
|
26
|
-
env.roles_for(:app).length.should == 2
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'accepts non-enumerable types' do
|
30
|
-
env.role(:app, 'example.com')
|
31
|
-
env.roles_for(:app).length.should == 1
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
describe '#server' do
|
37
|
-
|
38
|
-
it "can create a server with properties" do
|
39
|
-
env.server('example.com', roles: [:app, "web"], my: :value)
|
40
|
-
env.roles_for(:app).first.hostname.should == 'example.com'
|
41
|
-
env.roles_for(:web).first.hostname.should == 'example.com'
|
42
|
-
env.roles_for(:all).first.properties.my.should == :value
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
describe '#roles' do
|
48
|
-
|
49
|
-
before do
|
50
|
-
env.server('example.com', roles: :app, active: true)
|
51
|
-
env.server('example.org', roles: :app)
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'raises if the filter would remove all matching hosts' do
|
55
|
-
pending
|
56
|
-
env.server('example.org', active: true)
|
57
|
-
lambda do
|
58
|
-
env.roles_for(:app, filter: lambda { |s| !s.properties.active })
|
59
|
-
end.should raise_error
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'can filter hosts by properties on the host object using symbol as shorthand' do
|
63
|
-
env.roles_for(:app, filter: :active).length.should == 1
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'can select hosts by properties on the host object using symbol as shorthand' do
|
67
|
-
env.roles_for(:app, select: :active).length.should == 1
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'can filter hosts by properties on the host using a regular proc' do
|
71
|
-
env.roles_for(:app, filter: lambda { |h| h.properties.active } ).length.should == 1
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'can select hosts by properties on the host using a regular proc' do
|
75
|
-
env.roles_for(:app, select: lambda { |h| h.properties.active } ).length.should == 1
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
|
80
8
|
end
|
81
|
-
|
82
9
|
end
|
83
10
|
end
|