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.
- checksums.yaml +7 -0
- data/.docker/Dockerfile +7 -0
- data/.docker/ssh_key_rsa +49 -0
- data/.docker/ssh_key_rsa.pub +1 -0
- data/.docker/ubuntu_setup.sh +23 -0
- data/.github/issue_template.md +19 -0
- data/.github/pull_request_template.md +22 -0
- data/.github/release-drafter.yml +25 -0
- data/.github/workflows/ci.yml +80 -0
- data/.github/workflows/release-drafter.yml +18 -0
- data/.gitignore +23 -8
- data/.rubocop.yml +62 -0
- data/CHANGELOG.md +1 -0
- data/CONTRIBUTING.md +63 -0
- data/DEVELOPMENT.md +112 -0
- data/Gemfile +42 -9
- data/LICENSE.txt +21 -0
- data/README.md +221 -0
- data/RELEASING.md +17 -0
- data/Rakefile +17 -8
- data/UPGRADING-3.7.md +86 -0
- data/bin/cap +2 -3
- data/bin/capify +7 -89
- data/capistrano.gemspec +29 -43
- data/docker-compose.yml +8 -0
- data/features/configuration.feature +28 -0
- data/features/deploy.feature +92 -0
- data/features/deploy_failure.feature +17 -0
- data/features/doctor.feature +11 -0
- data/features/installation.feature +21 -0
- data/features/sshconnect.feature +11 -0
- data/features/stage_failure.feature +9 -0
- data/features/step_definitions/assertions.rb +162 -0
- data/features/step_definitions/cap_commands.rb +21 -0
- data/features/step_definitions/setup.rb +91 -0
- data/features/subdirectory.feature +9 -0
- data/features/support/docker_gateway.rb +53 -0
- data/features/support/env.rb +1 -0
- data/features/support/remote_command_helpers.rb +29 -0
- data/features/support/remote_ssh_helpers.rb +33 -0
- data/lib/Capfile +3 -0
- data/lib/capistrano/all.rb +17 -0
- data/lib/capistrano/application.rb +153 -0
- data/lib/capistrano/configuration/empty_filter.rb +9 -0
- data/lib/capistrano/configuration/filter.rb +26 -0
- 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 +76 -0
- data/lib/capistrano/configuration/role_filter.rb +29 -0
- data/lib/capistrano/configuration/scm_resolver.rb +149 -0
- data/lib/capistrano/configuration/server.rb +137 -0
- data/lib/capistrano/configuration/servers.rb +56 -96
- data/lib/capistrano/configuration/validated_variables.rb +110 -0
- data/lib/capistrano/configuration/variables.rb +79 -94
- data/lib/capistrano/configuration.rb +178 -33
- data/lib/capistrano/console.rb +1 -0
- data/lib/capistrano/defaults.rb +36 -0
- data/lib/capistrano/deploy.rb +3 -0
- 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 +2 -0
- data/lib/capistrano/dsl/env.rb +43 -0
- data/lib/capistrano/dsl/paths.rb +89 -0
- data/lib/capistrano/dsl/stages.rb +31 -0
- data/lib/capistrano/dsl/task_enhancements.rb +61 -0
- data/lib/capistrano/dsl.rb +95 -0
- data/lib/capistrano/framework.rb +2 -0
- data/lib/capistrano/i18n.rb +46 -0
- data/lib/capistrano/immutable_task.rb +30 -0
- data/lib/capistrano/install.rb +1 -0
- data/lib/capistrano/plugin.rb +95 -0
- data/lib/capistrano/proc_helpers.rb +13 -0
- data/lib/capistrano/scm/git.rb +105 -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 +84 -0
- data/lib/capistrano/scm/tasks/hg.rake +53 -0
- data/lib/capistrano/scm/tasks/svn.rake +53 -0
- data/lib/capistrano/scm.rb +115 -0
- data/lib/capistrano/setup.rb +36 -0
- data/lib/capistrano/tasks/console.rake +25 -0
- data/lib/capistrano/tasks/deploy.rake +280 -0
- data/lib/capistrano/tasks/doctor.rake +24 -0
- data/lib/capistrano/tasks/framework.rake +67 -0
- data/lib/capistrano/tasks/install.rake +41 -0
- data/lib/capistrano/templates/Capfile +38 -0
- data/lib/capistrano/templates/deploy.rb.erb +39 -0
- data/lib/capistrano/templates/stage.rb.erb +61 -0
- data/lib/capistrano/upload_task.rb +9 -0
- data/lib/capistrano/version.rb +1 -14
- data/lib/capistrano/version_validator.rb +32 -0
- data/lib/capistrano.rb +0 -3
- data/spec/integration/dsl_spec.rb +632 -0
- data/spec/integration_spec_helper.rb +5 -0
- data/spec/lib/capistrano/application_spec.rb +60 -0
- data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/filter_spec.rb +109 -0
- 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 +92 -0
- data/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +56 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +309 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +331 -0
- data/spec/lib/capistrano/configuration_spec.rb +357 -0
- 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 +228 -0
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +108 -0
- data/spec/lib/capistrano/dsl_spec.rb +125 -0
- 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 +194 -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 +103 -0
- data/spec/lib/capistrano/upload_task_spec.rb +19 -0
- data/spec/lib/capistrano/version_validator_spec.rb +118 -0
- data/spec/lib/capistrano_spec.rb +7 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/matchers.rb +5 -0
- data/spec/support/tasks/database.rake +11 -0
- data/spec/support/tasks/fail.rake +8 -0
- data/spec/support/tasks/failed.rake +5 -0
- data/spec/support/tasks/plugin.rake +6 -0
- data/spec/support/tasks/root.rake +11 -0
- data/spec/support/test_app.rb +205 -0
- metadata +234 -208
- data/.rvmrc +0 -1
- data/CHANGELOG +0 -954
- data/README.mdown +0 -76
- data/lib/capistrano/callback.rb +0 -45
- data/lib/capistrano/cli/execute.rb +0 -85
- data/lib/capistrano/cli/help.rb +0 -125
- data/lib/capistrano/cli/help.txt +0 -81
- data/lib/capistrano/cli/options.rb +0 -243
- data/lib/capistrano/cli/ui.rb +0 -40
- data/lib/capistrano/cli.rb +0 -47
- data/lib/capistrano/command.rb +0 -286
- data/lib/capistrano/configuration/actions/file_transfer.rb +0 -51
- data/lib/capistrano/configuration/actions/inspect.rb +0 -46
- data/lib/capistrano/configuration/actions/invocation.rb +0 -298
- data/lib/capistrano/configuration/callbacks.rb +0 -148
- data/lib/capistrano/configuration/connections.rb +0 -230
- data/lib/capistrano/configuration/execution.rb +0 -143
- data/lib/capistrano/configuration/loading.rb +0 -197
- data/lib/capistrano/configuration/namespaces.rb +0 -197
- data/lib/capistrano/configuration/roles.rb +0 -73
- data/lib/capistrano/errors.rb +0 -19
- data/lib/capistrano/ext/string.rb +0 -5
- data/lib/capistrano/extensions.rb +0 -57
- data/lib/capistrano/logger.rb +0 -59
- data/lib/capistrano/processable.rb +0 -53
- data/lib/capistrano/recipes/compat.rb +0 -32
- data/lib/capistrano/recipes/deploy/assets.rb +0 -57
- data/lib/capistrano/recipes/deploy/dependencies.rb +0 -44
- data/lib/capistrano/recipes/deploy/local_dependency.rb +0 -54
- data/lib/capistrano/recipes/deploy/remote_dependency.rb +0 -111
- data/lib/capistrano/recipes/deploy/scm/accurev.rb +0 -169
- data/lib/capistrano/recipes/deploy/scm/base.rb +0 -196
- data/lib/capistrano/recipes/deploy/scm/bzr.rb +0 -86
- data/lib/capistrano/recipes/deploy/scm/cvs.rb +0 -153
- data/lib/capistrano/recipes/deploy/scm/darcs.rb +0 -96
- data/lib/capistrano/recipes/deploy/scm/git.rb +0 -282
- data/lib/capistrano/recipes/deploy/scm/mercurial.rb +0 -137
- data/lib/capistrano/recipes/deploy/scm/none.rb +0 -44
- data/lib/capistrano/recipes/deploy/scm/perforce.rb +0 -138
- data/lib/capistrano/recipes/deploy/scm/subversion.rb +0 -121
- data/lib/capistrano/recipes/deploy/scm.rb +0 -19
- data/lib/capistrano/recipes/deploy/strategy/base.rb +0 -88
- data/lib/capistrano/recipes/deploy/strategy/checkout.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/copy.rb +0 -224
- data/lib/capistrano/recipes/deploy/strategy/export.rb +0 -20
- data/lib/capistrano/recipes/deploy/strategy/remote.rb +0 -52
- data/lib/capistrano/recipes/deploy/strategy/remote_cache.rb +0 -57
- data/lib/capistrano/recipes/deploy/strategy.rb +0 -19
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/deploy.rb +0 -568
- data/lib/capistrano/recipes/standard.rb +0 -37
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/role.rb +0 -102
- data/lib/capistrano/server_definition.rb +0 -56
- data/lib/capistrano/shell.rb +0 -260
- data/lib/capistrano/ssh.rb +0 -101
- data/lib/capistrano/task_definition.rb +0 -75
- data/lib/capistrano/transfer.rb +0 -216
- data/rvmrc.sample +0 -1
- data/test/cli/execute_test.rb +0 -132
- data/test/cli/help_test.rb +0 -165
- data/test/cli/options_test.rb +0 -329
- data/test/cli/ui_test.rb +0 -28
- data/test/cli_test.rb +0 -17
- data/test/command_test.rb +0 -289
- data/test/configuration/actions/file_transfer_test.rb +0 -61
- data/test/configuration/actions/inspect_test.rb +0 -65
- data/test/configuration/actions/invocation_test.rb +0 -247
- data/test/configuration/callbacks_test.rb +0 -220
- data/test/configuration/connections_test.rb +0 -420
- data/test/configuration/execution_test.rb +0 -175
- data/test/configuration/loading_test.rb +0 -132
- data/test/configuration/namespace_dsl_test.rb +0 -311
- data/test/configuration/roles_test.rb +0 -144
- data/test/configuration/servers_test.rb +0 -183
- data/test/configuration/variables_test.rb +0 -190
- data/test/configuration_test.rb +0 -88
- data/test/deploy/local_dependency_test.rb +0 -76
- data/test/deploy/remote_dependency_test.rb +0 -135
- data/test/deploy/scm/accurev_test.rb +0 -23
- data/test/deploy/scm/base_test.rb +0 -55
- data/test/deploy/scm/bzr_test.rb +0 -51
- data/test/deploy/scm/darcs_test.rb +0 -37
- data/test/deploy/scm/git_test.rb +0 -184
- data/test/deploy/scm/mercurial_test.rb +0 -134
- data/test/deploy/scm/none_test.rb +0 -35
- data/test/deploy/scm/subversion_test.rb +0 -32
- data/test/deploy/strategy/copy_test.rb +0 -321
- data/test/extensions_test.rb +0 -69
- data/test/fixtures/cli_integration.rb +0 -5
- data/test/fixtures/config.rb +0 -5
- data/test/fixtures/custom.rb +0 -3
- data/test/logger_test.rb +0 -123
- data/test/recipes_test.rb +0 -25
- data/test/role_test.rb +0 -11
- data/test/server_definition_test.rb +0 -121
- data/test/shell_test.rb +0 -90
- data/test/ssh_test.rb +0 -113
- data/test/task_definition_test.rb +0 -116
- data/test/transfer_test.rb +0 -160
- data/test/utils.rb +0 -37
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
describe Configuration do
|
|
5
|
+
let(:config) { Configuration.new }
|
|
6
|
+
let(:servers) { stub }
|
|
7
|
+
|
|
8
|
+
describe ".new" do
|
|
9
|
+
it "accepts initial hash" do
|
|
10
|
+
configuration = described_class.new(custom: "value")
|
|
11
|
+
expect(configuration.fetch(:custom)).to eq("value")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe ".env" do
|
|
16
|
+
it "is a global accessor to a single instance" do
|
|
17
|
+
Configuration.env.set(:test, true)
|
|
18
|
+
expect(Configuration.env.fetch(:test)).to be_truthy
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe ".reset!" do
|
|
23
|
+
it "blows away the existing `env` and creates a new one" do
|
|
24
|
+
old_env = Configuration.env
|
|
25
|
+
Configuration.reset!
|
|
26
|
+
expect(Configuration.env).not_to be old_env
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe "roles" do
|
|
31
|
+
context "adding a role" do
|
|
32
|
+
subject { config.role(:app, %w{server1 server2}) }
|
|
33
|
+
|
|
34
|
+
before do
|
|
35
|
+
Configuration::Servers.expects(:new).returns(servers)
|
|
36
|
+
servers.expects(:add_role).with(:app, %w{server1 server2}, {})
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "adds the role" do
|
|
40
|
+
expect(subject)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
describe "setting and fetching" do
|
|
46
|
+
subject { config.fetch(:key, :default) }
|
|
47
|
+
|
|
48
|
+
context "set" do
|
|
49
|
+
it "sets by value" do
|
|
50
|
+
config.set(:key, :value)
|
|
51
|
+
expect(subject).to eq :value
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it "sets by block" do
|
|
55
|
+
config.set(:key) { :value }
|
|
56
|
+
expect(subject).to eq :value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "raises an exception when given both a value and block" do
|
|
60
|
+
expect { config.set(:key, :value) { :value } }.to raise_error(Capistrano::ValidationError)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "set_if_empty" do
|
|
65
|
+
it "sets by value when none is present" do
|
|
66
|
+
config.set_if_empty(:key, :value)
|
|
67
|
+
expect(subject).to eq :value
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it "sets by block when none is present" do
|
|
71
|
+
config.set_if_empty(:key) { :value }
|
|
72
|
+
expect(subject).to eq :value
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it "does not overwrite existing values" do
|
|
76
|
+
config.set(:key, :value)
|
|
77
|
+
config.set_if_empty(:key, :update)
|
|
78
|
+
config.set_if_empty(:key) { :update }
|
|
79
|
+
expect(subject).to eq :value
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
context "value is not set" do
|
|
84
|
+
it "returns the default value" do
|
|
85
|
+
expect(subject).to eq :default
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "value is a proc" do
|
|
90
|
+
subject { config.fetch(:key, proc { :proc }) }
|
|
91
|
+
it "calls the proc" do
|
|
92
|
+
expect(subject).to eq :proc
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "value is a lambda" do
|
|
97
|
+
subject { config.fetch(:key, -> { :lambda }) }
|
|
98
|
+
it "calls the lambda" do
|
|
99
|
+
expect(subject).to eq :lambda
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "value inside proc inside a proc" do
|
|
104
|
+
subject { config.fetch(:key, proc { proc { "some value" } }) }
|
|
105
|
+
it "calls all procs and lambdas" do
|
|
106
|
+
expect(subject).to eq "some value"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "value inside lambda inside a lambda" do
|
|
111
|
+
subject { config.fetch(:key, -> { -> { "some value" } }) }
|
|
112
|
+
it "calls all procs and lambdas" do
|
|
113
|
+
expect(subject).to eq "some value"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
context "value inside lambda inside a proc" do
|
|
118
|
+
subject { config.fetch(:key, proc { -> { "some value" } }) }
|
|
119
|
+
it "calls all procs and lambdas" do
|
|
120
|
+
expect(subject).to eq "some value"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context "value inside proc inside a lambda" do
|
|
125
|
+
subject { config.fetch(:key, -> { proc { "some value" } }) }
|
|
126
|
+
it "calls all procs and lambdas" do
|
|
127
|
+
expect(subject).to eq "some value"
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "lambda with parameters" do
|
|
132
|
+
subject { config.fetch(:key, ->(c) { c }).call(42) }
|
|
133
|
+
it "is returned as a lambda" do
|
|
134
|
+
expect(subject).to eq 42
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
context "block is passed to fetch" do
|
|
139
|
+
subject { config.fetch(:key, :default) { raise "we need this!" } }
|
|
140
|
+
|
|
141
|
+
it "returns the block value" do
|
|
142
|
+
expect { subject }.to raise_error(RuntimeError)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "validations" do
|
|
147
|
+
before do
|
|
148
|
+
config.validate :key do |_, value|
|
|
149
|
+
raise Capistrano::ValidationError unless value.length > 3
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "validates string without error" do
|
|
154
|
+
config.set(:key, "longer_value")
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it "validates block without error" do
|
|
158
|
+
config.set(:key) { "longer_value" }
|
|
159
|
+
expect(config.fetch(:key)).to eq "longer_value"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
it "validates lambda without error" do
|
|
163
|
+
config.set :key, -> { "longer_value" }
|
|
164
|
+
expect(config.fetch(:key)).to eq "longer_value"
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it "raises an exception on invalid string" do
|
|
168
|
+
expect { config.set(:key, "sho") }.to raise_error(Capistrano::ValidationError)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "raises an exception on invalid string provided by block" do
|
|
172
|
+
config.set(:key) { "sho" }
|
|
173
|
+
expect { config.fetch(:key) }.to raise_error(Capistrano::ValidationError)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it "raises an exception on invalid string provided by lambda" do
|
|
177
|
+
config.set :key, -> { "sho" }
|
|
178
|
+
expect { config.fetch(:key) }.to raise_error(Capistrano::ValidationError)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
context "appending" do
|
|
183
|
+
subject { config.append(:linked_dirs, "vendor/bundle", "tmp") }
|
|
184
|
+
|
|
185
|
+
it "returns appended value" do
|
|
186
|
+
expect(subject).to eq ["vendor/bundle", "tmp"]
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context "on non-array variable" do
|
|
190
|
+
before { config.set(:linked_dirs, "string") }
|
|
191
|
+
subject { config.append(:linked_dirs, "vendor/bundle") }
|
|
192
|
+
|
|
193
|
+
it "returns appended value" do
|
|
194
|
+
expect(subject).to eq ["string", "vendor/bundle"]
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context "removing" do
|
|
200
|
+
before :each do
|
|
201
|
+
config.set(:linked_dirs, ["vendor/bundle", "tmp"])
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
subject { config.remove(:linked_dirs, "vendor/bundle") }
|
|
205
|
+
|
|
206
|
+
it "returns without removed value" do
|
|
207
|
+
expect(subject).to eq ["tmp"]
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
context "on non-array variable" do
|
|
211
|
+
before { config.set(:linked_dirs, "string") }
|
|
212
|
+
|
|
213
|
+
context "when removing same value" do
|
|
214
|
+
subject { config.remove(:linked_dirs, "string") }
|
|
215
|
+
|
|
216
|
+
it "returns without removed value" do
|
|
217
|
+
expect(subject).to eq []
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
context "when removing different value" do
|
|
222
|
+
subject { config.remove(:linked_dirs, "othervalue") }
|
|
223
|
+
|
|
224
|
+
it "returns without removed value" do
|
|
225
|
+
expect(subject).to eq ["string"]
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
describe "keys" do
|
|
233
|
+
subject { config.keys }
|
|
234
|
+
|
|
235
|
+
before do
|
|
236
|
+
config.set(:key1, :value1)
|
|
237
|
+
config.set(:key2, :value2)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
it "returns all set keys" do
|
|
241
|
+
expect(subject).to match_array %i(key1 key2)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
describe "deleting" do
|
|
246
|
+
before do
|
|
247
|
+
config.set(:key, :value)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "deletes the value" do
|
|
251
|
+
config.delete(:key)
|
|
252
|
+
expect(config.fetch(:key)).to be_nil
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
describe "asking" do
|
|
257
|
+
let(:question) { stub }
|
|
258
|
+
let(:options) { {} }
|
|
259
|
+
|
|
260
|
+
before do
|
|
261
|
+
Configuration::Question.expects(:new).with(:branch, :default, options)
|
|
262
|
+
.returns(question)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
it "prompts for the value when fetching" do
|
|
266
|
+
config.ask(:branch, :default, options)
|
|
267
|
+
expect(config.fetch(:branch)).to eq question
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
describe "setting the backend" do
|
|
272
|
+
it "by default, is SSHKit" do
|
|
273
|
+
expect(config.backend).to eq SSHKit
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
it "can be set to another class" do
|
|
277
|
+
config.backend = :test
|
|
278
|
+
expect(config.backend).to eq :test
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
describe "ssh_options for Netssh" do
|
|
282
|
+
it "merges them with the :ssh_options variable" do
|
|
283
|
+
config.set :format, :pretty
|
|
284
|
+
config.set :log_level, :debug
|
|
285
|
+
config.set :ssh_options, user: "albert"
|
|
286
|
+
SSHKit::Backend::Netssh.configure { |ssh| ssh.ssh_options = { password: "einstein" } }
|
|
287
|
+
config.configure_backend
|
|
288
|
+
|
|
289
|
+
expect(
|
|
290
|
+
config.backend.config.backend.config.ssh_options
|
|
291
|
+
).to include(user: "albert", password: "einstein")
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
describe "dry_run?" do
|
|
297
|
+
it "returns false when using default backend" do
|
|
298
|
+
expect(config.dry_run?).to eq(false)
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "returns true when using printer backend" do
|
|
302
|
+
config.set :sshkit_backend, SSHKit::Backend::Printer
|
|
303
|
+
|
|
304
|
+
expect(config.dry_run?).to eq(true)
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
describe "custom filtering" do
|
|
309
|
+
it "accepts a custom filter object" do
|
|
310
|
+
filter = Object.new
|
|
311
|
+
def filter.filter(servers)
|
|
312
|
+
servers
|
|
313
|
+
end
|
|
314
|
+
config.add_filter(filter)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
it "accepts a custom filter as a block" do
|
|
318
|
+
config.add_filter { |servers| servers }
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it "raises an error if passed a block and an object" do
|
|
322
|
+
filter = Object.new
|
|
323
|
+
def filter.filter(servers)
|
|
324
|
+
servers
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
expect { config.add_filter(filter) { |servers| servers } }.to raise_error(ArgumentError)
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "raises an error if the filter lacks a filter method" do
|
|
331
|
+
filter = Object.new
|
|
332
|
+
expect { config.add_filter(filter) }.to raise_error(TypeError)
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
it "calls the filter method of a custom filter" do
|
|
336
|
+
ENV.delete "ROLES"
|
|
337
|
+
ENV.delete "HOSTS"
|
|
338
|
+
|
|
339
|
+
servers = Configuration::Servers.new
|
|
340
|
+
|
|
341
|
+
servers.add_host("test1")
|
|
342
|
+
servers.add_host("test2")
|
|
343
|
+
servers.add_host("test3")
|
|
344
|
+
|
|
345
|
+
filtered_servers = servers.take(2)
|
|
346
|
+
|
|
347
|
+
filter = mock("custom filter")
|
|
348
|
+
filter.expects(:filter)
|
|
349
|
+
.with { |subset| subset.is_a? Configuration::Servers }
|
|
350
|
+
.returns(filtered_servers)
|
|
351
|
+
|
|
352
|
+
config.add_filter(filter)
|
|
353
|
+
expect(config.filter(servers)).to eq(filtered_servers)
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/doctor/environment_doctor"
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
module Doctor
|
|
6
|
+
describe EnvironmentDoctor do
|
|
7
|
+
let(:doc) { EnvironmentDoctor.new }
|
|
8
|
+
|
|
9
|
+
it "prints using 4-space indentation" do
|
|
10
|
+
expect { doc.call }.to output(/^ {4}/).to_stdout
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "prints the Ruby version" do
|
|
14
|
+
expect { doc.call }.to\
|
|
15
|
+
output(/#{Regexp.quote(RUBY_DESCRIPTION)}/).to_stdout
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it "prints the Rubygems version" do
|
|
19
|
+
expect { doc.call }.to output(/#{Regexp.quote(Gem::VERSION)}/).to_stdout
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe "Rake" do
|
|
23
|
+
before do
|
|
24
|
+
load File.expand_path("../../../../../lib/capistrano/doctor.rb",
|
|
25
|
+
__FILE__)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
after do
|
|
29
|
+
Rake::Task.clear
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "has an doctor:environment task that calls EnvironmentDoctor", capture_io: true do
|
|
33
|
+
EnvironmentDoctor.any_instance.expects(:call)
|
|
34
|
+
Rake::Task["doctor:environment"].invoke
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "has a doctor task that depends on doctor:environment" do
|
|
38
|
+
expect(Rake::Task["doctor"].prerequisites).to \
|
|
39
|
+
include("doctor:environment")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/doctor/gems_doctor"
|
|
3
|
+
require "airbrussh/version"
|
|
4
|
+
require "sshkit/version"
|
|
5
|
+
require "net/ssh/version"
|
|
6
|
+
|
|
7
|
+
module Capistrano
|
|
8
|
+
module Doctor
|
|
9
|
+
describe GemsDoctor do
|
|
10
|
+
let(:doc) { GemsDoctor.new }
|
|
11
|
+
|
|
12
|
+
it "prints using 4-space indentation" do
|
|
13
|
+
expect { doc.call }.to output(/^ {4}/).to_stdout
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "prints the Capistrano version" do
|
|
17
|
+
expect { doc.call }.to\
|
|
18
|
+
output(/capistrano\s+#{Regexp.quote(Capistrano::VERSION)}/).to_stdout
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "prints the Rake version" do
|
|
22
|
+
expect { doc.call }.to\
|
|
23
|
+
output(/rake\s+#{Regexp.quote(Rake::VERSION)}/).to_stdout
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "prints the SSHKit version" do
|
|
27
|
+
expect { doc.call }.to\
|
|
28
|
+
output(/sshkit\s+#{Regexp.quote(SSHKit::VERSION)}/).to_stdout
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "prints the Airbrussh version" do
|
|
32
|
+
expect { doc.call }.to\
|
|
33
|
+
output(/airbrussh\s+#{Regexp.quote(Airbrussh::VERSION)}/).to_stdout
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "prints the net-ssh version" do
|
|
37
|
+
expect { doc.call }.to\
|
|
38
|
+
output(/net-ssh\s+#{Regexp.quote(Net::SSH::Version::STRING)}/).to_stdout
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "warns that new version is available" do
|
|
42
|
+
Gem.stubs(:latest_version_for).returns(Gem::Version.new("99.0.0"))
|
|
43
|
+
expect { doc.call }.to output(/\(update available\)/).to_stdout
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "Rake" do
|
|
47
|
+
before do
|
|
48
|
+
load File.expand_path("../../../../../lib/capistrano/doctor.rb",
|
|
49
|
+
__FILE__)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
after do
|
|
53
|
+
Rake::Task.clear
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "has an doctor:gems task that calls GemsDoctor", capture_io: true do
|
|
57
|
+
GemsDoctor.any_instance.expects(:call)
|
|
58
|
+
Rake::Task["doctor:gems"].invoke
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "has a doctor task that depends on doctor:gems" do
|
|
62
|
+
expect(Rake::Task["doctor"].prerequisites).to include("doctor:gems")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/doctor/output_helpers"
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
module Doctor
|
|
6
|
+
describe OutputHelpers do
|
|
7
|
+
include OutputHelpers
|
|
8
|
+
|
|
9
|
+
# Force color for the purpose of these tests
|
|
10
|
+
before { ENV.stubs(:[]).with("SSHKIT_COLOR").returns("1") }
|
|
11
|
+
|
|
12
|
+
it "prints titles in blue with newlines and without indentation" do
|
|
13
|
+
expect { title("Hello!") }.to\
|
|
14
|
+
output("\e[0;34;49m\nHello!\n\e[0m\n").to_stdout
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "prints warnings in yellow with 4-space indentation" do
|
|
18
|
+
expect { warning("Yikes!") }.to\
|
|
19
|
+
output(" \e[0;33;49mYikes!\e[0m\n").to_stdout
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "overrides puts to indent 4 spaces per line" do
|
|
23
|
+
expect { puts("one\ntwo") }.to output(" one\n two\n").to_stdout
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "formats tables with indent, aligned columns and per-row color" do
|
|
27
|
+
data = [
|
|
28
|
+
["one", ".", "1"],
|
|
29
|
+
["two", "..", "2"],
|
|
30
|
+
["three", "...", "3"]
|
|
31
|
+
]
|
|
32
|
+
block = proc do |record, row|
|
|
33
|
+
row.yellow if record.first == "two"
|
|
34
|
+
row << record[0]
|
|
35
|
+
row << record[1]
|
|
36
|
+
row << record[2]
|
|
37
|
+
end
|
|
38
|
+
expected_output = <<-OUT
|
|
39
|
+
one . 1
|
|
40
|
+
\e[0;33;49mtwo .. 2\e[0m
|
|
41
|
+
three ... 3
|
|
42
|
+
OUT
|
|
43
|
+
expect { table(data, &block) }.to output(expected_output).to_stdout
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
require "capistrano/doctor/servers_doctor"
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
module Doctor
|
|
6
|
+
describe ServersDoctor do
|
|
7
|
+
include Capistrano::DSL
|
|
8
|
+
let(:doc) { ServersDoctor.new }
|
|
9
|
+
|
|
10
|
+
before { Capistrano::Configuration.reset! }
|
|
11
|
+
after { Capistrano::Configuration.reset! }
|
|
12
|
+
|
|
13
|
+
it "prints using 4-space indentation" do
|
|
14
|
+
expect { doc.call }.to output(/^ {4}/).to_stdout
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "prints the number of defined servers" do
|
|
18
|
+
role :app, %w(example.com)
|
|
19
|
+
server "www@example.com:22"
|
|
20
|
+
|
|
21
|
+
expect { doc.call }.to output(/Servers \(2\)/).to_stdout
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
describe "prints the server's details" do
|
|
25
|
+
it "including username" do
|
|
26
|
+
server "www@example.com"
|
|
27
|
+
expect { doc.call }.to output(/www@example.com/).to_stdout
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "including port" do
|
|
31
|
+
server "www@example.com:22"
|
|
32
|
+
expect { doc.call }.to output(/www@example.com:22/).to_stdout
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "including roles" do
|
|
36
|
+
role :app, %w(example.com)
|
|
37
|
+
expect { doc.call }.to output(/example.com\s+\[:app\]/).to_stdout
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "including empty roles" do
|
|
41
|
+
server "example.com"
|
|
42
|
+
expect { doc.call }.to output(/example.com\s+\[\]/).to_stdout
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it "including properties" do
|
|
46
|
+
server "example.com", roles: %w(app db), primary: true
|
|
47
|
+
expect { doc.call }.to \
|
|
48
|
+
output(/example.com\s+\[:app, :db\]\s+\{ :primary => true \}/).to_stdout
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "including misleading role name alert" do
|
|
52
|
+
server "example.com", roles: ["web app db"]
|
|
53
|
+
warning_msg = 'Whitespace detected in role(s) :"web app db". ' \
|
|
54
|
+
'This might be a result of a mistyped "%w()" array literal'
|
|
55
|
+
|
|
56
|
+
expect { doc.call }.to output(/#{Regexp.escape(warning_msg)}/).to_stdout
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it "doesn't fail for no servers" do
|
|
61
|
+
expect { doc.call }.to output("\nServers (0)\n \n").to_stdout
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "Rake" do
|
|
65
|
+
before do
|
|
66
|
+
load File.expand_path("../../../../../lib/capistrano/doctor.rb",
|
|
67
|
+
__FILE__)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
after do
|
|
71
|
+
Rake::Task.clear
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it "has an doctor:servers task that calls ServersDoctor", capture_io: true do
|
|
75
|
+
ServersDoctor.any_instance.expects(:call)
|
|
76
|
+
Rake::Task["doctor:servers"].invoke
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it "has a doctor task that depends on doctor:servers" do
|
|
80
|
+
expect(Rake::Task["doctor"].prerequisites).to \
|
|
81
|
+
include("doctor:servers")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -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
|