capistrano 3.4.0 → 3.17.1

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 (138) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +129 -0
  3. data/.github/issue_template.md +19 -0
  4. data/.github/pull_request_template.md +22 -0
  5. data/.github/release-drafter.yml +17 -0
  6. data/.github/workflows/push.yml +12 -0
  7. data/.gitignore +8 -5
  8. data/.rubocop.yml +62 -0
  9. data/CHANGELOG.md +1 -307
  10. data/CONTRIBUTING.md +63 -93
  11. data/DEVELOPMENT.md +127 -0
  12. data/Dangerfile +1 -0
  13. data/Gemfile +40 -3
  14. data/LICENSE.txt +1 -1
  15. data/README.md +127 -44
  16. data/RELEASING.md +17 -0
  17. data/Rakefile +13 -2
  18. data/UPGRADING-3.7.md +86 -0
  19. data/bin/cap +1 -1
  20. data/capistrano.gemspec +21 -24
  21. data/features/deploy.feature +35 -1
  22. data/features/doctor.feature +11 -0
  23. data/features/installation.feature +8 -3
  24. data/features/stage_failure.feature +9 -0
  25. data/features/step_definitions/assertions.rb +51 -18
  26. data/features/step_definitions/cap_commands.rb +9 -0
  27. data/features/step_definitions/setup.rb +53 -9
  28. data/features/subdirectory.feature +9 -0
  29. data/features/support/env.rb +5 -5
  30. data/features/support/remote_command_helpers.rb +12 -6
  31. data/features/support/vagrant_helpers.rb +17 -11
  32. data/lib/Capfile +1 -1
  33. data/lib/capistrano/all.rb +10 -10
  34. data/lib/capistrano/application.rb +47 -34
  35. data/lib/capistrano/configuration/empty_filter.rb +9 -0
  36. data/lib/capistrano/configuration/filter.rb +17 -47
  37. data/lib/capistrano/configuration/host_filter.rb +29 -0
  38. data/lib/capistrano/configuration/null_filter.rb +9 -0
  39. data/lib/capistrano/configuration/plugin_installer.rb +51 -0
  40. data/lib/capistrano/configuration/question.rb +31 -9
  41. data/lib/capistrano/configuration/role_filter.rb +29 -0
  42. data/lib/capistrano/configuration/scm_resolver.rb +149 -0
  43. data/lib/capistrano/configuration/server.rb +29 -23
  44. data/lib/capistrano/configuration/servers.rb +21 -14
  45. data/lib/capistrano/configuration/validated_variables.rb +110 -0
  46. data/lib/capistrano/configuration/variables.rb +112 -0
  47. data/lib/capistrano/configuration.rb +91 -44
  48. data/lib/capistrano/defaults.rb +26 -4
  49. data/lib/capistrano/deploy.rb +1 -1
  50. data/lib/capistrano/doctor/environment_doctor.rb +19 -0
  51. data/lib/capistrano/doctor/gems_doctor.rb +45 -0
  52. data/lib/capistrano/doctor/output_helpers.rb +79 -0
  53. data/lib/capistrano/doctor/servers_doctor.rb +105 -0
  54. data/lib/capistrano/doctor/variables_doctor.rb +74 -0
  55. data/lib/capistrano/doctor.rb +6 -0
  56. data/lib/capistrano/dotfile.rb +1 -2
  57. data/lib/capistrano/dsl/env.rb +9 -47
  58. data/lib/capistrano/dsl/paths.rb +11 -25
  59. data/lib/capistrano/dsl/stages.rb +14 -2
  60. data/lib/capistrano/dsl/task_enhancements.rb +7 -12
  61. data/lib/capistrano/dsl.rb +47 -16
  62. data/lib/capistrano/framework.rb +1 -1
  63. data/lib/capistrano/i18n.rb +32 -24
  64. data/lib/capistrano/immutable_task.rb +30 -0
  65. data/lib/capistrano/install.rb +1 -1
  66. data/lib/capistrano/plugin.rb +95 -0
  67. data/lib/capistrano/proc_helpers.rb +13 -0
  68. data/lib/capistrano/scm/git.rb +100 -0
  69. data/lib/capistrano/scm/hg.rb +55 -0
  70. data/lib/capistrano/scm/plugin.rb +13 -0
  71. data/lib/capistrano/scm/svn.rb +56 -0
  72. data/lib/capistrano/scm/tasks/git.rake +73 -0
  73. data/lib/capistrano/scm/tasks/hg.rake +53 -0
  74. data/lib/capistrano/scm/tasks/svn.rake +53 -0
  75. data/lib/capistrano/scm.rb +7 -20
  76. data/lib/capistrano/setup.rb +20 -6
  77. data/lib/capistrano/tasks/console.rake +4 -8
  78. data/lib/capistrano/tasks/deploy.rake +105 -73
  79. data/lib/capistrano/tasks/doctor.rake +24 -0
  80. data/lib/capistrano/tasks/framework.rake +13 -14
  81. data/lib/capistrano/tasks/install.rake +14 -15
  82. data/lib/capistrano/templates/Capfile +21 -10
  83. data/lib/capistrano/templates/deploy.rb.erb +17 -26
  84. data/lib/capistrano/templates/stage.rb.erb +9 -9
  85. data/lib/capistrano/upload_task.rb +1 -1
  86. data/lib/capistrano/version.rb +1 -1
  87. data/lib/capistrano/version_validator.rb +5 -10
  88. data/spec/integration/dsl_spec.rb +289 -240
  89. data/spec/integration_spec_helper.rb +3 -5
  90. data/spec/lib/capistrano/application_spec.rb +23 -39
  91. data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
  92. data/spec/lib/capistrano/configuration/filter_spec.rb +83 -85
  93. data/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
  94. data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
  95. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
  96. data/spec/lib/capistrano/configuration/question_spec.rb +58 -26
  97. data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
  98. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +55 -0
  99. data/spec/lib/capistrano/configuration/server_spec.rb +106 -113
  100. data/spec/lib/capistrano/configuration/servers_spec.rb +129 -145
  101. data/spec/lib/capistrano/configuration_spec.rb +224 -63
  102. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
  103. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
  104. data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
  105. data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
  106. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
  107. data/spec/lib/capistrano/dsl/paths_spec.rb +97 -59
  108. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +57 -37
  109. data/spec/lib/capistrano/dsl_spec.rb +84 -11
  110. data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
  111. data/spec/lib/capistrano/plugin_spec.rb +84 -0
  112. data/spec/lib/capistrano/scm/git_spec.rb +184 -0
  113. data/spec/lib/capistrano/scm/hg_spec.rb +109 -0
  114. data/spec/lib/capistrano/scm/svn_spec.rb +137 -0
  115. data/spec/lib/capistrano/scm_spec.rb +7 -8
  116. data/spec/lib/capistrano/upload_task_spec.rb +7 -7
  117. data/spec/lib/capistrano/version_validator_spec.rb +61 -46
  118. data/spec/lib/capistrano_spec.rb +2 -3
  119. data/spec/spec_helper.rb +21 -8
  120. data/spec/support/Vagrantfile +9 -10
  121. data/spec/support/tasks/database.rake +3 -3
  122. data/spec/support/tasks/fail.rake +4 -3
  123. data/spec/support/tasks/failed.rake +2 -2
  124. data/spec/support/tasks/plugin.rake +6 -0
  125. data/spec/support/tasks/root.rake +4 -4
  126. data/spec/support/test_app.rb +64 -39
  127. metadata +100 -55
  128. data/.travis.yml +0 -13
  129. data/features/remote_file_task.feature +0 -14
  130. data/lib/capistrano/git.rb +0 -46
  131. data/lib/capistrano/hg.rb +0 -43
  132. data/lib/capistrano/svn.rb +0 -38
  133. data/lib/capistrano/tasks/git.rake +0 -81
  134. data/lib/capistrano/tasks/hg.rake +0 -52
  135. data/lib/capistrano/tasks/svn.rake +0 -52
  136. data/spec/lib/capistrano/git_spec.rb +0 -81
  137. data/spec/lib/capistrano/hg_spec.rb +0 -81
  138. data/spec/lib/capistrano/svn_spec.rb +0 -79
@@ -0,0 +1,89 @@
1
+ require "spec_helper"
2
+ require "capistrano/doctor/variables_doctor"
3
+
4
+ module Capistrano
5
+ module Doctor
6
+ describe VariablesDoctor do
7
+ include Capistrano::DSL
8
+
9
+ let(:doc) { VariablesDoctor.new }
10
+
11
+ before do
12
+ set :branch, "master"
13
+ set :pty, false
14
+
15
+ env.variables.untrusted! do
16
+ set :application, "my_app"
17
+ set :repo_tree, "public"
18
+ set :repo_url, ".git"
19
+ set :copy_strategy, :scp
20
+ set :custom_setting, "hello"
21
+ set "string_setting", "hello"
22
+ ask :secret
23
+ end
24
+
25
+ fetch :custom_setting
26
+ end
27
+
28
+ after { Capistrano::Configuration.reset! }
29
+
30
+ it "prints using 4-space indentation" do
31
+ expect { doc.call }.to output(/^ {4}/).to_stdout
32
+ end
33
+
34
+ it "prints variable names and values" do
35
+ expect { doc.call }.to output(/:branch\s+"master"$/).to_stdout
36
+ expect { doc.call }.to output(/:pty\s+false$/).to_stdout
37
+ expect { doc.call }.to output(/:application\s+"my_app"$/).to_stdout
38
+ expect { doc.call }.to output(/:repo_url\s+".git"$/).to_stdout
39
+ expect { doc.call }.to output(/:repo_tree\s+"public"$/).to_stdout
40
+ expect { doc.call }.to output(/:copy_strategy\s+:scp$/).to_stdout
41
+ expect { doc.call }.to output(/:custom_setting\s+"hello"$/).to_stdout
42
+ expect { doc.call }.to output(/"string_setting"\s+"hello"$/).to_stdout
43
+ end
44
+
45
+ it "prints unanswered question variable as <ask>" do
46
+ expect { doc.call }.to output(/:secret\s+<ask>$/).to_stdout
47
+ end
48
+
49
+ it "prints warning for unrecognized variable" do
50
+ expect { doc.call }.to \
51
+ output(/:copy_strategy is not a recognized Capistrano setting/)\
52
+ .to_stdout
53
+ end
54
+
55
+ it "does not print warning for unrecognized variable that is fetched" do
56
+ expect { doc.call }.not_to \
57
+ output(/:custom_setting is not a recognized Capistrano setting/)\
58
+ .to_stdout
59
+ end
60
+
61
+ it "does not print warning for whitelisted variable" do
62
+ expect { doc.call }.not_to \
63
+ output(/:repo_tree is not a recognized Capistrano setting/)\
64
+ .to_stdout
65
+ end
66
+
67
+ describe "Rake" do
68
+ before do
69
+ load File.expand_path("../../../../../lib/capistrano/doctor.rb",
70
+ __FILE__)
71
+ end
72
+
73
+ after do
74
+ Rake::Task.clear
75
+ end
76
+
77
+ it "has an doctor:variables task that calls VariablesDoctor", capture_io: true do
78
+ VariablesDoctor.any_instance.expects(:call)
79
+ Rake::Task["doctor:variables"].invoke
80
+ end
81
+
82
+ it "has a doctor task that depends on doctor:variables" do
83
+ expect(Rake::Task["doctor"].prerequisites).to \
84
+ include("doctor:variables")
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -1,189 +1,227 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  describe Capistrano::DSL::Paths do
4
-
5
4
  let(:dsl) { Class.new.extend Capistrano::DSL }
6
- let(:parent) { Pathname.new('/var/shared') }
5
+ let(:parent) { Pathname.new("/var/shared") }
7
6
  let(:paths) { Class.new.extend Capistrano::DSL::Paths }
8
7
 
9
8
  let(:linked_dirs) { %w{log public/system} }
10
- let(:linked_files) { %w{config/database.yml log/my.log} }
9
+ let(:linked_files) { %w{config/database.yml log/my.log log/access.log} }
11
10
 
12
11
  before do
13
- dsl.set(:deploy_to, '/var/www')
12
+ dsl.set(:deploy_to, "/var/www")
14
13
  end
15
14
 
16
- describe '#linked_dirs' do
15
+ describe "#linked_dirs" do
17
16
  subject { paths.linked_dirs(parent) }
18
17
 
19
18
  before do
20
19
  paths.expects(:fetch).with(:linked_dirs).returns(linked_dirs)
21
20
  end
22
21
 
23
- it 'returns the full pathnames' do
24
- expect(subject).to eq [Pathname.new('/var/shared/log'), Pathname.new('/var/shared/public/system')]
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
+ ]
25
27
  end
26
28
  end
27
29
 
28
-
29
- describe '#linked_files' do
30
+ describe "#linked_files" do
30
31
  subject { paths.linked_files(parent) }
31
32
 
32
33
  before do
33
34
  paths.expects(:fetch).with(:linked_files).returns(linked_files)
34
35
  end
35
36
 
36
- it 'returns the full pathnames' do
37
- expect(subject).to eq [Pathname.new('/var/shared/config/database.yml'), Pathname.new('/var/shared/log/my.log')]
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
+ ]
38
43
  end
39
44
  end
40
45
 
41
- describe '#linked_file_dirs' do
46
+ describe "#linked_file_dirs" do
42
47
  subject { paths.linked_file_dirs(parent) }
43
48
 
44
49
  before do
45
50
  paths.expects(:fetch).with(:linked_files).returns(linked_files)
46
51
  end
47
52
 
48
- it 'returns the full paths names of the parent dirs' do
49
- expect(subject).to eq [Pathname.new('/var/shared/config'), Pathname.new('/var/shared/log')]
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
+ ]
50
58
  end
51
59
  end
52
60
 
53
- describe '#linked_dir_parents' do
61
+ describe "#linked_dir_parents" do
54
62
  subject { paths.linked_dir_parents(parent) }
55
63
 
56
64
  before do
57
65
  paths.expects(:fetch).with(:linked_dirs).returns(linked_dirs)
58
66
  end
59
67
 
60
- it 'returns the full paths names of the parent dirs' do
61
- expect(subject).to eq [Pathname.new('/var/shared'), Pathname.new('/var/shared/public')]
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
+ ]
62
73
  end
63
74
  end
64
75
 
65
- describe '#release path' do
66
-
76
+ describe "#release path" do
67
77
  subject { dsl.release_path }
68
78
 
69
- context 'where no release path has been set' do
79
+ context "where no release path has been set" do
70
80
  before do
71
81
  dsl.delete(:release_path)
72
82
  end
73
83
 
74
- it 'returns the `current_path` value' do
75
- expect(subject.to_s).to eq '/var/www/current'
84
+ it "returns the `current_path` value" do
85
+ expect(subject.to_s).to eq "/var/www/current"
76
86
  end
77
87
  end
78
88
 
79
- context 'where the release path has been set' do
89
+ context "where the release path has been set" do
80
90
  before do
81
- dsl.set(:release_path,'/var/www/release_path')
91
+ dsl.set(:release_path, "/var/www/release_path")
82
92
  end
83
93
 
84
- it 'returns the set `release_path` value' do
85
- expect(subject.to_s).to eq '/var/www/release_path'
94
+ it "returns the set `release_path` value" do
95
+ expect(subject.to_s).to eq "/var/www/release_path"
86
96
  end
87
97
  end
88
98
  end
89
99
 
90
- describe '#set_release_path' do
100
+ describe "#set_release_path" do
91
101
  let(:now) { Time.parse("Oct 21 16:29:00 2015") }
92
102
  subject { dsl.release_path }
93
103
 
94
- context 'without a timestamp' do
104
+ context "without a timestamp" do
95
105
  before do
96
106
  dsl.env.expects(:timestamp).returns(now)
97
107
  dsl.set_release_path
98
108
  end
99
109
 
100
- it 'returns the release path with the current env timestamp' do
101
- expect(subject.to_s).to eq '/var/www/releases/20151021162900'
110
+ it "returns the release path with the current env timestamp" do
111
+ expect(subject.to_s).to eq "/var/www/releases/20151021162900"
102
112
  end
103
113
  end
104
114
 
105
- context 'with a timestamp' do
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
106
130
  before do
107
- dsl.set_release_path('timestamp')
131
+ paths.expects(:fetch).with(:releases_directory, "releases").returns("test123")
132
+ paths.expects(:fetch).with(:deploy_to).returns("/var/www")
108
133
  end
109
134
 
110
- it 'returns the release path with the timestamp' do
111
- expect(subject.to_s).to eq '/var/www/releases/timestamp'
135
+ it "returns the releases path with the custom directory" do
136
+ expect(subject.to_s).to eq "/var/www/test123"
112
137
  end
113
138
  end
114
139
  end
115
140
 
116
- describe '#deploy_config_path' do
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
117
157
  subject { dsl.deploy_config_path.to_s }
118
158
 
119
- context 'when not specified' do
159
+ context "when not specified" do
120
160
  before do
121
161
  dsl.delete(:deploy_config_path)
122
162
  end
123
163
 
124
164
  it 'returns "config/deploy.rb"' do
125
- expect(subject).to eq 'config/deploy.rb'
165
+ expect(subject).to eq "config/deploy.rb"
126
166
  end
127
167
  end
128
168
 
129
- context 'when the variable :deploy_config_path is set' do
169
+ context "when the variable :deploy_config_path is set" do
130
170
  before do
131
- dsl.set(:deploy_config_path, 'my/custom/path.rb')
171
+ dsl.set(:deploy_config_path, "my/custom/path.rb")
132
172
  end
133
173
 
134
- it 'returns the custom path' do
135
- expect(subject).to eq 'my/custom/path.rb'
174
+ it "returns the custom path" do
175
+ expect(subject).to eq "my/custom/path.rb"
136
176
  end
137
177
  end
138
178
  end
139
179
 
140
- describe '#stage_config_path' do
180
+ describe "#stage_config_path" do
141
181
  subject { dsl.stage_config_path.to_s }
142
182
 
143
- context 'when not specified' do
144
-
183
+ context "when not specified" do
145
184
  before do
146
185
  dsl.delete(:stage_config_path)
147
186
  end
148
187
 
149
188
  it 'returns "config/deploy"' do
150
- expect(subject).to eq 'config/deploy'
189
+ expect(subject).to eq "config/deploy"
151
190
  end
152
191
  end
153
192
 
154
- context 'when the variable :stage_config_path is set' do
193
+ context "when the variable :stage_config_path is set" do
155
194
  before do
156
- dsl.set(:stage_config_path, 'my/custom/path')
195
+ dsl.set(:stage_config_path, "my/custom/path")
157
196
  end
158
197
 
159
- it 'returns the custom path' do
160
- expect(subject).to eq 'my/custom/path'
198
+ it "returns the custom path" do
199
+ expect(subject).to eq "my/custom/path"
161
200
  end
162
201
  end
163
202
  end
164
203
 
165
- describe '#repo_path' do
204
+ describe "#repo_path" do
166
205
  subject { dsl.repo_path.to_s }
167
206
 
168
- context 'when not specified' do
169
-
207
+ context "when not specified" do
170
208
  before do
171
209
  dsl.delete(:repo_path)
172
210
  end
173
211
 
174
212
  it 'returns the default #{deploy_to}/repo' do
175
- dsl.set(:deploy_to, '/var/www')
176
- expect(subject).to eq '/var/www/repo'
213
+ dsl.set(:deploy_to, "/var/www")
214
+ expect(subject).to eq "/var/www/repo"
177
215
  end
178
216
  end
179
217
 
180
- context 'when the variable :repo_path is set' do
218
+ context "when the variable :repo_path is set" do
181
219
  before do
182
- dsl.set(:repo_path, 'my/custom/path')
220
+ dsl.set(:repo_path, "my/custom/path")
183
221
  end
184
222
 
185
- it 'returns the custom path' do
186
- expect(subject).to eq 'my/custom/path'
223
+ it "returns the custom path" do
224
+ expect(subject).to eq "my/custom/path"
187
225
  end
188
226
  end
189
227
  end
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  module Capistrano
4
4
  class DummyTaskEnhancements
@@ -8,8 +8,7 @@ module Capistrano
8
8
  describe TaskEnhancements do
9
9
  let(:task_enhancements) { DummyTaskEnhancements.new }
10
10
 
11
- describe 'ordering' do
12
-
11
+ describe "ordering" do
13
12
  after do
14
13
  task.clear
15
14
  before_task.clear
@@ -19,69 +18,90 @@ module Capistrano
19
18
 
20
19
  let(:order) { [] }
21
20
  let!(:task) do
22
- Rake::Task.define_task('task', [:order]) do |t, args|
23
- args['order'].push 'task'
21
+ Rake::Task.define_task("task", [:order]) do |_t, args|
22
+ args["order"].push "task"
24
23
  end
25
24
  end
26
25
 
27
26
  let!(:before_task) do
28
- Rake::Task.define_task('before_task') do
29
- order.push 'before_task'
27
+ Rake::Task.define_task("before_task") do
28
+ order.push "before_task"
30
29
  end
31
30
  end
32
31
 
33
32
  let!(:after_task) do
34
- Rake::Task.define_task('after_task') do
35
- order.push 'after_task'
33
+ Rake::Task.define_task("after_task") do
34
+ order.push "after_task"
36
35
  end
37
36
  end
38
37
 
39
- it 'invokes in proper order if define after than before' do
40
- task_enhancements.after('task', 'after_task')
41
- task_enhancements.before('task', 'before_task')
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")
42
41
 
43
- Rake::Task['task'].invoke order
42
+ Rake::Task["task"].invoke order
44
43
 
45
- expect(order).to eq(['before_task', 'task', 'after_task'])
44
+ expect(order).to eq(%w(before_task task after_task))
46
45
  end
47
46
 
48
- it 'invokes in proper order if define before than after' do
49
- task_enhancements.before('task', 'before_task')
50
- task_enhancements.after('task', 'after_task')
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")
51
50
 
52
- Rake::Task['task'].invoke order
51
+ Rake::Task["task"].invoke order
53
52
 
54
- expect(order).to eq(['before_task', 'task', 'after_task'])
53
+ expect(order).to eq(%w(before_task task after_task))
55
54
  end
56
55
 
57
- it 'invokes in proper order and with arguments and block' do
58
- task_enhancements.after('task', 'after_task_custom', :order) do |t, args|
59
- order.push 'after_task'
60
- end
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")
61
58
 
62
- task_enhancements.before('task', 'before_task_custom', :order) do |t, args|
63
- order.push 'before_task'
59
+ Rake::Task.define_task("not_loaded_task") do
60
+ order.push "not_loaded_task"
64
61
  end
65
62
 
66
- Rake::Task['task'].invoke(order)
63
+ Rake::Task["task"].invoke order
67
64
 
68
- expect(order).to eq(['before_task', 'task', 'after_task'])
65
+ expect(order).to eq(%w(task not_loaded_task))
69
66
  end
70
67
 
71
- end
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
72
 
73
- describe 'remote_file' do
74
- subject(:remote_file) { task_enhancements.remote_file('source' => 'destination') }
73
+ task_enhancements.before("task", "before_task_custom", :order) do |_t, _args|
74
+ order.push "before_task"
75
+ end
75
76
 
76
- it { expect(remote_file.name).to eq('source') }
77
- it { is_expected.to be_a(Capistrano::UploadTask) }
77
+ Rake::Task["task"].invoke(order)
78
78
 
79
- describe 'namespaced' do
80
- let(:app) { Rake.application }
81
- around { |ex| app.in_namespace('namespace', &ex) }
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
82
101
 
83
- it { expect(remote_file.name).to eq('source') }
84
- it { is_expected.to be_a(Capistrano::UploadTask) }
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')
85
105
  end
86
106
  end
87
107
  end
@@ -1,7 +1,6 @@
1
- require 'spec_helper'
1
+ require "spec_helper"
2
2
 
3
3
  module Capistrano
4
-
5
4
  class DummyDSL
6
5
  include DSL
7
6
  end
@@ -10,27 +9,27 @@ module Capistrano
10
9
  describe DSL do
11
10
  let(:dsl) { DummyDSL.new }
12
11
 
13
- describe '#t' do
12
+ describe "#t" do
14
13
  before do
15
- I18n.expects(:t).with(:phrase, {count: 2, scope: :capistrano})
14
+ I18n.expects(:t).with(:phrase, count: 2, scope: :capistrano)
16
15
  end
17
16
 
18
- it 'delegates to I18n' do
17
+ it "delegates to I18n" do
19
18
  dsl.t(:phrase, count: 2)
20
19
  end
21
20
  end
22
21
 
23
- describe '#stage_set?' do
22
+ describe "#stage_set?" do
24
23
  subject { dsl.stage_set? }
25
24
 
26
- context 'stage is set' do
25
+ context "stage is set" do
27
26
  before do
28
27
  dsl.set(:stage, :sandbox)
29
28
  end
30
29
  it { expect(subject).to be_truthy }
31
30
  end
32
31
 
33
- context 'stage is not set' do
32
+ context "stage is not set" do
34
33
  before do
35
34
  dsl.set(:stage, nil)
36
35
  end
@@ -38,15 +37,89 @@ module Capistrano
38
37
  end
39
38
  end
40
39
 
41
- describe '#sudo' do
42
-
40
+ describe "#sudo" do
43
41
  before do
44
42
  dsl.expects(:execute).with(:sudo, :my, :command)
45
43
  end
46
44
 
47
- it 'prepends sudo, delegates to execute' do
45
+ it "prepends sudo, delegates to execute" do
48
46
  dsl.sudo(:my, :command)
49
47
  end
50
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 reenable 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 reenable 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
51
124
  end
52
125
  end