capistrano 3.4.1 → 3.5.0

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.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -5
  3. data/.rubocop.yml +49 -0
  4. data/.travis.yml +5 -4
  5. data/CHANGELOG.md +72 -9
  6. data/CONTRIBUTING.md +61 -93
  7. data/DEVELOPMENT.md +122 -0
  8. data/Gemfile +2 -2
  9. data/LICENSE.txt +1 -1
  10. data/README.md +121 -43
  11. data/RELEASING.md +16 -0
  12. data/Rakefile +4 -1
  13. data/bin/cap +1 -1
  14. data/capistrano.gemspec +16 -21
  15. data/features/doctor.feature +11 -0
  16. data/features/step_definitions/assertions.rb +17 -17
  17. data/features/step_definitions/cap_commands.rb +0 -1
  18. data/features/step_definitions/setup.rb +12 -8
  19. data/features/support/env.rb +5 -5
  20. data/features/support/remote_command_helpers.rb +8 -6
  21. data/features/support/vagrant_helpers.rb +5 -4
  22. data/issue_template.md +21 -0
  23. data/lib/Capfile +5 -1
  24. data/lib/capistrano/all.rb +9 -10
  25. data/lib/capistrano/application.rb +36 -26
  26. data/lib/capistrano/configuration.rb +56 -41
  27. data/lib/capistrano/configuration/empty_filter.rb +9 -0
  28. data/lib/capistrano/configuration/filter.rb +18 -47
  29. data/lib/capistrano/configuration/host_filter.rb +30 -0
  30. data/lib/capistrano/configuration/null_filter.rb +9 -0
  31. data/lib/capistrano/configuration/plugin_installer.rb +33 -0
  32. data/lib/capistrano/configuration/question.rb +10 -7
  33. data/lib/capistrano/configuration/role_filter.rb +30 -0
  34. data/lib/capistrano/configuration/server.rb +22 -23
  35. data/lib/capistrano/configuration/servers.rb +6 -7
  36. data/lib/capistrano/configuration/variables.rb +136 -0
  37. data/lib/capistrano/defaults.rb +13 -3
  38. data/lib/capistrano/deploy.rb +1 -1
  39. data/lib/capistrano/doctor.rb +5 -0
  40. data/lib/capistrano/doctor/environment_doctor.rb +19 -0
  41. data/lib/capistrano/doctor/gems_doctor.rb +45 -0
  42. data/lib/capistrano/doctor/output_helpers.rb +79 -0
  43. data/lib/capistrano/doctor/variables_doctor.rb +66 -0
  44. data/lib/capistrano/dotfile.rb +1 -2
  45. data/lib/capistrano/dsl.rb +12 -14
  46. data/lib/capistrano/dsl/env.rb +11 -42
  47. data/lib/capistrano/dsl/paths.rb +12 -13
  48. data/lib/capistrano/dsl/stages.rb +2 -4
  49. data/lib/capistrano/dsl/task_enhancements.rb +5 -7
  50. data/lib/capistrano/framework.rb +1 -1
  51. data/lib/capistrano/git.rb +17 -9
  52. data/lib/capistrano/hg.rb +4 -4
  53. data/lib/capistrano/i18n.rb +24 -24
  54. data/lib/capistrano/immutable_task.rb +29 -0
  55. data/lib/capistrano/install.rb +1 -1
  56. data/lib/capistrano/plugin.rb +95 -0
  57. data/lib/capistrano/scm.rb +7 -20
  58. data/lib/capistrano/setup.rb +19 -5
  59. data/lib/capistrano/svn.rb +9 -5
  60. data/lib/capistrano/tasks/console.rake +4 -8
  61. data/lib/capistrano/tasks/deploy.rake +75 -62
  62. data/lib/capistrano/tasks/doctor.rake +19 -0
  63. data/lib/capistrano/tasks/framework.rake +13 -14
  64. data/lib/capistrano/tasks/git.rake +10 -11
  65. data/lib/capistrano/tasks/hg.rake +7 -7
  66. data/lib/capistrano/tasks/install.rake +14 -15
  67. data/lib/capistrano/tasks/svn.rake +7 -7
  68. data/lib/capistrano/templates/Capfile +3 -3
  69. data/lib/capistrano/templates/deploy.rb.erb +6 -5
  70. data/lib/capistrano/upload_task.rb +1 -1
  71. data/lib/capistrano/version.rb +1 -1
  72. data/lib/capistrano/version_validator.rb +4 -6
  73. data/spec/integration/dsl_spec.rb +286 -239
  74. data/spec/integration_spec_helper.rb +3 -5
  75. data/spec/lib/capistrano/application_spec.rb +22 -14
  76. data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
  77. data/spec/lib/capistrano/configuration/filter_spec.rb +82 -84
  78. data/spec/lib/capistrano/configuration/host_filter_spec.rb +61 -0
  79. data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
  80. data/spec/lib/capistrano/configuration/question_spec.rb +12 -16
  81. data/spec/lib/capistrano/configuration/role_filter_spec.rb +64 -0
  82. data/spec/lib/capistrano/configuration/server_spec.rb +102 -110
  83. data/spec/lib/capistrano/configuration/servers_spec.rb +124 -141
  84. data/spec/lib/capistrano/configuration_spec.rb +150 -61
  85. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
  86. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +61 -0
  87. data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
  88. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +79 -0
  89. data/spec/lib/capistrano/dsl/paths_spec.rb +58 -50
  90. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +62 -32
  91. data/spec/lib/capistrano/dsl_spec.rb +6 -8
  92. data/spec/lib/capistrano/git_spec.rb +35 -7
  93. data/spec/lib/capistrano/hg_spec.rb +14 -5
  94. data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
  95. data/spec/lib/capistrano/plugin_spec.rb +84 -0
  96. data/spec/lib/capistrano/scm_spec.rb +6 -7
  97. data/spec/lib/capistrano/svn_spec.rb +40 -14
  98. data/spec/lib/capistrano/upload_task_spec.rb +7 -7
  99. data/spec/lib/capistrano/version_validator_spec.rb +37 -45
  100. data/spec/lib/capistrano_spec.rb +2 -3
  101. data/spec/spec_helper.rb +8 -8
  102. data/spec/support/Vagrantfile +9 -10
  103. data/spec/support/tasks/database.rake +3 -3
  104. data/spec/support/tasks/fail.rake +4 -3
  105. data/spec/support/tasks/failed.rake +2 -2
  106. data/spec/support/tasks/plugin.rake +6 -0
  107. data/spec/support/tasks/root.rake +4 -4
  108. data/spec/support/test_app.rb +31 -30
  109. metadata +93 -14
@@ -0,0 +1,64 @@
1
+ require "spec_helper"
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ describe RoleFilter do
6
+ subject(:role_filter) { RoleFilter.new(values) }
7
+
8
+ let(:available) do
9
+ [
10
+ Server.new("server1").add_roles([:web, :db]),
11
+ Server.new("server2").add_role(:web),
12
+ Server.new("server3").add_role(:redis),
13
+ Server.new("server4").add_role(:db),
14
+ Server.new("server5").add_role(:stageweb)
15
+ ]
16
+ end
17
+
18
+ shared_examples "it filters roles correctly" do |expected_size, expected|
19
+ it "filters correctly" do
20
+ set = role_filter.filter(available)
21
+ expect(set.size).to eq(expected_size)
22
+ expect(set.map(&:hostname)).to eq(expected)
23
+ end
24
+ end
25
+
26
+ describe '#filter' do
27
+ context "with a single role string" do
28
+ let(:values) { "web" }
29
+ it_behaves_like "it filters roles correctly", 2, %w{server1 server2}
30
+ end
31
+
32
+ context "with a single role" do
33
+ let(:values) { [:web] }
34
+ it_behaves_like "it filters roles correctly", 2, %w{server1 server2}
35
+ end
36
+
37
+ context "with multiple roles in a string" do
38
+ let(:values) { "web,db" }
39
+ it_behaves_like "it filters roles correctly", 3, %w{server1 server2 server4}
40
+ end
41
+
42
+ context "with multiple roles" do
43
+ let(:values) { [:web, :db] }
44
+ it_behaves_like "it filters roles correctly", 3, %w{server1 server2 server4}
45
+ end
46
+
47
+ context "with a regex" do
48
+ let(:values) { /red/ }
49
+ it_behaves_like "it filters roles correctly", 1, %w{server3}
50
+ end
51
+
52
+ context "with a regex string" do
53
+ let(:values) { "/red|web/" }
54
+ it_behaves_like "it filters roles correctly", 4, %w{server1 server2 server3 server5}
55
+ end
56
+
57
+ context "with both a string and regex" do
58
+ let(:values) { "db,/red/" }
59
+ it_behaves_like "it filters roles correctly", 3, %w{server1 server3 server4}
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,141 +1,139 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  module Capistrano
4
4
  class Configuration
5
5
  describe Server do
6
- let(:server) { Server.new('root@hostname:1234') }
6
+ let(:server) { Server.new("root@hostname:1234") }
7
7
 
8
- describe 'adding a role' do
8
+ describe "adding a role" do
9
9
  subject { server.add_role(:test) }
10
- it 'adds the role' do
11
- expect{subject}.to change{server.roles.size}.from(0).to(1)
10
+ it "adds the role" do
11
+ expect { subject }.to change { server.roles.size }.from(0).to(1)
12
12
  end
13
13
  end
14
14
 
15
- describe 'adding roles' do
15
+ describe "adding roles" do
16
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)
17
+ it "adds the roles" do
18
+ expect { subject }.to change { server.roles.size }.from(0).to(2)
19
19
  end
20
20
  end
21
21
 
22
-
23
- describe 'checking roles' do
22
+ describe "checking roles" do
24
23
  subject { server.has_role?(:test) }
25
24
 
26
25
  before do
27
26
  server.add_role(:test)
28
27
  end
29
28
 
30
- it 'adds the role' do
29
+ it "adds the role" do
31
30
  expect(subject).to be_truthy
32
31
  end
33
32
  end
34
33
 
35
- describe 'comparing identity' do
34
+ describe "comparing identity" do
36
35
  subject { server.hostname == Server[hostname].hostname }
37
36
 
38
- context 'with the same user, hostname and port' do
39
- let(:hostname) { 'root@hostname:1234' }
37
+ context "with the same user, hostname and port" do
38
+ let(:hostname) { "root@hostname:1234" }
40
39
  it { expect(subject).to be_truthy }
41
40
  end
42
41
 
43
- context 'with a different user' do
44
- let(:hostname) { 'deployer@hostname:1234' }
42
+ context "with a different user" do
43
+ let(:hostname) { "deployer@hostname:1234" }
45
44
  it { expect(subject).to be_truthy }
46
45
  end
47
46
 
48
- context 'with a different port' do
49
- let(:hostname) { 'root@hostname:5678' }
47
+ context "with a different port" do
48
+ let(:hostname) { "root@hostname:5678" }
50
49
  it { expect(subject).to be_truthy }
51
50
  end
52
51
 
53
- context 'with a different hostname' do
54
- let(:hostname) { 'root@otherserver:1234' }
52
+ context "with a different hostname" do
53
+ let(:hostname) { "root@otherserver:1234" }
55
54
  it { expect(subject).to be_falsey }
56
55
  end
57
56
  end
58
57
 
59
- describe 'identifying as primary' do
58
+ describe "identifying as primary" do
60
59
  subject { server.primary }
61
- context 'server is primary' do
60
+ context "server is primary" do
62
61
  before do
63
62
  server.set(:primary, true)
64
63
  end
65
- it 'returns self' do
64
+ it "returns self" do
66
65
  expect(subject).to eq server
67
66
  end
68
67
  end
69
68
 
70
- context 'server is not primary' do
71
- it 'is falesy' do
69
+ context "server is not primary" do
70
+ it "is falesy" do
72
71
  expect(subject).to be_falsey
73
72
  end
74
73
  end
75
74
  end
76
75
 
77
- describe 'assigning properties' do
78
-
76
+ describe "assigning properties" do
79
77
  before do
80
78
  server.with(properties)
81
79
  end
82
80
 
83
- context 'properties contains roles' do
84
- let(:properties) { {roles: [:clouds]} }
81
+ context "properties contains roles" do
82
+ let(:properties) { { roles: [:clouds] } }
85
83
 
86
- it 'adds the roles' do
84
+ it "adds the roles" do
87
85
  expect(server.roles.first).to eq :clouds
88
86
  end
89
87
  end
90
88
 
91
- context 'properties contains user' do
92
- let(:properties) { {user: 'tomc'} }
89
+ context "properties contains user" do
90
+ let(:properties) { { user: "tomc" } }
93
91
 
94
- it 'sets the user' do
95
- expect(server.user).to eq 'tomc'
92
+ it "sets the user" do
93
+ expect(server.user).to eq "tomc"
96
94
  end
97
95
 
98
- it 'sets the netssh_options user' do
99
- expect(server.netssh_options[:user]).to eq 'tomc'
96
+ it "sets the netssh_options user" do
97
+ expect(server.netssh_options[:user]).to eq "tomc"
100
98
  end
101
99
  end
102
100
 
103
- context 'properties contains port' do
104
- let(:properties) { {port: 2222} }
101
+ context "properties contains port" do
102
+ let(:properties) { { port: 2222 } }
105
103
 
106
- it 'sets the port' do
104
+ it "sets the port" do
107
105
  expect(server.port).to eq 2222
108
106
  end
109
107
  end
110
108
 
111
- context 'properties contains key' do
112
- let(:properties) { {key: '/key'} }
109
+ context "properties contains key" do
110
+ let(:properties) { { key: "/key" } }
113
111
 
114
- it 'adds the key' do
115
- expect(server.keys).to include '/key'
112
+ it "adds the key" do
113
+ expect(server.keys).to include "/key"
116
114
  end
117
115
  end
118
116
 
119
- context 'properties contains password' do
120
- let(:properties) { {password: 'supersecret'} }
117
+ context "properties contains password" do
118
+ let(:properties) { { password: "supersecret" } }
121
119
 
122
- it 'adds the key' do
123
- expect(server.password).to eq 'supersecret'
120
+ it "adds the key" do
121
+ expect(server.password).to eq "supersecret"
124
122
  end
125
123
  end
126
124
 
127
- context 'new properties' do
125
+ context "new properties" do
128
126
  let(:properties) { { webscales: 5 } }
129
127
 
130
- it 'adds the properties' do
128
+ it "adds the properties" do
131
129
  expect(server.properties.webscales).to eq 5
132
130
  end
133
131
  end
134
132
 
135
- context 'existing properties' do
133
+ context "existing properties" do
136
134
  let(:properties) { { webscales: 6 } }
137
135
 
138
- it 'keeps the existing properties' do
136
+ it "keeps the existing properties" do
139
137
  expect(server.properties.webscales).to eq 6
140
138
  server.properties.webscales = 5
141
139
  expect(server.properties.webscales).to eq 5
@@ -152,128 +150,123 @@ module Capistrano
152
150
  server.properties.active = true
153
151
  end
154
152
 
155
- context 'options are empty' do
153
+ context "options are empty" do
156
154
  it { expect(subject).to be_truthy }
157
155
  end
158
156
 
159
- context 'value is a symbol' do
160
- context 'value matches server property' do
161
-
162
- context 'with :filter' do
163
- let(:options) { { filter: :active }}
157
+ context "value is a symbol" do
158
+ context "value matches server property" do
159
+ context "with :filter" do
160
+ let(:options) { { filter: :active } }
164
161
  it { expect(subject).to be_truthy }
165
162
  end
166
163
 
167
- context 'with :select' do
168
- let(:options) { { select: :active }}
164
+ context "with :select" do
165
+ let(:options) { { select: :active } }
169
166
  it { expect(subject).to be_truthy }
170
167
  end
171
168
 
172
- context 'with :exclude' do
173
- let(:options) { { exclude: :active }}
169
+ context "with :exclude" do
170
+ let(:options) { { exclude: :active } }
174
171
  it { expect(subject).to be_falsey }
175
172
  end
176
173
  end
177
174
 
178
- context 'value does not match server properly' do
179
- context 'with :active true' do
180
- let(:options) { { active: true }}
175
+ context "value does not match server properly" do
176
+ context "with :active true" do
177
+ let(:options) { { active: true } }
181
178
  it { expect(subject).to be_truthy }
182
179
  end
183
180
 
184
- context 'with :active false' do
185
- let(:options) { { active: false }}
181
+ context "with :active false" do
182
+ let(:options) { { active: false } }
186
183
  it { expect(subject).to be_falsey }
187
184
  end
188
185
  end
189
186
 
190
- context 'value does not match server properly' do
191
- context 'with :filter' do
192
- let(:options) { { filter: :inactive }}
187
+ context "value does not match server properly" do
188
+ context "with :filter" do
189
+ let(:options) { { filter: :inactive } }
193
190
  it { expect(subject).to be_falsey }
194
191
  end
195
192
 
196
- context 'with :select' do
197
- let(:options) { { select: :inactive }}
193
+ context "with :select" do
194
+ let(:options) { { select: :inactive } }
198
195
  it { expect(subject).to be_falsey }
199
196
  end
200
197
 
201
- context 'with :exclude' do
202
- let(:options) { { exclude: :inactive }}
198
+ context "with :exclude" do
199
+ let(:options) { { exclude: :inactive } }
203
200
  it { expect(subject).to be_truthy }
204
201
  end
205
202
  end
206
203
  end
207
204
 
208
- context 'key is a property' do
209
- context 'with :active true' do
210
- let(:options) { { active: true }}
205
+ context "key is a property" do
206
+ context "with :active true" do
207
+ let(:options) { { active: true } }
211
208
  it { expect(subject).to be_truthy }
212
209
  end
213
210
 
214
- context 'with :active false' do
215
- let(:options) { { active: false }}
211
+ context "with :active false" do
212
+ let(:options) { { active: false } }
216
213
  it { expect(subject).to be_falsey }
217
214
  end
218
215
  end
219
216
 
220
- context 'value is a proc' do
221
- context 'value matches server property' do
222
-
223
- context 'with :filter' do
217
+ context "value is a proc" do
218
+ context "value matches server property" do
219
+ context "with :filter" do
224
220
  let(:options) { { filter: ->(s) { s.properties.active } } }
225
221
  it { expect(subject).to be_truthy }
226
222
  end
227
223
 
228
- context 'with :select' do
224
+ context "with :select" do
229
225
  let(:options) { { select: ->(s) { s.properties.active } } }
230
226
  it { expect(subject).to be_truthy }
231
227
  end
232
228
 
233
- context 'with :exclude' do
229
+ context "with :exclude" do
234
230
  let(:options) { { exclude: ->(s) { s.properties.active } } }
235
231
  it { expect(subject).to be_falsey }
236
232
  end
237
-
238
233
  end
239
234
 
240
- context 'value does not match server properly' do
241
- context 'with :filter' do
235
+ context "value does not match server properly" do
236
+ context "with :filter" do
242
237
  let(:options) { { filter: ->(s) { s.properties.inactive } } }
243
238
  it { expect(subject).to be_falsey }
244
239
  end
245
240
 
246
- context 'with :select' do
241
+ context "with :select" do
247
242
  let(:options) { { select: ->(s) { s.properties.inactive } } }
248
243
  it { expect(subject).to be_falsey }
249
244
  end
250
245
 
251
- context 'with :exclude' do
246
+ context "with :exclude" do
252
247
  let(:options) { { exclude: ->(s) { s.properties.inactive } } }
253
248
  it { expect(subject).to be_truthy }
254
249
  end
255
-
256
250
  end
257
251
  end
258
-
259
252
  end
260
253
 
261
- describe 'assign ssh_options' do
262
- let(:server) { Server.new('user_name@hostname') }
254
+ describe "assign ssh_options" do
255
+ let(:server) { Server.new("user_name@hostname") }
263
256
 
264
- context 'defaults' do
265
- it 'forward agent' do
257
+ context "defaults" do
258
+ it "forward agent" do
266
259
  expect(server.netssh_options[:forward_agent]).to eq true
267
260
  end
268
- it 'contains user' do
269
- expect(server.netssh_options[:user]).to eq 'user_name'
261
+ it "contains user" do
262
+ expect(server.netssh_options[:user]).to eq "user_name"
270
263
  end
271
264
  end
272
265
 
273
- context 'custom' do
266
+ context "custom" do
274
267
  let(:properties) do
275
268
  { ssh_options: {
276
- user: 'another_user',
269
+ user: "another_user",
277
270
  keys: %w(/home/another_user/.ssh/id_rsa),
278
271
  forward_agent: false,
279
272
  auth_methods: %w(publickey password) } }
@@ -283,31 +276,30 @@ module Capistrano
283
276
  server.with(properties)
284
277
  end
285
278
 
286
- it 'not forward agent' do
279
+ it "not forward agent" do
287
280
  expect(server.netssh_options[:forward_agent]).to eq false
288
281
  end
289
- it 'contains correct user' do
290
- expect(server.netssh_options[:user]).to eq 'another_user'
282
+ it "contains correct user" do
283
+ expect(server.netssh_options[:user]).to eq "another_user"
291
284
  end
292
- it 'does not affect server user in host' do
293
- expect(server.user).to eq 'user_name'
285
+ it "does not affect server user in host" do
286
+ expect(server.user).to eq "user_name"
294
287
  end
295
- it 'contains keys' do
288
+ it "contains keys" do
296
289
  expect(server.netssh_options[:keys]).to eq %w(/home/another_user/.ssh/id_rsa)
297
290
  end
298
- it 'contains auth_methods' do
291
+ it "contains auth_methods" do
299
292
  expect(server.netssh_options[:auth_methods]).to eq %w(publickey password)
300
293
  end
301
294
  end
302
-
303
295
  end
304
296
 
305
297
  describe ".[]" do
306
- it 'creates a server if its argument is not already a server' do
307
- expect(Server['hostname:1234']).to be_a Server
298
+ it "creates a server if its argument is not already a server" do
299
+ expect(Server["hostname:1234"]).to be_a Server
308
300
  end
309
301
 
310
- it 'returns its argument if it is already a server' do
302
+ it "returns its argument if it is already a server" do
311
303
  expect(Server[server]).to be server
312
304
  end
313
305
  end