capistrano 3.4.1 → 3.5.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/.gitignore +7 -5
- data/.rubocop.yml +49 -0
- data/.travis.yml +5 -4
- data/CHANGELOG.md +72 -9
- data/CONTRIBUTING.md +61 -93
- data/DEVELOPMENT.md +122 -0
- data/Gemfile +2 -2
- data/LICENSE.txt +1 -1
- data/README.md +121 -43
- data/RELEASING.md +16 -0
- data/Rakefile +4 -1
- data/bin/cap +1 -1
- data/capistrano.gemspec +16 -21
- data/features/doctor.feature +11 -0
- data/features/step_definitions/assertions.rb +17 -17
- data/features/step_definitions/cap_commands.rb +0 -1
- data/features/step_definitions/setup.rb +12 -8
- data/features/support/env.rb +5 -5
- data/features/support/remote_command_helpers.rb +8 -6
- data/features/support/vagrant_helpers.rb +5 -4
- data/issue_template.md +21 -0
- data/lib/Capfile +5 -1
- data/lib/capistrano/all.rb +9 -10
- data/lib/capistrano/application.rb +36 -26
- data/lib/capistrano/configuration.rb +56 -41
- data/lib/capistrano/configuration/empty_filter.rb +9 -0
- data/lib/capistrano/configuration/filter.rb +18 -47
- data/lib/capistrano/configuration/host_filter.rb +30 -0
- data/lib/capistrano/configuration/null_filter.rb +9 -0
- data/lib/capistrano/configuration/plugin_installer.rb +33 -0
- data/lib/capistrano/configuration/question.rb +10 -7
- data/lib/capistrano/configuration/role_filter.rb +30 -0
- data/lib/capistrano/configuration/server.rb +22 -23
- data/lib/capistrano/configuration/servers.rb +6 -7
- data/lib/capistrano/configuration/variables.rb +136 -0
- data/lib/capistrano/defaults.rb +13 -3
- data/lib/capistrano/deploy.rb +1 -1
- data/lib/capistrano/doctor.rb +5 -0
- data/lib/capistrano/doctor/environment_doctor.rb +19 -0
- data/lib/capistrano/doctor/gems_doctor.rb +45 -0
- data/lib/capistrano/doctor/output_helpers.rb +79 -0
- data/lib/capistrano/doctor/variables_doctor.rb +66 -0
- data/lib/capistrano/dotfile.rb +1 -2
- data/lib/capistrano/dsl.rb +12 -14
- data/lib/capistrano/dsl/env.rb +11 -42
- data/lib/capistrano/dsl/paths.rb +12 -13
- data/lib/capistrano/dsl/stages.rb +2 -4
- data/lib/capistrano/dsl/task_enhancements.rb +5 -7
- data/lib/capistrano/framework.rb +1 -1
- data/lib/capistrano/git.rb +17 -9
- data/lib/capistrano/hg.rb +4 -4
- data/lib/capistrano/i18n.rb +24 -24
- data/lib/capistrano/immutable_task.rb +29 -0
- data/lib/capistrano/install.rb +1 -1
- data/lib/capistrano/plugin.rb +95 -0
- data/lib/capistrano/scm.rb +7 -20
- data/lib/capistrano/setup.rb +19 -5
- data/lib/capistrano/svn.rb +9 -5
- data/lib/capistrano/tasks/console.rake +4 -8
- data/lib/capistrano/tasks/deploy.rake +75 -62
- data/lib/capistrano/tasks/doctor.rake +19 -0
- data/lib/capistrano/tasks/framework.rake +13 -14
- data/lib/capistrano/tasks/git.rake +10 -11
- data/lib/capistrano/tasks/hg.rake +7 -7
- data/lib/capistrano/tasks/install.rake +14 -15
- data/lib/capistrano/tasks/svn.rake +7 -7
- data/lib/capistrano/templates/Capfile +3 -3
- data/lib/capistrano/templates/deploy.rb.erb +6 -5
- data/lib/capistrano/upload_task.rb +1 -1
- data/lib/capistrano/version.rb +1 -1
- data/lib/capistrano/version_validator.rb +4 -6
- data/spec/integration/dsl_spec.rb +286 -239
- data/spec/integration_spec_helper.rb +3 -5
- data/spec/lib/capistrano/application_spec.rb +22 -14
- data/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/filter_spec.rb +82 -84
- data/spec/lib/capistrano/configuration/host_filter_spec.rb +61 -0
- data/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
- data/spec/lib/capistrano/configuration/question_spec.rb +12 -16
- data/spec/lib/capistrano/configuration/role_filter_spec.rb +64 -0
- data/spec/lib/capistrano/configuration/server_spec.rb +102 -110
- data/spec/lib/capistrano/configuration/servers_spec.rb +124 -141
- data/spec/lib/capistrano/configuration_spec.rb +150 -61
- data/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
- data/spec/lib/capistrano/doctor/gems_doctor_spec.rb +61 -0
- data/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
- data/spec/lib/capistrano/doctor/variables_doctor_spec.rb +79 -0
- data/spec/lib/capistrano/dsl/paths_spec.rb +58 -50
- data/spec/lib/capistrano/dsl/task_enhancements_spec.rb +62 -32
- data/spec/lib/capistrano/dsl_spec.rb +6 -8
- data/spec/lib/capistrano/git_spec.rb +35 -7
- data/spec/lib/capistrano/hg_spec.rb +14 -5
- data/spec/lib/capistrano/immutable_task_spec.rb +31 -0
- data/spec/lib/capistrano/plugin_spec.rb +84 -0
- data/spec/lib/capistrano/scm_spec.rb +6 -7
- data/spec/lib/capistrano/svn_spec.rb +40 -14
- data/spec/lib/capistrano/upload_task_spec.rb +7 -7
- data/spec/lib/capistrano/version_validator_spec.rb +37 -45
- data/spec/lib/capistrano_spec.rb +2 -3
- data/spec/spec_helper.rb +8 -8
- data/spec/support/Vagrantfile +9 -10
- data/spec/support/tasks/database.rake +3 -3
- data/spec/support/tasks/fail.rake +4 -3
- data/spec/support/tasks/failed.rake +2 -2
- data/spec/support/tasks/plugin.rake +6 -0
- data/spec/support/tasks/root.rake +4 -4
- data/spec/support/test_app.rb +31 -30
- metadata +93 -14
@@ -1,55 +1,26 @@
|
|
1
|
-
require
|
1
|
+
require "capistrano/configuration"
|
2
|
+
require "capistrano/configuration/empty_filter"
|
3
|
+
require "capistrano/configuration/host_filter"
|
4
|
+
require "capistrano/configuration/null_filter"
|
5
|
+
require "capistrano/configuration/role_filter"
|
2
6
|
|
3
7
|
module Capistrano
|
4
8
|
class Configuration
|
5
9
|
class Filter
|
6
|
-
def initialize
|
7
|
-
raise "Invalid filter type #{type}" unless [:host
|
8
|
-
av = Array(values)
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
av.map!{|v| (v.is_a?(String) && v =~ /^(?<name>[-A-Za-z0-9.]+)(,\g<name>)*$/) ? v.split(',') : v }
|
17
|
-
av.flatten!
|
18
|
-
av.map! do |v|
|
19
|
-
case v
|
20
|
-
when Regexp then v
|
21
|
-
else
|
22
|
-
vs = v.to_s
|
23
|
-
vs =~ /^[-A-Za-z0-9.]+$/ ? vs : Regexp.new(vs)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
Regexp.union av
|
27
|
-
when :role
|
28
|
-
av.map!{|v| v.is_a?(String) ? v.split(',') : v }
|
29
|
-
av.flatten!
|
30
|
-
av.map! do |v|
|
31
|
-
case v
|
32
|
-
when Regexp then v
|
33
|
-
else
|
34
|
-
vs = v.to_s
|
35
|
-
vs =~ %r{^/(.+)/$} ? Regexp.new($1) : %r{^#{vs}$}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
Regexp.union av
|
39
|
-
else
|
40
|
-
nil
|
41
|
-
end
|
10
|
+
def initialize(type, values=nil)
|
11
|
+
raise "Invalid filter type #{type}" unless [:host, :role].include? type
|
12
|
+
av = Array(values)
|
13
|
+
@strategy = case
|
14
|
+
when av.empty? then EmptyFilter.new
|
15
|
+
when av.include?(:all), av.include?("all") then NullFilter.new
|
16
|
+
when type == :host then HostFilter.new(values)
|
17
|
+
when type == :role then RoleFilter.new(values)
|
18
|
+
else NullFilter.new
|
19
|
+
end
|
42
20
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
when :none then return []
|
47
|
-
when :all then return servers
|
48
|
-
when :host
|
49
|
-
as.select {|s| @rex.match s.hostname}
|
50
|
-
when :role
|
51
|
-
as.select {|s| s.roles.any? {|r| @rex.match r} }
|
52
|
-
end
|
21
|
+
|
22
|
+
def filter(servers)
|
23
|
+
@strategy.filter servers
|
53
24
|
end
|
54
25
|
end
|
55
26
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Configuration
|
3
|
+
class HostFilter
|
4
|
+
def initialize(values)
|
5
|
+
av = Array(values).dup
|
6
|
+
av.map! { |v| (v.is_a?(String) && v =~ /^(?<name>[-A-Za-z0-9.]+)(,\g<name>)*$/) ? v.split(",") : v }
|
7
|
+
av.flatten!
|
8
|
+
@rex = regex_matcher(av)
|
9
|
+
end
|
10
|
+
|
11
|
+
def filter(servers)
|
12
|
+
Array(servers).select { |s| @rex.match s.to_s }
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def regex_matcher(values)
|
18
|
+
values.map! do |v|
|
19
|
+
case v
|
20
|
+
when Regexp then v
|
21
|
+
else
|
22
|
+
vs = v.to_s
|
23
|
+
vs =~ /^[-A-Za-z0-9.]+$/ ? vs : Regexp.new(vs)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Regexp.union values
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Encapsulates the logic for installing plugins into Capistrano. Plugins must
|
2
|
+
# simply conform to a basic API; the PluginInstaller takes care of invoking the
|
3
|
+
# API at appropriate times.
|
4
|
+
#
|
5
|
+
# This class is not used directly; instead it is typically accessed via the
|
6
|
+
# `install_plugin` method of the Capistrano DSL.
|
7
|
+
#
|
8
|
+
module Capistrano
|
9
|
+
class Configuration
|
10
|
+
class PluginInstaller
|
11
|
+
# "Installs" a Plugin into Capistrano by loading its tasks, hooks, and
|
12
|
+
# defaults at the appropriate time. The hooks in particular can be
|
13
|
+
# skipped, if you want full control over when and how the plugin's tasks
|
14
|
+
# are executed. Simply pass `load_hooks:false` to opt out.
|
15
|
+
#
|
16
|
+
# The plugin class or instance may be provided. These are equivalent:
|
17
|
+
#
|
18
|
+
# install(Capistrano::SCM::Git)
|
19
|
+
# install(Capistrano::SCM::Git.new)
|
20
|
+
#
|
21
|
+
def install(plugin, load_hooks:true)
|
22
|
+
plugin = plugin.is_a?(Class) ? plugin.new : plugin
|
23
|
+
|
24
|
+
plugin.define_tasks
|
25
|
+
plugin.register_hooks if load_hooks
|
26
|
+
|
27
|
+
Rake::Task.define_task("load:defaults") do
|
28
|
+
plugin.set_defaults
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Capistrano
|
2
2
|
class Configuration
|
3
3
|
class Question
|
4
|
-
|
5
|
-
|
6
|
-
@
|
4
|
+
def initialize(key, default, options={})
|
5
|
+
@key = key
|
6
|
+
@default = default
|
7
|
+
@options = options
|
7
8
|
end
|
8
9
|
|
9
10
|
def call
|
@@ -12,6 +13,7 @@ module Capistrano
|
|
12
13
|
end
|
13
14
|
|
14
15
|
private
|
16
|
+
|
15
17
|
attr_reader :key, :default, :options
|
16
18
|
|
17
19
|
def ask_question
|
@@ -28,20 +30,21 @@ module Capistrano
|
|
28
30
|
|
29
31
|
def response
|
30
32
|
return @response if defined? @response
|
31
|
-
|
33
|
+
|
32
34
|
@response = (gets || "").chomp
|
33
35
|
end
|
34
|
-
|
36
|
+
|
35
37
|
def gets
|
36
38
|
if echo?
|
37
39
|
$stdin.gets
|
38
40
|
else
|
39
|
-
$stdin.noecho(&:gets).tap{ $stdout.print "\n" }
|
41
|
+
$stdin.noecho(&:gets).tap { $stdout.print "\n" }
|
40
42
|
end
|
41
43
|
rescue Errno::EIO
|
42
44
|
# when stdio gets closed
|
45
|
+
return
|
43
46
|
end
|
44
|
-
|
47
|
+
|
45
48
|
def question
|
46
49
|
I18n.t(:question, key: key, default_value: default, scope: :capistrano)
|
47
50
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Configuration
|
3
|
+
class RoleFilter
|
4
|
+
def initialize(values)
|
5
|
+
av = Array(values).dup
|
6
|
+
av.map! { |v| v.is_a?(String) ? v.split(",") : v }
|
7
|
+
av.flatten!
|
8
|
+
@rex = regex_matcher(av)
|
9
|
+
end
|
10
|
+
|
11
|
+
def filter(servers)
|
12
|
+
Array(servers).select { |s| s.is_a?(String) ? false : s.roles.any? { |r| @rex.match r } }
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def regex_matcher(values)
|
18
|
+
values.map! do |v|
|
19
|
+
case v
|
20
|
+
when Regexp then v
|
21
|
+
else
|
22
|
+
vs = v.to_s
|
23
|
+
vs =~ %r{^/(.+)/$} ? Regexp.new($1) : /^#{vs}$/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Regexp.union values
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "set"
|
2
2
|
module Capistrano
|
3
3
|
class Configuration
|
4
4
|
class Server < SSHKit::Host
|
@@ -25,19 +25,21 @@ module Capistrano
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def select?(options)
|
28
|
-
options.each do |k,v|
|
29
|
-
callable = v.respond_to?(:call) ? v: ->(server){server.fetch(v)}
|
30
|
-
result =
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
options.each do |k, v|
|
29
|
+
callable = v.respond_to?(:call) ? v : ->(server) { server.fetch(v) }
|
30
|
+
result = \
|
31
|
+
case k
|
32
|
+
when :filter, :select
|
33
|
+
callable.call(self)
|
34
|
+
when :exclude
|
35
|
+
!callable.call(self)
|
36
|
+
else
|
37
|
+
fetch(k) == v
|
38
|
+
end
|
38
39
|
return false unless result
|
39
40
|
end
|
40
|
-
|
41
|
+
|
42
|
+
true
|
41
43
|
end
|
42
44
|
|
43
45
|
def primary
|
@@ -54,7 +56,7 @@ module Capistrano
|
|
54
56
|
end
|
55
57
|
|
56
58
|
def netssh_options
|
57
|
-
@netssh_options ||= super.merge(
|
59
|
+
@netssh_options ||= super.merge(fetch(:ssh_options) || {})
|
58
60
|
end
|
59
61
|
|
60
62
|
def roles_array
|
@@ -62,7 +64,7 @@ module Capistrano
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def matches?(other)
|
65
|
-
hostname == other.hostname
|
67
|
+
hostname == other.hostname && port == other.port
|
66
68
|
end
|
67
69
|
|
68
70
|
private
|
@@ -76,18 +78,17 @@ module Capistrano
|
|
76
78
|
end
|
77
79
|
|
78
80
|
class Properties
|
79
|
-
|
80
81
|
def initialize
|
81
82
|
@properties = {}
|
82
83
|
end
|
83
84
|
|
84
85
|
def set(key, value)
|
85
86
|
pval = @properties[key]
|
86
|
-
if pval.is_a?
|
87
|
+
if pval.is_a?(Hash) && value.is_a?(Hash)
|
87
88
|
pval.merge!(value)
|
88
|
-
elsif pval.is_a?
|
89
|
+
elsif pval.is_a?(Set) && value.is_a?(Set)
|
89
90
|
pval.merge(value)
|
90
|
-
elsif pval.is_a?
|
91
|
+
elsif pval.is_a?(Array) && value.is_a?(Array)
|
91
92
|
pval.concat value
|
92
93
|
else
|
93
94
|
@properties[key] = value
|
@@ -98,8 +99,8 @@ module Capistrano
|
|
98
99
|
@properties[key]
|
99
100
|
end
|
100
101
|
|
101
|
-
def respond_to?(method,
|
102
|
-
@properties.
|
102
|
+
def respond_to?(method, _include_all=false)
|
103
|
+
@properties.key?(method)
|
103
104
|
end
|
104
105
|
|
105
106
|
def roles
|
@@ -121,11 +122,9 @@ module Capistrano
|
|
121
122
|
private
|
122
123
|
|
123
124
|
def lvalue(key)
|
124
|
-
key.to_s.chomp(
|
125
|
+
key.to_s.chomp("=").to_sym
|
125
126
|
end
|
126
|
-
|
127
127
|
end
|
128
|
-
|
129
128
|
end
|
130
129
|
end
|
131
130
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "set"
|
2
|
+
require "capistrano/configuration"
|
3
|
+
require "capistrano/configuration/filter"
|
4
4
|
|
5
5
|
module Capistrano
|
6
6
|
class Configuration
|
@@ -9,9 +9,8 @@ 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 }
|
12
|
+
if (server = servers.find { |s| s.matches? new_host })
|
13
13
|
server.user = new_host.user if new_host.user
|
14
|
-
server.port = new_host.port if new_host.port
|
15
14
|
server.with(properties)
|
16
15
|
else
|
17
16
|
servers << new_host.with(properties)
|
@@ -38,12 +37,12 @@ module Capistrano
|
|
38
37
|
if block_given?
|
39
38
|
yield host, role, props
|
40
39
|
else
|
41
|
-
rps << (props || {}).merge(
|
40
|
+
rps << (props || {}).merge(role: role, hostname: host.hostname)
|
42
41
|
end
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
46
|
-
block_given? ? nil: rps
|
45
|
+
block_given? ? nil : rps
|
47
46
|
end
|
48
47
|
|
49
48
|
def fetch_primary(role)
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Capistrano
|
2
|
+
class Configuration
|
3
|
+
# Holds the variables assigned at Capistrano runtime via `set` and retrieved
|
4
|
+
# with `fetch`. Does internal bookkeeping to help identify user mistakes
|
5
|
+
# like spelling errors or unused variables that may lead to unexpected
|
6
|
+
# behavior. Also allows validation rules to be registered with `validate`.
|
7
|
+
class Variables
|
8
|
+
CAPISTRANO_LOCATION = File.expand_path("../..", __FILE__).freeze
|
9
|
+
IGNORED_LOCATIONS = [
|
10
|
+
"#{CAPISTRANO_LOCATION}/configuration/variables.rb:",
|
11
|
+
"#{CAPISTRANO_LOCATION}/configuration.rb:",
|
12
|
+
"#{CAPISTRANO_LOCATION}/dsl/env.rb:",
|
13
|
+
"/dsl.rb:",
|
14
|
+
"/forwardable.rb:"
|
15
|
+
].freeze
|
16
|
+
private_constant :CAPISTRANO_LOCATION, :IGNORED_LOCATIONS
|
17
|
+
|
18
|
+
def initialize(values={})
|
19
|
+
@trusted_keys = []
|
20
|
+
@fetched_keys = []
|
21
|
+
@locations = {}
|
22
|
+
@values = values
|
23
|
+
@trusted = true
|
24
|
+
end
|
25
|
+
|
26
|
+
def untrusted!
|
27
|
+
@trusted = false
|
28
|
+
yield
|
29
|
+
ensure
|
30
|
+
@trusted = true
|
31
|
+
end
|
32
|
+
|
33
|
+
def set(key, value=nil, &block)
|
34
|
+
invoke_validations(key, value, &block)
|
35
|
+
@trusted_keys << key if trusted?
|
36
|
+
remember_location(key)
|
37
|
+
values[key] = block || value
|
38
|
+
trace_set(key)
|
39
|
+
values[key]
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch(key, default=nil, &block)
|
43
|
+
fetched_keys << key
|
44
|
+
peek(key, default, &block)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Internal use only.
|
48
|
+
def peek(key, default=nil, &block)
|
49
|
+
value = fetch_for(key, default, &block)
|
50
|
+
while callable_without_parameters?(value)
|
51
|
+
value = (values[key] = value.call)
|
52
|
+
end
|
53
|
+
value
|
54
|
+
end
|
55
|
+
|
56
|
+
def fetch_for(key, default, &block)
|
57
|
+
block ? values.fetch(key, &block) : values.fetch(key, default)
|
58
|
+
end
|
59
|
+
|
60
|
+
def delete(key)
|
61
|
+
values.delete(key)
|
62
|
+
end
|
63
|
+
|
64
|
+
def validate(key, &validator)
|
65
|
+
vs = (validators[key] || [])
|
66
|
+
vs << validator
|
67
|
+
validators[key] = vs
|
68
|
+
end
|
69
|
+
|
70
|
+
def trusted_keys
|
71
|
+
@trusted_keys.dup
|
72
|
+
end
|
73
|
+
|
74
|
+
def untrusted_keys
|
75
|
+
keys - @trusted_keys
|
76
|
+
end
|
77
|
+
|
78
|
+
def keys
|
79
|
+
values.keys
|
80
|
+
end
|
81
|
+
|
82
|
+
# Keys that have been set, but which have never been fetched.
|
83
|
+
def unused_keys
|
84
|
+
keys - fetched_keys
|
85
|
+
end
|
86
|
+
|
87
|
+
# Returns an array of source file location(s) where the given key was
|
88
|
+
# assigned (i.e. where `set` was called). If the key was never assigned,
|
89
|
+
# returns `nil`.
|
90
|
+
def source_locations(key)
|
91
|
+
locations[key]
|
92
|
+
end
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
attr_reader :locations, :values, :fetched_keys
|
97
|
+
|
98
|
+
def trusted?
|
99
|
+
@trusted
|
100
|
+
end
|
101
|
+
|
102
|
+
def remember_location(key)
|
103
|
+
location = caller.find do |line|
|
104
|
+
IGNORED_LOCATIONS.none? { |i| line.include?(i) }
|
105
|
+
end
|
106
|
+
(locations[key] ||= []) << location
|
107
|
+
end
|
108
|
+
|
109
|
+
def callable_without_parameters?(x)
|
110
|
+
x.respond_to?(:call) && (!x.respond_to?(:arity) || x.arity == 0)
|
111
|
+
end
|
112
|
+
|
113
|
+
def validators
|
114
|
+
@validators ||= {}
|
115
|
+
end
|
116
|
+
|
117
|
+
def invoke_validations(key, value, &block)
|
118
|
+
unless value.nil? || block.nil?
|
119
|
+
raise Capistrano::ValidationError,
|
120
|
+
"Value and block both passed to Configuration#set"
|
121
|
+
end
|
122
|
+
|
123
|
+
return unless validators.key? key
|
124
|
+
|
125
|
+
validators[key].each do |validator|
|
126
|
+
validator.call(key, block || value)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def trace_set(key)
|
131
|
+
return unless fetch(:print_config_variables, false)
|
132
|
+
puts "Config variable set: #{key.inspect} => #{values[key].inspect}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|