capistrano 3.11.0 → 3.16.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 +4 -4
- data/.github/pull_request_template.md +0 -4
- data/.github/release-drafter.yml +17 -0
- data/.github/workflows/push.yml +12 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +10 -7
- data/CHANGELOG.md +1 -651
- data/Dangerfile +1 -1
- data/Gemfile +33 -1
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/RELEASING.md +3 -3
- data/Rakefile +5 -0
- data/capistrano.gemspec +8 -3
- data/features/deploy.feature +6 -0
- data/features/step_definitions/assertions.rb +1 -1
- data/features/step_definitions/setup.rb +6 -4
- data/features/support/vagrant_helpers.rb +6 -0
- data/lib/capistrano/configuration/question.rb +16 -4
- data/lib/capistrano/dsl.rb +1 -1
- data/lib/capistrano/i18n.rb +2 -0
- data/lib/capistrano/scm/git.rb +10 -4
- data/lib/capistrano/scm/tasks/git.rake +8 -7
- data/lib/capistrano/tasks/deploy.rake +3 -2
- data/lib/capistrano/templates/stage.rb.erb +1 -1
- data/lib/capistrano/version.rb +1 -1
- data/spec/integration/dsl_spec.rb +5 -3
- data/spec/lib/capistrano/application_spec.rb +16 -40
- data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +1 -1
- data/spec/lib/capistrano/configuration/question_spec.rb +31 -13
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +3 -2
- data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +1 -1
- data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +1 -1
- data/spec/lib/capistrano/doctor/servers_doctor_spec.rb +1 -1
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +1 -1
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +6 -6
- data/spec/lib/capistrano/dsl_spec.rb +5 -5
- data/spec/lib/capistrano/plugin_spec.rb +2 -2
- data/spec/lib/capistrano/scm/git_spec.rb +27 -5
- data/spec/spec_helper.rb +13 -0
- data/spec/support/test_app.rb +8 -3
- metadata +15 -23
data/Gemfile
CHANGED
@@ -4,7 +4,39 @@ source "https://rubygems.org"
|
|
4
4
|
gemspec
|
5
5
|
|
6
6
|
group :cucumber do
|
7
|
-
|
7
|
+
# Latest versions of cucumber don't support Ruby < 2.1
|
8
|
+
# rubocop:disable Bundler/DuplicatedGem
|
9
|
+
if Gem::Requirement.new("< 2.1").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
10
|
+
gem "cucumber", "< 3.0.1"
|
11
|
+
else
|
12
|
+
gem "cucumber"
|
13
|
+
end
|
14
|
+
# rubocop:enable Bundler/DuplicatedGem
|
8
15
|
gem "rspec"
|
9
16
|
gem "rspec-core", "~> 3.4.4"
|
10
17
|
end
|
18
|
+
|
19
|
+
# Latest versions of net-ssh don't support Ruby < 2.2.6
|
20
|
+
if Gem::Requirement.new("< 2.2.6").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
21
|
+
gem "net-ssh", "< 5.0.0"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Latest versions of public_suffix don't support Ruby < 2.1
|
25
|
+
if Gem::Requirement.new("< 2.1").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
26
|
+
gem "public_suffix", "< 3.0.0"
|
27
|
+
end
|
28
|
+
|
29
|
+
# Latest versions of i18n don't support Ruby < 2.4
|
30
|
+
if Gem::Requirement.new("< 2.4").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
31
|
+
gem "i18n", "< 1.3.0"
|
32
|
+
end
|
33
|
+
|
34
|
+
# Latest versions of rake don't support Ruby < 2.2
|
35
|
+
if Gem::Requirement.new("< 2.2").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
36
|
+
gem "rake", "< 13.0.0"
|
37
|
+
end
|
38
|
+
|
39
|
+
# We only run danger once on a new-ish ruby; no need to install it otherwise
|
40
|
+
if Gem::Requirement.new("> 2.4").satisfied_by?(Gem::Version.new(RUBY_VERSION))
|
41
|
+
gem "danger"
|
42
|
+
end
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2012-
|
3
|
+
Copyright (c) 2012-2020 Tom Clements, Lee Hambley
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -107,7 +107,7 @@ Add Capistrano to your project's Gemfile using `require: false`:
|
|
107
107
|
|
108
108
|
``` ruby
|
109
109
|
group :development do
|
110
|
-
gem "capistrano", "~> 3.
|
110
|
+
gem "capistrano", "~> 3.16", require: false
|
111
111
|
end
|
112
112
|
```
|
113
113
|
|
@@ -200,7 +200,7 @@ Contributions to Capistrano, in the form of code, documentation or idea, are gla
|
|
200
200
|
|
201
201
|
MIT License (MIT)
|
202
202
|
|
203
|
-
Copyright (c) 2012-
|
203
|
+
Copyright (c) 2012-2020 Tom Clements, Lee Hambley
|
204
204
|
|
205
205
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
206
206
|
of this software and associated documentation files (the "Software"), to deal
|
data/RELEASING.md
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
2. **Ensure all tests are passing by running `rake spec` and `rake features`.**
|
12
12
|
3. Determine which would be the correct next version number according to [semver](http://semver.org/).
|
13
13
|
4. Update the version in `./lib/capistrano/version.rb`.
|
14
|
-
|
15
|
-
|
16
|
-
6. Commit the changelog and version in a single commit, the message should be "Preparing vX.Y.Z"
|
14
|
+
5. Update the version in the `./README.md` Gemfile example (`gem "capistrano", "~> X.Y"`).
|
15
|
+
6. Commit the `version.rb` and `README.md` changes in a single commit, the message should be "Release vX.Y.Z"
|
17
16
|
7. Run `rake release`; this will tag, push to GitHub, and publish to rubygems.org.
|
17
|
+
8. Update the draft release on the [GitHub releases page](https://github.com/capistrano/capistrano/releases) to point to the new tag and publish the release
|
data/Rakefile
CHANGED
data/capistrano.gemspec
CHANGED
@@ -11,8 +11,14 @@ Gem::Specification.new do |gem|
|
|
11
11
|
gem.email = ["seenmyfate@gmail.com", "lee.hambley@gmail.com"]
|
12
12
|
gem.description = "Capistrano is a utility and framework for executing commands in parallel on multiple remote machines, via SSH."
|
13
13
|
gem.summary = "Capistrano - Welcome to easy deployment with Ruby over SSH"
|
14
|
-
gem.homepage = "
|
15
|
-
|
14
|
+
gem.homepage = "https://capistranorb.com/"
|
15
|
+
gem.metadata = {
|
16
|
+
"bug_tracker_uri" => "https://github.com/capistrano/capistrano/issues",
|
17
|
+
"changelog_uri" => "https://github.com/capistrano/capistrano/releases",
|
18
|
+
"source_code_uri" => "https://github.com/capistrano/capistrano",
|
19
|
+
"homepage_uri" => "https://capistranorb.com/",
|
20
|
+
"documentation_uri" => "https://capistranorb.com/"
|
21
|
+
}
|
16
22
|
gem.files = `git ls-files -z`.split("\x0").reject { |f| f =~ /^docs/ }
|
17
23
|
gem.executables = %w(cap capify)
|
18
24
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -26,7 +32,6 @@ Gem::Specification.new do |gem|
|
|
26
32
|
gem.add_dependency "rake", ">= 10.0.0"
|
27
33
|
gem.add_dependency "sshkit", ">= 1.9.0"
|
28
34
|
|
29
|
-
gem.add_development_dependency "danger"
|
30
35
|
gem.add_development_dependency "mocha"
|
31
36
|
gem.add_development_dependency "rspec"
|
32
37
|
gem.add_development_dependency "rubocop", "0.48.1"
|
data/features/deploy.feature
CHANGED
@@ -70,6 +70,12 @@ Feature: Deploy
|
|
70
70
|
Then 3 valid releases are kept
|
71
71
|
And the current directory will be a symlink to the release
|
72
72
|
|
73
|
+
Scenario: Cleanup when there are more releases than arguments can handle
|
74
|
+
Given config stage file has line "set :keep_releases, 3"
|
75
|
+
And 5000 valid existing releases
|
76
|
+
When I run cap "deploy:cleanup"
|
77
|
+
Then 3 valid releases are kept
|
78
|
+
|
73
79
|
Scenario: Rolling Back
|
74
80
|
Given I make 2 deployments
|
75
81
|
When I run cap "deploy:rollback"
|
@@ -5,7 +5,7 @@ Then(/^references in the remote repo are listed$/) do
|
|
5
5
|
end
|
6
6
|
|
7
7
|
Then(/^git wrapper permissions are 0700$/) do
|
8
|
-
permissions_test = %Q([ $(stat -c "%a" #{TestApp.
|
8
|
+
permissions_test = %Q([ $(stat -c "%a" #{TestApp.git_wrapper_path_glob}) == "700" ])
|
9
9
|
_stdout, _stderr, status = vagrant_cli_command("ssh -c #{permissions_test.shellescape}")
|
10
10
|
|
11
11
|
expect(status).to be_success
|
@@ -80,10 +80,12 @@ end
|
|
80
80
|
|
81
81
|
Given(/^(\d+) valid existing releases$/) do |num|
|
82
82
|
a_day = 86_400 # in seconds
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
(1...num).each_slice(100) do |num_batch|
|
84
|
+
dirs = num_batch.map do |i|
|
85
|
+
offset = -(a_day * i)
|
86
|
+
TestApp.release_path(TestApp.timestamp(offset))
|
87
|
+
end
|
88
|
+
run_vagrant_command("mkdir -p #{dirs.join(' ')}")
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
@@ -30,6 +30,12 @@ module VagrantHelpers
|
|
30
30
|
return [stdout, stderr] if status.success?
|
31
31
|
raise VagrantSSHCommandError, status
|
32
32
|
end
|
33
|
+
|
34
|
+
def puts(message)
|
35
|
+
# Attach log messages to the current cucumber feature (`log`),
|
36
|
+
# or simply puts to the console (`super`) if we are outside of cucumber.
|
37
|
+
respond_to?(:log) ? log(message) : super(message)
|
38
|
+
end
|
33
39
|
end
|
34
40
|
|
35
41
|
World(VagrantHelpers)
|
@@ -36,12 +36,12 @@ module Capistrano
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def gets
|
39
|
-
return unless
|
39
|
+
return unless stdin.tty?
|
40
40
|
|
41
41
|
if echo?
|
42
|
-
|
42
|
+
stdin.gets
|
43
43
|
else
|
44
|
-
|
44
|
+
stdin.noecho(&:gets).tap { $stdout.print "\n" }
|
45
45
|
end
|
46
46
|
rescue Errno::EIO
|
47
47
|
# when stdio gets closed
|
@@ -49,7 +49,11 @@ module Capistrano
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def question
|
52
|
-
if default.nil?
|
52
|
+
if prompt && default.nil?
|
53
|
+
I18n.t(:question_prompt, key: prompt, scope: :capistrano)
|
54
|
+
elsif prompt
|
55
|
+
I18n.t(:question_prompt_default, key: prompt, default_value: default, scope: :capistrano)
|
56
|
+
elsif default.nil?
|
53
57
|
I18n.t(:question, key: key, scope: :capistrano)
|
54
58
|
else
|
55
59
|
I18n.t(:question_default, key: key, default_value: default, scope: :capistrano)
|
@@ -59,6 +63,14 @@ module Capistrano
|
|
59
63
|
def echo?
|
60
64
|
(options || {}).fetch(:echo, true)
|
61
65
|
end
|
66
|
+
|
67
|
+
def stdin
|
68
|
+
(options || {}).fetch(:stdin, $stdin)
|
69
|
+
end
|
70
|
+
|
71
|
+
def prompt
|
72
|
+
(options || {}).fetch(:prompt, nil)
|
73
|
+
end
|
62
74
|
end
|
63
75
|
end
|
64
76
|
end
|
data/lib/capistrano/dsl.rb
CHANGED
data/lib/capistrano/i18n.rb
CHANGED
@@ -12,6 +12,8 @@ en = {
|
|
12
12
|
written_file: "create %{file}",
|
13
13
|
question: "Please enter %{key}: ",
|
14
14
|
question_default: "Please enter %{key} (%{default_value}): ",
|
15
|
+
question_prompt: "%{key}: ",
|
16
|
+
question_prompt_default: "%{key} (%{default_value}): ",
|
15
17
|
keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
|
16
18
|
skip_cleanup: "Skipping cleanup of invalid releases on %{host}; unexpected foldername found (should be timestamp)",
|
17
19
|
wont_delete_current_release: "Current release was marked for being removed but it's going to be skipped on %{host}",
|
data/lib/capistrano/scm/git.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "capistrano/scm/plugin"
|
2
2
|
require "cgi"
|
3
|
+
require "securerandom"
|
3
4
|
require "shellwords"
|
4
5
|
require "uri"
|
5
6
|
|
@@ -7,10 +8,9 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
7
8
|
def set_defaults
|
8
9
|
set_if_empty :git_shallow_clone, false
|
9
10
|
set_if_empty :git_wrapper_path, lambda {
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
"#{fetch(:tmp_dir)}/git-ssh-#{suffix}.sh"
|
11
|
+
# Use a unique name that won't collide with other deployments, and
|
12
|
+
# that cannot be guessed by other processes that have access to /tmp.
|
13
|
+
"#{fetch(:tmp_dir)}/git-ssh-#{SecureRandom.hex(10)}.sh"
|
14
14
|
}
|
15
15
|
set_if_empty :git_environmental_variables, lambda {
|
16
16
|
{
|
@@ -18,6 +18,8 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
18
18
|
git_ssh: fetch(:git_wrapper_path)
|
19
19
|
}
|
20
20
|
}
|
21
|
+
set_if_empty :git_max_concurrent_connections, 10
|
22
|
+
set_if_empty :git_wait_interval, 0
|
21
23
|
end
|
22
24
|
|
23
25
|
def register_hooks
|
@@ -58,6 +60,10 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
63
|
+
def verify_commit
|
64
|
+
git :"verify-commit", fetch_revision
|
65
|
+
end
|
66
|
+
|
61
67
|
def archive_to_release_path
|
62
68
|
if (tree = fetch(:repo_tree))
|
63
69
|
tree = tree.slice %r#^/?(.*?)/?$#, 1
|
@@ -4,9 +4,9 @@ git_plugin = self
|
|
4
4
|
namespace :git do
|
5
5
|
desc "Upload the git wrapper script, this script guarantees that we can script git without getting an interactive prompt"
|
6
6
|
task :wrapper do
|
7
|
-
on release_roles
|
7
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
8
8
|
execute :mkdir, "-p", File.dirname(fetch(:git_wrapper_path)).shellescape
|
9
|
-
upload! StringIO.new("#!/bin/sh -e\nexec /usr/bin/ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no \"$@\"\n"), fetch(:git_wrapper_path)
|
9
|
+
upload! StringIO.new("#!/bin/sh -e\nexec /usr/bin/env ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no \"$@\"\n"), fetch(:git_wrapper_path)
|
10
10
|
execute :chmod, "700", fetch(:git_wrapper_path).shellescape
|
11
11
|
end
|
12
12
|
end
|
@@ -14,7 +14,7 @@ namespace :git do
|
|
14
14
|
desc "Check that the repository is reachable"
|
15
15
|
task check: :'git:wrapper' do
|
16
16
|
fetch(:branch)
|
17
|
-
on release_roles
|
17
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
18
18
|
with fetch(:git_environmental_variables) do
|
19
19
|
git_plugin.check_repo_is_reachable
|
20
20
|
end
|
@@ -23,7 +23,7 @@ namespace :git do
|
|
23
23
|
|
24
24
|
desc "Clone the repo to the cache"
|
25
25
|
task clone: :'git:wrapper' do
|
26
|
-
on release_roles
|
26
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
27
27
|
if git_plugin.repo_mirror_exists?
|
28
28
|
info t(:mirror_exists, at: repo_path)
|
29
29
|
else
|
@@ -38,10 +38,11 @@ namespace :git do
|
|
38
38
|
|
39
39
|
desc "Update the repo mirror to reflect the origin state"
|
40
40
|
task update: :'git:clone' do
|
41
|
-
on release_roles
|
41
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
42
42
|
within repo_path do
|
43
43
|
with fetch(:git_environmental_variables) do
|
44
44
|
git_plugin.update_mirror
|
45
|
+
git_plugin.verify_commit if fetch(:git_verify_commit)
|
45
46
|
end
|
46
47
|
end
|
47
48
|
end
|
@@ -49,7 +50,7 @@ namespace :git do
|
|
49
50
|
|
50
51
|
desc "Copy repo to releases"
|
51
52
|
task create_release: :'git:update' do
|
52
|
-
on release_roles
|
53
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
53
54
|
with fetch(:git_environmental_variables) do
|
54
55
|
within repo_path do
|
55
56
|
execute :mkdir, "-p", release_path
|
@@ -61,7 +62,7 @@ namespace :git do
|
|
61
62
|
|
62
63
|
desc "Determine the revision that will be deployed"
|
63
64
|
task :set_current_revision do
|
64
|
-
on release_roles
|
65
|
+
on release_roles(:all), in: :groups, limit: fetch(:git_max_concurrent_connections), wait: fetch(:git_wait_interval) do
|
65
66
|
within repo_path do
|
66
67
|
with fetch(:git_environmental_variables) do
|
67
68
|
set :current_revision, git_plugin.fetch_revision
|
@@ -168,8 +168,9 @@ namespace :deploy do
|
|
168
168
|
debug t(:no_current_release, host: host.to_s)
|
169
169
|
end
|
170
170
|
if directories.any?
|
171
|
-
|
172
|
-
|
171
|
+
directories.each_slice(100) do |directories_batch|
|
172
|
+
execute :rm, "-rf", *directories_batch
|
173
|
+
end
|
173
174
|
else
|
174
175
|
info t(:no_old_releases, host: host.to_s, keep_releases: fetch(:keep_releases))
|
175
176
|
end
|
data/lib/capistrano/version.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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,12 +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,
|
7
|
-
let(:question_without_echo) { Question.new(key, default, echo: false) }
|
8
|
-
let(:question_without_default) { Question.new(key, nil) }
|
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") }
|
9
11
|
let(:default) { :default }
|
10
12
|
let(:key) { :branch }
|
11
|
-
let(:
|
13
|
+
let(:stdin) { stub(tty?: true) }
|
12
14
|
|
13
15
|
describe ".new" do
|
14
16
|
it "takes a key, default, options" do
|
@@ -22,15 +24,15 @@ module Capistrano
|
|
22
24
|
|
23
25
|
it "returns the echoed value" do
|
24
26
|
$stdout.expects(:print).with("Please enter branch (default): ")
|
25
|
-
|
26
|
-
|
27
|
+
stdin.expects(:gets).returns(branch)
|
28
|
+
stdin.expects(:noecho).never
|
27
29
|
|
28
30
|
expect(question.call).to eq(branch)
|
29
31
|
end
|
30
32
|
|
31
33
|
it "returns the value but does not echo it" do
|
32
34
|
$stdout.expects(:print).with("Please enter branch (default): ")
|
33
|
-
|
35
|
+
stdin.expects(:noecho).returns(branch)
|
34
36
|
$stdout.expects(:print).with("\n")
|
35
37
|
|
36
38
|
expect(question_without_echo.call).to eq(branch)
|
@@ -38,11 +40,27 @@ module Capistrano
|
|
38
40
|
|
39
41
|
it "returns the value but has no default between parenthesis" do
|
40
42
|
$stdout.expects(:print).with("Please enter branch: ")
|
41
|
-
|
42
|
-
|
43
|
+
stdin.expects(:gets).returns(branch)
|
44
|
+
stdin.expects(:noecho).never
|
43
45
|
|
44
46
|
expect(question_without_default.call).to eq(branch)
|
45
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
|
46
64
|
end
|
47
65
|
|
48
66
|
context "value is not entered" do
|
@@ -50,7 +68,7 @@ module Capistrano
|
|
50
68
|
|
51
69
|
before do
|
52
70
|
$stdout.expects(:print).with("Please enter branch (default): ")
|
53
|
-
|
71
|
+
stdin.expects(:gets).returns("")
|
54
72
|
end
|
55
73
|
|
56
74
|
it "returns the default as the value" do
|
@@ -58,10 +76,10 @@ module Capistrano
|
|
58
76
|
end
|
59
77
|
end
|
60
78
|
|
61
|
-
context "tty unavailable" do
|
79
|
+
context "tty unavailable", capture_io: true do
|
62
80
|
before do
|
63
|
-
|
64
|
-
|
81
|
+
stdin.expects(:gets).never
|
82
|
+
stdin.expects(:tty?).returns(false)
|
65
83
|
end
|
66
84
|
|
67
85
|
it "returns the default as the value" do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require "spec_helper"
|
2
|
+
require "capistrano/scm"
|
2
3
|
|
3
4
|
module Capistrano
|
4
5
|
class Configuration
|
@@ -24,12 +25,12 @@ module Capistrano
|
|
24
25
|
expect { resolver.resolve }.to output(/will not load the git scm/i).to_stderr
|
25
26
|
end
|
26
27
|
|
27
|
-
it "activates the git scm" do
|
28
|
+
it "activates the git scm", capture_io: true do
|
28
29
|
resolver.resolve
|
29
30
|
expect(Rake::Task["git:wrapper"]).not_to be_nil
|
30
31
|
end
|
31
32
|
|
32
|
-
it "sets :scm to :git" do
|
33
|
+
it "sets :scm to :git", capture_io: true do
|
33
34
|
resolver.resolve
|
34
35
|
expect(fetch(:scm)).to eq(:git)
|
35
36
|
end
|
@@ -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
|
@@ -74,7 +74,7 @@ module Capistrano
|
|
74
74
|
Rake::Task.clear
|
75
75
|
end
|
76
76
|
|
77
|
-
it "has an doctor:variables task that calls VariablesDoctor" do
|
77
|
+
it "has an doctor:variables task that calls VariablesDoctor", capture_io: true do
|
78
78
|
VariablesDoctor.any_instance.expects(:call)
|
79
79
|
Rake::Task["doctor:variables"].invoke
|
80
80
|
end
|