capistrano 2.8.0 → 3.19.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 (239) hide show
  1. checksums.yaml +7 -0
  2. data/.docker/Dockerfile +7 -0
  3. data/.docker/ssh_key_rsa +49 -0
  4. data/.docker/ssh_key_rsa.pub +1 -0
  5. data/.docker/ubuntu_setup.sh +23 -0
  6. data/.github/issue_template.md +19 -0
  7. data/.github/pull_request_template.md +22 -0
  8. data/.github/release-drafter.yml +25 -0
  9. data/.github/workflows/ci.yml +80 -0
  10. data/.github/workflows/release-drafter.yml +18 -0
  11. data/.gitignore +23 -8
  12. data/.rubocop.yml +62 -0
  13. data/CHANGELOG.md +1 -0
  14. data/CONTRIBUTING.md +63 -0
  15. data/DEVELOPMENT.md +112 -0
  16. data/Gemfile +42 -9
  17. data/LICENSE.txt +21 -0
  18. data/README.md +221 -0
  19. data/RELEASING.md +17 -0
  20. data/Rakefile +17 -8
  21. data/UPGRADING-3.7.md +86 -0
  22. data/bin/cap +2 -3
  23. data/bin/capify +7 -89
  24. data/capistrano.gemspec +29 -43
  25. data/docker-compose.yml +8 -0
  26. data/features/configuration.feature +28 -0
  27. data/features/deploy.feature +92 -0
  28. data/features/deploy_failure.feature +17 -0
  29. data/features/doctor.feature +11 -0
  30. data/features/installation.feature +21 -0
  31. data/features/sshconnect.feature +11 -0
  32. data/features/stage_failure.feature +9 -0
  33. data/features/step_definitions/assertions.rb +162 -0
  34. data/features/step_definitions/cap_commands.rb +21 -0
  35. data/features/step_definitions/setup.rb +91 -0
  36. data/features/subdirectory.feature +9 -0
  37. data/features/support/docker_gateway.rb +53 -0
  38. data/features/support/env.rb +1 -0
  39. data/features/support/remote_command_helpers.rb +29 -0
  40. data/features/support/remote_ssh_helpers.rb +33 -0
  41. data/lib/Capfile +3 -0
  42. data/lib/capistrano/all.rb +17 -0
  43. data/lib/capistrano/application.rb +153 -0
  44. data/lib/capistrano/configuration/empty_filter.rb +9 -0
  45. data/lib/capistrano/configuration/filter.rb +26 -0
  46. data/lib/capistrano/configuration/host_filter.rb +29 -0
  47. data/lib/capistrano/configuration/null_filter.rb +9 -0
  48. data/lib/capistrano/configuration/plugin_installer.rb +51 -0
  49. data/lib/capistrano/configuration/question.rb +76 -0
  50. data/lib/capistrano/configuration/role_filter.rb +29 -0
  51. data/lib/capistrano/configuration/scm_resolver.rb +149 -0
  52. data/lib/capistrano/configuration/server.rb +137 -0
  53. data/lib/capistrano/configuration/servers.rb +56 -96
  54. data/lib/capistrano/configuration/validated_variables.rb +110 -0
  55. data/lib/capistrano/configuration/variables.rb +79 -94
  56. data/lib/capistrano/configuration.rb +178 -33
  57. data/lib/capistrano/console.rb +1 -0
  58. data/lib/capistrano/defaults.rb +36 -0
  59. data/lib/capistrano/deploy.rb +3 -0
  60. data/lib/capistrano/doctor/environment_doctor.rb +19 -0
  61. data/lib/capistrano/doctor/gems_doctor.rb +45 -0
  62. data/lib/capistrano/doctor/output_helpers.rb +79 -0
  63. data/lib/capistrano/doctor/servers_doctor.rb +105 -0
  64. data/lib/capistrano/doctor/variables_doctor.rb +74 -0
  65. data/lib/capistrano/doctor.rb +6 -0
  66. data/lib/capistrano/dotfile.rb +2 -0
  67. data/lib/capistrano/dsl/env.rb +43 -0
  68. data/lib/capistrano/dsl/paths.rb +89 -0
  69. data/lib/capistrano/dsl/stages.rb +31 -0
  70. data/lib/capistrano/dsl/task_enhancements.rb +61 -0
  71. data/lib/capistrano/dsl.rb +95 -0
  72. data/lib/capistrano/framework.rb +2 -0
  73. data/lib/capistrano/i18n.rb +46 -0
  74. data/lib/capistrano/immutable_task.rb +30 -0
  75. data/lib/capistrano/install.rb +1 -0
  76. data/lib/capistrano/plugin.rb +95 -0
  77. data/lib/capistrano/proc_helpers.rb +13 -0
  78. data/lib/capistrano/scm/git.rb +105 -0
  79. data/lib/capistrano/scm/hg.rb +55 -0
  80. data/lib/capistrano/scm/plugin.rb +13 -0
  81. data/lib/capistrano/scm/svn.rb +56 -0
  82. data/lib/capistrano/scm/tasks/git.rake +84 -0
  83. data/lib/capistrano/scm/tasks/hg.rake +53 -0
  84. data/lib/capistrano/scm/tasks/svn.rake +53 -0
  85. data/lib/capistrano/scm.rb +115 -0
  86. data/lib/capistrano/setup.rb +36 -0
  87. data/lib/capistrano/tasks/console.rake +25 -0
  88. data/lib/capistrano/tasks/deploy.rake +280 -0
  89. data/lib/capistrano/tasks/doctor.rake +24 -0
  90. data/lib/capistrano/tasks/framework.rake +67 -0
  91. data/lib/capistrano/tasks/install.rake +41 -0
  92. data/lib/capistrano/templates/Capfile +38 -0
  93. data/lib/capistrano/templates/deploy.rb.erb +39 -0
  94. data/lib/capistrano/templates/stage.rb.erb +61 -0
  95. data/lib/capistrano/upload_task.rb +9 -0
  96. data/lib/capistrano/version.rb +1 -14
  97. data/lib/capistrano/version_validator.rb +32 -0
  98. data/lib/capistrano.rb +0 -3
  99. data/spec/integration/dsl_spec.rb +632 -0
  100. data/spec/integration_spec_helper.rb +5 -0
  101. data/spec/lib/capistrano/application_spec.rb +60 -0
  102. data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
  103. data/spec/lib/capistrano/configuration/filter_spec.rb +109 -0
  104. data/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
  105. data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
  106. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
  107. data/spec/lib/capistrano/configuration/question_spec.rb +92 -0
  108. data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
  109. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +56 -0
  110. data/spec/lib/capistrano/configuration/server_spec.rb +309 -0
  111. data/spec/lib/capistrano/configuration/servers_spec.rb +331 -0
  112. data/spec/lib/capistrano/configuration_spec.rb +357 -0
  113. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
  114. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
  115. data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
  116. data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
  117. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
  118. data/spec/lib/capistrano/dsl/paths_spec.rb +228 -0
  119. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +108 -0
  120. data/spec/lib/capistrano/dsl_spec.rb +125 -0
  121. data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
  122. data/spec/lib/capistrano/plugin_spec.rb +84 -0
  123. data/spec/lib/capistrano/scm/git_spec.rb +194 -0
  124. data/spec/lib/capistrano/scm/hg_spec.rb +109 -0
  125. data/spec/lib/capistrano/scm/svn_spec.rb +137 -0
  126. data/spec/lib/capistrano/scm_spec.rb +103 -0
  127. data/spec/lib/capistrano/upload_task_spec.rb +19 -0
  128. data/spec/lib/capistrano/version_validator_spec.rb +118 -0
  129. data/spec/lib/capistrano_spec.rb +7 -0
  130. data/spec/spec_helper.rb +29 -0
  131. data/spec/support/matchers.rb +5 -0
  132. data/spec/support/tasks/database.rake +11 -0
  133. data/spec/support/tasks/fail.rake +8 -0
  134. data/spec/support/tasks/failed.rake +5 -0
  135. data/spec/support/tasks/plugin.rake +6 -0
  136. data/spec/support/tasks/root.rake +11 -0
  137. data/spec/support/test_app.rb +205 -0
  138. metadata +234 -208
  139. data/.rvmrc +0 -1
  140. data/CHANGELOG +0 -954
  141. data/README.mdown +0 -76
  142. data/lib/capistrano/callback.rb +0 -45
  143. data/lib/capistrano/cli/execute.rb +0 -85
  144. data/lib/capistrano/cli/help.rb +0 -125
  145. data/lib/capistrano/cli/help.txt +0 -81
  146. data/lib/capistrano/cli/options.rb +0 -243
  147. data/lib/capistrano/cli/ui.rb +0 -40
  148. data/lib/capistrano/cli.rb +0 -47
  149. data/lib/capistrano/command.rb +0 -286
  150. data/lib/capistrano/configuration/actions/file_transfer.rb +0 -51
  151. data/lib/capistrano/configuration/actions/inspect.rb +0 -46
  152. data/lib/capistrano/configuration/actions/invocation.rb +0 -298
  153. data/lib/capistrano/configuration/callbacks.rb +0 -148
  154. data/lib/capistrano/configuration/connections.rb +0 -230
  155. data/lib/capistrano/configuration/execution.rb +0 -143
  156. data/lib/capistrano/configuration/loading.rb +0 -197
  157. data/lib/capistrano/configuration/namespaces.rb +0 -197
  158. data/lib/capistrano/configuration/roles.rb +0 -73
  159. data/lib/capistrano/errors.rb +0 -19
  160. data/lib/capistrano/ext/string.rb +0 -5
  161. data/lib/capistrano/extensions.rb +0 -57
  162. data/lib/capistrano/logger.rb +0 -59
  163. data/lib/capistrano/processable.rb +0 -53
  164. data/lib/capistrano/recipes/compat.rb +0 -32
  165. data/lib/capistrano/recipes/deploy/assets.rb +0 -57
  166. data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
  167. data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -54
  168. data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -111
  169. data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
  170. data/lib/capistrano/recipes/deploy/scm/base.rb +0 -196
  171. data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
  172. data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -153
  173. data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -96
  174. data/lib/capistrano/recipes/deploy/scm/git.rb +0 -282
  175. data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -137
  176. data/lib/capistrano/recipes/deploy/scm/none.rb +0 -44
  177. data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -138
  178. data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -121
  179. data/lib/capistrano/recipes/deploy/scm.rb +0 -19
  180. data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -88
  181. data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
  182. data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -224
  183. data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
  184. data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
  185. data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -57
  186. data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
  187. data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
  188. data/lib/capistrano/recipes/deploy.rb +0 -568
  189. data/lib/capistrano/recipes/standard.rb +0 -37
  190. data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
  191. data/lib/capistrano/role.rb +0 -102
  192. data/lib/capistrano/server_definition.rb +0 -56
  193. data/lib/capistrano/shell.rb +0 -260
  194. data/lib/capistrano/ssh.rb +0 -101
  195. data/lib/capistrano/task_definition.rb +0 -75
  196. data/lib/capistrano/transfer.rb +0 -216
  197. data/rvmrc.sample +0 -1
  198. data/test/cli/execute_test.rb +0 -132
  199. data/test/cli/help_test.rb +0 -165
  200. data/test/cli/options_test.rb +0 -329
  201. data/test/cli/ui_test.rb +0 -28
  202. data/test/cli_test.rb +0 -17
  203. data/test/command_test.rb +0 -289
  204. data/test/configuration/actions/file_transfer_test.rb +0 -61
  205. data/test/configuration/actions/inspect_test.rb +0 -65
  206. data/test/configuration/actions/invocation_test.rb +0 -247
  207. data/test/configuration/callbacks_test.rb +0 -220
  208. data/test/configuration/connections_test.rb +0 -420
  209. data/test/configuration/execution_test.rb +0 -175
  210. data/test/configuration/loading_test.rb +0 -132
  211. data/test/configuration/namespace_dsl_test.rb +0 -311
  212. data/test/configuration/roles_test.rb +0 -144
  213. data/test/configuration/servers_test.rb +0 -183
  214. data/test/configuration/variables_test.rb +0 -190
  215. data/test/configuration_test.rb +0 -88
  216. data/test/deploy/local_dependency_test.rb +0 -76
  217. data/test/deploy/remote_dependency_test.rb +0 -135
  218. data/test/deploy/scm/accurev_test.rb +0 -23
  219. data/test/deploy/scm/base_test.rb +0 -55
  220. data/test/deploy/scm/bzr_test.rb +0 -51
  221. data/test/deploy/scm/darcs_test.rb +0 -37
  222. data/test/deploy/scm/git_test.rb +0 -184
  223. data/test/deploy/scm/mercurial_test.rb +0 -134
  224. data/test/deploy/scm/none_test.rb +0 -35
  225. data/test/deploy/scm/subversion_test.rb +0 -32
  226. data/test/deploy/strategy/copy_test.rb +0 -321
  227. data/test/extensions_test.rb +0 -69
  228. data/test/fixtures/cli_integration.rb +0 -5
  229. data/test/fixtures/config.rb +0 -5
  230. data/test/fixtures/custom.rb +0 -3
  231. data/test/logger_test.rb +0 -123
  232. data/test/recipes_test.rb +0 -25
  233. data/test/role_test.rb +0 -11
  234. data/test/server_definition_test.rb +0 -121
  235. data/test/shell_test.rb +0 -90
  236. data/test/ssh_test.rb +0 -113
  237. data/test/task_definition_test.rb +0 -116
  238. data/test/transfer_test.rb +0 -160
  239. data/test/utils.rb +0 -37
@@ -0,0 +1,228 @@
1
+ require "spec_helper"
2
+
3
+ describe Capistrano::DSL::Paths do
4
+ let(:dsl) { Class.new.extend Capistrano::DSL }
5
+ let(:parent) { Pathname.new("/var/shared") }
6
+ let(:paths) { Class.new.extend Capistrano::DSL::Paths }
7
+
8
+ let(:linked_dirs) { %w{log public/system} }
9
+ let(:linked_files) { %w{config/database.yml log/my.log log/access.log} }
10
+
11
+ before do
12
+ dsl.set(:deploy_to, "/var/www")
13
+ end
14
+
15
+ describe "#linked_dirs" do
16
+ subject { paths.linked_dirs(parent) }
17
+
18
+ before do
19
+ paths.expects(:fetch).with(:linked_dirs).returns(linked_dirs)
20
+ end
21
+
22
+ it "returns the full pathnames" do
23
+ expect(subject).to eq [
24
+ Pathname.new("/var/shared/log"),
25
+ Pathname.new("/var/shared/public/system")
26
+ ]
27
+ end
28
+ end
29
+
30
+ describe "#linked_files" do
31
+ subject { paths.linked_files(parent) }
32
+
33
+ before do
34
+ paths.expects(:fetch).with(:linked_files).returns(linked_files)
35
+ end
36
+
37
+ it "returns the full pathnames" do
38
+ expect(subject).to eq [
39
+ Pathname.new("/var/shared/config/database.yml"),
40
+ Pathname.new("/var/shared/log/my.log"),
41
+ Pathname.new("/var/shared/log/access.log")
42
+ ]
43
+ end
44
+ end
45
+
46
+ describe "#linked_file_dirs" do
47
+ subject { paths.linked_file_dirs(parent) }
48
+
49
+ before do
50
+ paths.expects(:fetch).with(:linked_files).returns(linked_files)
51
+ end
52
+
53
+ it "returns the full paths names of the parent dirs" do
54
+ expect(subject).to eq [
55
+ Pathname.new("/var/shared/config"),
56
+ Pathname.new("/var/shared/log")
57
+ ]
58
+ end
59
+ end
60
+
61
+ describe "#linked_dir_parents" do
62
+ subject { paths.linked_dir_parents(parent) }
63
+
64
+ before do
65
+ paths.expects(:fetch).with(:linked_dirs).returns(linked_dirs)
66
+ end
67
+
68
+ it "returns the full paths names of the parent dirs" do
69
+ expect(subject).to eq [
70
+ Pathname.new("/var/shared"),
71
+ Pathname.new("/var/shared/public")
72
+ ]
73
+ end
74
+ end
75
+
76
+ describe "#release path" do
77
+ subject { dsl.release_path }
78
+
79
+ context "where no release path has been set" do
80
+ before do
81
+ dsl.delete(:release_path)
82
+ end
83
+
84
+ it "returns the `current_path` value" do
85
+ expect(subject.to_s).to eq "/var/www/current"
86
+ end
87
+ end
88
+
89
+ context "where the release path has been set" do
90
+ before do
91
+ dsl.set(:release_path, "/var/www/release_path")
92
+ end
93
+
94
+ it "returns the set `release_path` value" do
95
+ expect(subject.to_s).to eq "/var/www/release_path"
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "#set_release_path" do
101
+ let(:now) { Time.parse("Oct 21 16:29:00 2015") }
102
+ subject { dsl.release_path }
103
+
104
+ context "without a timestamp" do
105
+ before do
106
+ dsl.env.expects(:timestamp).returns(now)
107
+ dsl.set_release_path
108
+ end
109
+
110
+ it "returns the release path with the current env timestamp" do
111
+ expect(subject.to_s).to eq "/var/www/releases/20151021162900"
112
+ end
113
+ end
114
+
115
+ context "with a timestamp" do
116
+ before do
117
+ dsl.set_release_path("timestamp")
118
+ end
119
+
120
+ it "returns the release path with the timestamp" do
121
+ expect(subject.to_s).to eq "/var/www/releases/timestamp"
122
+ end
123
+ end
124
+ end
125
+
126
+ describe "#releases_path" do
127
+ subject { paths.releases_path }
128
+
129
+ context "with custom releases directory" do
130
+ before do
131
+ paths.expects(:fetch).with(:releases_directory, "releases").returns("test123")
132
+ paths.expects(:fetch).with(:deploy_to).returns("/var/www")
133
+ end
134
+
135
+ it "returns the releases path with the custom directory" do
136
+ expect(subject.to_s).to eq "/var/www/test123"
137
+ end
138
+ end
139
+ end
140
+
141
+ describe "#shared_path" do
142
+ subject { paths.shared_path }
143
+
144
+ context "with custom shared directory" do
145
+ before do
146
+ paths.expects(:fetch).with(:shared_directory, "shared").returns("test123")
147
+ paths.expects(:fetch).with(:deploy_to).returns("/var/www")
148
+ end
149
+
150
+ it "returns the shared path with the custom directory" do
151
+ expect(subject.to_s).to eq "/var/www/test123"
152
+ end
153
+ end
154
+ end
155
+
156
+ describe "#deploy_config_path" do
157
+ subject { dsl.deploy_config_path.to_s }
158
+
159
+ context "when not specified" do
160
+ before do
161
+ dsl.delete(:deploy_config_path)
162
+ end
163
+
164
+ it 'returns "config/deploy.rb"' do
165
+ expect(subject).to eq "config/deploy.rb"
166
+ end
167
+ end
168
+
169
+ context "when the variable :deploy_config_path is set" do
170
+ before do
171
+ dsl.set(:deploy_config_path, "my/custom/path.rb")
172
+ end
173
+
174
+ it "returns the custom path" do
175
+ expect(subject).to eq "my/custom/path.rb"
176
+ end
177
+ end
178
+ end
179
+
180
+ describe "#stage_config_path" do
181
+ subject { dsl.stage_config_path.to_s }
182
+
183
+ context "when not specified" do
184
+ before do
185
+ dsl.delete(:stage_config_path)
186
+ end
187
+
188
+ it 'returns "config/deploy"' do
189
+ expect(subject).to eq "config/deploy"
190
+ end
191
+ end
192
+
193
+ context "when the variable :stage_config_path is set" do
194
+ before do
195
+ dsl.set(:stage_config_path, "my/custom/path")
196
+ end
197
+
198
+ it "returns the custom path" do
199
+ expect(subject).to eq "my/custom/path"
200
+ end
201
+ end
202
+ end
203
+
204
+ describe "#repo_path" do
205
+ subject { dsl.repo_path.to_s }
206
+
207
+ context "when not specified" do
208
+ before do
209
+ dsl.delete(:repo_path)
210
+ end
211
+
212
+ it 'returns the default #{deploy_to}/repo' do
213
+ dsl.set(:deploy_to, "/var/www")
214
+ expect(subject).to eq "/var/www/repo"
215
+ end
216
+ end
217
+
218
+ context "when the variable :repo_path is set" do
219
+ before do
220
+ dsl.set(:repo_path, "my/custom/path")
221
+ end
222
+
223
+ it "returns the custom path" do
224
+ expect(subject).to eq "my/custom/path"
225
+ end
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,108 @@
1
+ require "spec_helper"
2
+
3
+ module Capistrano
4
+ class DummyTaskEnhancements
5
+ include TaskEnhancements
6
+ end
7
+
8
+ describe TaskEnhancements do
9
+ let(:task_enhancements) { DummyTaskEnhancements.new }
10
+
11
+ describe "ordering" do
12
+ after do
13
+ task.clear
14
+ before_task.clear
15
+ after_task.clear
16
+ Rake::Task.clear
17
+ end
18
+
19
+ let(:order) { [] }
20
+ let!(:task) do
21
+ Rake::Task.define_task("task", [:order]) do |_t, args|
22
+ args["order"].push "task"
23
+ end
24
+ end
25
+
26
+ let!(:before_task) do
27
+ Rake::Task.define_task("before_task") do
28
+ order.push "before_task"
29
+ end
30
+ end
31
+
32
+ let!(:after_task) do
33
+ Rake::Task.define_task("after_task") do
34
+ order.push "after_task"
35
+ end
36
+ end
37
+
38
+ it "invokes in proper order if define after than before", capture_io: true do
39
+ task_enhancements.after("task", "after_task")
40
+ task_enhancements.before("task", "before_task")
41
+
42
+ Rake::Task["task"].invoke order
43
+
44
+ expect(order).to eq(%w(before_task task after_task))
45
+ end
46
+
47
+ it "invokes in proper order if define before than after", capture_io: true do
48
+ task_enhancements.before("task", "before_task")
49
+ task_enhancements.after("task", "after_task")
50
+
51
+ Rake::Task["task"].invoke order
52
+
53
+ expect(order).to eq(%w(before_task task after_task))
54
+ end
55
+
56
+ it "invokes in proper order when referring to as-yet undefined tasks", capture_io: true do
57
+ task_enhancements.after("task", "not_loaded_task")
58
+
59
+ Rake::Task.define_task("not_loaded_task") do
60
+ order.push "not_loaded_task"
61
+ end
62
+
63
+ Rake::Task["task"].invoke order
64
+
65
+ expect(order).to eq(%w(task not_loaded_task))
66
+ end
67
+
68
+ it "invokes in proper order and with arguments and block", capture_io: true do
69
+ task_enhancements.after("task", "after_task_custom", :order) do |_t, _args|
70
+ order.push "after_task"
71
+ end
72
+
73
+ task_enhancements.before("task", "before_task_custom", :order) do |_t, _args|
74
+ order.push "before_task"
75
+ end
76
+
77
+ Rake::Task["task"].invoke(order)
78
+
79
+ expect(order).to eq(%w(before_task task after_task))
80
+ end
81
+
82
+ it "invokes using the correct namespace when defined within a namespace", capture_io: true do
83
+ Rake.application.in_namespace("namespace") do
84
+ Rake::Task.define_task("task") do |t|
85
+ order.push(t.name)
86
+ end
87
+ task_enhancements.before("task", "before_task", :order) do |t|
88
+ order.push(t.name)
89
+ end
90
+ task_enhancements.after("task", "after_task", :order) do |t|
91
+ order.push(t.name)
92
+ end
93
+ end
94
+
95
+ Rake::Task["namespace:task"].invoke
96
+
97
+ expect(order).to eq(
98
+ ["namespace:before_task", "namespace:task", "namespace:after_task"]
99
+ )
100
+ end
101
+
102
+ it "raises a sensible error if the task isn't found", capture_io: true do
103
+ task_enhancements.after("task", "non_existent_task")
104
+ expect { Rake::Task["task"].invoke order }.to raise_error(ArgumentError, 'Task "non_existent_task" not found')
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,125 @@
1
+ require "spec_helper"
2
+
3
+ module Capistrano
4
+ class DummyDSL
5
+ include DSL
6
+ end
7
+
8
+ # see also - spec/integration/dsl_spec.rb
9
+ describe DSL do
10
+ let(:dsl) { DummyDSL.new }
11
+
12
+ describe "#t" do
13
+ before do
14
+ I18n.expects(:t).with(:phrase, count: 2, scope: :capistrano)
15
+ end
16
+
17
+ it "delegates to I18n" do
18
+ dsl.t(:phrase, count: 2)
19
+ end
20
+ end
21
+
22
+ describe "#stage_set?" do
23
+ subject { dsl.stage_set? }
24
+
25
+ context "stage is set" do
26
+ before do
27
+ dsl.set(:stage, :sandbox)
28
+ end
29
+ it { expect(subject).to be_truthy }
30
+ end
31
+
32
+ context "stage is not set" do
33
+ before do
34
+ dsl.set(:stage, nil)
35
+ end
36
+ it { expect(subject).to be_falsey }
37
+ end
38
+ end
39
+
40
+ describe "#sudo" do
41
+ before do
42
+ dsl.expects(:execute).with(:sudo, :my, :command)
43
+ end
44
+
45
+ it "prepends sudo, delegates to execute" do
46
+ dsl.sudo(:my, :command)
47
+ end
48
+ end
49
+
50
+ describe "#execute" do
51
+ context "use outside of on scope" do
52
+ after do
53
+ task.clear
54
+ Rake::Task.clear
55
+ end
56
+
57
+ let(:task) do
58
+ Rake::Task.define_task("execute_outside_scope") do
59
+ dsl.execute "whoami"
60
+ end
61
+ end
62
+
63
+ it "prints helpful message to stderr", capture_io: true do
64
+ expect do
65
+ expect do
66
+ task.invoke
67
+ end.to output(/^.*Warning: `execute' should be wrapped in an `on' scope/).to_stderr
68
+ end.to raise_error(NoMethodError)
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#invoke" do
74
+ context "reinvoking" do
75
+ it "will not re-enable invoking task", capture_io: true do
76
+ counter = 0
77
+
78
+ Rake::Task.define_task("A") do
79
+ counter += 1
80
+ end
81
+
82
+ expect do
83
+ dsl.invoke("A")
84
+ dsl.invoke("A")
85
+ end.to change { counter }.by(1)
86
+ end
87
+
88
+ it "will print a message on stderr", capture_io: true do
89
+ Rake::Task.define_task("B")
90
+
91
+ expect do
92
+ dsl.invoke("B")
93
+ dsl.invoke("B")
94
+ end.to output(/If you really meant to run this task again, use invoke!/).to_stderr
95
+ end
96
+ end
97
+ end
98
+
99
+ describe "#invoke!" do
100
+ context "reinvoking" do
101
+ it "will re-enable invoking task", capture_io: true do
102
+ counter = 0
103
+
104
+ Rake::Task.define_task("C") do
105
+ counter += 1
106
+ end
107
+
108
+ expect do
109
+ dsl.invoke!("C")
110
+ dsl.invoke!("C")
111
+ end.to change { counter }.by(2)
112
+ end
113
+
114
+ it "will not print a message on stderr", capture_io: true do
115
+ Rake::Task.define_task("D")
116
+
117
+ expect do
118
+ dsl.invoke!("D")
119
+ dsl.invoke!("D")
120
+ end.to_not output(/If you really meant to run this task again, use invoke!/).to_stderr
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,31 @@
1
+ require "spec_helper"
2
+ require "rake"
3
+ require "capistrano/immutable_task"
4
+
5
+ module Capistrano
6
+ describe ImmutableTask do
7
+ after do
8
+ # Ensure that any tasks we create in these tests don't pollute other tests
9
+ Rake::Task.clear
10
+ end
11
+
12
+ it "prints warning and raises when task is enhanced" do
13
+ extend(Rake::DSL)
14
+
15
+ load_defaults = Rake::Task.define_task("load:defaults")
16
+ load_defaults.extend(Capistrano::ImmutableTask)
17
+
18
+ $stderr.expects(:puts).with do |message|
19
+ message =~ /^ERROR: load:defaults has already been invoked/
20
+ end
21
+
22
+ expect do
23
+ namespace :load do
24
+ task :defaults do
25
+ # Never reached since load_defaults is frozen and can't be enhanced
26
+ end
27
+ end
28
+ end.to raise_error(/frozen/i)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,84 @@
1
+ require "spec_helper"
2
+ require "capistrano/plugin"
3
+
4
+ module Capistrano
5
+ describe Plugin do
6
+ include Rake::DSL
7
+ include Capistrano::DSL
8
+
9
+ class DummyPlugin < Capistrano::Plugin
10
+ def define_tasks
11
+ task :hello do
12
+ end
13
+ end
14
+
15
+ def register_hooks
16
+ before "deploy:published", "hello"
17
+ end
18
+ end
19
+
20
+ class ExternalTasksPlugin < Capistrano::Plugin
21
+ def define_tasks
22
+ eval_rakefile(
23
+ File.expand_path("../../../support/tasks/plugin.rake", __FILE__)
24
+ )
25
+ end
26
+
27
+ # Called from plugin.rake to demonstrate that helper methods work
28
+ def hello
29
+ set :plugin_result, "hello"
30
+ end
31
+ end
32
+
33
+ before do
34
+ # Define an example task to allow testing hooks
35
+ task "deploy:published"
36
+ end
37
+
38
+ after do
39
+ # Clean up any tasks or variables we created during the tests
40
+ Rake::Task.clear
41
+ Capistrano::Configuration.reset!
42
+ end
43
+
44
+ it "defines tasks when constructed" do
45
+ install_plugin(DummyPlugin)
46
+ expect(Rake::Task["hello"]).not_to be_nil
47
+ end
48
+
49
+ it "registers hooks when constructed" do
50
+ install_plugin(DummyPlugin)
51
+ expect(Rake::Task["deploy:published"].prerequisites).to include("hello")
52
+ end
53
+
54
+ it "skips registering hooks if load_hooks: false" do
55
+ install_plugin(DummyPlugin, load_hooks: false)
56
+ expect(Rake::Task["deploy:published"].prerequisites).to be_empty
57
+ end
58
+
59
+ it "doesn't call set_defaults immediately" do
60
+ dummy = DummyPlugin.new
61
+ install_plugin(dummy)
62
+ dummy.expects(:set_defaults).never
63
+ end
64
+
65
+ it "calls set_defaults during load:defaults", capture_io: true do
66
+ dummy = DummyPlugin.new
67
+ dummy.expects(:set_defaults).once
68
+ install_plugin(dummy)
69
+ Rake::Task["load:defaults"].invoke
70
+ end
71
+
72
+ it "is able to load tasks from a .rake file", capture_io: true do
73
+ install_plugin(ExternalTasksPlugin)
74
+ Rake::Task["plugin_test"].invoke
75
+ expect(fetch(:plugin_result)).to eq("hello")
76
+ end
77
+
78
+ it "exposes the SSHKit backend to subclasses" do
79
+ SSHKit::Backend.expects(:current).returns(:backend)
80
+ plugin = DummyPlugin.new
81
+ expect(plugin.send(:backend)).to eq(:backend)
82
+ end
83
+ end
84
+ end