capistrano 3.7.0 → 3.17.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 (81) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +113 -0
  3. data/.github/pull_request_template.md +0 -4
  4. data/.github/release-drafter.yml +17 -0
  5. data/.github/workflows/push.yml +12 -0
  6. data/.rubocop.yml +13 -0
  7. data/CHANGELOG.md +1 -484
  8. data/CONTRIBUTING.md +2 -0
  9. data/DEVELOPMENT.md +5 -6
  10. data/Dangerfile +1 -54
  11. data/Gemfile +39 -3
  12. data/LICENSE.txt +1 -1
  13. data/README.md +10 -4
  14. data/RELEASING.md +3 -3
  15. data/Rakefile +13 -5
  16. data/UPGRADING-3.7.md +1 -12
  17. data/capistrano.gemspec +9 -8
  18. data/features/deploy.feature +34 -1
  19. data/features/installation.feature +8 -3
  20. data/features/step_definitions/assertions.rb +31 -3
  21. data/features/step_definitions/cap_commands.rb +10 -0
  22. data/features/step_definitions/setup.rb +37 -1
  23. data/features/subdirectory.feature +9 -0
  24. data/features/support/remote_command_helpers.rb +4 -0
  25. data/features/support/vagrant_helpers.rb +15 -8
  26. data/lib/Capfile +0 -4
  27. data/lib/capistrano/application.rb +11 -3
  28. data/lib/capistrano/configuration/filter.rb +1 -1
  29. data/lib/capistrano/configuration/host_filter.rb +1 -2
  30. data/lib/capistrano/configuration/question.rb +22 -3
  31. data/lib/capistrano/configuration/role_filter.rb +1 -2
  32. data/lib/capistrano/configuration/scm_resolver.rb +8 -3
  33. data/lib/capistrano/configuration/server.rb +1 -0
  34. data/lib/capistrano/configuration/servers.rb +16 -8
  35. data/lib/capistrano/configuration/variables.rb +2 -2
  36. data/lib/capistrano/configuration.rb +7 -3
  37. data/lib/capistrano/defaults.rb +1 -1
  38. data/lib/capistrano/doctor/servers_doctor.rb +1 -1
  39. data/lib/capistrano/doctor/variables_doctor.rb +12 -3
  40. data/lib/capistrano/dsl/paths.rb +3 -16
  41. data/lib/capistrano/dsl.rb +10 -2
  42. data/lib/capistrano/i18n.rb +7 -2
  43. data/lib/capistrano/immutable_task.rb +3 -2
  44. data/lib/capistrano/scm/git.rb +34 -7
  45. data/lib/capistrano/scm/hg.rb +8 -1
  46. data/lib/capistrano/scm/svn.rb +9 -0
  47. data/lib/capistrano/scm/tasks/git.rake +10 -9
  48. data/lib/capistrano/scm/tasks/hg.rake +1 -1
  49. data/lib/capistrano/tasks/deploy.rake +22 -10
  50. data/lib/capistrano/templates/deploy.rb.erb +10 -4
  51. data/lib/capistrano/templates/stage.rb.erb +1 -1
  52. data/lib/capistrano/version.rb +1 -1
  53. data/spec/integration/dsl_spec.rb +5 -3
  54. data/spec/lib/capistrano/application_spec.rb +16 -40
  55. data/spec/lib/capistrano/configuration/filter_spec.rb +1 -1
  56. data/spec/lib/capistrano/configuration/host_filter_spec.rb +10 -5
  57. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +1 -1
  58. data/spec/lib/capistrano/configuration/question_spec.rb +47 -11
  59. data/spec/lib/capistrano/configuration/role_filter_spec.rb +2 -2
  60. data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +55 -0
  61. data/spec/lib/capistrano/configuration/server_spec.rb +1 -1
  62. data/spec/lib/capistrano/configuration/servers_spec.rb +6 -5
  63. data/spec/lib/capistrano/configuration_spec.rb +2 -2
  64. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +1 -1
  65. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +1 -1
  66. data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +1 -1
  67. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +9 -1
  68. data/spec/lib/capistrano/dsl/paths_spec.rb +30 -0
  69. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +6 -6
  70. data/spec/lib/capistrano/dsl_spec.rb +48 -7
  71. data/spec/lib/capistrano/immutable_task_spec.rb +1 -1
  72. data/spec/lib/capistrano/plugin_spec.rb +2 -2
  73. data/spec/lib/capistrano/scm/git_spec.rb +54 -1
  74. data/spec/lib/capistrano/scm/hg_spec.rb +6 -1
  75. data/spec/lib/capistrano/scm/svn_spec.rb +21 -0
  76. data/spec/lib/capistrano/version_validator_spec.rb +23 -0
  77. data/spec/spec_helper.rb +13 -0
  78. data/spec/support/Vagrantfile +1 -1
  79. data/spec/support/test_app.rb +28 -14
  80. metadata +20 -80
  81. data/.travis.yml +0 -26
@@ -356,14 +356,16 @@ describe Capistrano::DSL do
356
356
  end
357
357
 
358
358
  describe "asking for a variable" do
359
+ let(:stdin) { stub(tty?: true) }
360
+
359
361
  before do
360
- dsl.ask(:scm, :svn)
362
+ dsl.ask(:scm, :svn, stdin: stdin)
361
363
  $stdout.stubs(:print)
362
364
  end
363
365
 
364
366
  context "variable is provided" do
365
367
  before do
366
- $stdin.expects(:gets).returns("git")
368
+ stdin.expects(:gets).returns("git")
367
369
  end
368
370
 
369
371
  it "sets the input as the variable" do
@@ -373,7 +375,7 @@ describe Capistrano::DSL do
373
375
 
374
376
  context "variable is not provided" do
375
377
  before do
376
- $stdin.expects(:gets).returns("")
378
+ stdin.expects(:gets).returns("")
377
379
  end
378
380
 
379
381
  it "sets the variable as the default" do
@@ -5,46 +5,40 @@ describe Capistrano::Application do
5
5
 
6
6
  it "provides a --format option which enables the choice of output formatting"
7
7
 
8
- let(:help_output) do
9
- out, _err = capture_io do
10
- flags "--help", "-h"
11
- end
12
- out
13
- end
14
-
15
- it "displays documentation URL as help banner" do
16
- expect(help_output.lines.first).to match(/capistranorb.com/)
8
+ it "displays documentation URL as help banner", capture_io: true do
9
+ flags "--help", "-h"
10
+ expect($stdout.string.each_line.first).to match(/capistranorb.com/)
17
11
  end
18
12
 
19
13
  %w(quiet silent verbose).each do |switch|
20
- it "doesn't include --#{switch} in help" do
21
- expect(help_output).not_to match(/--#{switch}/)
14
+ it "doesn't include --#{switch} in help", capture_io: true do
15
+ flags "--help", "-h"
16
+ expect($stdout.string).not_to match(/--#{switch}/)
22
17
  end
23
18
  end
24
19
 
25
- it "overrides the rake method, but still prints the rake version" do
26
- out, _err = capture_io do
27
- flags "--version", "-V"
28
- end
20
+ it "overrides the rake method, but still prints the rake version", capture_io: true do
21
+ flags "--version", "-V"
22
+ out = $stdout.string
29
23
  expect(out).to match(/\bCapistrano Version\b/)
30
24
  expect(out).to match(/\b#{Capistrano::VERSION}\b/)
31
25
  expect(out).to match(/\bRake Version\b/)
32
26
  expect(out).to match(/\b#{Rake::VERSION}\b/)
33
27
  end
34
28
 
35
- it "overrides the rake method, and sets the sshkit_backend to SSHKit::Backend::Printer" do
36
- capture_io do
37
- flags "--dry-run", "-n"
38
- end
29
+ it "overrides the rake method, and sets the sshkit_backend to SSHKit::Backend::Printer", capture_io: true do
30
+ flags "--dry-run", "-n"
39
31
  sshkit_backend = Capistrano::Configuration.fetch(:sshkit_backend)
40
32
  expect(sshkit_backend).to eq(SSHKit::Backend::Printer)
41
33
  end
42
34
 
43
- it "enables printing all config variables on command line parameter" do
44
- capture_io do
35
+ it "enables printing all config variables on command line parameter", capture_io: true do
36
+ begin
45
37
  flags "--print-config-variables", "-p"
38
+ expect(Capistrano::Configuration.fetch(:print_config_variables)).to be true
39
+ ensure
40
+ Capistrano::Configuration.reset!
46
41
  end
47
- expect(Capistrano::Configuration.fetch(:print_config_variables)).to be true
48
42
  end
49
43
 
50
44
  def flags(*sets)
@@ -63,22 +57,4 @@ describe Capistrano::Application do
63
57
  subject.run
64
58
  subject.options
65
59
  end
66
-
67
- def capture_io
68
- require "stringio"
69
-
70
- orig_stdout = $stdout
71
- orig_stderr = $stderr
72
- captured_stdout = StringIO.new
73
- captured_stderr = StringIO.new
74
- $stdout = captured_stdout
75
- $stderr = captured_stderr
76
-
77
- yield
78
-
79
- return captured_stdout.string, captured_stderr.string
80
- ensure
81
- $stdout = orig_stdout
82
- $stderr = orig_stderr
83
- end
84
60
  end
@@ -5,7 +5,7 @@ module Capistrano
5
5
  describe Filter do
6
6
  let(:available) do
7
7
  [
8
- Server.new("server1").add_roles([:web, :db]),
8
+ Server.new("server1").add_roles(%i(web db)),
9
9
  Server.new("server2").add_role(:web),
10
10
  Server.new("server3").add_role(:redis),
11
11
  Server.new("server4").add_role(:db),
@@ -10,7 +10,7 @@ module Capistrano
10
10
  Server.new("server2"),
11
11
  Server.new("server3"),
12
12
  Server.new("server4"),
13
- Server.new("server5")]
13
+ Server.new("server10")]
14
14
  end
15
15
 
16
16
  shared_examples "it filters hosts correctly" do |expected|
@@ -32,8 +32,8 @@ module Capistrano
32
32
  end
33
33
 
34
34
  context "with a comma separated string" do
35
- let(:values) { "server1,server3" }
36
- it_behaves_like "it filters hosts correctly", %w{server1 server3}
35
+ let(:values) { "server1,server10" }
36
+ it_behaves_like "it filters hosts correctly", %w{server1 server10}
37
37
  end
38
38
 
39
39
  context "with an array of strings" do
@@ -41,6 +41,11 @@ module Capistrano
41
41
  it_behaves_like "it filters hosts correctly", %w{server1 server3}
42
42
  end
43
43
 
44
+ context "with mixed splittable and unsplittable strings" do
45
+ let(:values) { %w{server1 server2,server3} }
46
+ it_behaves_like "it filters hosts correctly", %w{server1 server2 server3}
47
+ end
48
+
44
49
  context "with a regexp" do
45
50
  let(:values) { "server[13]$" }
46
51
  it_behaves_like "it filters hosts correctly", %w{server1 server3}
@@ -48,12 +53,12 @@ module Capistrano
48
53
 
49
54
  context "with a regexp with line boundaries" do
50
55
  let(:values) { "^server" }
51
- it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server5}
56
+ it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server10}
52
57
  end
53
58
 
54
59
  context "with a regexp with a comma" do
55
60
  let(:values) { 'server\d{1,3}$' }
56
- it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server5}
61
+ it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server10}
57
62
  end
58
63
 
59
64
  context "without number" do
@@ -49,7 +49,7 @@ module Capistrano
49
49
  expect(task.prerequisites).to eq([:example_prerequisite])
50
50
  end
51
51
 
52
- it "sets defaults when load:defaults is invoked" do
52
+ it "sets defaults when load:defaults is invoked", capture_io: true do
53
53
  expect(fetch(:example_variable)).to be_nil
54
54
  invoke "load:defaults"
55
55
  expect(fetch(:example_variable)).to eq("foo")
@@ -3,11 +3,14 @@ require "spec_helper"
3
3
  module Capistrano
4
4
  class Configuration
5
5
  describe Question do
6
- let(:question) { Question.new(key, default, options) }
7
- let(:question_without_echo) { Question.new(key, default, echo: false) }
6
+ let(:question) { Question.new(key, default, stdin: stdin) }
7
+ let(:question_without_echo) { Question.new(key, default, echo: false, stdin: stdin) }
8
+ let(:question_without_default) { Question.new(key, nil, stdin: stdin) }
9
+ let(:question_prompt) { Question.new(key, default, stdin: stdin, prompt: "Your favorite branch") }
10
+ let(:question_prompt_without_default) { Question.new(key, nil, stdin: stdin, prompt: "Your favorite branch") }
8
11
  let(:default) { :default }
9
12
  let(:key) { :branch }
10
- let(:options) { nil }
13
+ let(:stdin) { stub(tty?: true) }
11
14
 
12
15
  describe ".new" do
13
16
  it "takes a key, default, options" do
@@ -19,23 +22,45 @@ module Capistrano
19
22
  context "value is entered" do
20
23
  let(:branch) { "branch" }
21
24
 
22
- before do
23
- $stdout.expects(:print).with("Please enter branch (default): ")
24
- end
25
-
26
25
  it "returns the echoed value" do
27
- $stdin.expects(:gets).returns(branch)
28
- $stdin.expects(:noecho).never
26
+ $stdout.expects(:print).with("Please enter branch (default): ")
27
+ stdin.expects(:gets).returns(branch)
28
+ stdin.expects(:noecho).never
29
29
 
30
30
  expect(question.call).to eq(branch)
31
31
  end
32
32
 
33
33
  it "returns the value but does not echo it" do
34
- $stdin.expects(:noecho).returns(branch)
34
+ $stdout.expects(:print).with("Please enter branch (default): ")
35
+ stdin.expects(:noecho).returns(branch)
35
36
  $stdout.expects(:print).with("\n")
36
37
 
37
38
  expect(question_without_echo.call).to eq(branch)
38
39
  end
40
+
41
+ it "returns the value but has no default between parenthesis" do
42
+ $stdout.expects(:print).with("Please enter branch: ")
43
+ stdin.expects(:gets).returns(branch)
44
+ stdin.expects(:noecho).never
45
+
46
+ expect(question_without_default.call).to eq(branch)
47
+ end
48
+
49
+ it "uses prompt and returns the value" do
50
+ $stdout.expects(:print).with("Your favorite branch (default): ")
51
+ stdin.expects(:gets).returns(branch)
52
+ stdin.expects(:noecho).never
53
+
54
+ expect(question_prompt.call).to eq(branch)
55
+ end
56
+
57
+ it "uses prompt and returns the value but has no default between parenthesis" do
58
+ $stdout.expects(:print).with("Your favorite branch: ")
59
+ stdin.expects(:gets).returns(branch)
60
+ stdin.expects(:noecho).never
61
+
62
+ expect(question_prompt_without_default.call).to eq(branch)
63
+ end
39
64
  end
40
65
 
41
66
  context "value is not entered" do
@@ -43,13 +68,24 @@ module Capistrano
43
68
 
44
69
  before do
45
70
  $stdout.expects(:print).with("Please enter branch (default): ")
46
- $stdin.expects(:gets).returns("")
71
+ stdin.expects(:gets).returns("")
47
72
  end
48
73
 
49
74
  it "returns the default as the value" do
50
75
  expect(question.call).to eq(branch)
51
76
  end
52
77
  end
78
+
79
+ context "tty unavailable", capture_io: true do
80
+ before do
81
+ stdin.expects(:gets).never
82
+ stdin.expects(:tty?).returns(false)
83
+ end
84
+
85
+ it "returns the default as the value" do
86
+ expect(question.call).to eq(default)
87
+ end
88
+ end
53
89
  end
54
90
  end
55
91
  end
@@ -7,7 +7,7 @@ module Capistrano
7
7
 
8
8
  let(:available) do
9
9
  [
10
- Server.new("server1").add_roles([:web, :db]),
10
+ Server.new("server1").add_roles(%i(web db)),
11
11
  Server.new("server2").add_role(:web),
12
12
  Server.new("server3").add_role(:redis),
13
13
  Server.new("server4").add_role(:db),
@@ -41,7 +41,7 @@ module Capistrano
41
41
  end
42
42
 
43
43
  context "with multiple roles" do
44
- let(:values) { [:web, :db] }
44
+ let(:values) { %i(web db) }
45
45
  it_behaves_like "it filters roles correctly", 3, %w{server1 server2 server4}
46
46
  end
47
47
 
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+ require "capistrano/scm"
3
+
4
+ module Capistrano
5
+ class Configuration
6
+ describe SCMResolver do
7
+ include Capistrano::DSL
8
+
9
+ let(:resolver) { SCMResolver.new }
10
+
11
+ before do
12
+ Rake::Task.define_task("deploy:check")
13
+ Rake::Task.define_task("deploy:new_release_path")
14
+ Rake::Task.define_task("deploy:set_current_revision")
15
+ set :scm, SCMResolver::DEFAULT_GIT
16
+ end
17
+
18
+ after do
19
+ Rake::Task.clear
20
+ Capistrano::Configuration.reset!
21
+ end
22
+
23
+ context "default scm, no plugin installed" do
24
+ it "emits a warning" do
25
+ expect { resolver.resolve }.to output(/will not load the git scm/i).to_stderr
26
+ end
27
+
28
+ it "activates the git scm", capture_io: true do
29
+ resolver.resolve
30
+ expect(Rake::Task["git:wrapper"]).not_to be_nil
31
+ end
32
+
33
+ it "sets :scm to :git", capture_io: true do
34
+ resolver.resolve
35
+ expect(fetch(:scm)).to eq(:git)
36
+ end
37
+ end
38
+
39
+ context "default scm, git plugin installed" do
40
+ before do
41
+ install_plugin Capistrano::SCM::Git
42
+ end
43
+
44
+ it "emits no warning" do
45
+ expect { resolver.resolve }.not_to output.to_stderr
46
+ end
47
+
48
+ it "deletes :scm" do
49
+ resolver.resolve
50
+ expect(fetch(:scm)).to be_nil
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -13,7 +13,7 @@ module Capistrano
13
13
  end
14
14
 
15
15
  describe "adding roles" do
16
- subject { server.add_roles([:things, :stuff]) }
16
+ subject { server.add_roles(%i(things stuff)) }
17
17
  it "adds the roles" do
18
18
  expect { subject }.to change { server.roles.size }.from(0).to(2)
19
19
  end
@@ -56,7 +56,7 @@ module Capistrano
56
56
 
57
57
  describe "collecting server roles" do
58
58
  let(:app) { Set.new([:app]) }
59
- let(:web_app) { Set.new([:web, :app]) }
59
+ let(:web_app) { Set.new(%i(web app)) }
60
60
  let(:web) { Set.new([:web]) }
61
61
 
62
62
  before do
@@ -108,7 +108,7 @@ module Capistrano
108
108
  end
109
109
 
110
110
  it "returns the correct app and web servers" do
111
- expect(servers.roles_for([:app, :web]).map(&:hostname)).to eq %w{1 2 3}
111
+ expect(servers.roles_for(%i(app web)).map(&:hostname)).to eq %w{1 2 3}
112
112
  end
113
113
 
114
114
  it "returns all servers" do
@@ -130,13 +130,14 @@ module Capistrano
130
130
 
131
131
  it "can accept multiple servers with the same hostname but different ports or users" do
132
132
  servers.add_host("1", roles: [:app, "web"], test: :value, port: 12)
133
+ expect(servers.count).to eq(2)
133
134
  servers.add_host("1", roles: [:app, "web"], test: :value, port: 34)
134
135
  servers.add_host("1", roles: [:app, "web"], test: :value, user: "root")
135
136
  servers.add_host("1", roles: [:app, "web"], test: :value, user: "deployer")
136
137
  servers.add_host("1", roles: [:app, "web"], test: :value, user: "root", port: 34)
137
138
  servers.add_host("1", roles: [:app, "web"], test: :value, user: "deployer", port: 34)
138
139
  servers.add_host("1", roles: [:app, "web"], test: :value, user: "deployer", port: 56)
139
- expect(servers.count).to eq(5)
140
+ expect(servers.count).to eq(4)
140
141
  end
141
142
 
142
143
  describe "with a :user property" do
@@ -283,7 +284,7 @@ module Capistrano
283
284
  end
284
285
 
285
286
  context "when selecting specific roles" do
286
- let(:roles) { [:app, :web] }
287
+ let(:roles) { %i(app web) }
287
288
  it "ignores it" do
288
289
  expect(subject).to eq %w{1 2 3 4}
289
290
  end
@@ -311,7 +312,7 @@ module Capistrano
311
312
  end
312
313
 
313
314
  context "when selecting specific roles" do
314
- let(:roles) { [:app, :web] }
315
+ let(:roles) { %i(app web) }
315
316
  it "ignores it" do
316
317
  expect(subject).to eq %w{1 2 3 4}
317
318
  end
@@ -238,7 +238,7 @@ module Capistrano
238
238
  end
239
239
 
240
240
  it "returns all set keys" do
241
- expect(subject).to match_array [:key1, :key2]
241
+ expect(subject).to match_array %i(key1 key2)
242
242
  end
243
243
  end
244
244
 
@@ -255,7 +255,7 @@ module Capistrano
255
255
 
256
256
  describe "asking" do
257
257
  let(:question) { stub }
258
- let(:options) { Hash.new }
258
+ let(:options) { {} }
259
259
 
260
260
  before do
261
261
  Configuration::Question.expects(:new).with(:branch, :default, options)
@@ -29,7 +29,7 @@ module Capistrano
29
29
  Rake::Task.clear
30
30
  end
31
31
 
32
- it "has an doctor:environment task that calls EnvironmentDoctor" do
32
+ it "has an doctor:environment task that calls EnvironmentDoctor", capture_io: true do
33
33
  EnvironmentDoctor.any_instance.expects(:call)
34
34
  Rake::Task["doctor:environment"].invoke
35
35
  end
@@ -53,7 +53,7 @@ module Capistrano
53
53
  Rake::Task.clear
54
54
  end
55
55
 
56
- it "has an doctor:gems task that calls GemsDoctor" do
56
+ it "has an doctor:gems task that calls GemsDoctor", capture_io: true do
57
57
  GemsDoctor.any_instance.expects(:call)
58
58
  Rake::Task["doctor:gems"].invoke
59
59
  end
@@ -71,7 +71,7 @@ module Capistrano
71
71
  Rake::Task.clear
72
72
  end
73
73
 
74
- it "has an doctor:servers task that calls ServersDoctor" do
74
+ it "has an doctor:servers task that calls ServersDoctor", capture_io: true do
75
75
  ServersDoctor.any_instance.expects(:call)
76
76
  Rake::Task["doctor:servers"].invoke
77
77
  end
@@ -14,6 +14,7 @@ module Capistrano
14
14
 
15
15
  env.variables.untrusted! do
16
16
  set :application, "my_app"
17
+ set :repo_tree, "public"
17
18
  set :repo_url, ".git"
18
19
  set :copy_strategy, :scp
19
20
  set :custom_setting, "hello"
@@ -35,6 +36,7 @@ module Capistrano
35
36
  expect { doc.call }.to output(/:pty\s+false$/).to_stdout
36
37
  expect { doc.call }.to output(/:application\s+"my_app"$/).to_stdout
37
38
  expect { doc.call }.to output(/:repo_url\s+".git"$/).to_stdout
39
+ expect { doc.call }.to output(/:repo_tree\s+"public"$/).to_stdout
38
40
  expect { doc.call }.to output(/:copy_strategy\s+:scp$/).to_stdout
39
41
  expect { doc.call }.to output(/:custom_setting\s+"hello"$/).to_stdout
40
42
  expect { doc.call }.to output(/"string_setting"\s+"hello"$/).to_stdout
@@ -56,6 +58,12 @@ module Capistrano
56
58
  .to_stdout
57
59
  end
58
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
+
59
67
  describe "Rake" do
60
68
  before do
61
69
  load File.expand_path("../../../../../lib/capistrano/doctor.rb",
@@ -66,7 +74,7 @@ module Capistrano
66
74
  Rake::Task.clear
67
75
  end
68
76
 
69
- it "has an doctor:variables task that calls VariablesDoctor" do
77
+ it "has an doctor:variables task that calls VariablesDoctor", capture_io: true do
70
78
  VariablesDoctor.any_instance.expects(:call)
71
79
  Rake::Task["doctor:variables"].invoke
72
80
  end
@@ -123,6 +123,36 @@ describe Capistrano::DSL::Paths do
123
123
  end
124
124
  end
125
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
+
126
156
  describe "#deploy_config_path" do
127
157
  subject { dsl.deploy_config_path.to_s }
128
158
 
@@ -35,7 +35,7 @@ module Capistrano
35
35
  end
36
36
  end
37
37
 
38
- it "invokes in proper order if define after than before" do
38
+ it "invokes in proper order if define after than before", capture_io: true do
39
39
  task_enhancements.after("task", "after_task")
40
40
  task_enhancements.before("task", "before_task")
41
41
 
@@ -44,7 +44,7 @@ module Capistrano
44
44
  expect(order).to eq(%w(before_task task after_task))
45
45
  end
46
46
 
47
- it "invokes in proper order if define before than after" do
47
+ it "invokes in proper order if define before than after", capture_io: true do
48
48
  task_enhancements.before("task", "before_task")
49
49
  task_enhancements.after("task", "after_task")
50
50
 
@@ -53,7 +53,7 @@ module Capistrano
53
53
  expect(order).to eq(%w(before_task task after_task))
54
54
  end
55
55
 
56
- it "invokes in proper order when referring to as-yet undefined tasks" do
56
+ it "invokes in proper order when referring to as-yet undefined tasks", capture_io: true do
57
57
  task_enhancements.after("task", "not_loaded_task")
58
58
 
59
59
  Rake::Task.define_task("not_loaded_task") do
@@ -65,7 +65,7 @@ module Capistrano
65
65
  expect(order).to eq(%w(task not_loaded_task))
66
66
  end
67
67
 
68
- it "invokes in proper order and with arguments and block" do
68
+ it "invokes in proper order and with arguments and block", capture_io: true do
69
69
  task_enhancements.after("task", "after_task_custom", :order) do |_t, _args|
70
70
  order.push "after_task"
71
71
  end
@@ -79,7 +79,7 @@ module Capistrano
79
79
  expect(order).to eq(%w(before_task task after_task))
80
80
  end
81
81
 
82
- it "invokes using the correct namespace when defined within a namespace" do
82
+ it "invokes using the correct namespace when defined within a namespace", capture_io: true do
83
83
  Rake.application.in_namespace("namespace") do
84
84
  Rake::Task.define_task("task") do |t|
85
85
  order.push(t.name)
@@ -99,7 +99,7 @@ module Capistrano
99
99
  )
100
100
  end
101
101
 
102
- it "raises a sensible error if the task isn't found" do
102
+ it "raises a sensible error if the task isn't found", capture_io: true do
103
103
  task_enhancements.after("task", "non_existent_task")
104
104
  expect { Rake::Task["task"].invoke order }.to raise_error(ArgumentError, 'Task "non_existent_task" not found')
105
105
  end
@@ -60,7 +60,7 @@ module Capistrano
60
60
  end
61
61
  end
62
62
 
63
- it "prints helpful message to stderr" do
63
+ it "prints helpful message to stderr", capture_io: true do
64
64
  expect do
65
65
  expect do
66
66
  task.invoke
@@ -71,13 +71,54 @@ module Capistrano
71
71
  end
72
72
 
73
73
  describe "#invoke" do
74
- it "will print a message on stderr, when reinvoking task" do
75
- Rake::Task.define_task("some_task")
74
+ context "reinvoking" do
75
+ it "will not reenable invoking task", capture_io: true do
76
+ counter = 0
76
77
 
77
- dsl.invoke("some_task")
78
- expect do
79
- dsl.invoke("some_task")
80
- end.to output(/.*Capistrano tasks may only be invoked once.*/).to_stderr
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
81
122
  end
82
123
  end
83
124
  end
@@ -16,7 +16,7 @@ module Capistrano
16
16
  load_defaults.extend(Capistrano::ImmutableTask)
17
17
 
18
18
  $stderr.expects(:puts).with do |message|
19
- message =~ /^WARNING: load:defaults has already been invoked/
19
+ message =~ /^ERROR: load:defaults has already been invoked/
20
20
  end
21
21
 
22
22
  expect do