capistrano 3.7.2 → 3.8.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/CHANGELOG.md +35 -1
- data/Dangerfile +1 -54
- data/README.md +1 -1
- data/capistrano.gemspec +0 -1
- data/features/step_definitions/assertions.rb +4 -2
- data/features/step_definitions/cap_commands.rb +4 -0
- data/features/subdirectory.feature +9 -0
- data/lib/Capfile +0 -4
- data/lib/capistrano/application.rb +10 -2
- data/lib/capistrano/configuration/question.rb +5 -1
- data/lib/capistrano/configuration/scm_resolver.rb +5 -1
- data/lib/capistrano/configuration/server.rb +1 -0
- data/lib/capistrano/configuration/servers.rb +14 -8
- data/lib/capistrano/doctor/variables_doctor.rb +1 -1
- data/lib/capistrano/dsl/paths.rb +1 -14
- data/lib/capistrano/i18n.rb +2 -1
- data/lib/capistrano/scm/git.rb +23 -5
- data/lib/capistrano/scm/hg.rb +8 -1
- data/lib/capistrano/scm/svn.rb +9 -0
- data/lib/capistrano/scm/tasks/git.rake +2 -2
- data/lib/capistrano/version.rb +1 -1
- data/spec/lib/capistrano/configuration/question_spec.rb +11 -4
- data/spec/lib/capistrano/configuration/scm_resolver_spec.rb +54 -0
- data/spec/lib/capistrano/configuration/servers_spec.rb +2 -1
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +8 -0
- data/spec/lib/capistrano/scm/git_spec.rb +25 -0
- data/spec/lib/capistrano/scm/hg_spec.rb +6 -1
- data/spec/lib/capistrano/scm/svn_spec.rb +21 -0
- data/spec/support/test_app.rb +7 -5
- metadata +6 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bf003b9169b22ddd324533323c2ccd5a3873aec
|
4
|
+
data.tar.gz: 5fd9c7d79004cbc67c515903f280b74f80bd3c87
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89eca74965d39609a504a1032356e66a762847d69ff6a45951585a3e1002f3575ab0a9837dc545fe7536f8b38297f83ad93e894ac454bda219e07b847c9797c
|
7
|
+
data.tar.gz: 2b0fa5af27a608a391476c31d57640e875b97408e503b279bca9fd0bf05b83aa54ab0dad693f51f29ede1261ed77ba76206d55189810f6d27ee3a62c1792228f
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,12 @@
|
|
1
1
|
# Capistrano 3.x Changelog
|
2
2
|
|
3
|
-
|
3
|
+
All notable changes to this project will be documented in this file, in reverse chronological order. This project adheres to [Semantic Versioning](http://semver.org).
|
4
|
+
|
5
|
+
**Capistrano uses a six-week release cadence.** Every six weeks, give or take, any changes in master will be published as a new rubygems version. If you'd like to use a feature or fix that is in master and you can't wait for the next planned release, put this in your project's Gemfile to use the master branch directly:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem "capistrano", :github => "capistrano/capistrano"
|
9
|
+
```
|
4
10
|
|
5
11
|
## master
|
6
12
|
|
@@ -8,6 +14,34 @@ https://github.com/capistrano/capistrano/compare/v3.7.2...HEAD
|
|
8
14
|
|
9
15
|
* Your contribution here!
|
10
16
|
|
17
|
+
## `3.8.0` (2017-03-10)
|
18
|
+
|
19
|
+
https://github.com/capistrano/capistrano/compare/v3.7.2...v3.8.0
|
20
|
+
|
21
|
+
### Potentially breaking changes:
|
22
|
+
|
23
|
+
* [#1846](https://github.com/capistrano/capistrano/pull/1846): add_host will add a new host in a case where it used to incorrectly update an existing one (potentially breaking) [(@dbenamy)](https://github.com/dbenamy)
|
24
|
+
|
25
|
+
### New features:
|
26
|
+
|
27
|
+
* [#1860](https://github.com/capistrano/capistrano/pull/1860): Allow cap to be run within subdir and still work - [@mattbrictson](https://github.com/mattbrictson)
|
28
|
+
|
29
|
+
### Fixes:
|
30
|
+
|
31
|
+
* [#1835](https://github.com/capistrano/capistrano/pull/1835): Stopped printing parenthesis in ask prompt if no default or nil was passed as argument [(@chamini2)](https://github.com/chamini2)
|
32
|
+
* [#1840](https://github.com/capistrano/capistrano/pull/1840): Git plugin: shellescape git_wrapper_path [(@olleolleolle)](https://github.com/olleolleolle)
|
33
|
+
* [#1843](https://github.com/capistrano/capistrano/pull/1843): Properly shell escape git:wrapper steps - [@mattbrictson](https://github.com/mattbrictson)
|
34
|
+
* [#1846](https://github.com/capistrano/capistrano/pull/1846): Defining a role is now O(hosts) instead of O(hosts^2) [(@dbenamy)](https://github.com/dbenamy)
|
35
|
+
* Run `svn switch` to work with svn branches if repo_url is changed
|
36
|
+
* [#1856](https://github.com/capistrano/capistrano/pull/1856): Fix hg repo_tree implementation - [@mattbrictson](https://github.com/mattbrictson)
|
37
|
+
* [#1857](https://github.com/capistrano/capistrano/pull/1857): Don't emit doctor warning when repo_tree is set - [@mattbrictson](https://github.com/mattbrictson)
|
38
|
+
|
39
|
+
### Other changes:
|
40
|
+
|
41
|
+
* [capistrano-harrow#4](https://github.com/harrowio/capistrano-harrow/issues/4): Drop dependency on `capistrano-harrow` gem. Gem can still be installed separately [(@leehambley)](https://github.com/leehambley)
|
42
|
+
* [#1859](https://github.com/capistrano/capistrano/pull/1859): Move git-specific repo_url logic into git plugin - [@mattbrictson](https://github.com/mattbrictson)
|
43
|
+
* [#1858](https://github.com/capistrano/capistrano/pull/1858): Unset the :scm variable when an SCM plugin is used - [@mattbrictson](https://github.com/mattbrictson)
|
44
|
+
|
11
45
|
## `3.7.2` (2017-01-27)
|
12
46
|
|
13
47
|
https://github.com/capistrano/capistrano/compare/v3.7.1...v3.7.2
|
data/Dangerfile
CHANGED
@@ -1,54 +1 @@
|
|
1
|
-
|
2
|
-
# Q: What is a Dangerfile, anyway? A: See http://danger.systems/
|
3
|
-
|
4
|
-
# ------------------------------------------------------------------------------
|
5
|
-
# Additional pull request data
|
6
|
-
# ------------------------------------------------------------------------------
|
7
|
-
project_name = github.pr_json["base"]["repo"]["name"]
|
8
|
-
pr_number = github.pr_json["number"]
|
9
|
-
pr_url = github.pr_json["_links"]["html"]["href"]
|
10
|
-
|
11
|
-
# ------------------------------------------------------------------------------
|
12
|
-
# What changed?
|
13
|
-
# ------------------------------------------------------------------------------
|
14
|
-
has_lib_changes = !git.modified_files.grep(/^lib/).empty?
|
15
|
-
has_test_changes = !git.modified_files.grep(/^(features|spec)/).empty?
|
16
|
-
has_changelog_changes = git.modified_files.include?("CHANGELOG.md")
|
17
|
-
|
18
|
-
# ------------------------------------------------------------------------------
|
19
|
-
# You've made changes to lib, but didn't write any tests?
|
20
|
-
# ------------------------------------------------------------------------------
|
21
|
-
if has_lib_changes && !has_test_changes
|
22
|
-
warn("There are code changes, but no corresponding tests. "\
|
23
|
-
"Please include tests if this PR introduces any modifications in "\
|
24
|
-
"#{project_name}'s behavior.",
|
25
|
-
:sticky => false)
|
26
|
-
end
|
27
|
-
|
28
|
-
# ------------------------------------------------------------------------------
|
29
|
-
# Have you updated CHANGELOG.md?
|
30
|
-
# ------------------------------------------------------------------------------
|
31
|
-
if !has_changelog_changes && has_lib_changes
|
32
|
-
markdown <<-MARKDOWN
|
33
|
-
Here's an example of a CHANGELOG.md entry (place it immediately under the `* Your contribution here!` line):
|
34
|
-
|
35
|
-
```markdown
|
36
|
-
* [##{pr_number}](#{pr_url}): #{github.pr_title} - [@#{github.pr_author}](https://github.com/#{github.pr_author}).
|
37
|
-
```
|
38
|
-
MARKDOWN
|
39
|
-
warn("Please update CHANGELOG.md with a description of your changes. "\
|
40
|
-
"If this PR is not a user-facing change (e.g. just refactoring), "\
|
41
|
-
"you can disregard this.", :sticky => false)
|
42
|
-
end
|
43
|
-
|
44
|
-
# ------------------------------------------------------------------------------
|
45
|
-
# Did you remove the CHANGELOG's "Your contribution here!" line?
|
46
|
-
# ------------------------------------------------------------------------------
|
47
|
-
if has_changelog_changes
|
48
|
-
unless IO.read("CHANGELOG.md") =~ /^\* Your contribution here/i
|
49
|
-
fail(
|
50
|
-
"Please put the `* Your contribution here!` line back into CHANGELOG.md.",
|
51
|
-
:sticky => false
|
52
|
-
)
|
53
|
-
end
|
54
|
-
end
|
1
|
+
danger.import_dangerfile(github: "capistrano/danger")
|
data/README.md
CHANGED
data/capistrano.gemspec
CHANGED
@@ -24,7 +24,6 @@ Gem::Specification.new do |gem|
|
|
24
24
|
gem.add_dependency "i18n"
|
25
25
|
gem.add_dependency "rake", ">= 10.0.0"
|
26
26
|
gem.add_dependency "sshkit", ">= 1.9.0"
|
27
|
-
gem.add_dependency "capistrano-harrow"
|
28
27
|
|
29
28
|
gem.add_development_dependency "danger"
|
30
29
|
gem.add_development_dependency "mocha"
|
@@ -1,10 +1,12 @@
|
|
1
|
+
require "shellwords"
|
2
|
+
|
1
3
|
Then(/^references in the remote repo are listed$/) do
|
2
4
|
expect(@output).to include("refs/heads/master")
|
3
5
|
end
|
4
6
|
|
5
7
|
Then(/^git wrapper permissions are 0700$/) do
|
6
|
-
permissions_test = %Q([ $(stat -c "%a" #{TestApp.git_wrapper_path}) == "700" ])
|
7
|
-
expect(vagrant_cli_command("ssh -c
|
8
|
+
permissions_test = %Q([ $(stat -c "%a" #{TestApp.git_wrapper_path.shellescape}) == "700" ])
|
9
|
+
expect(vagrant_cli_command("ssh -c #{permissions_test.shellescape}")).to be_success
|
8
10
|
end
|
9
11
|
|
10
12
|
Then(/^the shared path is created$/) do
|
@@ -2,6 +2,10 @@ When(/^I run cap "(.*?)"$/) do |task|
|
|
2
2
|
@success, @output = TestApp.cap(task)
|
3
3
|
end
|
4
4
|
|
5
|
+
When(/^I run cap "(.*?)" within the "(.*?)" directory$/) do |task, directory|
|
6
|
+
@success, @output = TestApp.cap(task, directory)
|
7
|
+
end
|
8
|
+
|
5
9
|
When(/^I run cap "(.*?)" as part of a release$/) do |task|
|
6
10
|
TestApp.cap("deploy:new_release_path #{task}")
|
7
11
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Feature: cap can be run from a subdirectory, and will still find the Capfile
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given a test app with the default configuration
|
5
|
+
And servers with the roles app and web
|
6
|
+
|
7
|
+
Scenario: Running cap from a subdirectory
|
8
|
+
When I run cap "git:check" within the "config" directory
|
9
|
+
Then the task is successful
|
data/lib/Capfile
CHANGED
@@ -2,7 +2,7 @@ module Capistrano
|
|
2
2
|
class Application < Rake::Application
|
3
3
|
def initialize
|
4
4
|
super
|
5
|
-
@rakefiles = %w{capfile Capfile capfile.rb Capfile.rb}
|
5
|
+
@rakefiles = %w{capfile Capfile capfile.rb Capfile.rb}
|
6
6
|
end
|
7
7
|
|
8
8
|
def name
|
@@ -76,6 +76,15 @@ module Capistrano
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
# allows the `cap install` task to load without a capfile
|
80
|
+
def find_rakefile_location
|
81
|
+
if (location = super).nil?
|
82
|
+
[capfile, Dir.pwd]
|
83
|
+
else
|
84
|
+
location
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
79
88
|
private
|
80
89
|
|
81
90
|
def backtrace_pattern
|
@@ -96,7 +105,6 @@ module Capistrano
|
|
96
105
|
super
|
97
106
|
end
|
98
107
|
|
99
|
-
# allows the `cap install` task to load without a capfile
|
100
108
|
def capfile
|
101
109
|
File.expand_path(File.join(File.dirname(__FILE__), "..", "Capfile"))
|
102
110
|
end
|
@@ -46,7 +46,11 @@ module Capistrano
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def question
|
49
|
-
|
49
|
+
if default.nil?
|
50
|
+
I18n.t(:question, key: key, scope: :capistrano)
|
51
|
+
else
|
52
|
+
I18n.t(:question_default, key: key, default_value: default, scope: :capistrano)
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
56
|
def echo?
|
@@ -29,8 +29,12 @@ module Capistrano
|
|
29
29
|
set(:scm, :git) if using_default_scm?
|
30
30
|
|
31
31
|
print_deprecation_warnings_if_applicable
|
32
|
+
|
32
33
|
# Note that `scm_plugin_installed?` comes from Capistrano::DSL
|
33
|
-
|
34
|
+
if scm_plugin_installed?
|
35
|
+
delete(:scm)
|
36
|
+
return
|
37
|
+
end
|
34
38
|
|
35
39
|
if built_in_scm_name?
|
36
40
|
load_built_in_scm
|
@@ -9,11 +9,15 @@ module Capistrano
|
|
9
9
|
|
10
10
|
def add_host(host, properties={})
|
11
11
|
new_host = Server[host]
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
new_host.port = properties[:port] if properties.key?(:port)
|
13
|
+
# This matching logic must stay in sync with `Server#matches?`.
|
14
|
+
key = ServerKey.new(new_host.hostname, new_host.port)
|
15
|
+
existing = servers_by_key[key]
|
16
|
+
if existing
|
17
|
+
existing.user = new_host.user if new_host.user
|
18
|
+
existing.with(properties)
|
15
19
|
else
|
16
|
-
|
20
|
+
servers_by_key[key] = new_host.with(properties)
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
@@ -26,7 +30,7 @@ module Capistrano
|
|
26
30
|
|
27
31
|
def roles_for(names)
|
28
32
|
options = extract_options(names)
|
29
|
-
s = Filter.new(:role, names).filter(
|
33
|
+
s = Filter.new(:role, names).filter(servers_by_key.values)
|
30
34
|
s.select { |server| server.select?(options) }
|
31
35
|
end
|
32
36
|
|
@@ -53,13 +57,15 @@ module Capistrano
|
|
53
57
|
end
|
54
58
|
|
55
59
|
def each
|
56
|
-
|
60
|
+
servers_by_key.values.each { |server| yield server }
|
57
61
|
end
|
58
62
|
|
59
63
|
private
|
60
64
|
|
61
|
-
|
62
|
-
|
65
|
+
ServerKey = Struct.new(:hostname, :port)
|
66
|
+
|
67
|
+
def servers_by_key
|
68
|
+
@servers_by_key ||= {}
|
63
69
|
end
|
64
70
|
|
65
71
|
def extract_options(array)
|
@@ -7,7 +7,7 @@ module Capistrano
|
|
7
7
|
class VariablesDoctor
|
8
8
|
# These are keys that have no default values in Capistrano, but are
|
9
9
|
# nonetheless expected to be set.
|
10
|
-
WHITELIST = [:application, :repo_url].freeze
|
10
|
+
WHITELIST = [:application, :repo_url, :repo_tree].freeze
|
11
11
|
private_constant :WHITELIST
|
12
12
|
|
13
13
|
include Capistrano::Doctor::OutputHelpers
|
data/lib/capistrano/dsl/paths.rb
CHANGED
@@ -36,20 +36,7 @@ module Capistrano
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def repo_url
|
39
|
-
|
40
|
-
require "uri"
|
41
|
-
if fetch(:git_http_username) && fetch(:git_http_password)
|
42
|
-
URI.parse(fetch(:repo_url)).tap do |repo_uri|
|
43
|
-
repo_uri.user = fetch(:git_http_username)
|
44
|
-
repo_uri.password = CGI.escape(fetch(:git_http_password))
|
45
|
-
end.to_s
|
46
|
-
elsif fetch(:git_http_username)
|
47
|
-
URI.parse(fetch(:repo_url)).tap do |repo_uri|
|
48
|
-
repo_uri.user = fetch(:git_http_username)
|
49
|
-
end.to_s
|
50
|
-
else
|
51
|
-
fetch(:repo_url)
|
52
|
-
end
|
39
|
+
fetch(:repo_url)
|
53
40
|
end
|
54
41
|
|
55
42
|
def repo_path
|
data/lib/capistrano/i18n.rb
CHANGED
@@ -10,7 +10,8 @@ en = {
|
|
10
10
|
finished: "Finished",
|
11
11
|
stage_not_set: "Stage not set, please call something such as `cap production deploy`, where production is a stage you have defined.",
|
12
12
|
written_file: "create %{file}",
|
13
|
-
question: "Please enter %{key}
|
13
|
+
question: "Please enter %{key}: ",
|
14
|
+
question_default: "Please enter %{key} (%{default_value}): ",
|
14
15
|
keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
|
15
16
|
skip_cleanup: "Skipping cleanup of old releases on %{host}; unexpected foldername found (should be timestamp)",
|
16
17
|
no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
|
data/lib/capistrano/scm/git.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require "capistrano/scm/plugin"
|
2
|
+
require "cgi"
|
3
|
+
require "shellwords"
|
4
|
+
require "uri"
|
2
5
|
|
3
6
|
class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
4
7
|
def set_defaults
|
@@ -6,7 +9,7 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
6
9
|
set_if_empty :git_wrapper_path, lambda {
|
7
10
|
# Try to avoid permissions issues when multiple users deploy the same app
|
8
11
|
# by using different file names in the same dir for each deployer and stage.
|
9
|
-
suffix = [:application, :stage, :local_user].map { |key| fetch(key).to_s }.join("-")
|
12
|
+
suffix = [:application, :stage, :local_user].map { |key| fetch(key).to_s }.join("-")
|
10
13
|
"#{fetch(:tmp_dir)}/git-ssh-#{suffix}.sh"
|
11
14
|
}
|
12
15
|
set_if_empty :git_environmental_variables, lambda {
|
@@ -32,20 +35,20 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
32
35
|
end
|
33
36
|
|
34
37
|
def check_repo_is_reachable
|
35
|
-
git :'ls-remote',
|
38
|
+
git :'ls-remote', git_repo_url, "HEAD"
|
36
39
|
end
|
37
40
|
|
38
41
|
def clone_repo
|
39
42
|
if (depth = fetch(:git_shallow_clone))
|
40
|
-
git :clone, "--mirror", "--depth", depth, "--no-single-branch",
|
43
|
+
git :clone, "--mirror", "--depth", depth, "--no-single-branch", git_repo_url, repo_path.to_s
|
41
44
|
else
|
42
|
-
git :clone, "--mirror",
|
45
|
+
git :clone, "--mirror", git_repo_url, repo_path.to_s
|
43
46
|
end
|
44
47
|
end
|
45
48
|
|
46
49
|
def update_mirror
|
47
50
|
# Update the origin URL if necessary.
|
48
|
-
git :remote, "set-url", "origin",
|
51
|
+
git :remote, "set-url", "origin", git_repo_url
|
49
52
|
|
50
53
|
# Note: Requires git version 1.9 or greater
|
51
54
|
if (depth = fetch(:git_shallow_clone))
|
@@ -73,4 +76,19 @@ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
|
|
73
76
|
args.unshift :git
|
74
77
|
backend.execute(*args)
|
75
78
|
end
|
79
|
+
|
80
|
+
def git_repo_url
|
81
|
+
if fetch(:git_http_username) && fetch(:git_http_password)
|
82
|
+
URI.parse(repo_url).tap do |repo_uri|
|
83
|
+
repo_uri.user = fetch(:git_http_username)
|
84
|
+
repo_uri.password = CGI.escape(fetch(:git_http_password))
|
85
|
+
end.to_s
|
86
|
+
elsif fetch(:git_http_username)
|
87
|
+
URI.parse(repo_url).tap do |repo_uri|
|
88
|
+
repo_uri.user = fetch(:git_http_username)
|
89
|
+
end.to_s
|
90
|
+
else
|
91
|
+
repo_url
|
92
|
+
end
|
93
|
+
end
|
76
94
|
end
|
data/lib/capistrano/scm/hg.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "capistrano/scm/plugin"
|
2
|
+
require "securerandom"
|
2
3
|
|
3
4
|
class Capistrano::SCM::Hg < Capistrano::SCM::Plugin
|
4
5
|
def register_hooks
|
@@ -36,7 +37,13 @@ class Capistrano::SCM::Hg < Capistrano::SCM::Plugin
|
|
36
37
|
if (tree = fetch(:repo_tree))
|
37
38
|
tree = tree.slice %r#^/?(.*?)/?$#, 1
|
38
39
|
components = tree.split("/").size
|
39
|
-
|
40
|
+
temp_tar = "#{fetch(:tmp_dir)}/#{SecureRandom.hex(10)}.tar"
|
41
|
+
|
42
|
+
hg "archive -p . -I", tree, "--rev", fetch(:branch), temp_tar
|
43
|
+
|
44
|
+
backend.execute :mkdir, "-p", release_path
|
45
|
+
backend.execute :tar, "-x --strip-components #{components} -f", temp_tar, "-C", release_path
|
46
|
+
backend.execute :rm, temp_tar
|
40
47
|
else
|
41
48
|
hg "archive", release_path, "--rev", fetch(:branch)
|
42
49
|
end
|
data/lib/capistrano/scm/svn.rb
CHANGED
@@ -34,6 +34,9 @@ class Capistrano::SCM::Svn < Capistrano::SCM::Plugin
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def update_mirror
|
37
|
+
# Switch the repository URL if necessary.
|
38
|
+
repo_mirror_url = fetch_repo_mirror_url
|
39
|
+
svn :switch, repo_url unless repo_mirror_url == repo_url
|
37
40
|
svn :update
|
38
41
|
end
|
39
42
|
|
@@ -44,4 +47,10 @@ class Capistrano::SCM::Svn < Capistrano::SCM::Plugin
|
|
44
47
|
def fetch_revision
|
45
48
|
backend.capture(:svnversion, repo_path.to_s)
|
46
49
|
end
|
50
|
+
|
51
|
+
def fetch_repo_mirror_url
|
52
|
+
backend.capture(:svn, :info, repo_path.to_s).each_line do |line|
|
53
|
+
return $1 if /\AURL: (.*)\n\z/ =~ line
|
54
|
+
end
|
55
|
+
end
|
47
56
|
end
|
@@ -5,9 +5,9 @@ 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
7
|
on release_roles :all do
|
8
|
-
execute :mkdir, "-p", File.dirname(fetch(:git_wrapper_path))
|
8
|
+
execute :mkdir, "-p", File.dirname(fetch(:git_wrapper_path)).shellescape
|
9
9
|
upload! StringIO.new("#!/bin/sh -e\nexec /usr/bin/ssh -o PasswordAuthentication=no -o StrictHostKeyChecking=no \"$@\"\n"), fetch(:git_wrapper_path)
|
10
|
-
execute :chmod, "700", fetch(:git_wrapper_path)
|
10
|
+
execute :chmod, "700", fetch(:git_wrapper_path).shellescape
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
data/lib/capistrano/version.rb
CHANGED
@@ -5,6 +5,7 @@ module Capistrano
|
|
5
5
|
describe Question do
|
6
6
|
let(:question) { Question.new(key, default, options) }
|
7
7
|
let(:question_without_echo) { Question.new(key, default, echo: false) }
|
8
|
+
let(:question_without_default) { Question.new(key, nil) }
|
8
9
|
let(:default) { :default }
|
9
10
|
let(:key) { :branch }
|
10
11
|
let(:options) { nil }
|
@@ -19,11 +20,8 @@ module Capistrano
|
|
19
20
|
context "value is entered" do
|
20
21
|
let(:branch) { "branch" }
|
21
22
|
|
22
|
-
before do
|
23
|
-
$stdout.expects(:print).with("Please enter branch (default): ")
|
24
|
-
end
|
25
|
-
|
26
23
|
it "returns the echoed value" do
|
24
|
+
$stdout.expects(:print).with("Please enter branch (default): ")
|
27
25
|
$stdin.expects(:gets).returns(branch)
|
28
26
|
$stdin.expects(:noecho).never
|
29
27
|
|
@@ -31,11 +29,20 @@ module Capistrano
|
|
31
29
|
end
|
32
30
|
|
33
31
|
it "returns the value but does not echo it" do
|
32
|
+
$stdout.expects(:print).with("Please enter branch (default): ")
|
34
33
|
$stdin.expects(:noecho).returns(branch)
|
35
34
|
$stdout.expects(:print).with("\n")
|
36
35
|
|
37
36
|
expect(question_without_echo.call).to eq(branch)
|
38
37
|
end
|
38
|
+
|
39
|
+
it "returns the value but has no default between parenthesis" do
|
40
|
+
$stdout.expects(:print).with("Please enter branch: ")
|
41
|
+
$stdin.expects(:gets).returns(branch)
|
42
|
+
$stdin.expects(:noecho).never
|
43
|
+
|
44
|
+
expect(question_without_default.call).to eq(branch)
|
45
|
+
end
|
39
46
|
end
|
40
47
|
|
41
48
|
context "value is not entered" do
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Capistrano
|
4
|
+
class Configuration
|
5
|
+
describe SCMResolver do
|
6
|
+
include Capistrano::DSL
|
7
|
+
|
8
|
+
let(:resolver) { SCMResolver.new }
|
9
|
+
|
10
|
+
before do
|
11
|
+
Rake::Task.define_task("deploy:check")
|
12
|
+
Rake::Task.define_task("deploy:new_release_path")
|
13
|
+
Rake::Task.define_task("deploy:set_current_revision")
|
14
|
+
set :scm, SCMResolver::DEFAULT_GIT
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
Rake::Task.clear
|
19
|
+
Capistrano::Configuration.reset!
|
20
|
+
end
|
21
|
+
|
22
|
+
context "default scm, no plugin installed" do
|
23
|
+
it "emits a warning" do
|
24
|
+
expect { resolver.resolve }.to output(/will not load the git scm/i).to_stderr
|
25
|
+
end
|
26
|
+
|
27
|
+
it "activates the git scm" do
|
28
|
+
resolver.resolve
|
29
|
+
expect(Rake::Task["git:wrapper"]).not_to be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "sets :scm to :git" do
|
33
|
+
resolver.resolve
|
34
|
+
expect(fetch(:scm)).to eq(:git)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "default scm, git plugin installed" do
|
39
|
+
before do
|
40
|
+
install_plugin Capistrano::SCM::Git
|
41
|
+
end
|
42
|
+
|
43
|
+
it "emits no warning" do
|
44
|
+
expect { resolver.resolve }.not_to output.to_stderr
|
45
|
+
end
|
46
|
+
|
47
|
+
it "deletes :scm" do
|
48
|
+
resolver.resolve
|
49
|
+
expect(fetch(:scm)).to be_nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -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(
|
140
|
+
expect(servers.count).to eq(4)
|
140
141
|
end
|
141
142
|
|
142
143
|
describe "with a :user property" do
|
@@ -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",
|
@@ -27,6 +27,17 @@ module Capistrano
|
|
27
27
|
Capistrano::Configuration.reset!
|
28
28
|
end
|
29
29
|
|
30
|
+
describe "#set_defaults" do
|
31
|
+
it "makes git_wrapper_path using application, stage, and local_user" do
|
32
|
+
env.set(:tmp_dir, "/tmp")
|
33
|
+
env.set(:application, "my_app")
|
34
|
+
env.set(:stage, "staging")
|
35
|
+
env.set(:local_user, "(Git Web User) via ShipIt")
|
36
|
+
subject.set_defaults
|
37
|
+
expect(env.fetch(:git_wrapper_path)).to eq("/tmp/git-ssh-my_app-staging-(Git Web User) via ShipIt.sh")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
30
41
|
describe "#git" do
|
31
42
|
it "should call execute git in the context, with arguments" do
|
32
43
|
backend.expects(:execute).with(:git, :init)
|
@@ -70,6 +81,20 @@ module Capistrano
|
|
70
81
|
|
71
82
|
subject.clone_repo
|
72
83
|
end
|
84
|
+
|
85
|
+
context "with username and password specified" do
|
86
|
+
before do
|
87
|
+
env.set(:git_http_username, "hello")
|
88
|
+
env.set(:git_http_password, "topsecret")
|
89
|
+
env.set(:repo_url, "https://example.com/repo.git")
|
90
|
+
env.set(:repo_path, "path")
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should include the credentials in the url" do
|
94
|
+
backend.expects(:execute).with(:git, :clone, "--mirror", "https://hello:topsecret@example.com/repo.git", "path")
|
95
|
+
subject.clone_repo
|
96
|
+
end
|
97
|
+
end
|
73
98
|
end
|
74
99
|
|
75
100
|
describe "#update_mirror" do
|
@@ -85,8 +85,13 @@ module Capistrano
|
|
85
85
|
env.set(:repo_tree, "tree")
|
86
86
|
env.set(:branch, :branch)
|
87
87
|
env.set(:release_path, "path")
|
88
|
+
env.set(:tmp_dir, "/tmp")
|
88
89
|
|
89
|
-
|
90
|
+
SecureRandom.stubs(:hex).with(10).returns("random")
|
91
|
+
backend.expects(:execute).with(:hg, "archive -p . -I", "tree", "--rev", :branch, "/tmp/random.tar")
|
92
|
+
backend.expects(:execute).with(:mkdir, "-p", "path")
|
93
|
+
backend.expects(:execute).with(:tar, "-x --strip-components 1 -f", "/tmp/random.tar", "-C", "path")
|
94
|
+
backend.expects(:execute).with(:rm, "/tmp/random.tar")
|
90
95
|
|
91
96
|
subject.archive_to_release_path
|
92
97
|
end
|
@@ -71,6 +71,10 @@ module Capistrano
|
|
71
71
|
|
72
72
|
describe "#update_mirror" do
|
73
73
|
it "should run svn update" do
|
74
|
+
env.set(:repo_url, "url")
|
75
|
+
env.set(:repo_path, "path")
|
76
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: url\n")
|
77
|
+
|
74
78
|
env.set(:svn_username, "someuser")
|
75
79
|
env.set(:svn_password, "somepassword")
|
76
80
|
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword")
|
@@ -80,6 +84,10 @@ module Capistrano
|
|
80
84
|
|
81
85
|
context "for specific revision" do
|
82
86
|
it "should run svn update" do
|
87
|
+
env.set(:repo_url, "url")
|
88
|
+
env.set(:repo_path, "path")
|
89
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: url\n")
|
90
|
+
|
83
91
|
env.set(:svn_username, "someuser")
|
84
92
|
env.set(:svn_password, "somepassword")
|
85
93
|
env.set(:svn_revision, "12345")
|
@@ -88,6 +96,19 @@ module Capistrano
|
|
88
96
|
subject.update_mirror
|
89
97
|
end
|
90
98
|
end
|
99
|
+
|
100
|
+
it "should run svn switch if repo_url is changed" do
|
101
|
+
env.set(:repo_url, "url")
|
102
|
+
env.set(:repo_path, "path")
|
103
|
+
backend.expects(:capture).with(:svn, :info, "path").returns("URL: old_url\n")
|
104
|
+
|
105
|
+
env.set(:svn_username, "someuser")
|
106
|
+
env.set(:svn_password, "somepassword")
|
107
|
+
backend.expects(:execute).with(:svn, :switch, "url", "--username someuser", "--password somepassword")
|
108
|
+
backend.expects(:execute).with(:svn, :update, "--username someuser", "--password somepassword")
|
109
|
+
|
110
|
+
subject.update_mirror
|
111
|
+
end
|
91
112
|
end
|
92
113
|
|
93
114
|
describe "#archive_to_release_path" do
|
data/spec/support/test_app.rb
CHANGED
@@ -19,6 +19,7 @@ module TestApp
|
|
19
19
|
set :linked_files, #{linked_files}
|
20
20
|
set :linked_dirs, #{linked_dirs}
|
21
21
|
set :format_options, log_file: nil
|
22
|
+
set :local_user, #{current_user.inspect}
|
22
23
|
CONFIG
|
23
24
|
end
|
24
25
|
|
@@ -89,13 +90,14 @@ module TestApp
|
|
89
90
|
File.open(shared_path.join(path), "w")
|
90
91
|
end
|
91
92
|
|
92
|
-
def cap(task)
|
93
|
-
run "bundle exec cap #{stage} #{task}"
|
93
|
+
def cap(task, subdirectory=nil)
|
94
|
+
run "bundle exec cap #{stage} #{task}", subdirectory
|
94
95
|
end
|
95
96
|
|
96
|
-
def run(command)
|
97
|
+
def run(command, subdirectory=nil)
|
97
98
|
output = nil
|
98
|
-
|
99
|
+
dir = subdirectory ? test_app_path.join(subdirectory) : test_app_path
|
100
|
+
Dir.chdir(dir) do
|
99
101
|
output = `#{command}`
|
100
102
|
end
|
101
103
|
[$CHILD_STATUS.success?, output]
|
@@ -154,7 +156,7 @@ module TestApp
|
|
154
156
|
end
|
155
157
|
|
156
158
|
def current_user
|
157
|
-
|
159
|
+
"(GitHub Web Flow) via ShipIt"
|
158
160
|
end
|
159
161
|
|
160
162
|
def task_dir
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capistrano
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Clements
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2017-
|
12
|
+
date: 2017-03-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: airbrussh
|
@@ -67,20 +67,6 @@ dependencies:
|
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: 1.9.0
|
70
|
-
- !ruby/object:Gem::Dependency
|
71
|
-
name: capistrano-harrow
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '0'
|
77
|
-
type: :runtime
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ">="
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0'
|
84
70
|
- !ruby/object:Gem::Dependency
|
85
71
|
name: danger
|
86
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -176,6 +162,7 @@ files:
|
|
176
162
|
- features/step_definitions/assertions.rb
|
177
163
|
- features/step_definitions/cap_commands.rb
|
178
164
|
- features/step_definitions/setup.rb
|
165
|
+
- features/subdirectory.feature
|
179
166
|
- features/support/env.rb
|
180
167
|
- features/support/remote_command_helpers.rb
|
181
168
|
- features/support/vagrant_helpers.rb
|
@@ -247,6 +234,7 @@ files:
|
|
247
234
|
- spec/lib/capistrano/configuration/plugin_installer_spec.rb
|
248
235
|
- spec/lib/capistrano/configuration/question_spec.rb
|
249
236
|
- spec/lib/capistrano/configuration/role_filter_spec.rb
|
237
|
+
- spec/lib/capistrano/configuration/scm_resolver_spec.rb
|
250
238
|
- spec/lib/capistrano/configuration/server_spec.rb
|
251
239
|
- spec/lib/capistrano/configuration/servers_spec.rb
|
252
240
|
- spec/lib/capistrano/configuration_spec.rb
|
@@ -312,6 +300,7 @@ test_files:
|
|
312
300
|
- features/step_definitions/assertions.rb
|
313
301
|
- features/step_definitions/cap_commands.rb
|
314
302
|
- features/step_definitions/setup.rb
|
303
|
+
- features/subdirectory.feature
|
315
304
|
- features/support/env.rb
|
316
305
|
- features/support/remote_command_helpers.rb
|
317
306
|
- features/support/vagrant_helpers.rb
|
@@ -325,6 +314,7 @@ test_files:
|
|
325
314
|
- spec/lib/capistrano/configuration/plugin_installer_spec.rb
|
326
315
|
- spec/lib/capistrano/configuration/question_spec.rb
|
327
316
|
- spec/lib/capistrano/configuration/role_filter_spec.rb
|
317
|
+
- spec/lib/capistrano/configuration/scm_resolver_spec.rb
|
328
318
|
- spec/lib/capistrano/configuration/server_spec.rb
|
329
319
|
- spec/lib/capistrano/configuration/servers_spec.rb
|
330
320
|
- spec/lib/capistrano/configuration_spec.rb
|