capistrano 2.1.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +20 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.md +89 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +674 -0
  7. data/README.md +226 -0
  8. data/Rakefile +5 -0
  9. data/bin/cap +2 -3
  10. data/bin/capify +7 -77
  11. data/capistrano-public_cert.pem +22 -0
  12. data/capistrano.gemspec +35 -0
  13. data/features/deploy.feature +52 -0
  14. data/features/installation.feature +16 -0
  15. data/features/remote_file_task.feature +14 -0
  16. data/features/step_definitions/assertions.rb +90 -0
  17. data/features/step_definitions/cap_commands.rb +8 -0
  18. data/features/step_definitions/setup.rb +25 -0
  19. data/features/support/env.rb +12 -0
  20. data/features/support/remote_command_helpers.rb +20 -0
  21. data/lib/Capfile +3 -0
  22. data/lib/capistrano/all.rb +16 -0
  23. data/lib/capistrano/application.rb +60 -0
  24. data/lib/capistrano/configuration/question.rb +42 -0
  25. data/lib/capistrano/configuration/server.rb +133 -0
  26. data/lib/capistrano/configuration/servers/role_filter.rb +86 -0
  27. data/lib/capistrano/configuration/servers.rb +53 -58
  28. data/lib/capistrano/configuration.rb +84 -30
  29. data/lib/capistrano/console.rb +1 -0
  30. data/lib/capistrano/defaults.rb +13 -0
  31. data/lib/capistrano/deploy.rb +3 -0
  32. data/lib/capistrano/dotfile.rb +3 -0
  33. data/lib/capistrano/dsl/env.rb +64 -0
  34. data/lib/capistrano/dsl/paths.rb +94 -0
  35. data/lib/capistrano/dsl/stages.rb +15 -0
  36. data/lib/capistrano/dsl/task_enhancements.rb +53 -0
  37. data/lib/capistrano/dsl.rb +48 -0
  38. data/lib/capistrano/git.rb +1 -0
  39. data/lib/capistrano/hg.rb +1 -0
  40. data/lib/capistrano/i18n.rb +34 -0
  41. data/lib/capistrano/install.rb +1 -0
  42. data/lib/capistrano/setup.rb +21 -0
  43. data/lib/capistrano/tasks/console.rake +21 -0
  44. data/lib/capistrano/tasks/deploy.rake +204 -0
  45. data/lib/capistrano/tasks/framework.rake +67 -0
  46. data/lib/capistrano/tasks/git.rake +62 -0
  47. data/lib/capistrano/tasks/hg.rake +39 -0
  48. data/lib/capistrano/tasks/install.rake +39 -0
  49. data/lib/capistrano/templates/Capfile +26 -0
  50. data/lib/capistrano/templates/deploy.rb.erb +40 -0
  51. data/lib/capistrano/templates/stage.rb.erb +42 -0
  52. data/lib/capistrano/version.rb +1 -20
  53. data/lib/capistrano/version_validator.rb +37 -0
  54. data/lib/capistrano.rb +0 -2
  55. data/spec/integration/dsl_spec.rb +344 -0
  56. data/spec/integration_spec_helper.rb +7 -0
  57. data/spec/lib/capistrano/application_spec.rb +61 -0
  58. data/spec/lib/capistrano/configuration/question_spec.rb +54 -0
  59. data/spec/lib/capistrano/configuration/server_spec.rb +249 -0
  60. data/spec/lib/capistrano/configuration/servers/role_filter_spec.rb +140 -0
  61. data/spec/lib/capistrano/configuration/servers_spec.rb +184 -0
  62. data/spec/lib/capistrano/configuration_spec.rb +101 -0
  63. data/spec/lib/capistrano/dsl/env_spec.rb +10 -0
  64. data/spec/lib/capistrano/dsl/paths_spec.rb +69 -0
  65. data/spec/lib/capistrano/dsl_spec.rb +63 -0
  66. data/spec/lib/capistrano/version_validator_spec.rb +103 -0
  67. data/spec/lib/capistrano_spec.rb +8 -0
  68. data/spec/spec_helper.rb +15 -0
  69. data/spec/support/.gitignore +1 -0
  70. data/spec/support/Vagrantfile +13 -0
  71. data/spec/support/matchers.rb +5 -0
  72. data/spec/support/tasks/database.cap +11 -0
  73. data/spec/support/test_app.rb +138 -0
  74. metadata +251 -179
  75. data/CHANGELOG +0 -512
  76. data/MIT-LICENSE +0 -20
  77. data/README +0 -43
  78. data/examples/sample.rb +0 -14
  79. data/lib/capistrano/callback.rb +0 -45
  80. data/lib/capistrano/cli/execute.rb +0 -82
  81. data/lib/capistrano/cli/help.rb +0 -102
  82. data/lib/capistrano/cli/help.txt +0 -53
  83. data/lib/capistrano/cli/options.rb +0 -183
  84. data/lib/capistrano/cli/ui.rb +0 -28
  85. data/lib/capistrano/cli.rb +0 -47
  86. data/lib/capistrano/command.rb +0 -161
  87. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -35
  88. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  89. data/lib/capistrano/configuration/actions/invocation.rb +0 -134
  90. data/lib/capistrano/configuration/callbacks.rb +0 -148
  91. data/lib/capistrano/configuration/connections.rb +0 -159
  92. data/lib/capistrano/configuration/execution.rb +0 -126
  93. data/lib/capistrano/configuration/loading.rb +0 -198
  94. data/lib/capistrano/configuration/namespaces.rb +0 -196
  95. data/lib/capistrano/configuration/roles.rb +0 -51
  96. data/lib/capistrano/configuration/variables.rb +0 -127
  97. data/lib/capistrano/errors.rb +0 -15
  98. data/lib/capistrano/extensions.rb +0 -57
  99. data/lib/capistrano/gateway.rb +0 -131
  100. data/lib/capistrano/logger.rb +0 -59
  101. data/lib/capistrano/recipes/compat.rb +0 -32
  102. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  103. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -46
  104. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -96
  105. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  106. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -192
  107. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  108. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -151
  109. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -85
  110. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -191
  111. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -129
  112. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -126
  113. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -114
  114. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  115. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -64
  116. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  117. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -144
  118. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  119. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  120. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -47
  121. data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
  122. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  123. data/lib/capistrano/recipes/deploy.rb +0 -494
  124. data/lib/capistrano/recipes/standard.rb +0 -37
  125. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  126. data/lib/capistrano/recipes/upgrade.rb +0 -33
  127. data/lib/capistrano/server_definition.rb +0 -51
  128. data/lib/capistrano/shell.rb +0 -256
  129. data/lib/capistrano/ssh.rb +0 -109
  130. data/lib/capistrano/task_definition.rb +0 -69
  131. data/lib/capistrano/upload.rb +0 -146
  132. data/test/cli/execute_test.rb +0 -132
  133. data/test/cli/help_test.rb +0 -139
  134. data/test/cli/options_test.rb +0 -226
  135. data/test/cli/ui_test.rb +0 -28
  136. data/test/cli_test.rb +0 -17
  137. data/test/command_test.rb +0 -309
  138. data/test/configuration/actions/file_transfer_test.rb +0 -40
  139. data/test/configuration/actions/inspect_test.rb +0 -62
  140. data/test/configuration/actions/invocation_test.rb +0 -202
  141. data/test/configuration/callbacks_test.rb +0 -206
  142. data/test/configuration/connections_test.rb +0 -288
  143. data/test/configuration/execution_test.rb +0 -159
  144. data/test/configuration/loading_test.rb +0 -127
  145. data/test/configuration/namespace_dsl_test.rb +0 -297
  146. data/test/configuration/roles_test.rb +0 -47
  147. data/test/configuration/servers_test.rb +0 -90
  148. data/test/configuration/variables_test.rb +0 -180
  149. data/test/configuration_test.rb +0 -81
  150. data/test/deploy/scm/accurev_test.rb +0 -23
  151. data/test/deploy/scm/base_test.rb +0 -55
  152. data/test/deploy/scm/git_test.rb +0 -112
  153. data/test/deploy/strategy/copy_test.rb +0 -147
  154. data/test/extensions_test.rb +0 -69
  155. data/test/fixtures/cli_integration.rb +0 -5
  156. data/test/fixtures/config.rb +0 -5
  157. data/test/fixtures/custom.rb +0 -3
  158. data/test/gateway_test.rb +0 -167
  159. data/test/logger_test.rb +0 -123
  160. data/test/server_definition_test.rb +0 -108
  161. data/test/shell_test.rb +0 -64
  162. data/test/ssh_test.rb +0 -97
  163. data/test/task_definition_test.rb +0 -101
  164. data/test/upload_test.rb +0 -131
  165. data/test/utils.rb +0 -42
  166. data/test/version_test.rb +0 -24
@@ -0,0 +1,249 @@
1
+ require 'spec_helper'
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ describe Server do
6
+ let(:server) { Server.new('hostname') }
7
+
8
+ describe 'adding a role' do
9
+ subject { server.add_role(:test) }
10
+ it 'adds the role' do
11
+ expect{subject}.to change{server.roles.size}.from(0).to(1)
12
+ end
13
+ end
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
+
23
+ describe 'checking roles' do
24
+ subject { server.has_role?(:test) }
25
+
26
+ before do
27
+ server.add_role(:test)
28
+ end
29
+
30
+ it 'adds the role' do
31
+ expect{subject}.to be_true
32
+ end
33
+ end
34
+
35
+ describe 'comparing identity' do
36
+ subject { server.matches? hostname }
37
+
38
+ context 'with the same hostname' do
39
+ let(:hostname) { 'hostname' }
40
+ it { should be_true }
41
+ end
42
+
43
+ context 'with the same hostname and a user' do
44
+ let(:hostname) { 'user@hostname' }
45
+ it { should be_true }
46
+ end
47
+
48
+ context 'with a different hostname' do
49
+ let(:hostname) { 'otherserver' }
50
+ it { should be_false }
51
+ end
52
+ end
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
+
137
+ describe '#include?' do
138
+ let(:options) { {} }
139
+
140
+ subject { server.select?(options) }
141
+
142
+ before do
143
+ server.properties.active = true
144
+ end
145
+
146
+ context 'options are empty' do
147
+ it { should be_true }
148
+ end
149
+
150
+ context 'value is a symbol' do
151
+ context 'value matches server property' do
152
+
153
+ context 'with :filter' do
154
+ let(:options) { { filter: :active }}
155
+ it { should be_true }
156
+ end
157
+
158
+ context 'with :select' do
159
+ let(:options) { { select: :active }}
160
+ it { should be_true }
161
+ end
162
+ end
163
+
164
+ context 'value does not match server properly' do
165
+ context 'with :filter' do
166
+ let(:options) { { filter: :inactive }}
167
+ it { should be_false }
168
+ end
169
+
170
+ context 'with :select' do
171
+ let(:options) { { select: :inactive }}
172
+ it { should be_false }
173
+ end
174
+ end
175
+ end
176
+
177
+ context 'value is a proc' do
178
+ context 'value matches server property' do
179
+
180
+ context 'with :filter' do
181
+ let(:options) { { filter: ->(s) { s.properties.active } } }
182
+ it { should be_true }
183
+ end
184
+
185
+ context 'with :select' do
186
+ let(:options) { { select: ->(s) { s.properties.active } } }
187
+ it { should be_true }
188
+ end
189
+ end
190
+
191
+ context 'value does not match server properly' do
192
+ context 'with :filter' do
193
+ let(:options) { { filter: ->(s) { s.properties.inactive } } }
194
+ it { should be_false }
195
+ end
196
+
197
+ context 'with :select' do
198
+ let(:options) { { select: ->(s) { s.properties.inactive } } }
199
+ it { should be_false }
200
+ end
201
+ end
202
+ end
203
+
204
+ end
205
+
206
+ describe 'assign ssh_options' do
207
+ let(:server) { Server.new('user_name@hostname') }
208
+
209
+ context 'defaults' do
210
+ it 'forward agent' do
211
+ expect(server.netssh_options[:forward_agent]).to eq true
212
+ end
213
+ it 'contains user' do
214
+ expect(server.netssh_options[:user]).to eq 'user_name'
215
+ end
216
+ end
217
+
218
+ context 'custom' do
219
+ let(:properties) do
220
+ { ssh_options: {
221
+ user: 'another_user',
222
+ keys: %w(/home/another_user/.ssh/id_rsa),
223
+ forward_agent: false,
224
+ auth_methods: %w(publickey password) } }
225
+ end
226
+
227
+ before do
228
+ server.with(properties)
229
+ end
230
+
231
+ it 'not forward agent' do
232
+ expect(server.netssh_options[:forward_agent]).to eq false
233
+ end
234
+ it 'contains correct user' do
235
+ expect(server.netssh_options[:user]).to eq 'another_user'
236
+ end
237
+ it 'contains keys' do
238
+ expect(server.netssh_options[:keys]).to eq %w(/home/another_user/.ssh/id_rsa)
239
+ end
240
+ it 'contains auth_methods' do
241
+ expect(server.netssh_options[:auth_methods]).to eq %w(publickey password)
242
+ end
243
+ end
244
+
245
+ end
246
+
247
+ end
248
+ end
249
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ class Servers
6
+
7
+ describe RoleFilter do
8
+ let(:role_filter) { RoleFilter.new(required, available) }
9
+ let(:required) { [] }
10
+ let(:available) { [:web, :app, :db] }
11
+
12
+ describe '#new' do
13
+ it 'takes two arrays of role names' do
14
+ expect(role_filter)
15
+ end
16
+ end
17
+
18
+ describe '.for' do
19
+
20
+ subject { RoleFilter.for(required, available) }
21
+
22
+ context 'without env vars' do
23
+ context ':all required' do
24
+ let(:required) { [:all] }
25
+
26
+ it 'returns all available names' do
27
+ expect(subject).to eq available
28
+ end
29
+ end
30
+
31
+ context 'role names required' do
32
+ let(:required) { [:web, :app] }
33
+ it 'returns all required names' do
34
+ expect(subject).to eq required
35
+ end
36
+ end
37
+ end
38
+
39
+ context 'with ENV vars' do
40
+ before do
41
+ ENV.stubs(:[]).with('ROLES').returns('app,web')
42
+ end
43
+
44
+ context ':all required' do
45
+ let(:required) { [:all] }
46
+
47
+ it 'returns available names defined in ROLES' do
48
+ expect(subject).to eq [:app, :web]
49
+ end
50
+ end
51
+
52
+ context 'role names required' do
53
+ let(:required) { [:web, :db] }
54
+ it 'returns all required names defined in ROLES' do
55
+ expect(subject).to eq [:web]
56
+ end
57
+ end
58
+ end
59
+
60
+ context 'with configuration filters' do
61
+ before do
62
+ Configuration.env.set(:filter, roles: %w{app web})
63
+ end
64
+
65
+ context ':all required' do
66
+ let(:required) { [:all] }
67
+
68
+ it 'returns available names defined in the filter' do
69
+ expect(subject).to eq [:app, :web]
70
+ end
71
+ end
72
+
73
+ context 'role names required' do
74
+ let(:required) { [:web, :db] }
75
+ it 'returns all required names defined in the filter' do
76
+ expect(subject).to eq [:web]
77
+ end
78
+ end
79
+
80
+ after do
81
+ Configuration.env.delete(:filter)
82
+ end
83
+ end
84
+
85
+ context 'with a single configuration filter' do
86
+ before do
87
+ Configuration.env.set(:filter, roles: 'web')
88
+ end
89
+
90
+ context ':all required' do
91
+ let(:required) { [:all] }
92
+
93
+ it 'returns available names defined in the filter' do
94
+ expect(subject).to eq [:web]
95
+ end
96
+ end
97
+
98
+ context 'role names required' do
99
+ let(:required) { [:web, :db] }
100
+ it 'returns all required names defined in the filter' do
101
+ expect(subject).to eq [:web]
102
+ end
103
+ end
104
+
105
+ after do
106
+ Configuration.env.delete(:filter)
107
+ end
108
+ end
109
+
110
+ context 'with configuration filters and ENV vars' do
111
+ before do
112
+ Configuration.env.set(:filter, roles: %w{app})
113
+ ENV.stubs(:[]).with('ROLES').returns('web')
114
+ end
115
+
116
+ context ':all required' do
117
+ let(:required) { [:all] }
118
+
119
+ it 'returns available names defined in the filter' do
120
+ expect(subject).to eq [:web, :app]
121
+ end
122
+ end
123
+
124
+ context 'role names required' do
125
+ let(:required) { [:web, :db] }
126
+ it 'returns all required names defined in the filter' do
127
+ expect(subject).to eq [:web]
128
+ end
129
+ end
130
+
131
+ after do
132
+ Configuration.env.delete(:filter)
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ module Capistrano
4
+ class Configuration
5
+ describe Servers do
6
+ let(:servers) { Servers.new }
7
+
8
+ describe 'adding a role' do
9
+
10
+ it 'adds two new server instances' do
11
+ expect{servers.add_role(:app, %w{1 2})}.
12
+ to change{servers.count}.from(0).to(2)
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
+
31
+ end
32
+
33
+ describe 'adding a role to an existing server' do
34
+ before do
35
+ servers.add_role(:web, %w{1 2})
36
+ servers.add_role(:app, %w{1 2})
37
+ end
38
+
39
+ it 'adds new roles to existing servers' do
40
+ expect(servers.count).to eq 2
41
+ end
42
+
43
+ end
44
+
45
+ describe 'collecting server roles' do
46
+ let(:app) { Set.new([:app]) }
47
+ let(:web_app) { Set.new([:web, :app]) }
48
+ let(:web) { Set.new([:web]) }
49
+
50
+ before do
51
+ servers.add_role(:app, %w{1 2 3})
52
+ servers.add_role(:web, %w{2 3 4})
53
+ end
54
+
55
+ it 'returns an array of the roles' do
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]
58
+ end
59
+ end
60
+
61
+ describe 'finding the primary server' do
62
+ it 'takes the first server if none have the primary property' do
63
+ servers.add_role(:app, %w{1 2})
64
+ servers.fetch_primary(:app).hostname.should == '1'
65
+ end
66
+
67
+ it 'takes the first server with the primary have the primary flag' do
68
+ servers.add_role(:app, %w{1 2})
69
+ servers.add_host('2', primary: true)
70
+ servers.fetch_primary(:app).hostname.should == '2'
71
+ end
72
+ end
73
+
74
+ describe 'fetching servers' do
75
+ before do
76
+ servers.add_role(:app, %w{1 2})
77
+ servers.add_role(:web, %w{2 3})
78
+ end
79
+
80
+ it 'returns the correct app servers' do
81
+ expect(servers.roles_for([:app]).map(&:hostname)).to eq %w{1 2}
82
+ end
83
+
84
+ it 'returns the correct web servers' do
85
+ expect(servers.roles_for([:web]).map(&:hostname)).to eq %w{2 3}
86
+ end
87
+
88
+ it 'returns the correct app and web servers' do
89
+ expect(servers.roles_for([:app, :web]).map(&:hostname)).to eq %w{1 2 3}
90
+ end
91
+
92
+ it 'returns all servers' do
93
+ expect(servers.roles_for([:all]).map(&:hostname)).to eq %w{1 2 3}
94
+ end
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 'selecting 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 'is empty if the filter would remove all matching hosts' do
119
+ expect(servers.roles_for([:app, select: :inactive])).to be_empty
120
+ end
121
+
122
+ it 'can filter hosts by properties on the host object using symbol as shorthand' do
123
+ expect(servers.roles_for([:app, filter: :active]).length).to eq 1
124
+ end
125
+
126
+ it 'can select hosts by properties on the host object using symbol as shorthand' do
127
+ expect(servers.roles_for([:app, select: :active]).length).to eq 1
128
+ end
129
+
130
+ it 'can filter hosts by properties on the host using a regular proc' do
131
+ expect(servers.roles_for([:app, filter: ->(h) { h.properties.active }]).length).to eq 1
132
+ end
133
+
134
+ it 'can select hosts by properties on the host using a regular proc' do
135
+ expect(servers.roles_for([:app, select: ->(h) { h.properties.active }]).length).to eq 1
136
+ end
137
+
138
+ it 'is empty if the regular proc filter would remove all matching hosts' do
139
+ expect(servers.roles_for([:app, select: ->(h) { h.properties.inactive }])).to be_empty
140
+ end
141
+
142
+ end
143
+
144
+ describe 'filtering roles' do
145
+
146
+ before do
147
+ ENV.stubs(:[]).with('ROLES').returns('web,db')
148
+ servers.add_host('1', roles: :app, active: true)
149
+ servers.add_host('2', roles: :app)
150
+ servers.add_host('3', roles: :web)
151
+ servers.add_host('4', roles: :web)
152
+ servers.add_host('5', roles: :db)
153
+ end
154
+
155
+ subject { servers.roles_for(roles).map(&:hostname) }
156
+
157
+ context 'when selecting all roles' do
158
+ let(:roles) { [:all] }
159
+
160
+ it 'returns the roles specified by ROLE' do
161
+ expect(subject).to eq %w{3 4 5}
162
+ end
163
+ end
164
+
165
+ context 'when selecting roles included in ROLE' do
166
+ let(:roles) { [:app, :web] }
167
+
168
+ it 'returns only roles that match ROLE' do
169
+ expect(subject).to eq %w{3 4}
170
+ end
171
+ end
172
+
173
+ context 'when selecting roles not included in ROLE' do
174
+ let(:roles) { [:app] }
175
+
176
+ it 'is empty' do
177
+ expect(subject).to be_empty
178
+ end
179
+ end
180
+ end
181
+
182
+ end
183
+ end
184
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ module Capistrano
4
+ describe Configuration do
5
+ let(:config) { Configuration.new }
6
+ let(:servers) { stub }
7
+
8
+ describe '.env' do
9
+ it 'is a global accessor to a single instance' do
10
+ Configuration.env.set(:test, true)
11
+ expect(Configuration.env.fetch(:test)).to be_true
12
+ end
13
+ end
14
+
15
+ describe 'roles' do
16
+ context 'adding a role' do
17
+ subject { config.role(:app, %w{server1 server2}) }
18
+
19
+ before do
20
+ Configuration::Servers.expects(:new).returns(servers)
21
+ servers.expects(:add_role).with(:app, %w{server1 server2}, {})
22
+ end
23
+
24
+ it 'adds the role' do
25
+ expect(subject)
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'setting and fetching' do
31
+ subject { config.fetch(:key, :default) }
32
+
33
+ context 'value is set' do
34
+ before do
35
+ config.set(:key, :value)
36
+ end
37
+
38
+ it 'returns the set value' do
39
+ expect(subject).to eq :value
40
+ end
41
+ end
42
+
43
+ context 'value is not set' do
44
+ it 'returns the default value' do
45
+ expect(subject).to eq :default
46
+ end
47
+ end
48
+
49
+ context 'value is a proc' do
50
+ subject { config.fetch(:key, Proc.new { :proc } ) }
51
+ it 'calls the proc' do
52
+ expect(subject).to eq :proc
53
+ end
54
+ end
55
+
56
+ context 'block is passed to fetch' do
57
+ subject { config.fetch(:key, :default) { fail 'we need this!' } }
58
+
59
+ it 'returns the block value' do
60
+ expect { subject }.to raise_error
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'deleting' do
66
+ before do
67
+ config.set(:key, :value)
68
+ end
69
+
70
+ it 'deletes the value' do
71
+ config.delete(:key)
72
+ expect(config.fetch(:key)).to be_nil
73
+ end
74
+ end
75
+
76
+ describe 'asking' do
77
+ let(:question) { stub }
78
+
79
+ before do
80
+ Configuration::Question.expects(:new).with(config, :branch, :default).
81
+ returns(question)
82
+ end
83
+
84
+ it 'prompts for the value when fetching' do
85
+ config.ask(:branch, :default)
86
+ expect(config.fetch(:branch)).to eq question
87
+ end
88
+ end
89
+
90
+ describe 'setting the backend' do
91
+ it 'by default, is SSHKit' do
92
+ expect(config.backend).to eq SSHKit
93
+ end
94
+
95
+ it 'can be set to another class' do
96
+ config.backend = :test
97
+ expect(config.backend).to eq :test
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ module Capistrano
4
+ module DSL
5
+
6
+ describe Env do
7
+
8
+ end
9
+ end
10
+ end