capistrano 3.6.0 → 3.7.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/issue_template.md +19 -0
  3. data/.github/pull_request_template.md +26 -0
  4. data/.gitignore +1 -0
  5. data/.travis.yml +10 -2
  6. data/CHANGELOG.md +63 -1
  7. data/DEVELOPMENT.md +7 -1
  8. data/Dangerfile +54 -0
  9. data/README.md +4 -5
  10. data/capistrano.gemspec +3 -2
  11. data/features/support/vagrant_helpers.rb +3 -5
  12. data/lib/capistrano/all.rb +1 -0
  13. data/lib/capistrano/configuration/host_filter.rb +1 -1
  14. data/lib/capistrano/configuration/plugin_installer.rb +20 -2
  15. data/lib/capistrano/configuration/role_filter.rb +1 -1
  16. data/lib/capistrano/configuration/scm_resolver.rb +144 -0
  17. data/lib/capistrano/configuration/validated_variables.rb +48 -13
  18. data/lib/capistrano/configuration/variables.rb +0 -8
  19. data/lib/capistrano/configuration.rb +30 -3
  20. data/lib/capistrano/defaults.rb +3 -1
  21. data/lib/capistrano/doctor/variables_doctor.rb +1 -1
  22. data/lib/capistrano/dsl/env.rb +2 -9
  23. data/lib/capistrano/dsl/paths.rb +1 -1
  24. data/lib/capistrano/dsl/task_enhancements.rb +0 -8
  25. data/lib/capistrano/dsl.rb +2 -1
  26. data/lib/capistrano/i18n.rb +1 -0
  27. data/lib/capistrano/scm/git.rb +73 -0
  28. data/lib/capistrano/scm/hg.rb +48 -0
  29. data/lib/capistrano/scm/plugin.rb +13 -0
  30. data/lib/capistrano/scm/svn.rb +47 -0
  31. data/lib/capistrano/{tasks → scm/tasks}/git.rake +9 -24
  32. data/lib/capistrano/{tasks → scm/tasks}/hg.rake +11 -10
  33. data/lib/capistrano/{tasks → scm/tasks}/svn.rake +11 -10
  34. data/lib/capistrano/setup.rb +1 -1
  35. data/lib/capistrano/tasks/deploy.rake +4 -5
  36. data/lib/capistrano/templates/Capfile +18 -7
  37. data/lib/capistrano/templates/deploy.rb.erb +7 -10
  38. data/lib/capistrano/templates/stage.rb.erb +8 -8
  39. data/lib/capistrano/version.rb +1 -1
  40. data/lib/capistrano/version_validator.rb +2 -5
  41. data/spec/lib/capistrano/configuration/host_filter_spec.rb +5 -0
  42. data/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
  43. data/spec/lib/capistrano/configuration/role_filter_spec.rb +17 -1
  44. data/spec/lib/capistrano/configuration_spec.rb +61 -2
  45. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +0 -7
  46. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +0 -15
  47. data/spec/lib/capistrano/scm/git_spec.rb +131 -0
  48. data/spec/lib/capistrano/scm/hg_spec.rb +104 -0
  49. data/spec/lib/capistrano/scm/svn_spec.rb +116 -0
  50. data/spec/lib/capistrano/scm_spec.rb +1 -1
  51. metadata +37 -19
  52. data/features/remote_file_task.feature +0 -14
  53. data/issue_template.md +0 -21
  54. data/lib/capistrano/git.rb +0 -54
  55. data/lib/capistrano/hg.rb +0 -43
  56. data/lib/capistrano/svn.rb +0 -42
  57. data/spec/lib/capistrano/git_spec.rb +0 -109
  58. data/spec/lib/capistrano/hg_spec.rb +0 -90
  59. data/spec/lib/capistrano/svn_spec.rb +0 -105
@@ -102,12 +102,33 @@ module Capistrano
102
102
  end
103
103
  end
104
104
 
105
+ def configure_scm
106
+ Capistrano::Configuration::SCMResolver.new.resolve
107
+ end
108
+
105
109
  def timestamp
106
110
  @timestamp ||= Time.now.utc
107
111
  end
108
112
 
113
+ def add_filter(filter=nil, &block)
114
+ if block
115
+ raise ArgumentError, "Both a block and an object were given" if filter
116
+
117
+ filter = Object.new
118
+ def filter.filter(servers)
119
+ block.call(servers)
120
+ end
121
+ elsif !filter.respond_to? :filter
122
+ raise TypeError, "Provided custom filter <#{filter.inspect}> does " \
123
+ "not have a public 'filter' method"
124
+ end
125
+ @custom_filters ||= []
126
+ @custom_filters << filter
127
+ end
128
+
109
129
  def setup_filters
110
- @filters = cmdline_filters.clone
130
+ @filters = cmdline_filters
131
+ @filters += @custom_filters if @custom_filters
111
132
  @filters << Filter.new(:role, ENV["ROLES"]) if ENV["ROLES"]
112
133
  @filters << Filter.new(:host, ENV["HOSTS"]) if ENV["HOSTS"]
113
134
  fh = fetch_for(:filter, {}) || {}
@@ -130,8 +151,14 @@ module Capistrano
130
151
  fetch(:sshkit_backend) == SSHKit::Backend::Printer
131
152
  end
132
153
 
133
- def install_plugin(plugin, load_hooks: true)
134
- installer.install(plugin, load_hooks: load_hooks)
154
+ def install_plugin(plugin, load_hooks: true, load_immediately: false)
155
+ installer.install(plugin,
156
+ load_hooks: load_hooks,
157
+ load_immediately: load_immediately)
158
+ end
159
+
160
+ def scm_plugin_installed?
161
+ installer.scm_installed?
135
162
  end
136
163
 
137
164
  def servers
@@ -18,7 +18,9 @@ end
18
18
  end
19
19
  end
20
20
 
21
- set_if_empty :scm, :git
21
+ # We use a special :_default_git value so that SCMResolver can tell whether the
22
+ # default has been replaced by the user via `set`.
23
+ set_if_empty :scm, Capistrano::Configuration::SCMResolver::DEFAULT_GIT
22
24
  set_if_empty :branch, "master"
23
25
  set_if_empty :deploy_to, -> { "/var/www/#{fetch(:application)}" }
24
26
  set_if_empty :tmp_dir, "/tmp"
@@ -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, :git_strategy, :hg_strategy, :svn_strategy].freeze
10
+ WHITELIST = [:application, :repo_url].freeze
11
11
  private_constant :WHITELIST
12
12
 
13
13
  include Capistrano::Doctor::OutputHelpers
@@ -7,15 +7,8 @@ module Capistrano
7
7
  def_delegators :env,
8
8
  :configure_backend, :fetch, :set, :set_if_empty, :delete,
9
9
  :ask, :role, :server, :primary, :validate, :append,
10
- :remove, :dry_run?, :install_plugin
11
-
12
- def is_question?(key)
13
- env.is_question?(key)
14
- end
15
-
16
- def any?(key)
17
- env.any?(key)
18
- end
10
+ :remove, :dry_run?, :install_plugin, :any?, :is_question?,
11
+ :configure_scm, :scm_plugin_installed?
19
12
 
20
13
  def roles(*names)
21
14
  env.roles_for(names.flatten)
@@ -19,7 +19,7 @@ module Capistrano
19
19
  end
20
20
 
21
21
  def release_path
22
- fetch(:release_path, current_path)
22
+ fetch(:release_path) { current_path }
23
23
  end
24
24
 
25
25
  def set_release_path(timestamp=now)
@@ -17,14 +17,6 @@ module Capistrano
17
17
  end
18
18
  end
19
19
 
20
- def remote_file(task)
21
- warn("[Deprecation Warning] `remote_file` is deprecated and will be "\
22
- "removed in Capistrano 3.7.0")
23
-
24
- target_roles = task.delete(:roles) { :all }
25
- define_remote_file_task(task, target_roles)
26
- end
27
-
28
20
  def define_remote_file_task(task, target_roles)
29
21
  Capistrano::UploadTask.define_task(task) do |t|
30
22
  prerequisite_file = t.prerequisites.first
@@ -13,7 +13,8 @@ module Capistrano
13
13
 
14
14
  def invoke(task_name, *args)
15
15
  task = Rake::Task[task_name]
16
- if task && task.already_invoked
16
+ # NOTE: We access instance variable since the accessor was only added recently. Once Capistrano depends on rake 11+, we can revert the following line
17
+ if task && task.instance_variable_get(:@already_invoked)
17
18
  file, line, = caller.first.split(":")
18
19
  colors = SSHKit::Color.new($stderr)
19
20
  $stderr.puts colors.colorize("Skipping task `#{task_name}'.", :yellow)
@@ -12,6 +12,7 @@ en = {
12
12
  written_file: "create %{file}",
13
13
  question: "Please enter %{key} (%{default_value}): ",
14
14
  keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
15
+ skip_cleanup: "Skipping cleanup of old releases on %{host}; unexpected foldername found (should be timestamp)",
15
16
  no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
16
17
  linked_file_does_not_exist: "linked file %{file} does not exist on %{host}",
17
18
  cannot_rollback: "There are no older releases to rollback to",
@@ -0,0 +1,73 @@
1
+ require "capistrano/scm/plugin"
2
+
3
+ class Capistrano::SCM::Git < Capistrano::SCM::Plugin
4
+ def set_defaults
5
+ set_if_empty :git_shallow_clone, false
6
+ set_if_empty :git_wrapper_path, lambda {
7
+ # Try to avoid permissions issues when multiple users deploy the same app
8
+ # 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+/, "-")
10
+ "#{fetch(:tmp_dir)}/git-ssh-#{suffix}.sh"
11
+ }
12
+ set_if_empty :git_environmental_variables, lambda {
13
+ {
14
+ git_askpass: "/bin/echo",
15
+ git_ssh: fetch(:git_wrapper_path)
16
+ }
17
+ }
18
+ end
19
+
20
+ def register_hooks
21
+ after "deploy:new_release_path", "git:create_release"
22
+ before "deploy:check", "git:check"
23
+ before "deploy:set_current_revision", "git:set_current_revision"
24
+ end
25
+
26
+ def define_tasks
27
+ eval_rakefile File.expand_path("../tasks/git.rake", __FILE__)
28
+ end
29
+
30
+ def repo_mirror_exists?
31
+ backend.test " [ -f #{repo_path}/HEAD ] "
32
+ end
33
+
34
+ def check_repo_is_reachable
35
+ git :'ls-remote --heads', repo_url
36
+ end
37
+
38
+ def clone_repo
39
+ if (depth = fetch(:git_shallow_clone))
40
+ git :clone, "--mirror", "--depth", depth, "--no-single-branch", repo_url, repo_path.to_s
41
+ else
42
+ git :clone, "--mirror", repo_url, repo_path.to_s
43
+ end
44
+ end
45
+
46
+ def update_mirror
47
+ # Note: Requires git version 1.9 or greater
48
+ if (depth = fetch(:git_shallow_clone))
49
+ git :fetch, "--depth", depth, "origin", fetch(:branch)
50
+ else
51
+ git :remote, :update, "--prune"
52
+ end
53
+ end
54
+
55
+ def archive_to_release_path
56
+ if (tree = fetch(:repo_tree))
57
+ tree = tree.slice %r#^/?(.*?)/?$#, 1
58
+ components = tree.split("/").size
59
+ git :archive, fetch(:branch), tree, "| #{SSHKit.config.command_map[:tar]} -x --strip-components #{components} -f - -C", release_path
60
+ else
61
+ git :archive, fetch(:branch), "| #{SSHKit.config.command_map[:tar]} -x -f - -C", release_path
62
+ end
63
+ end
64
+
65
+ def fetch_revision
66
+ backend.capture(:git, "rev-list --max-count=1 #{fetch(:branch)}")
67
+ end
68
+
69
+ def git(*args)
70
+ args.unshift :git
71
+ backend.execute(*args)
72
+ end
73
+ end
@@ -0,0 +1,48 @@
1
+ require "capistrano/scm/plugin"
2
+
3
+ class Capistrano::SCM::Hg < Capistrano::SCM::Plugin
4
+ def register_hooks
5
+ after "deploy:new_release_path", "hg:create_release"
6
+ before "deploy:check", "hg:check"
7
+ before "deploy:set_current_revision", "hg:set_current_revision"
8
+ end
9
+
10
+ def define_tasks
11
+ eval_rakefile File.expand_path("../tasks/hg.rake", __FILE__)
12
+ end
13
+
14
+ def hg(*args)
15
+ args.unshift(:hg)
16
+ backend.execute(*args)
17
+ end
18
+
19
+ def repo_mirror_exists?
20
+ backend.test " [ -d #{repo_path}/.hg ] "
21
+ end
22
+
23
+ def check_repo_is_reachable
24
+ hg "id", repo_url
25
+ end
26
+
27
+ def clone_repo
28
+ hg "clone", "--noupdate", repo_url, repo_path.to_s
29
+ end
30
+
31
+ def update_mirror
32
+ hg "pull"
33
+ end
34
+
35
+ def archive_to_release_path
36
+ if (tree = fetch(:repo_tree))
37
+ tree = tree.slice %r#^/?(.*?)/?$#, 1
38
+ 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
+ else
41
+ hg "archive", release_path, "--rev", fetch(:branch)
42
+ end
43
+ end
44
+
45
+ def fetch_revision
46
+ backend.capture(:hg, "log --rev #{fetch(:branch)} --template \"{node}\n\"")
47
+ end
48
+ end
@@ -0,0 +1,13 @@
1
+ require "capistrano/plugin"
2
+ require "capistrano/scm"
3
+
4
+ # Base class for all built-in and third-party SCM plugins. Notice that this
5
+ # class doesn't really do anything other than provide an `scm?` predicate. This
6
+ # tells Capistrano that the plugin provides SCM functionality. All other plugin
7
+ # features are inherited from Capistrano::Plugin.
8
+ #
9
+ class Capistrano::SCM::Plugin < Capistrano::Plugin
10
+ def scm?
11
+ true
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ require "capistrano/scm/plugin"
2
+
3
+ class Capistrano::SCM::Svn < Capistrano::SCM::Plugin
4
+ def register_hooks
5
+ after "deploy:new_release_path", "svn:create_release"
6
+ before "deploy:check", "svn:check"
7
+ before "deploy:set_current_revision", "svn:set_current_revision"
8
+ end
9
+
10
+ def define_tasks
11
+ eval_rakefile File.expand_path("../tasks/svn.rake", __FILE__)
12
+ end
13
+
14
+ def svn(*args)
15
+ args.unshift(:svn)
16
+ args.push "--username #{fetch(:svn_username)}" if fetch(:svn_username)
17
+ args.push "--password #{fetch(:svn_password)}" if fetch(:svn_password)
18
+ args.push "--revision #{fetch(:svn_revision)}" if fetch(:svn_revision)
19
+ backend.execute(*args)
20
+ end
21
+
22
+ def repo_mirror_exists?
23
+ backend.test " [ -d #{repo_path}/.svn ] "
24
+ end
25
+
26
+ def check_repo_is_reachable
27
+ svn_username = fetch(:svn_username) ? "--username #{fetch(:svn_username)}" : ""
28
+ svn_password = fetch(:svn_password) ? "--password #{fetch(:svn_password)}" : ""
29
+ backend.test :svn, :info, repo_url, svn_username, svn_password
30
+ end
31
+
32
+ def clone_repo
33
+ svn :checkout, repo_url, repo_path.to_s
34
+ end
35
+
36
+ def update_mirror
37
+ svn :update
38
+ end
39
+
40
+ def archive_to_release_path
41
+ svn :export, "--force", ".", release_path
42
+ end
43
+
44
+ def fetch_revision
45
+ backend.capture(:svnversion, repo_path.to_s)
46
+ end
47
+ end
@@ -1,22 +1,7 @@
1
- namespace :git do
2
- def strategy
3
- @strategy ||= Capistrano::Git.new(self, fetch(:git_strategy, Capistrano::Git::DefaultStrategy))
4
- end
5
-
6
- set :git_wrapper_path, lambda {
7
- # Try to avoid permissions issues when multiple users deploy the same app
8
- # 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("-")
10
- "#{fetch(:tmp_dir)}/git-ssh-#{suffix}.sh"
11
- }
12
-
13
- set :git_environmental_variables, lambda {
14
- {
15
- git_askpass: "/bin/echo",
16
- git_ssh: fetch(:git_wrapper_path)
17
- }
18
- }
1
+ # This trick lets us access the Git plugin within `on` blocks.
2
+ git_plugin = self
19
3
 
4
+ namespace :git do
20
5
  desc "Upload the git wrapper script, this script guarantees that we can script git without getting an interactive prompt"
21
6
  task :wrapper do
22
7
  on release_roles :all do
@@ -31,7 +16,7 @@ namespace :git do
31
16
  fetch(:branch)
32
17
  on release_roles :all do
33
18
  with fetch(:git_environmental_variables) do
34
- strategy.check
19
+ git_plugin.check_repo_is_reachable
35
20
  end
36
21
  end
37
22
  end
@@ -39,12 +24,12 @@ namespace :git do
39
24
  desc "Clone the repo to the cache"
40
25
  task clone: :'git:wrapper' do
41
26
  on release_roles :all do
42
- if strategy.test
27
+ if git_plugin.repo_mirror_exists?
43
28
  info t(:mirror_exists, at: repo_path)
44
29
  else
45
30
  within deploy_path do
46
31
  with fetch(:git_environmental_variables) do
47
- strategy.clone
32
+ git_plugin.clone_repo
48
33
  end
49
34
  end
50
35
  end
@@ -56,7 +41,7 @@ namespace :git do
56
41
  on release_roles :all do
57
42
  within repo_path do
58
43
  with fetch(:git_environmental_variables) do
59
- strategy.update
44
+ git_plugin.update_mirror
60
45
  end
61
46
  end
62
47
  end
@@ -68,7 +53,7 @@ namespace :git do
68
53
  with fetch(:git_environmental_variables) do
69
54
  within repo_path do
70
55
  execute :mkdir, "-p", release_path
71
- strategy.release
56
+ git_plugin.archive_to_release_path
72
57
  end
73
58
  end
74
59
  end
@@ -79,7 +64,7 @@ namespace :git do
79
64
  on release_roles :all do
80
65
  within repo_path do
81
66
  with fetch(:git_environmental_variables) do
82
- set :current_revision, strategy.fetch_revision
67
+ set :current_revision, git_plugin.fetch_revision
83
68
  end
84
69
  end
85
70
  end
@@ -1,23 +1,24 @@
1
- namespace :hg do
2
- def strategy
3
- @strategy ||= Capistrano::Hg.new(self, fetch(:hg_strategy, Capistrano::Hg::DefaultStrategy))
4
- end
1
+ # TODO: this is nearly identical to git.rake. DRY up?
5
2
 
3
+ # This trick lets us access the Hg plugin within `on` blocks.
4
+ hg_plugin = self
5
+
6
+ namespace :hg do
6
7
  desc "Check that the repo is reachable"
7
8
  task :check do
8
9
  on release_roles :all do
9
- strategy.check
10
+ hg_plugin.check_repo_is_reachable
10
11
  end
11
12
  end
12
13
 
13
14
  desc "Clone the repo to the cache"
14
15
  task :clone do
15
16
  on release_roles :all do
16
- if strategy.test
17
+ if hg_plugin.repo_mirror_exists?
17
18
  info t(:mirror_exists, at: repo_path)
18
19
  else
19
20
  within deploy_path do
20
- strategy.clone
21
+ hg_plugin.clone_repo
21
22
  end
22
23
  end
23
24
  end
@@ -27,7 +28,7 @@ namespace :hg do
27
28
  task update: :'hg:clone' do
28
29
  on release_roles :all do
29
30
  within repo_path do
30
- strategy.update
31
+ hr.update_mirror
31
32
  end
32
33
  end
33
34
  end
@@ -36,7 +37,7 @@ namespace :hg do
36
37
  task create_release: :'hg:update' do
37
38
  on release_roles :all do
38
39
  within repo_path do
39
- strategy.release
40
+ hg_plugin.archive_to_release_path
40
41
  end
41
42
  end
42
43
  end
@@ -45,7 +46,7 @@ namespace :hg do
45
46
  task :set_current_revision do
46
47
  on release_roles :all do
47
48
  within repo_path do
48
- set :current_revision, strategy.fetch_revision
49
+ set :current_revision, hg_plugin.fetch_revision
49
50
  end
50
51
  end
51
52
  end
@@ -1,23 +1,24 @@
1
- namespace :svn do
2
- def strategy
3
- @strategy ||= Capistrano::Svn.new(self, fetch(:svn_strategy, Capistrano::Svn::DefaultStrategy))
4
- end
1
+ # TODO: this is nearly identical to git.rake. DRY up?
5
2
 
3
+ # This trick lets us access the Svn plugin within `on` blocks.
4
+ svn_plugin = self
5
+
6
+ namespace :svn do
6
7
  desc "Check that the repo is reachable"
7
8
  task :check do
8
9
  on release_roles :all do
9
- strategy.check
10
+ svn_plugin.check_repo_is_reachable
10
11
  end
11
12
  end
12
13
 
13
14
  desc "Clone the repo to the cache"
14
15
  task :clone do
15
16
  on release_roles :all do
16
- if strategy.test
17
+ if svn_plugin.repo_mirror_exists?
17
18
  info t(:mirror_exists, at: repo_path)
18
19
  else
19
20
  within deploy_path do
20
- strategy.clone
21
+ svn_plugin.clone_repo
21
22
  end
22
23
  end
23
24
  end
@@ -27,7 +28,7 @@ namespace :svn do
27
28
  task update: :'svn:clone' do
28
29
  on release_roles :all do
29
30
  within repo_path do
30
- strategy.update
31
+ svn_plugin.update_mirror
31
32
  end
32
33
  end
33
34
  end
@@ -36,7 +37,7 @@ namespace :svn do
36
37
  task create_release: :'svn:update' do
37
38
  on release_roles :all do
38
39
  within repo_path do
39
- strategy.release
40
+ svn_plugin.archive_to_release_path
40
41
  end
41
42
  end
42
43
  end
@@ -45,7 +46,7 @@ namespace :svn do
45
46
  task :set_current_revision do
46
47
  on release_roles :all do
47
48
  within repo_path do
48
- set :current_revision, strategy.fetch_revision
49
+ set :current_revision, svn_plugin.fetch_revision
49
50
  end
50
51
  end
51
52
  end
@@ -27,7 +27,7 @@ stages.each do |stage|
27
27
  load deploy_config_path
28
28
  load stage_config_path.join("#{stage}.rb")
29
29
  end
30
- load "capistrano/#{fetch(:scm)}.rb"
30
+ configure_scm
31
31
  I18n.locale = fetch(:locale, :en)
32
32
  configure_backend
33
33
  end
@@ -26,7 +26,6 @@ namespace :deploy do
26
26
  end
27
27
 
28
28
  task updating: :new_release_path do
29
- invoke "#{scm}:create_release"
30
29
  invoke "deploy:set_current_revision"
31
30
  invoke "deploy:symlink:shared"
32
31
  end
@@ -53,7 +52,6 @@ namespace :deploy do
53
52
 
54
53
  desc "Check required files and directories exist"
55
54
  task :check do
56
- invoke "#{scm}:check"
57
55
  invoke "deploy:check:directories"
58
56
  invoke "deploy:check:linked_dirs"
59
57
  invoke "deploy:check:make_linked_dirs"
@@ -150,8 +148,10 @@ namespace :deploy do
150
148
  desc "Clean up old releases"
151
149
  task :cleanup do
152
150
  on release_roles :all do |host|
153
- releases = capture(:ls, "-xtr", releases_path).split
154
- if releases.count >= fetch(:keep_releases)
151
+ releases = capture(:ls, "-x", releases_path).split
152
+ if !(releases.all? { |e| /^\d{14}$/ =~ e })
153
+ warn t(:skip_cleanup, host: host.to_s)
154
+ elsif releases.count >= fetch(:keep_releases)
155
155
  info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: releases.count)
156
156
  directories = (releases - releases.last(fetch(:keep_releases)))
157
157
  if directories.any?
@@ -225,7 +225,6 @@ namespace :deploy do
225
225
 
226
226
  desc "Place a REVISION file with the current revision SHA in the current release path"
227
227
  task :set_current_revision do
228
- invoke "#{scm}:set_current_revision"
229
228
  on release_roles(:all) do
230
229
  within release_path do
231
230
  execute :echo, "\"#{fetch(:current_revision)}\" >> REVISION"
@@ -4,6 +4,17 @@ require "capistrano/setup"
4
4
  # Include default deployment tasks
5
5
  require "capistrano/deploy"
6
6
 
7
+ # Load the SCM plugin appropriate to your project:
8
+ #
9
+ # require "capistrano/scm/hg"
10
+ # install_plugin Capistrano::SCM::Hg
11
+ # or
12
+ # require "capistrano/scm/svn"
13
+ # install_plugin Capistrano::SCM::Svn
14
+ # or
15
+ require "capistrano/scm/git"
16
+ install_plugin Capistrano::SCM::Git
17
+
7
18
  # Include tasks from other gems included in your Gemfile
8
19
  #
9
20
  # For documentation on these, see for example:
@@ -15,13 +26,13 @@ require "capistrano/deploy"
15
26
  # https://github.com/capistrano/rails
16
27
  # https://github.com/capistrano/passenger
17
28
  #
18
- # require 'capistrano/rvm'
19
- # require 'capistrano/rbenv'
20
- # require 'capistrano/chruby'
21
- # require 'capistrano/bundler'
22
- # require 'capistrano/rails/assets'
23
- # require 'capistrano/rails/migrations'
24
- # require 'capistrano/passenger'
29
+ # require "capistrano/rvm"
30
+ # require "capistrano/rbenv"
31
+ # require "capistrano/chruby"
32
+ # require "capistrano/bundler"
33
+ # require "capistrano/rails/assets"
34
+ # require "capistrano/rails/migrations"
35
+ # require "capistrano/passenger"
25
36
 
26
37
  # Load custom tasks from `lib/capistrano/tasks` if you have any defined
27
38
  Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
@@ -1,33 +1,30 @@
1
1
  # config valid only for current version of Capistrano
2
- lock '<%= Capistrano::VERSION %>'
2
+ lock "<%= Capistrano::VERSION %>"
3
3
 
4
- set :application, 'my_app_name'
5
- set :repo_url, 'git@example.com:me/my_repo.git'
4
+ set :application, "my_app_name"
5
+ set :repo_url, "git@example.com:me/my_repo.git"
6
6
 
7
7
  # Default branch is :master
8
8
  # ask :branch, `git rev-parse --abbrev-ref HEAD`.chomp
9
9
 
10
10
  # Default deploy_to directory is /var/www/my_app_name
11
- # set :deploy_to, '/var/www/my_app_name'
12
-
13
- # Default value for :scm is :git
14
- # set :scm, :git
11
+ # set :deploy_to, "/var/www/my_app_name"
15
12
 
16
13
  # Default value for :format is :airbrussh.
17
14
  # set :format, :airbrussh
18
15
 
19
16
  # You can configure the Airbrussh format using :format_options.
20
17
  # These are the defaults.
21
- # set :format_options, command_output: true, log_file: 'log/capistrano.log', color: :auto, truncate: :auto
18
+ # set :format_options, command_output: true, log_file: "log/capistrano.log", color: :auto, truncate: :auto
22
19
 
23
20
  # Default value for :pty is false
24
21
  # set :pty, true
25
22
 
26
23
  # Default value for :linked_files is []
27
- # append :linked_files, 'config/database.yml', 'config/secrets.yml'
24
+ # append :linked_files, "config/database.yml", "config/secrets.yml"
28
25
 
29
26
  # Default value for linked_dirs is []
30
- # append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'public/system'
27
+ # append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "public/system"
31
28
 
32
29
  # Default value for default_env is {}
33
30
  # set :default_env, { path: "/opt/ruby/bin:$PATH" }