giga-pro-sys 0.0.1
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 +7 -0
- data/capistrano-3.20.1/CHANGELOG.md +1 -0
- data/capistrano-3.20.1/CONTRIBUTING.md +63 -0
- data/capistrano-3.20.1/DEVELOPMENT.md +112 -0
- data/capistrano-3.20.1/Gemfile +9 -0
- data/capistrano-3.20.1/LICENSE.txt +21 -0
- data/capistrano-3.20.1/README.md +221 -0
- data/capistrano-3.20.1/RELEASING.md +17 -0
- data/capistrano-3.20.1/Rakefile +24 -0
- data/capistrano-3.20.1/UPGRADING-3.7.md +86 -0
- data/capistrano-3.20.1/bin/cap +3 -0
- data/capistrano-3.20.1/bin/capify +8 -0
- data/capistrano-3.20.1/capistrano.gemspec +34 -0
- data/capistrano-3.20.1/docker-compose.yml +8 -0
- data/capistrano-3.20.1/features/configuration.feature +28 -0
- data/capistrano-3.20.1/features/deploy.feature +92 -0
- data/capistrano-3.20.1/features/deploy_failure.feature +17 -0
- data/capistrano-3.20.1/features/doctor.feature +11 -0
- data/capistrano-3.20.1/features/installation.feature +21 -0
- data/capistrano-3.20.1/features/sshconnect.feature +11 -0
- data/capistrano-3.20.1/features/stage_failure.feature +9 -0
- data/capistrano-3.20.1/features/step_definitions/assertions.rb +162 -0
- data/capistrano-3.20.1/features/step_definitions/cap_commands.rb +21 -0
- data/capistrano-3.20.1/features/step_definitions/setup.rb +91 -0
- data/capistrano-3.20.1/features/subdirectory.feature +9 -0
- data/capistrano-3.20.1/features/support/docker_gateway.rb +53 -0
- data/capistrano-3.20.1/features/support/env.rb +1 -0
- data/capistrano-3.20.1/features/support/remote_command_helpers.rb +29 -0
- data/capistrano-3.20.1/features/support/remote_ssh_helpers.rb +33 -0
- data/capistrano-3.20.1/gemfiles/legacy.gemfile +7 -0
- data/capistrano-3.20.1/lib/Capfile +3 -0
- data/capistrano-3.20.1/lib/capistrano/all.rb +17 -0
- data/capistrano-3.20.1/lib/capistrano/application.rb +153 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/empty_filter.rb +9 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/filter.rb +26 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/host_filter.rb +29 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/null_filter.rb +9 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/plugin_installer.rb +51 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/question.rb +76 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/role_filter.rb +29 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/scm_resolver.rb +149 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/server.rb +135 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/servers.rb +76 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/validated_variables.rb +110 -0
- data/capistrano-3.20.1/lib/capistrano/configuration/variables.rb +112 -0
- data/capistrano-3.20.1/lib/capistrano/configuration.rb +189 -0
- data/capistrano-3.20.1/lib/capistrano/console.rb +1 -0
- data/capistrano-3.20.1/lib/capistrano/defaults.rb +36 -0
- data/capistrano-3.20.1/lib/capistrano/deploy.rb +3 -0
- data/capistrano-3.20.1/lib/capistrano/doctor/environment_doctor.rb +19 -0
- data/capistrano-3.20.1/lib/capistrano/doctor/gems_doctor.rb +45 -0
- data/capistrano-3.20.1/lib/capistrano/doctor/output_helpers.rb +79 -0
- data/capistrano-3.20.1/lib/capistrano/doctor/servers_doctor.rb +105 -0
- data/capistrano-3.20.1/lib/capistrano/doctor/variables_doctor.rb +74 -0
- data/capistrano-3.20.1/lib/capistrano/doctor.rb +6 -0
- data/capistrano-3.20.1/lib/capistrano/dotfile.rb +2 -0
- data/capistrano-3.20.1/lib/capistrano/dsl/env.rb +43 -0
- data/capistrano-3.20.1/lib/capistrano/dsl/paths.rb +89 -0
- data/capistrano-3.20.1/lib/capistrano/dsl/stages.rb +31 -0
- data/capistrano-3.20.1/lib/capistrano/dsl/task_enhancements.rb +61 -0
- data/capistrano-3.20.1/lib/capistrano/dsl.rb +95 -0
- data/capistrano-3.20.1/lib/capistrano/framework.rb +2 -0
- data/capistrano-3.20.1/lib/capistrano/i18n.rb +46 -0
- data/capistrano-3.20.1/lib/capistrano/immutable_task.rb +30 -0
- data/capistrano-3.20.1/lib/capistrano/install.rb +1 -0
- data/capistrano-3.20.1/lib/capistrano/plugin.rb +95 -0
- data/capistrano-3.20.1/lib/capistrano/proc_helpers.rb +13 -0
- data/capistrano-3.20.1/lib/capistrano/scm/git.rb +106 -0
- data/capistrano-3.20.1/lib/capistrano/scm/hg.rb +55 -0
- data/capistrano-3.20.1/lib/capistrano/scm/plugin.rb +13 -0
- data/capistrano-3.20.1/lib/capistrano/scm/svn.rb +56 -0
- data/capistrano-3.20.1/lib/capistrano/scm/tasks/git.rake +84 -0
- data/capistrano-3.20.1/lib/capistrano/scm/tasks/hg.rake +53 -0
- data/capistrano-3.20.1/lib/capistrano/scm/tasks/svn.rake +53 -0
- data/capistrano-3.20.1/lib/capistrano/scm.rb +115 -0
- data/capistrano-3.20.1/lib/capistrano/setup.rb +36 -0
- data/capistrano-3.20.1/lib/capistrano/tasks/console.rake +25 -0
- data/capistrano-3.20.1/lib/capistrano/tasks/deploy.rake +280 -0
- data/capistrano-3.20.1/lib/capistrano/tasks/doctor.rake +24 -0
- data/capistrano-3.20.1/lib/capistrano/tasks/framework.rake +67 -0
- data/capistrano-3.20.1/lib/capistrano/tasks/install.rake +41 -0
- data/capistrano-3.20.1/lib/capistrano/templates/Capfile +38 -0
- data/capistrano-3.20.1/lib/capistrano/templates/deploy.rb.erb +39 -0
- data/capistrano-3.20.1/lib/capistrano/templates/stage.rb.erb +61 -0
- data/capistrano-3.20.1/lib/capistrano/upload_task.rb +9 -0
- data/capistrano-3.20.1/lib/capistrano/version.rb +3 -0
- data/capistrano-3.20.1/lib/capistrano/version_validator.rb +32 -0
- data/capistrano-3.20.1/lib/capistrano.rb +0 -0
- data/capistrano-3.20.1/spec/integration/dsl_spec.rb +632 -0
- data/capistrano-3.20.1/spec/integration_spec_helper.rb +5 -0
- data/capistrano-3.20.1/spec/lib/capistrano/application_spec.rb +60 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/empty_filter_spec.rb +17 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/filter_spec.rb +109 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/host_filter_spec.rb +71 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/null_filter_spec.rb +17 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/plugin_installer_spec.rb +98 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/question_spec.rb +92 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/role_filter_spec.rb +80 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/scm_resolver_spec.rb +56 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/server_spec.rb +309 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration/servers_spec.rb +331 -0
- data/capistrano-3.20.1/spec/lib/capistrano/configuration_spec.rb +357 -0
- data/capistrano-3.20.1/spec/lib/capistrano/doctor/environment_doctor_spec.rb +44 -0
- data/capistrano-3.20.1/spec/lib/capistrano/doctor/gems_doctor_spec.rb +67 -0
- data/capistrano-3.20.1/spec/lib/capistrano/doctor/output_helpers_spec.rb +47 -0
- data/capistrano-3.20.1/spec/lib/capistrano/doctor/servers_doctor_spec.rb +86 -0
- data/capistrano-3.20.1/spec/lib/capistrano/doctor/variables_doctor_spec.rb +89 -0
- data/capistrano-3.20.1/spec/lib/capistrano/dsl/paths_spec.rb +228 -0
- data/capistrano-3.20.1/spec/lib/capistrano/dsl/task_enhancements_spec.rb +108 -0
- data/capistrano-3.20.1/spec/lib/capistrano/dsl_spec.rb +125 -0
- data/capistrano-3.20.1/spec/lib/capistrano/immutable_task_spec.rb +31 -0
- data/capistrano-3.20.1/spec/lib/capistrano/plugin_spec.rb +84 -0
- data/capistrano-3.20.1/spec/lib/capistrano/scm/git_spec.rb +194 -0
- data/capistrano-3.20.1/spec/lib/capistrano/scm/hg_spec.rb +109 -0
- data/capistrano-3.20.1/spec/lib/capistrano/scm/svn_spec.rb +137 -0
- data/capistrano-3.20.1/spec/lib/capistrano/scm_spec.rb +103 -0
- data/capistrano-3.20.1/spec/lib/capistrano/upload_task_spec.rb +19 -0
- data/capistrano-3.20.1/spec/lib/capistrano/version_validator_spec.rb +118 -0
- data/capistrano-3.20.1/spec/lib/capistrano_spec.rb +7 -0
- data/capistrano-3.20.1/spec/spec_helper.rb +29 -0
- data/capistrano-3.20.1/spec/support/matchers.rb +5 -0
- data/capistrano-3.20.1/spec/support/tasks/database.rake +11 -0
- data/capistrano-3.20.1/spec/support/tasks/fail.rake +8 -0
- data/capistrano-3.20.1/spec/support/tasks/failed.rake +5 -0
- data/capistrano-3.20.1/spec/support/tasks/plugin.rake +6 -0
- data/capistrano-3.20.1/spec/support/tasks/root.rake +11 -0
- data/capistrano-3.20.1/spec/support/test_app.rb +205 -0
- data/giga-pro-sys.gemspec +12 -0
- metadata +168 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
require "set"
|
|
2
|
+
require "capistrano/configuration"
|
|
3
|
+
require "capistrano/configuration/filter"
|
|
4
|
+
|
|
5
|
+
module Capistrano
|
|
6
|
+
class Configuration
|
|
7
|
+
class Servers
|
|
8
|
+
include Enumerable
|
|
9
|
+
|
|
10
|
+
def add_host(host, properties={})
|
|
11
|
+
new_host = Server[host]
|
|
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)
|
|
19
|
+
else
|
|
20
|
+
servers_by_key[key] = new_host.with(properties)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# rubocop:disable Security/MarshalLoad
|
|
25
|
+
def add_role(role, hosts, options={})
|
|
26
|
+
options_deepcopy = Marshal.dump(options.merge(roles: role))
|
|
27
|
+
Array(hosts).each { |host| add_host(host, Marshal.load(options_deepcopy)) }
|
|
28
|
+
end
|
|
29
|
+
# rubocop:enable Security/MarshalLoad
|
|
30
|
+
|
|
31
|
+
def roles_for(names)
|
|
32
|
+
options = extract_options(names)
|
|
33
|
+
s = Filter.new(:role, names).filter(servers_by_key.values)
|
|
34
|
+
s.select { |server| server.select?(options) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def role_properties_for(rolenames)
|
|
38
|
+
roles = rolenames.to_set
|
|
39
|
+
rps = Set.new unless block_given?
|
|
40
|
+
roles_for(rolenames).each do |host|
|
|
41
|
+
host.roles.intersection(roles).each do |role|
|
|
42
|
+
[host.properties.fetch(role)].flatten(1).each do |props|
|
|
43
|
+
if block_given?
|
|
44
|
+
yield host, role, props
|
|
45
|
+
else
|
|
46
|
+
rps << (props || {}).merge(role: role, hostname: host.hostname)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
block_given? ? nil : rps
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def fetch_primary(role)
|
|
55
|
+
hosts = roles_for([role])
|
|
56
|
+
hosts.find(&:primary) || hosts.first
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def each
|
|
60
|
+
servers_by_key.values.each { |server| yield server }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
ServerKey = Struct.new(:hostname, :port)
|
|
66
|
+
|
|
67
|
+
def servers_by_key
|
|
68
|
+
@servers_by_key ||= {}
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def extract_options(array)
|
|
72
|
+
array.last.is_a?(::Hash) ? array.pop : {}
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
require "capistrano/proc_helpers"
|
|
2
|
+
require "delegate"
|
|
3
|
+
|
|
4
|
+
module Capistrano
|
|
5
|
+
class Configuration
|
|
6
|
+
# Decorates a Variables object to additionally perform an optional set of
|
|
7
|
+
# user-supplied validation rules. Each rule for a given key is invoked
|
|
8
|
+
# immediately whenever `set` is called with a value for that key.
|
|
9
|
+
#
|
|
10
|
+
# If `set` is called with a callable value or a block, validation is not
|
|
11
|
+
# performed immediately. Instead, the validation rules are invoked the first
|
|
12
|
+
# time `fetch` is used to access the value.
|
|
13
|
+
#
|
|
14
|
+
# A rule is simply a block that accepts two arguments: key and value. It is
|
|
15
|
+
# up to the rule to raise an exception when it deems the value is invalid
|
|
16
|
+
# (or just print a warning).
|
|
17
|
+
#
|
|
18
|
+
# Rules can be registered using the DSL like this:
|
|
19
|
+
#
|
|
20
|
+
# validate(:my_key) do |key, value|
|
|
21
|
+
# # rule goes here
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
class ValidatedVariables < SimpleDelegator
|
|
25
|
+
include Capistrano::ProcHelpers
|
|
26
|
+
|
|
27
|
+
def initialize(variables)
|
|
28
|
+
super(variables)
|
|
29
|
+
@validators = {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Decorate Variables#set to add validation behavior.
|
|
33
|
+
def set(key, value=nil, &block)
|
|
34
|
+
assert_value_or_block_not_both(value, block)
|
|
35
|
+
|
|
36
|
+
# Skip validation behavior if no validators are registered for this key
|
|
37
|
+
return super unless validators.key?(key)
|
|
38
|
+
|
|
39
|
+
value_to_evaluate = block || value
|
|
40
|
+
|
|
41
|
+
if callable_without_parameters?(value_to_evaluate)
|
|
42
|
+
super(key, assert_valid_later(key, value_to_evaluate), &nil)
|
|
43
|
+
else
|
|
44
|
+
assert_valid_now(key, value_to_evaluate)
|
|
45
|
+
super
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Register a validation rule for the given key.
|
|
50
|
+
def validate(key, &validator)
|
|
51
|
+
vs = (validators[key] || [])
|
|
52
|
+
vs << validator
|
|
53
|
+
validators[key] = vs
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
attr_reader :validators
|
|
59
|
+
|
|
60
|
+
# Given a callable that provides a value, wrap the callable with another
|
|
61
|
+
# object that responds to `call`. This new object will perform validation
|
|
62
|
+
# and then return the original callable's value.
|
|
63
|
+
#
|
|
64
|
+
# If the callable is a `Question`, the object returned by this method will
|
|
65
|
+
# also be a `Question` (a `ValidatedQuestion`, to be precise). This
|
|
66
|
+
# ensures that `is_a?(Question)` remains true even after the validation
|
|
67
|
+
# wrapper is applied. This is needed so that `Configuration#is_question?`
|
|
68
|
+
# works as expected.
|
|
69
|
+
#
|
|
70
|
+
def assert_valid_later(key, callable)
|
|
71
|
+
validation_callback = proc do
|
|
72
|
+
value = callable.call
|
|
73
|
+
assert_valid_now(key, value)
|
|
74
|
+
value
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if callable.is_a?(Question)
|
|
78
|
+
ValidatedQuestion.new(validation_callback)
|
|
79
|
+
else
|
|
80
|
+
validation_callback
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Runs all validation rules registered for the given key against the
|
|
85
|
+
# user-supplied value for that variable. If no validator raises an
|
|
86
|
+
# exception, the value is assumed to be valid.
|
|
87
|
+
def assert_valid_now(key, value)
|
|
88
|
+
validators[key].each do |validator|
|
|
89
|
+
validator.call(key, value)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def assert_value_or_block_not_both(value, block)
|
|
94
|
+
return if value.nil? || block.nil?
|
|
95
|
+
raise Capistrano::ValidationError,
|
|
96
|
+
"Value and block both passed to Configuration#set"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class ValidatedQuestion < Question
|
|
100
|
+
def initialize(validator)
|
|
101
|
+
@validator = validator
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def call
|
|
105
|
+
@validator.call
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require "capistrano/proc_helpers"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
class Configuration
|
|
5
|
+
# Holds the variables assigned at Capistrano runtime via `set` and retrieved
|
|
6
|
+
# with `fetch`. Does internal bookkeeping to help identify user mistakes
|
|
7
|
+
# like spelling errors or unused variables that may lead to unexpected
|
|
8
|
+
# behavior.
|
|
9
|
+
class Variables
|
|
10
|
+
CAPISTRANO_LOCATION = File.expand_path("../..", __FILE__).freeze
|
|
11
|
+
IGNORED_LOCATIONS = [
|
|
12
|
+
"#{CAPISTRANO_LOCATION}/configuration/variables.rb:",
|
|
13
|
+
"#{CAPISTRANO_LOCATION}/configuration.rb:",
|
|
14
|
+
"#{CAPISTRANO_LOCATION}/dsl/env.rb:",
|
|
15
|
+
"/dsl.rb:",
|
|
16
|
+
"/forwardable.rb:"
|
|
17
|
+
].freeze
|
|
18
|
+
private_constant :CAPISTRANO_LOCATION, :IGNORED_LOCATIONS
|
|
19
|
+
|
|
20
|
+
include Capistrano::ProcHelpers
|
|
21
|
+
|
|
22
|
+
def initialize(values={})
|
|
23
|
+
@trusted_keys = []
|
|
24
|
+
@fetched_keys = []
|
|
25
|
+
@locations = {}
|
|
26
|
+
@values = values
|
|
27
|
+
@trusted = true
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def untrusted!
|
|
31
|
+
@trusted = false
|
|
32
|
+
yield
|
|
33
|
+
ensure
|
|
34
|
+
@trusted = true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def set(key, value=nil, &block)
|
|
38
|
+
@trusted_keys << key if trusted? && !@trusted_keys.include?(key)
|
|
39
|
+
remember_location(key)
|
|
40
|
+
values[key] = block || value
|
|
41
|
+
trace_set(key)
|
|
42
|
+
values[key]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def fetch(key, default=nil, &block)
|
|
46
|
+
fetched_keys << key unless fetched_keys.include?(key)
|
|
47
|
+
peek(key, default, &block)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Internal use only.
|
|
51
|
+
def peek(key, default=nil, &block)
|
|
52
|
+
value = fetch_for(key, default, &block)
|
|
53
|
+
while callable_without_parameters?(value)
|
|
54
|
+
value = (values[key] = value.call)
|
|
55
|
+
end
|
|
56
|
+
value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def fetch_for(key, default, &block)
|
|
60
|
+
block ? values.fetch(key, &block) : values.fetch(key, default)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def delete(key)
|
|
64
|
+
values.delete(key)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def trusted_keys
|
|
68
|
+
@trusted_keys.dup
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def untrusted_keys
|
|
72
|
+
keys - @trusted_keys
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def keys
|
|
76
|
+
values.keys
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Keys that have been set, but which have never been fetched.
|
|
80
|
+
def unused_keys
|
|
81
|
+
keys - fetched_keys
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Returns an array of source file location(s) where the given key was
|
|
85
|
+
# assigned (i.e. where `set` was called). If the key was never assigned,
|
|
86
|
+
# returns `nil`.
|
|
87
|
+
def source_locations(key)
|
|
88
|
+
locations[key]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
attr_reader :locations, :values, :fetched_keys
|
|
94
|
+
|
|
95
|
+
def trusted?
|
|
96
|
+
@trusted
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def remember_location(key)
|
|
100
|
+
location = caller.find do |line|
|
|
101
|
+
IGNORED_LOCATIONS.none? { |i| line.include?(i) }
|
|
102
|
+
end
|
|
103
|
+
(locations[key] ||= []) << location
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def trace_set(key)
|
|
107
|
+
return unless fetch(:print_config_variables, false)
|
|
108
|
+
puts "Config variable set: #{key.inspect} => #{values[key].inspect}"
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
require_relative "configuration/filter"
|
|
2
|
+
require_relative "configuration/question"
|
|
3
|
+
require_relative "configuration/plugin_installer"
|
|
4
|
+
require_relative "configuration/server"
|
|
5
|
+
require_relative "configuration/servers"
|
|
6
|
+
require_relative "configuration/validated_variables"
|
|
7
|
+
require_relative "configuration/variables"
|
|
8
|
+
|
|
9
|
+
module Capistrano
|
|
10
|
+
class ValidationError < RuntimeError; end
|
|
11
|
+
|
|
12
|
+
class Configuration
|
|
13
|
+
def self.env
|
|
14
|
+
@env ||= new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.reset!
|
|
18
|
+
@env = new
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
extend Forwardable
|
|
22
|
+
attr_reader :variables
|
|
23
|
+
def_delegators :variables,
|
|
24
|
+
:set, :fetch, :fetch_for, :delete, :keys, :validate
|
|
25
|
+
|
|
26
|
+
def initialize(values={})
|
|
27
|
+
@variables = ValidatedVariables.new(Variables.new(values))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def ask(key, default=nil, options={})
|
|
31
|
+
question = Question.new(key, default, options)
|
|
32
|
+
set(key, question)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def set_if_empty(key, value=nil, &block)
|
|
36
|
+
set(key, value, &block) unless keys.include?(key)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def append(key, *values)
|
|
40
|
+
set(key, Array(fetch(key)).concat(values))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def remove(key, *values)
|
|
44
|
+
set(key, Array(fetch(key)) - values)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def any?(key)
|
|
48
|
+
value = fetch(key)
|
|
49
|
+
if value && value.respond_to?(:any?)
|
|
50
|
+
begin
|
|
51
|
+
return value.any?
|
|
52
|
+
rescue ArgumentError
|
|
53
|
+
# Gracefully ignore values whose `any?` method doesn't accept 0 args
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
!value.nil?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def is_question?(key)
|
|
61
|
+
value = fetch_for(key, nil)
|
|
62
|
+
!value.nil? && value.is_a?(Question)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def role(name, hosts, options={})
|
|
66
|
+
if name == :all
|
|
67
|
+
raise ArgumentError, "#{name} reserved name for role. Please choose another name"
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
servers.add_role(name, hosts, options)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def server(name, properties={})
|
|
74
|
+
servers.add_host(name, properties)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def roles_for(names)
|
|
78
|
+
servers.roles_for(names)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def role_properties_for(names, &block)
|
|
82
|
+
servers.role_properties_for(names, &block)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def primary(role)
|
|
86
|
+
servers.fetch_primary(role)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def backend
|
|
90
|
+
@backend ||= SSHKit
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
attr_writer :backend
|
|
94
|
+
|
|
95
|
+
def configure_backend
|
|
96
|
+
backend.configure do |sshkit|
|
|
97
|
+
configure_sshkit_output(sshkit)
|
|
98
|
+
sshkit.output_verbosity = fetch(:log_level)
|
|
99
|
+
sshkit.default_env = fetch(:default_env)
|
|
100
|
+
sshkit.backend = fetch(:sshkit_backend, SSHKit::Backend::Netssh)
|
|
101
|
+
sshkit.backend.configure do |backend|
|
|
102
|
+
backend.pty = fetch(:pty)
|
|
103
|
+
backend.connection_timeout = fetch(:connection_timeout)
|
|
104
|
+
backend.ssh_options = (backend.ssh_options || {}).merge(fetch(:ssh_options, {}))
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def configure_scm
|
|
110
|
+
Capistrano::Configuration::SCMResolver.new.resolve
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def timestamp
|
|
114
|
+
@timestamp ||= Time.now.utc
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def add_filter(filter=nil, &block)
|
|
118
|
+
if block
|
|
119
|
+
raise ArgumentError, "Both a block and an object were given" if filter
|
|
120
|
+
|
|
121
|
+
filter = Object.new
|
|
122
|
+
def filter.filter(servers)
|
|
123
|
+
block.call(servers)
|
|
124
|
+
end
|
|
125
|
+
elsif !filter.respond_to? :filter
|
|
126
|
+
raise TypeError, "Provided custom filter <#{filter.inspect}> does " \
|
|
127
|
+
"not have a public 'filter' method"
|
|
128
|
+
end
|
|
129
|
+
@custom_filters ||= []
|
|
130
|
+
@custom_filters << filter
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def setup_filters
|
|
134
|
+
@filters = cmdline_filters
|
|
135
|
+
@filters += @custom_filters if @custom_filters
|
|
136
|
+
@filters << Filter.new(:role, ENV["ROLES"]) if ENV["ROLES"]
|
|
137
|
+
@filters << Filter.new(:host, ENV["HOSTS"]) if ENV["HOSTS"]
|
|
138
|
+
fh = fetch_for(:filter, {}) || {}
|
|
139
|
+
@filters << Filter.new(:host, fh[:hosts]) if fh[:hosts]
|
|
140
|
+
@filters << Filter.new(:role, fh[:roles]) if fh[:roles]
|
|
141
|
+
@filters << Filter.new(:host, fh[:host]) if fh[:host]
|
|
142
|
+
@filters << Filter.new(:role, fh[:role]) if fh[:role]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def add_cmdline_filter(type, values)
|
|
146
|
+
cmdline_filters << Filter.new(type, values)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def filter(list)
|
|
150
|
+
setup_filters if @filters.nil?
|
|
151
|
+
@filters.reduce(list) { |l, f| f.filter l }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def dry_run?
|
|
155
|
+
fetch(:sshkit_backend) == SSHKit::Backend::Printer
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def install_plugin(plugin, load_hooks: true, load_immediately: false)
|
|
159
|
+
installer.install(plugin,
|
|
160
|
+
load_hooks: load_hooks,
|
|
161
|
+
load_immediately: load_immediately)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def scm_plugin_installed?
|
|
165
|
+
installer.scm_installed?
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def servers
|
|
169
|
+
@servers ||= Servers.new
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
def cmdline_filters
|
|
175
|
+
@cmdline_filters ||= []
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def installer
|
|
179
|
+
@installer ||= PluginInstaller.new
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def configure_sshkit_output(sshkit)
|
|
183
|
+
format_args = [fetch(:format)]
|
|
184
|
+
format_args.push(fetch(:format_options)) if any?(:format_options)
|
|
185
|
+
|
|
186
|
+
sshkit.use_format(*format_args)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
load File.expand_path("../tasks/console.rake", __FILE__)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
validate :application do |_key, value|
|
|
2
|
+
changed_value = value.gsub(/[^A-Z0-9\.\-]/i, "_")
|
|
3
|
+
if value != changed_value
|
|
4
|
+
warn %Q(The :application value "#{value}" is invalid!)
|
|
5
|
+
warn "Use only letters, numbers, hyphens, dots, and underscores. For example:"
|
|
6
|
+
warn " set :application, '#{changed_value}'"
|
|
7
|
+
raise Capistrano::ValidationError
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
%i(git_strategy hg_strategy svn_strategy).each do |strategy|
|
|
12
|
+
validate(strategy) do |key, _value|
|
|
13
|
+
warn(
|
|
14
|
+
"[Deprecation Warning] #{key} is deprecated and will be removed in "\
|
|
15
|
+
"Capistrano 3.7.0.\n"\
|
|
16
|
+
"https://github.com/capistrano/capistrano/blob/master/UPGRADING-3.7.md"
|
|
17
|
+
)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
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
|
|
24
|
+
set_if_empty :branch, "master"
|
|
25
|
+
set_if_empty :deploy_to, -> { "/var/www/#{fetch(:application)}" }
|
|
26
|
+
set_if_empty :tmp_dir, "/tmp"
|
|
27
|
+
|
|
28
|
+
set_if_empty :default_env, {}
|
|
29
|
+
set_if_empty :keep_releases, 5
|
|
30
|
+
|
|
31
|
+
set_if_empty :format, :airbrussh
|
|
32
|
+
set_if_empty :log_level, :debug
|
|
33
|
+
|
|
34
|
+
set_if_empty :pty, false
|
|
35
|
+
|
|
36
|
+
set_if_empty :local_user, -> { ENV["USER"] || ENV["LOGNAME"] || ENV["USERNAME"] }
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require "capistrano/doctor/output_helpers"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module Doctor
|
|
5
|
+
class EnvironmentDoctor
|
|
6
|
+
include Capistrano::Doctor::OutputHelpers
|
|
7
|
+
|
|
8
|
+
def call
|
|
9
|
+
title("Environment")
|
|
10
|
+
puts <<-OUT.gsub(/^\s+/, "")
|
|
11
|
+
Ruby #{RUBY_DESCRIPTION}
|
|
12
|
+
Rubygems #{Gem::VERSION}
|
|
13
|
+
Bundler #{defined?(Bundler::VERSION) ? Bundler::VERSION : 'N/A'}
|
|
14
|
+
Command #{$PROGRAM_NAME} #{ARGV.join(' ')}
|
|
15
|
+
OUT
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "capistrano/doctor/output_helpers"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module Doctor
|
|
5
|
+
# Prints table of all Capistrano-related gems and their version numbers. If
|
|
6
|
+
# there is a newer version of a gem available, call attention to it.
|
|
7
|
+
class GemsDoctor
|
|
8
|
+
include Capistrano::Doctor::OutputHelpers
|
|
9
|
+
|
|
10
|
+
def call
|
|
11
|
+
title("Gems")
|
|
12
|
+
table(all_gem_names) do |gem, row|
|
|
13
|
+
row.yellow if update_available?(gem)
|
|
14
|
+
row << gem
|
|
15
|
+
row << installed_gem_version(gem)
|
|
16
|
+
row << "(update available)" if update_available?(gem)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def installed_gem_version(gem_name)
|
|
23
|
+
Gem.loaded_specs[gem_name].version
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def update_available?(gem_name)
|
|
27
|
+
latest = Gem.latest_version_for(gem_name)
|
|
28
|
+
return false if latest.nil?
|
|
29
|
+
latest > installed_gem_version(gem_name)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def all_gem_names
|
|
33
|
+
core_gem_names + plugin_gem_names
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def core_gem_names
|
|
37
|
+
%w(capistrano airbrussh rake sshkit net-ssh) & Gem.loaded_specs.keys
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def plugin_gem_names
|
|
41
|
+
(Gem.loaded_specs.keys - ["capistrano"]).grep(/capistrano/).sort
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Capistrano
|
|
2
|
+
module Doctor
|
|
3
|
+
# Helper methods for pretty-printing doctor output to stdout. All output
|
|
4
|
+
# (other than `title`) is indented by four spaces to facilitate copying and
|
|
5
|
+
# pasting this output into e.g. GitHub or Stack Overflow to achieve code
|
|
6
|
+
# formatting.
|
|
7
|
+
module OutputHelpers
|
|
8
|
+
class Row
|
|
9
|
+
attr_reader :color
|
|
10
|
+
attr_reader :values
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@values = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def <<(value)
|
|
17
|
+
values << value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def yellow
|
|
21
|
+
@color = :yellow
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Prints a table for a given array of records. For each record, the block
|
|
26
|
+
# is yielded two arguments: the record and a Row object. To print values
|
|
27
|
+
# for that record, add values using `row << "some value"`. A row can
|
|
28
|
+
# optionally be highlighted in yellow using `row.yellow`.
|
|
29
|
+
def table(records, &block)
|
|
30
|
+
return if records.empty?
|
|
31
|
+
rows = collect_rows(records, &block)
|
|
32
|
+
col_widths = calculate_column_widths(rows)
|
|
33
|
+
|
|
34
|
+
rows.each do |row|
|
|
35
|
+
line = row.values.each_with_index.map do |value, col|
|
|
36
|
+
value.to_s.ljust(col_widths[col])
|
|
37
|
+
end.join(" ").rstrip
|
|
38
|
+
line = color.colorize(line, row.color) if row.color
|
|
39
|
+
puts line
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Prints a title in blue with surrounding newlines.
|
|
44
|
+
def title(text)
|
|
45
|
+
# Use $stdout directly to bypass the indentation that our `puts` does.
|
|
46
|
+
$stdout.puts(color.colorize("\n#{text}\n", :blue))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Prints text in yellow.
|
|
50
|
+
def warning(text)
|
|
51
|
+
puts color.colorize(text, :yellow)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Override `Kernel#puts` to prepend four spaces to each line.
|
|
55
|
+
def puts(string=nil)
|
|
56
|
+
$stdout.puts(string.to_s.gsub(/^/, " "))
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def collect_rows(records)
|
|
62
|
+
records.map do |rec|
|
|
63
|
+
Row.new.tap { |row| yield(rec, row) }
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def calculate_column_widths(rows)
|
|
68
|
+
num_columns = rows.map { |row| row.values.length }.max
|
|
69
|
+
Array.new(num_columns) do |col|
|
|
70
|
+
rows.map { |row| row.values[col].to_s.length }.max
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def color
|
|
75
|
+
@color ||= SSHKit::Color.new($stdout)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|