capistrano 3.7.2 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9e2c0975c618c32c327228eb811012535f44223
4
- data.tar.gz: 545d241645e8487733e8edb9d163ef92fa738e93
3
+ metadata.gz: 0bf003b9169b22ddd324533323c2ccd5a3873aec
4
+ data.tar.gz: 5fd9c7d79004cbc67c515903f280b74f80bd3c87
5
5
  SHA512:
6
- metadata.gz: d92ccd5bb651b77426b30e5acffe766178882a3dc97e0dfca0bbeed55a6e9fc9fd3d47d1e8c35fcee20fc62ec46d0815b09f5a7107fed4767859b465ce50ef83
7
- data.tar.gz: a588aea0a342852d0f9836aeb1d10ea87485650743671343d59878b4291cd014f1bea122600583933377bdf0444be43d271fa302803109be5cc41d1a7bbbc1da
6
+ metadata.gz: a89eca74965d39609a504a1032356e66a762847d69ff6a45951585a3e1002f3575ab0a9837dc545fe7536f8b38297f83ad93e894ac454bda219e07b847c9797c
7
+ data.tar.gz: 2b0fa5af27a608a391476c31d57640e875b97408e503b279bca9fd0bf05b83aa54ab0dad693f51f29ede1261ed77ba76206d55189810f6d27ee3a62c1792228f
@@ -1,6 +1,12 @@
1
1
  # Capistrano 3.x Changelog
2
2
 
3
- Reverse Chronological Order:
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
- # Adapted from https://github.com/ruby-grape/danger/blob/master/Dangerfile
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
@@ -103,7 +103,7 @@ Add Capistrano to your project's Gemfile:
103
103
 
104
104
  ``` ruby
105
105
  group :development do
106
- gem "capistrano", "~> 3.7"
106
+ gem "capistrano", "~> 3.8"
107
107
  end
108
108
  ```
109
109
 
@@ -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 '#{permissions_test}'")).to be_success
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
@@ -1,7 +1,3 @@
1
1
  #!/usr/bin/env cap
2
2
  include Capistrano::DSL
3
3
  require "capistrano/install"
4
-
5
- require "capistrano/harrow"
6
- require "capistrano/harrow/plugin"
7
- install_plugin Capistrano::Harrow::Plugin
@@ -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} << capfile
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
- I18n.t(:question, key: key, default_value: default, scope: :capistrano)
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
- return if scm_plugin_installed?
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
@@ -64,6 +64,7 @@ module Capistrano
64
64
  end
65
65
 
66
66
  def matches?(other)
67
+ # This matching logic must stay in sync with `Servers#add_host`.
67
68
  hostname == other.hostname && port == other.port
68
69
  end
69
70
 
@@ -9,11 +9,15 @@ module Capistrano
9
9
 
10
10
  def add_host(host, properties={})
11
11
  new_host = Server[host]
12
- if (server = servers.find { |s| s.matches? new_host })
13
- server.user = new_host.user if new_host.user
14
- server.with(properties)
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
- servers << new_host.with(properties)
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(servers)
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
- servers.each { |server| yield server }
60
+ servers_by_key.values.each { |server| yield server }
57
61
  end
58
62
 
59
63
  private
60
64
 
61
- def servers
62
- @servers ||= []
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
@@ -36,20 +36,7 @@ module Capistrano
36
36
  end
37
37
 
38
38
  def repo_url
39
- require "cgi"
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
@@ -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} (%{default_value}): ",
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}",
@@ -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("-").gsub(/\s+/, "-")
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', repo_url, "HEAD"
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", repo_url, repo_path.to_s
43
+ git :clone, "--mirror", "--depth", depth, "--no-single-branch", git_repo_url, repo_path.to_s
41
44
  else
42
- git :clone, "--mirror", repo_url, repo_path.to_s
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", repo_url
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
@@ -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
- hg "archive --type tgz -p . -I", tree, "--rev", fetch(:branch), "| tar -x --strip-components #{components} -f - -C", release_path
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
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module Capistrano
2
- VERSION = "3.7.2".freeze
2
+ VERSION = "3.8.0".freeze
3
3
  end
@@ -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(5)
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
- backend.expects(:execute).with(:hg, "archive --type tgz -p . -I", "tree", "--rev", :branch, "| tar -x --strip-components 1 -f - -C", "path")
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
@@ -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
- Dir.chdir(test_app_path) do
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
- `whoami`.chomp
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.7.2
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-01-28 00:00:00.000000000 Z
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