capistrano 3.4.1 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -5
  3. data/.rubocop.yml +49 -0
  4. data/.travis.yml +5 -4
  5. data/CHANGELOG.md +72 -9
  6. data/CONTRIBUTING.md +61 -93
  7. data/DEVELOPMENT.md +122 -0
  8. data/Gemfile +2 -2
  9. data/LICENSE.txt +1 -1
  10. data/README.md +121 -43
  11. data/RELEASING.md +16 -0
  12. data/Rakefile +4 -1
  13. data/bin/cap +1 -1
  14. data/capistrano.gemspec +16 -21
  15. data/features/doctor.feature +11 -0
  16. data/features/step_definitions/assertions.rb +17 -17
  17. data/features/step_definitions/cap_commands.rb +0 -1
  18. data/features/step_definitions/setup.rb +12 -8
  19. data/features/support/env.rb +5 -5
  20. data/features/support/remote_command_helpers.rb +8 -6
  21. data/features/support/vagrant_helpers.rb +5 -4
  22. data/issue_template.md +21 -0
  23. data/lib/Capfile +5 -1
  24. data/lib/capistrano/all.rb +9 -10
  25. data/lib/capistrano/application.rb +36 -26
  26. data/lib/capistrano/configuration.rb +56 -41
  27. data/lib/capistrano/configuration/empty_filter.rb +9 -0
  28. data/lib/capistrano/configuration/filter.rb +18 -47
  29. data/lib/capistrano/configuration/host_filter.rb +30 -0
  30. data/lib/capistrano/configuration/null_filter.rb +9 -0
  31. data/lib/capistrano/configuration/plugin_installer.rb +33 -0
  32. data/lib/capistrano/configuration/question.rb +10 -7
  33. data/lib/capistrano/configuration/role_filter.rb +30 -0
  34. data/lib/capistrano/configuration/server.rb +22 -23
  35. data/lib/capistrano/configuration/servers.rb +6 -7
  36. data/lib/capistrano/configuration/variables.rb +136 -0
  37. data/lib/capistrano/defaults.rb +13 -3
  38. data/lib/capistrano/deploy.rb +1 -1
  39. data/lib/capistrano/doctor.rb +5 -0
  40. data/lib/capistrano/doctor/environment_doctor.rb +19 -0
  41. data/lib/capistrano/doctor/gems_doctor.rb +45 -0
  42. data/lib/capistrano/doctor/output_helpers.rb +79 -0
  43. data/lib/capistrano/doctor/variables_doctor.rb +66 -0
  44. data/lib/capistrano/dotfile.rb +1 -2
  45. data/lib/capistrano/dsl.rb +12 -14
  46. data/lib/capistrano/dsl/env.rb +11 -42
  47. data/lib/capistrano/dsl/paths.rb +12 -13
  48. data/lib/capistrano/dsl/stages.rb +2 -4
  49. data/lib/capistrano/dsl/task_enhancements.rb +5 -7
  50. data/lib/capistrano/framework.rb +1 -1
  51. data/lib/capistrano/git.rb +17 -9
  52. data/lib/capistrano/hg.rb +4 -4
  53. data/lib/capistrano/i18n.rb +24 -24
  54. data/lib/capistrano/immutable_task.rb +29 -0
  55. data/lib/capistrano/install.rb +1 -1
  56. data/lib/capistrano/plugin.rb +95 -0
  57. data/lib/capistrano/scm.rb +7 -20
  58. data/lib/capistrano/setup.rb +19 -5
  59. data/lib/capistrano/svn.rb +9 -5
  60. data/lib/capistrano/tasks/console.rake +4 -8
  61. data/lib/capistrano/tasks/deploy.rake +75 -62
  62. data/lib/capistrano/tasks/doctor.rake +19 -0
  63. data/lib/capistrano/tasks/framework.rake +13 -14
  64. data/lib/capistrano/tasks/git.rake +10 -11
  65. data/lib/capistrano/tasks/hg.rake +7 -7
  66. data/lib/capistrano/tasks/install.rake +14 -15
  67. data/lib/capistrano/tasks/svn.rake +7 -7
  68. data/lib/capistrano/templates/Capfile +3 -3
  69. data/lib/capistrano/templates/deploy.rb.erb +6 -5
  70. data/lib/capistrano/upload_task.rb +1 -1
  71. data/lib/capistrano/version.rb +1 -1
  72. data/lib/capistrano/version_validator.rb +4 -6
  73. data/spec/integration/dsl_spec.rb +286 -239
  74. data/spec/integration_spec_helper.rb +3 -5
  75. data/spec/lib/capistrano/application_spec.rb +22 -14
  76. data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
  77. data/spec/lib/capistrano/configuration/filter_spec.rb +82 -84
  78. data/spec/lib/capistrano/configuration/host_filter_spec.rb +61 -0
  79. data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
  80. data/spec/lib/capistrano/configuration/question_spec.rb +12 -16
  81. data/spec/lib/capistrano/configuration/role_filter_spec.rb +64 -0
  82. data/spec/lib/capistrano/configuration/server_spec.rb +102 -110
  83. data/spec/lib/capistrano/configuration/servers_spec.rb +124 -141
  84. data/spec/lib/capistrano/configuration_spec.rb +150 -61
  85. data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
  86. data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +61 -0
  87. data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
  88. data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +79 -0
  89. data/spec/lib/capistrano/dsl/paths_spec.rb +58 -50
  90. data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +62 -32
  91. data/spec/lib/capistrano/dsl_spec.rb +6 -8
  92. data/spec/lib/capistrano/git_spec.rb +35 -7
  93. data/spec/lib/capistrano/hg_spec.rb +14 -5
  94. data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
  95. data/spec/lib/capistrano/plugin_spec.rb +84 -0
  96. data/spec/lib/capistrano/scm_spec.rb +6 -7
  97. data/spec/lib/capistrano/svn_spec.rb +40 -14
  98. data/spec/lib/capistrano/upload_task_spec.rb +7 -7
  99. data/spec/lib/capistrano/version_validator_spec.rb +37 -45
  100. data/spec/lib/capistrano_spec.rb +2 -3
  101. data/spec/spec_helper.rb +8 -8
  102. data/spec/support/Vagrantfile +9 -10
  103. data/spec/support/tasks/database.rake +3 -3
  104. data/spec/support/tasks/fail.rake +4 -3
  105. data/spec/support/tasks/failed.rake +2 -2
  106. data/spec/support/tasks/plugin.rake +6 -0
  107. data/spec/support/tasks/root.rake +4 -4
  108. data/spec/support/test_app.rb +31 -30
  109. metadata +93 -14
@@ -1,19 +1,17 @@
1
1
  module Capistrano
2
2
  module DSL
3
3
  module Stages
4
-
5
4
  def stages
6
- Dir[stage_definitions].map { |f| File.basename(f, '.rb') }
5
+ Dir[stage_definitions].map { |f| File.basename(f, ".rb") }
7
6
  end
8
7
 
9
8
  def stage_definitions
10
- stage_config_path.join('*.rb')
9
+ stage_config_path.join("*.rb")
11
10
  end
12
11
 
13
12
  def stage_set?
14
13
  !!fetch(:stage, false)
15
14
  end
16
-
17
15
  end
18
16
  end
19
17
  end
@@ -1,4 +1,4 @@
1
- require 'capistrano/upload_task'
1
+ require "capistrano/upload_task"
2
2
 
3
3
  module Capistrano
4
4
  module TaskEnhancements
@@ -9,9 +9,9 @@ module Capistrano
9
9
 
10
10
  def after(task, post_task, *args, &block)
11
11
  Rake::Task.define_task(post_task, *args, &block) if block_given?
12
- post_task = Rake::Task[post_task]
13
- Rake::Task[task].enhance do
14
- post_task.invoke
12
+ task = Rake::Task[task]
13
+ task.enhance do
14
+ Rake.application.lookup(post_task, task.scope).invoke
15
15
  end
16
16
  end
17
17
 
@@ -31,7 +31,6 @@ module Capistrano
31
31
  upload! File.open(prerequisite_file), file
32
32
  end
33
33
  end
34
-
35
34
  end
36
35
  end
37
36
 
@@ -54,13 +53,12 @@ module Capistrano
54
53
 
55
54
  def exit_deploy_because_of_exception(ex)
56
55
  warn t(:deploy_failed, ex: ex.message)
57
- invoke 'deploy:failed'
56
+ invoke "deploy:failed"
58
57
  exit(false)
59
58
  end
60
59
 
61
60
  def deploying?
62
61
  fetch(:deploying, false)
63
62
  end
64
-
65
63
  end
66
64
  end
@@ -1,2 +1,2 @@
1
1
  load File.expand_path("../tasks/framework.rake", __FILE__)
2
- require 'capistrano/install'
2
+ require "capistrano/install"
@@ -1,14 +1,13 @@
1
1
  load File.expand_path("../tasks/git.rake", __FILE__)
2
2
 
3
- require 'capistrano/scm'
3
+ require "capistrano/scm"
4
4
 
5
5
  class Capistrano::Git < Capistrano::SCM
6
-
7
6
  # execute git with argument in the context
8
7
  #
9
8
  def git(*args)
10
9
  args.unshift :git
11
- context.execute *args
10
+ context.execute(*args)
12
11
  end
13
12
 
14
13
  # The Capistrano default strategy for git. You should want to use this.
@@ -22,25 +21,34 @@ class Capistrano::Git < Capistrano::SCM
22
21
  end
23
22
 
24
23
  def clone
25
- git :clone, '--mirror', repo_url, repo_path
24
+ if (depth = fetch(:git_shallow_clone))
25
+ git :clone, "--mirror", "--depth", depth, "--no-single-branch", repo_url, repo_path
26
+ else
27
+ git :clone, "--mirror", repo_url, repo_path
28
+ end
26
29
  end
27
30
 
28
31
  def update
29
- git :remote, :update
32
+ # Note: Requires git version 1.9 or greater
33
+ if (depth = fetch(:git_shallow_clone))
34
+ git :fetch, "--depth", depth, "origin", fetch(:branch)
35
+ else
36
+ git :remote, :update, "--prune"
37
+ end
30
38
  end
31
39
 
32
40
  def release
33
- if tree = fetch(:repo_tree)
41
+ if (tree = fetch(:repo_tree))
34
42
  tree = tree.slice %r#^/?(.*?)/?$#, 1
35
- components = tree.split('/').size
43
+ components = tree.split("/").size
36
44
  git :archive, fetch(:branch), tree, "| tar -x --strip-components #{components} -f - -C", release_path
37
45
  else
38
- git :archive, fetch(:branch), '| tar -x -f - -C', release_path
46
+ git :archive, fetch(:branch), "| tar -x -f - -C", release_path
39
47
  end
40
48
  end
41
49
 
42
50
  def fetch_revision
43
- context.capture(:git, "rev-list --max-count=1 --abbrev-commit #{fetch(:branch)}")
51
+ context.capture(:git, "rev-list --max-count=1 #{fetch(:branch)}")
44
52
  end
45
53
  end
46
54
  end
@@ -1,12 +1,12 @@
1
1
  load File.expand_path("../tasks/hg.rake", __FILE__)
2
2
 
3
- require 'capistrano/scm'
3
+ require "capistrano/scm"
4
4
 
5
5
  class Capistrano::Hg < Capistrano::SCM
6
6
  # execute hg in context with arguments
7
7
  def hg(*args)
8
8
  args.unshift(:hg)
9
- context.execute *args
9
+ context.execute(*args)
10
10
  end
11
11
 
12
12
  module DefaultStrategy
@@ -27,9 +27,9 @@ class Capistrano::Hg < Capistrano::SCM
27
27
  end
28
28
 
29
29
  def release
30
- if tree = fetch(:repo_tree)
30
+ if (tree = fetch(:repo_tree))
31
31
  tree = tree.slice %r#^/?(.*?)/?$#, 1
32
- components = tree.split('/').size
32
+ components = tree.split("/").size
33
33
  hg "archive --type tgz -p . -I", tree, "--rev", fetch(:branch), "| tar -x --strip-components #{components} -f - -C", release_path
34
34
  else
35
35
  hg "archive", release_path, "--rev", fetch(:branch)
@@ -1,37 +1,37 @@
1
- require 'i18n'
1
+ require "i18n"
2
2
 
3
3
  en = {
4
- starting: 'Starting',
5
- capified: 'Capified',
6
- start: 'Start',
7
- update: 'Update',
8
- finalize: 'Finalise',
9
- finishing: 'Finishing',
10
- finished: 'Finished',
11
- stage_not_set: 'Stage not set, please call something such as `cap production deploy`, where production is a stage you have defined.',
12
- written_file: 'create %{file}',
13
- question: 'Please enter %{key} (%{default_value}): ',
14
- keeping_releases: 'Keeping %{keep_releases} of %{releases} deployed releases on %{host}',
15
- no_old_releases: 'No old releases (keeping newest %{keep_releases}) on %{host}',
16
- linked_file_does_not_exist: 'linked file %{file} does not exist on %{host}',
17
- cannot_rollback: 'There are no older releases to rollback to',
18
- mirror_exists: 'The repository mirror is at %{at}',
19
- revision_log_message: 'Branch %{branch} (at %{sha}) deployed as release %{release} by %{user}',
20
- rollback_log_message: '%{user} rolled back to release %{release}',
21
- deploy_failed: 'The deploy has failed with an error: %{ex}',
4
+ starting: "Starting",
5
+ capified: "Capified",
6
+ start: "Start",
7
+ update: "Update",
8
+ finalize: "Finalise",
9
+ finishing: "Finishing",
10
+ finished: "Finished",
11
+ stage_not_set: "Stage not set, please call something such as `cap production deploy`, where production is a stage you have defined.",
12
+ written_file: "create %{file}",
13
+ question: "Please enter %{key} (%{default_value}): ",
14
+ keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
15
+ no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
16
+ linked_file_does_not_exist: "linked file %{file} does not exist on %{host}",
17
+ cannot_rollback: "There are no older releases to rollback to",
18
+ mirror_exists: "The repository mirror is at %{at}",
19
+ revision_log_message: "Branch %{branch} (at %{sha}) deployed as release %{release} by %{user}",
20
+ rollback_log_message: "%{user} rolled back to release %{release}",
21
+ deploy_failed: "The deploy has failed with an error: %{ex}",
22
22
  console: {
23
- welcome: 'capistrano console - enter command to execute on %{stage}',
24
- bye: 'bye'
23
+ welcome: "capistrano console - enter command to execute on %{stage}",
24
+ bye: "bye"
25
25
  },
26
26
  error: {
27
27
  user: {
28
- does_not_exist: 'User %{user} does not exists',
29
- cannot_switch: 'Cannot switch to user %{user}'
28
+ does_not_exist: "User %{user} does not exists",
29
+ cannot_switch: "Cannot switch to user %{user}"
30
30
  }
31
31
  }
32
32
  }
33
33
 
34
- I18n.backend.store_translations(:en, { capistrano: en })
34
+ I18n.backend.store_translations(:en, capistrano: en)
35
35
 
36
36
  if I18n.respond_to?(:enforce_available_locales=)
37
37
  I18n.enforce_available_locales = true
@@ -0,0 +1,29 @@
1
+ module Capistrano
2
+ # This module extends a Rake::Task to freeze it to prevent it from being
3
+ # enhanced. This is used to prevent users from enhancing a task at the wrong
4
+ # point of Capistrano's boot process, which can happen if a Capistrano plugin
5
+ # is loaded in deploy.rb by mistake (instead of in the Capfile).
6
+ #
7
+ # Usage:
8
+ #
9
+ # task = Rake.application["load:defaults"]
10
+ # task.invoke
11
+ # task.extend(Capistrano::ImmutableTask) # prevent further modifications
12
+ #
13
+ module ImmutableTask
14
+ def self.extended(task)
15
+ task.freeze
16
+ end
17
+
18
+ def enhance(*args, &block)
19
+ $stderr.puts <<-MESSAGE
20
+ WARNING: #{name} has already been invoked and can no longer be modified.
21
+ Check that you haven't loaded a Capistrano plugin in deploy.rb by mistake.
22
+ Plugins must be loaded in the Capfile to initialize properly.
23
+ MESSAGE
24
+
25
+ # This will raise a frozen object error
26
+ super(*args, &block)
27
+ end
28
+ end
29
+ end
@@ -1 +1 @@
1
- load File.expand_path(File.join(File.dirname(__FILE__),'tasks/install.rake'))
1
+ load File.expand_path(File.join(File.dirname(__FILE__), "tasks/install.rake"))
@@ -0,0 +1,95 @@
1
+ require "capistrano/all"
2
+ require "rake/tasklib"
3
+
4
+ # IMPORTANT: The Capistrano::Plugin system is not yet considered a stable,
5
+ # public API, and is subject to change without notice. Eventually it will be
6
+ # officially documented and supported, but for now, use it at your own risk.
7
+ #
8
+ # Base class for Capistrano plugins. Makes building a Capistrano plugin as easy
9
+ # as writing a `Capistrano::Plugin` subclass and overriding any or all of its
10
+ # three template methods:
11
+ #
12
+ # * set_defaults
13
+ # * register_hooks
14
+ # * define_tasks
15
+ #
16
+ # Within the plugin you can use any methods of the Rake or Capistrano DSLs, like
17
+ # `fetch`, `invoke`, etc. In cases when you need to use SSHKit's backend outside
18
+ # of an `on` block, use the `backend` convenience method. E.g. `backend.test`,
19
+ # `backend.execute`, or `backend.capture`.
20
+ #
21
+ # Package up and distribute your plugin class as a gem and you're good to go!
22
+ #
23
+ # To use a plugin, all a user has to do is install it in the Capfile, like this:
24
+ #
25
+ # # Capfile
26
+ # require "capistrano/superfancy"
27
+ # install_plugin Capistrano::Superfancy
28
+ #
29
+ # Or, to install the plugin without its hooks:
30
+ #
31
+ # # Capfile
32
+ # require "capistrano/superfancy"
33
+ # install_plugin Capistrano::Superfancy, load_hooks: false
34
+ #
35
+ class Capistrano::Plugin < Rake::TaskLib
36
+ include Capistrano::DSL
37
+
38
+ # Implemented by subclasses to provide default values for settings needed by
39
+ # this plugin. Typically done using the `set_if_empty` Capistrano DSL method.
40
+ #
41
+ # Example:
42
+ #
43
+ # def set_defaults
44
+ # set_if_empty :my_plugin_option, true
45
+ # end
46
+ #
47
+ def set_defaults; end
48
+
49
+ # Implemented by subclasses to hook into Capistrano's deployment flow using
50
+ # using the `before` and `after` DSL methods. Note that `register_hooks` will
51
+ # not be called if the user has opted-out of hooks when installing the plugin.
52
+ #
53
+ # Example:
54
+ #
55
+ # def register_hooks
56
+ # after "deploy:updated", "my_plugin:do_something"
57
+ # end
58
+ #
59
+ def register_hooks; end
60
+
61
+ # Implemented by subclasses to define Rake tasks. Typically a plugin will call
62
+ # `eval_rakefile` to load Rake tasks from a separate .rake file.
63
+ #
64
+ # Example:
65
+ #
66
+ # def define_tasks
67
+ # eval_rakefile File.expand_path("../tasks.rake", __FILE__)
68
+ # end
69
+ #
70
+ # For simple tasks, you can define them inline. No need for a separate file.
71
+ #
72
+ # def define_tasks
73
+ # desc "Do something fantastic."
74
+ # task "my_plugin:fantastic" do
75
+ # ...
76
+ # end
77
+ # end
78
+ #
79
+ def define_tasks; end
80
+
81
+ private
82
+
83
+ # Read and eval a .rake file in such a way that `self` within the .rake file
84
+ # refers to this plugin instance. This gives the tasks in the file access to
85
+ # helper methods defined by the plugin.
86
+ def eval_rakefile(path)
87
+ contents = IO.read(path)
88
+ instance_eval(contents, path, 1)
89
+ end
90
+
91
+ # Convenience to access the current SSHKit backend outside of an `on` block.
92
+ def backend
93
+ SSHKit::Backend.current
94
+ end
95
+ end
@@ -1,5 +1,4 @@
1
1
  module Capistrano
2
-
3
2
  # Base class for SCM strategy providers.
4
3
  #
5
4
  # @abstract
@@ -25,7 +24,7 @@ module Capistrano
25
24
 
26
25
  # Call test in context
27
26
  def test!(*args)
28
- context.test *args
27
+ context.test(*args)
29
28
  end
30
29
 
31
30
  # The repository URL according to the context
@@ -59,9 +58,7 @@ module Capistrano
59
58
  # @return [Boolean]
60
59
  #
61
60
  def test
62
- raise NotImplementedError.new(
63
- "Your SCM strategy module should provide a #test method"
64
- )
61
+ raise NotImplementedError, "Your SCM strategy module should provide a #test method"
65
62
  end
66
63
 
67
64
  # @abstract
@@ -72,9 +69,7 @@ module Capistrano
72
69
  # @return [Boolean]
73
70
  #
74
71
  def check
75
- raise NotImplementedError.new(
76
- "Your SCM strategy module should provide a #check method"
77
- )
72
+ raise NotImplementedError, "Your SCM strategy module should provide a #check method"
78
73
  end
79
74
 
80
75
  # @abstract
@@ -84,9 +79,7 @@ module Capistrano
84
79
  # @return void
85
80
  #
86
81
  def clone
87
- raise NotImplementedError.new(
88
- "Your SCM strategy module should provide a #clone method"
89
- )
82
+ raise NotImplementedError, "Your SCM strategy module should provide a #clone method"
90
83
  end
91
84
 
92
85
  # @abstract
@@ -96,9 +89,7 @@ module Capistrano
96
89
  # @return void
97
90
  #
98
91
  def update
99
- raise NotImplementedError.new(
100
- "Your SCM strategy module should provide a #update method"
101
- )
92
+ raise NotImplementedError, "Your SCM strategy module should provide a #update method"
102
93
  end
103
94
 
104
95
  # @abstract
@@ -108,9 +99,7 @@ module Capistrano
108
99
  # @return void
109
100
  #
110
101
  def release
111
- raise NotImplementedError.new(
112
- "Your SCM strategy module should provide a #release method"
113
- )
102
+ raise NotImplementedError, "Your SCM strategy module should provide a #release method"
114
103
  end
115
104
 
116
105
  # @abstract
@@ -120,9 +109,7 @@ module Capistrano
120
109
  # @return void
121
110
  #
122
111
  def fetch_revision
123
- raise NotImplementedError.new(
124
- "Your SCM strategy module should provide a #fetch_revision method"
125
- )
112
+ raise NotImplementedError, "Your SCM strategy module should provide a #fetch_revision method"
126
113
  end
127
114
  end
128
115
  end
@@ -1,22 +1,36 @@
1
+ require "capistrano/doctor"
2
+ require "capistrano/immutable_task"
1
3
  include Capistrano::DSL
2
4
 
3
5
  namespace :load do
4
6
  task :defaults do
5
- load 'capistrano/defaults.rb'
7
+ load "capistrano/defaults.rb"
6
8
  end
7
9
  end
8
10
 
11
+ require "airbrussh/capistrano"
12
+ # We don't need to show the "using Airbrussh" banner announcement since
13
+ # Airbrussh is now the built-in formatter. Also enable command output by
14
+ # default; hiding the output might be confusing to users new to Capistrano.
15
+ Airbrussh.configure do |airbrussh|
16
+ airbrussh.banner = false
17
+ airbrussh.command_output = true
18
+ end
19
+
9
20
  stages.each do |stage|
10
21
  Rake::Task.define_task(stage) do
11
22
  set(:stage, stage.to_sym)
12
23
 
13
- invoke 'load:defaults'
14
- load deploy_config_path
15
- load stage_config_path.join("#{stage}.rb")
24
+ invoke "load:defaults"
25
+ Rake.application["load:defaults"].extend(Capistrano::ImmutableTask)
26
+ env.variables.untrusted! do
27
+ load deploy_config_path
28
+ load stage_config_path.join("#{stage}.rb")
29
+ end
16
30
  load "capistrano/#{fetch(:scm)}.rb"
17
31
  I18n.locale = fetch(:locale, :en)
18
32
  configure_backend
19
33
  end
20
34
  end
21
35
 
22
- require 'capistrano/dotfile'
36
+ require "capistrano/dotfile"