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.
- checksums.yaml +5 -5
- data/.circleci/config.yml +129 -0
- data/.github/issue_template.md +19 -0
- data/.github/pull_request_template.md +22 -0
- data/.github/release-drafter.yml +17 -0
- data/.github/workflows/push.yml +12 -0
- data/.gitignore +8 -5
- data/.rubocop.yml +62 -0
- data/CHANGELOG.md +1 -307
- data/CONTRIBUTING.md +63 -93
- data/DEVELOPMENT.md +127 -0
- data/Dangerfile +1 -0
- data/Gemfile +40 -3
- data/LICENSE.txt +1 -1
- data/README.md +127 -44
- data/RELEASING.md +17 -0
- data/Rakefile +13 -2
- data/UPGRADING-3.7.md +86 -0
- data/bin/cap +1 -1
- data/capistrano.gemspec +21 -24
- data/features/deploy.feature +35 -1
- data/features/doctor.feature +11 -0
- data/features/installation.feature +8 -3
- data/features/stage_failure.feature +9 -0
- data/features/step_definitions/assertions.rb +51 -18
- data/features/step_definitions/cap_commands.rb +9 -0
- data/features/step_definitions/setup.rb +53 -9
- data/features/subdirectory.feature +9 -0
- data/features/support/env.rb +5 -5
- data/features/support/remote_command_helpers.rb +12 -6
- data/features/support/vagrant_helpers.rb +17 -11
- data/lib/Capfile +1 -1
- data/lib/capistrano/all.rb +10 -10
- data/lib/capistrano/application.rb +47 -34
- data/lib/capistrano/configuration/empty_filter.rb +9 -0
- data/lib/capistrano/configuration/filter.rb +17 -47
- data/lib/capistrano/configuration/host_filter.rb +29 -0
- data/lib/capistrano/configuration/null_filter.rb +9 -0
- data/lib/capistrano/configuration/plugin_installer.rb +51 -0
- data/lib/capistrano/configuration/question.rb +31 -9
- data/lib/capistrano/configuration/role_filter.rb +29 -0
- data/lib/capistrano/configuration/scm_resolver.rb +149 -0
- data/lib/capistrano/configuration/server.rb +29 -23
- data/lib/capistrano/configuration/servers.rb +21 -14
- data/lib/capistrano/configuration/validated_variables.rb +110 -0
- data/lib/capistrano/configuration/variables.rb +112 -0
- data/lib/capistrano/configuration.rb +91 -44
- data/lib/capistrano/defaults.rb +26 -4
- data/lib/capistrano/deploy.rb +1 -1
- data/lib/capistrano/doctor/environment_doctor.rb +19 -0
- data/lib/capistrano/doctor/gems_doctor.rb +45 -0
- data/lib/capistrano/doctor/output_helpers.rb +79 -0
- data/lib/capistrano/doctor/servers_doctor.rb +105 -0
- data/lib/capistrano/doctor/variables_doctor.rb +74 -0
- data/lib/capistrano/doctor.rb +6 -0
- data/lib/capistrano/dotfile.rb +1 -2
- data/lib/capistrano/dsl/env.rb +9 -47
- data/lib/capistrano/dsl/paths.rb +11 -25
- data/lib/capistrano/dsl/stages.rb +14 -2
- data/lib/capistrano/dsl/task_enhancements.rb +7 -12
- data/lib/capistrano/dsl.rb +47 -16
- data/lib/capistrano/framework.rb +1 -1
- data/lib/capistrano/i18n.rb +32 -24
- data/lib/capistrano/immutable_task.rb +30 -0
- data/lib/capistrano/install.rb +1 -1
- data/lib/capistrano/plugin.rb +95 -0
- data/lib/capistrano/proc_helpers.rb +13 -0
- data/lib/capistrano/scm/git.rb +100 -0
- data/lib/capistrano/scm/hg.rb +55 -0
- data/lib/capistrano/scm/plugin.rb +13 -0
- data/lib/capistrano/scm/svn.rb +56 -0
- data/lib/capistrano/scm/tasks/git.rake +73 -0
- data/lib/capistrano/scm/tasks/hg.rake +53 -0
- data/lib/capistrano/scm/tasks/svn.rake +53 -0
- data/lib/capistrano/scm.rb +7 -20
- data/lib/capistrano/setup.rb +20 -6
- data/lib/capistrano/tasks/console.rake +4 -8
- data/lib/capistrano/tasks/deploy.rake +105 -73
- data/lib/capistrano/tasks/doctor.rake +24 -0
- data/lib/capistrano/tasks/framework.rake +13 -14
- data/lib/capistrano/tasks/install.rake +14 -15
- data/lib/capistrano/templates/Capfile +21 -10
- data/lib/capistrano/templates/deploy.rb.erb +17 -26
- data/lib/capistrano/templates/stage.rb.erb +9 -9
- data/lib/capistrano/upload_task.rb +1 -1
- data/lib/capistrano/version.rb +1 -1
- data/lib/capistrano/version_validator.rb +5 -10
- data/spec/integration/dsl_spec.rb +289 -240
- data/spec/integration_spec_helper.rb +3 -5
- data/spec/lib/capistrano/application_spec.rb +23 -39
- data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/filter_spec.rb +83 -85
- data/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
- data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +58 -26
- data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +55 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +106 -113
- data/spec/lib/capistrano/configuration/servers_spec.rb +129 -145
- data/spec/lib/capistrano/configuration_spec.rb +224 -63
- data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
- data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
- data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
- data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +97 -59
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +57 -37
- data/spec/lib/capistrano/dsl_spec.rb +84 -11
- data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
- data/spec/lib/capistrano/plugin_spec.rb +84 -0
- data/spec/lib/capistrano/scm/git_spec.rb +184 -0
- data/spec/lib/capistrano/scm/hg_spec.rb +109 -0
- data/spec/lib/capistrano/scm/svn_spec.rb +137 -0
- data/spec/lib/capistrano/scm_spec.rb +7 -8
- data/spec/lib/capistrano/upload_task_spec.rb +7 -7
- data/spec/lib/capistrano/version_validator_spec.rb +61 -46
- data/spec/lib/capistrano_spec.rb +2 -3
- data/spec/spec_helper.rb +21 -8
- data/spec/support/Vagrantfile +9 -10
- data/spec/support/tasks/database.rake +3 -3
- data/spec/support/tasks/fail.rake +4 -3
- data/spec/support/tasks/failed.rake +2 -2
- data/spec/support/tasks/plugin.rake +6 -0
- data/spec/support/tasks/root.rake +4 -4
- data/spec/support/test_app.rb +64 -39
- metadata +100 -55
- data/.travis.yml +0 -13
- data/features/remote_file_task.feature +0 -14
- data/lib/capistrano/git.rb +0 -46
- data/lib/capistrano/hg.rb +0 -43
- data/lib/capistrano/svn.rb +0 -38
- data/lib/capistrano/tasks/git.rake +0 -81
- data/lib/capistrano/tasks/hg.rake +0 -52
- data/lib/capistrano/tasks/svn.rake +0 -52
- data/spec/lib/capistrano/git_spec.rb +0 -81
- data/spec/lib/capistrano/hg_spec.rb +0 -81
- data/spec/lib/capistrano/svn_spec.rb +0 -79
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
describe Capistrano::Application do
|
|
4
|
-
|
|
5
4
|
it "provides a --trace option which enables SSHKit/NetSSH trace output"
|
|
6
5
|
|
|
7
6
|
it "provides a --format option which enables the choice of output formatting"
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
end
|
|
13
|
-
out
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "displays documentation URL as help banner" do
|
|
17
|
-
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/)
|
|
18
11
|
end
|
|
19
12
|
|
|
20
13
|
%w(quiet silent verbose).each do |switch|
|
|
21
|
-
it "doesn't include --#{switch} in help" do
|
|
22
|
-
|
|
14
|
+
it "doesn't include --#{switch} in help", capture_io: true do
|
|
15
|
+
flags "--help", "-h"
|
|
16
|
+
expect($stdout.string).not_to match(/--#{switch}/)
|
|
23
17
|
end
|
|
24
18
|
end
|
|
25
19
|
|
|
26
|
-
it "overrides the rake method, but still prints the rake version" do
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
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
|
|
30
23
|
expect(out).to match(/\bCapistrano Version\b/)
|
|
31
24
|
expect(out).to match(/\b#{Capistrano::VERSION}\b/)
|
|
32
25
|
expect(out).to match(/\bRake Version\b/)
|
|
33
|
-
expect(out).to match(/\b#{
|
|
26
|
+
expect(out).to match(/\b#{Rake::VERSION}\b/)
|
|
34
27
|
end
|
|
35
28
|
|
|
36
|
-
it "overrides the rake method, and sets the sshkit_backend to SSHKit::Backend::Printer" do
|
|
37
|
-
|
|
38
|
-
flags '--dry-run', '-n'
|
|
39
|
-
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"
|
|
40
31
|
sshkit_backend = Capistrano::Configuration.fetch(:sshkit_backend)
|
|
41
32
|
expect(sshkit_backend).to eq(SSHKit::Backend::Printer)
|
|
42
33
|
end
|
|
43
34
|
|
|
35
|
+
it "enables printing all config variables on command line parameter", capture_io: true do
|
|
36
|
+
begin
|
|
37
|
+
flags "--print-config-variables", "-p"
|
|
38
|
+
expect(Capistrano::Configuration.fetch(:print_config_variables)).to be true
|
|
39
|
+
ensure
|
|
40
|
+
Capistrano::Configuration.reset!
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
44
|
def flags(*sets)
|
|
45
45
|
sets.each do |set|
|
|
46
46
|
ARGV.clear
|
|
@@ -51,26 +51,10 @@ describe Capistrano::Application do
|
|
|
51
51
|
|
|
52
52
|
def command_line(*options)
|
|
53
53
|
options.each { |opt| ARGV << opt }
|
|
54
|
-
|
|
54
|
+
subject.define_singleton_method(:exit) do |*_args|
|
|
55
55
|
throw(:system_exit, :exit)
|
|
56
56
|
end
|
|
57
57
|
subject.run
|
|
58
58
|
subject.options
|
|
59
59
|
end
|
|
60
|
-
|
|
61
|
-
def capture_io
|
|
62
|
-
require 'stringio'
|
|
63
|
-
|
|
64
|
-
orig_stdout, orig_stderr = $stdout, $stderr
|
|
65
|
-
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
|
66
|
-
$stdout, $stderr = captured_stdout, captured_stderr
|
|
67
|
-
|
|
68
|
-
yield
|
|
69
|
-
|
|
70
|
-
return captured_stdout.string, captured_stderr.string
|
|
71
|
-
ensure
|
|
72
|
-
$stdout = orig_stdout
|
|
73
|
-
$stderr = orig_stderr
|
|
74
|
-
end
|
|
75
|
-
|
|
76
60
|
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
class Configuration
|
|
5
|
+
describe EmptyFilter do
|
|
6
|
+
subject(:empty_filter) { EmptyFilter.new }
|
|
7
|
+
|
|
8
|
+
describe "#filter" do
|
|
9
|
+
let(:servers) { mock("servers") }
|
|
10
|
+
|
|
11
|
+
it "returns an empty array" do
|
|
12
|
+
expect(empty_filter.filter(servers)).to eq([])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -1,109 +1,107 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
module Capistrano
|
|
4
4
|
class Configuration
|
|
5
|
-
|
|
6
5
|
describe Filter do
|
|
7
|
-
let(:available)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
let(:available) do
|
|
7
|
+
[
|
|
8
|
+
Server.new("server1").add_roles(%i(web db)),
|
|
9
|
+
Server.new("server2").add_role(:web),
|
|
10
|
+
Server.new("server3").add_role(:redis),
|
|
11
|
+
Server.new("server4").add_role(:db),
|
|
12
|
+
Server.new("server5").add_role(:stageweb)
|
|
13
|
+
]
|
|
14
|
+
end
|
|
12
15
|
|
|
13
|
-
describe
|
|
16
|
+
describe "#new" do
|
|
14
17
|
it "won't create an invalid type of filter" do
|
|
15
|
-
expect
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
expect do
|
|
19
|
+
Filter.new(:zarg)
|
|
20
|
+
end.to raise_error RuntimeError
|
|
18
21
|
end
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
context "with type :host" do
|
|
24
|
+
context "and no values" do
|
|
25
|
+
it "creates an EmptyFilter strategy" do
|
|
26
|
+
expect(Filter.new(:host).instance_variable_get(:@strategy)).to be_a(EmptyFilter)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
context "and :all" do
|
|
31
|
+
it "creates an NullFilter strategy" do
|
|
32
|
+
expect(Filter.new(:host, :all).instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
27
35
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
context "and [:all]" do
|
|
37
|
+
it "creates an NullFilter strategy" do
|
|
38
|
+
expect(Filter.new(:host, [:all]).instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
31
41
|
|
|
32
|
-
|
|
33
|
-
|
|
42
|
+
context "and [:all]" do
|
|
43
|
+
it "creates an NullFilter strategy" do
|
|
44
|
+
expect(Filter.new(:host, "all").instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
34
47
|
end
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
context "with type :role" do
|
|
50
|
+
context "and no values" do
|
|
51
|
+
it "creates an EmptyFilter strategy" do
|
|
52
|
+
expect(Filter.new(:role).instance_variable_get(:@strategy)).to be_a(EmptyFilter)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
37
55
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
it 'returns all hosts matching regexp' do
|
|
56
|
-
set = Filter.new(:host, 'server[13]$').filter(available)
|
|
57
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server3})
|
|
58
|
-
end
|
|
59
|
-
it 'correctly identifies a regex with a comma in' do
|
|
60
|
-
set = Filter.new(:host, 'server\d{1,3}$').filter(available)
|
|
61
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server2 server3 server4 server5})
|
|
56
|
+
context "and :all" do
|
|
57
|
+
it "creates an NullFilter strategy" do
|
|
58
|
+
expect(Filter.new(:role, :all).instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "and [:all]" do
|
|
63
|
+
it "creates an NullFilter strategy" do
|
|
64
|
+
expect(Filter.new(:role, [:all]).instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "and [:all]" do
|
|
69
|
+
it "creates an NullFilter strategy" do
|
|
70
|
+
expect(Filter.new(:role, "all").instance_variable_get(:@strategy)).to be_a(NullFilter)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
62
73
|
end
|
|
63
74
|
end
|
|
64
75
|
|
|
65
|
-
describe
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server2})
|
|
75
|
-
end
|
|
76
|
-
it 'returns hosts in a single role' do
|
|
77
|
-
set = Filter.new(:role, [:web]).filter(available)
|
|
78
|
-
expect(set.size).to eq(2)
|
|
79
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server2})
|
|
80
|
-
end
|
|
81
|
-
it 'returns hosts in multiple roles specified by a string' do
|
|
82
|
-
set = Filter.new(:role, 'web,db').filter(available)
|
|
83
|
-
expect(set.size).to eq(3)
|
|
84
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server2 server4})
|
|
85
|
-
end
|
|
86
|
-
it 'returns hosts in multiple roles' do
|
|
87
|
-
set = Filter.new(:role, [:web, :db]).filter(available)
|
|
88
|
-
expect(set.size).to eq(3)
|
|
89
|
-
expect(set.map(&:hostname)).to eq(%w{server1 server2 server4})
|
|
76
|
+
describe "#filter" do
|
|
77
|
+
let(:strategy) { filter.instance_variable_get(:@strategy) }
|
|
78
|
+
let(:results) { mock("result") }
|
|
79
|
+
|
|
80
|
+
shared_examples "it calls #filter on its strategy" do
|
|
81
|
+
it "calls #filter on its strategy" do
|
|
82
|
+
strategy.expects(:filter).with(available).returns(results)
|
|
83
|
+
expect(filter.filter(available)).to eq(results)
|
|
84
|
+
end
|
|
90
85
|
end
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
|
|
87
|
+
context "for an empty filter" do
|
|
88
|
+
let(:filter) { Filter.new(:role) }
|
|
89
|
+
it_behaves_like "it calls #filter on its strategy"
|
|
95
90
|
end
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
91
|
+
|
|
92
|
+
context "for a null filter" do
|
|
93
|
+
let(:filter) { Filter.new(:role, :all) }
|
|
94
|
+
it_behaves_like "it calls #filter on its strategy"
|
|
99
95
|
end
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
96
|
+
|
|
97
|
+
context "for a role filter" do
|
|
98
|
+
let(:filter) { Filter.new(:role, "web") }
|
|
99
|
+
it_behaves_like "it calls #filter on its strategy"
|
|
103
100
|
end
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
101
|
+
|
|
102
|
+
context "for a host filter" do
|
|
103
|
+
let(:filter) { Filter.new(:host, "server1") }
|
|
104
|
+
it_behaves_like "it calls #filter on its strategy"
|
|
107
105
|
end
|
|
108
106
|
end
|
|
109
107
|
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
class Configuration
|
|
5
|
+
describe HostFilter do
|
|
6
|
+
subject(:host_filter) { HostFilter.new(values) }
|
|
7
|
+
|
|
8
|
+
let(:available) do
|
|
9
|
+
[Server.new("server1"),
|
|
10
|
+
Server.new("server2"),
|
|
11
|
+
Server.new("server3"),
|
|
12
|
+
Server.new("server4"),
|
|
13
|
+
Server.new("server10")]
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
shared_examples "it filters hosts correctly" do |expected|
|
|
17
|
+
it "filters correctly" do
|
|
18
|
+
set = host_filter.filter(available)
|
|
19
|
+
expect(set.map(&:hostname)).to eq(expected)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "#filter" do
|
|
24
|
+
context "with a string" do
|
|
25
|
+
let(:values) { "server1" }
|
|
26
|
+
it_behaves_like "it filters hosts correctly", %w{server1}
|
|
27
|
+
|
|
28
|
+
context "and a single server" do
|
|
29
|
+
let(:available) { Server.new("server1") }
|
|
30
|
+
it_behaves_like "it filters hosts correctly", %w{server1}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context "with a comma separated string" do
|
|
35
|
+
let(:values) { "server1,server10" }
|
|
36
|
+
it_behaves_like "it filters hosts correctly", %w{server1 server10}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "with an array of strings" do
|
|
40
|
+
let(:values) { %w{server1 server3} }
|
|
41
|
+
it_behaves_like "it filters hosts correctly", %w{server1 server3}
|
|
42
|
+
end
|
|
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
|
+
|
|
49
|
+
context "with a regexp" do
|
|
50
|
+
let(:values) { "server[13]$" }
|
|
51
|
+
it_behaves_like "it filters hosts correctly", %w{server1 server3}
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "with a regexp with line boundaries" do
|
|
55
|
+
let(:values) { "^server" }
|
|
56
|
+
it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server10}
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
context "with a regexp with a comma" do
|
|
60
|
+
let(:values) { 'server\d{1,3}$' }
|
|
61
|
+
it_behaves_like "it filters hosts correctly", %w{server1 server2 server3 server4 server10}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "without number" do
|
|
65
|
+
let(:values) { "server" }
|
|
66
|
+
it_behaves_like "it filters hosts correctly", %w{}
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
class Configuration
|
|
5
|
+
describe NullFilter do
|
|
6
|
+
subject(:null_filter) { NullFilter.new }
|
|
7
|
+
|
|
8
|
+
describe "#filter" do
|
|
9
|
+
let(:servers) { mock("servers") }
|
|
10
|
+
|
|
11
|
+
it "returns the servers passed in as arguments" do
|
|
12
|
+
expect(null_filter.filter(servers)).to eq(servers)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/plugin"
|
|
3
|
+
require "capistrano/scm/plugin"
|
|
4
|
+
|
|
5
|
+
module Capistrano
|
|
6
|
+
class Configuration
|
|
7
|
+
class ExamplePlugin < Capistrano::Plugin
|
|
8
|
+
def set_defaults
|
|
9
|
+
set_if_empty :example_variable, "foo"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def define_tasks
|
|
13
|
+
task :example
|
|
14
|
+
task :example_prerequisite
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def register_hooks
|
|
18
|
+
before :example, :example_prerequisite
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class ExampleSCMPlugin < Capistrano::SCM::Plugin
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe PluginInstaller do
|
|
26
|
+
include Capistrano::DSL
|
|
27
|
+
|
|
28
|
+
let(:installer) { PluginInstaller.new }
|
|
29
|
+
let(:options) { {} }
|
|
30
|
+
let(:plugin) { ExamplePlugin.new }
|
|
31
|
+
|
|
32
|
+
before do
|
|
33
|
+
installer.install(plugin, **options)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
after do
|
|
37
|
+
Rake::Task.clear
|
|
38
|
+
Capistrano::Configuration.reset!
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context "installing plugin" do
|
|
42
|
+
it "defines tasks" do
|
|
43
|
+
expect(Rake::Task[:example]).to_not be_nil
|
|
44
|
+
expect(Rake::Task[:example_prerequisite]).to_not be_nil
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "registers hooks" do
|
|
48
|
+
task = Rake::Task[:example]
|
|
49
|
+
expect(task.prerequisites).to eq([:example_prerequisite])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it "sets defaults when load:defaults is invoked", capture_io: true do
|
|
53
|
+
expect(fetch(:example_variable)).to be_nil
|
|
54
|
+
invoke "load:defaults"
|
|
55
|
+
expect(fetch(:example_variable)).to eq("foo")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "doesn't say an SCM is installed" do
|
|
59
|
+
expect(installer.scm_installed?).to be_falsey
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "installing plugin class" do
|
|
64
|
+
let(:plugin) { ExamplePlugin }
|
|
65
|
+
|
|
66
|
+
it "defines tasks" do
|
|
67
|
+
expect(Rake::Task[:example]).to_not be_nil
|
|
68
|
+
expect(Rake::Task[:example_prerequisite]).to_not be_nil
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context "installing plugin without hooks" do
|
|
73
|
+
let(:options) { { load_hooks: false } }
|
|
74
|
+
|
|
75
|
+
it "doesn't register hooks" do
|
|
76
|
+
task = Rake::Task[:example]
|
|
77
|
+
expect(task.prerequisites).to be_empty
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context "installing plugin and loading immediately" do
|
|
82
|
+
let(:options) { { load_immediately: true } }
|
|
83
|
+
|
|
84
|
+
it "sets defaults immediately" do
|
|
85
|
+
expect(fetch(:example_variable)).to eq("foo")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "installing an SCM plugin" do
|
|
90
|
+
let(:plugin) { ExampleSCMPlugin }
|
|
91
|
+
|
|
92
|
+
it "says an SCM is installed" do
|
|
93
|
+
expect(installer.scm_installed?).to be_truthy
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -1,60 +1,92 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
module Capistrano
|
|
4
4
|
class Configuration
|
|
5
|
-
|
|
6
5
|
describe Question do
|
|
7
|
-
|
|
8
|
-
let(:
|
|
9
|
-
let(:
|
|
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") }
|
|
10
11
|
let(:default) { :default }
|
|
11
12
|
let(:key) { :branch }
|
|
12
|
-
let(:
|
|
13
|
+
let(:stdin) { stub(tty?: true) }
|
|
13
14
|
|
|
14
|
-
describe
|
|
15
|
-
it
|
|
15
|
+
describe ".new" do
|
|
16
|
+
it "takes a key, default, options" do
|
|
16
17
|
question
|
|
17
18
|
end
|
|
18
19
|
end
|
|
19
20
|
|
|
20
|
-
describe
|
|
21
|
-
context
|
|
22
|
-
let(:branch) {
|
|
23
|
-
|
|
24
|
-
before do
|
|
25
|
-
$stdout.expects(:print).with('Please enter branch (default): ')
|
|
26
|
-
end
|
|
21
|
+
describe "#call" do
|
|
22
|
+
context "value is entered" do
|
|
23
|
+
let(:branch) { "branch" }
|
|
27
24
|
|
|
28
|
-
it
|
|
29
|
-
$
|
|
30
|
-
|
|
25
|
+
it "returns the echoed value" do
|
|
26
|
+
$stdout.expects(:print).with("Please enter branch (default): ")
|
|
27
|
+
stdin.expects(:gets).returns(branch)
|
|
28
|
+
stdin.expects(:noecho).never
|
|
31
29
|
|
|
32
30
|
expect(question.call).to eq(branch)
|
|
33
31
|
end
|
|
34
32
|
|
|
35
|
-
it
|
|
36
|
-
$
|
|
33
|
+
it "returns the value but does not echo it" do
|
|
34
|
+
$stdout.expects(:print).with("Please enter branch (default): ")
|
|
35
|
+
stdin.expects(:noecho).returns(branch)
|
|
37
36
|
$stdout.expects(:print).with("\n")
|
|
38
37
|
|
|
39
38
|
expect(question_without_echo.call).to eq(branch)
|
|
40
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
|
|
41
64
|
end
|
|
42
65
|
|
|
43
|
-
context
|
|
66
|
+
context "value is not entered" do
|
|
44
67
|
let(:branch) { default }
|
|
45
68
|
|
|
46
69
|
before do
|
|
47
|
-
$stdout.expects(:print).with(
|
|
48
|
-
|
|
70
|
+
$stdout.expects(:print).with("Please enter branch (default): ")
|
|
71
|
+
stdin.expects(:gets).returns("")
|
|
49
72
|
end
|
|
50
73
|
|
|
51
|
-
|
|
52
|
-
it 'returns the default as the value' do
|
|
74
|
+
it "returns the default as the value" do
|
|
53
75
|
expect(question.call).to eq(branch)
|
|
54
76
|
end
|
|
55
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
|
|
56
89
|
end
|
|
57
90
|
end
|
|
58
|
-
|
|
59
91
|
end
|
|
60
92
|
end
|