piko-fast-tool 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/piko-fast-tool.gemspec +11 -0
- metadata +167 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require "capistrano/doctor/output_helpers"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module Doctor
|
|
5
|
+
class ServersDoctor
|
|
6
|
+
include Capistrano::Doctor::OutputHelpers
|
|
7
|
+
|
|
8
|
+
def initialize(env=Capistrano::Configuration.env)
|
|
9
|
+
@servers = env.servers.to_a
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def call
|
|
13
|
+
title("Servers (#{servers.size})")
|
|
14
|
+
rwc = RoleWhitespaceChecker.new(servers)
|
|
15
|
+
|
|
16
|
+
table(servers) do |server, row|
|
|
17
|
+
sd = ServerDecorator.new(server)
|
|
18
|
+
|
|
19
|
+
row << sd.uri_form
|
|
20
|
+
row << sd.roles
|
|
21
|
+
row << sd.properties
|
|
22
|
+
row.yellow if rwc.any_has_whitespace?(server.roles)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if rwc.whitespace_roles.any?
|
|
26
|
+
warning "\nWhitespace detected in role(s) #{rwc.whitespace_roles_decorated}. " \
|
|
27
|
+
"This might be a result of a mistyped \"%w()\" array literal."
|
|
28
|
+
end
|
|
29
|
+
puts
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
attr_reader :servers
|
|
35
|
+
|
|
36
|
+
class RoleWhitespaceChecker
|
|
37
|
+
attr_reader :whitespace_roles, :servers
|
|
38
|
+
|
|
39
|
+
def initialize(servers)
|
|
40
|
+
@servers = servers
|
|
41
|
+
@whitespace_roles = find_whitespace_roles
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def any_has_whitespace?(roles)
|
|
45
|
+
roles.any? { |role| include_whitespace?(role) }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def include_whitespace?(role)
|
|
49
|
+
role =~ /\s/
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def whitespace_roles_decorated
|
|
53
|
+
whitespace_roles.map(&:inspect).join(", ")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def find_whitespace_roles
|
|
59
|
+
servers.map(&:roles).flat_map(&:to_a).uniq
|
|
60
|
+
.select { |role| include_whitespace?(role) }
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class ServerDecorator
|
|
65
|
+
def initialize(server)
|
|
66
|
+
@server = server
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def uri_form
|
|
70
|
+
[
|
|
71
|
+
server.user,
|
|
72
|
+
server.user && "@",
|
|
73
|
+
server.hostname,
|
|
74
|
+
server.port && ":",
|
|
75
|
+
server.port
|
|
76
|
+
].compact.join
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def roles
|
|
80
|
+
server.roles.to_a.inspect
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def properties
|
|
84
|
+
return "" unless server.properties.keys.any?
|
|
85
|
+
pretty_inspect(server.properties.to_h)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
attr_reader :server
|
|
91
|
+
|
|
92
|
+
# Hashes with proper padding
|
|
93
|
+
def pretty_inspect(element)
|
|
94
|
+
return element.inspect unless element.is_a?(Hash)
|
|
95
|
+
|
|
96
|
+
pairs_string = element.keys.map do |key|
|
|
97
|
+
[pretty_inspect(key), pretty_inspect(element.fetch(key))].join(" => ")
|
|
98
|
+
end.join(", ")
|
|
99
|
+
|
|
100
|
+
"{ #{pairs_string} }"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require "capistrano/doctor/output_helpers"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module Doctor
|
|
5
|
+
# Prints a table of all Capistrano variables and their current values. If
|
|
6
|
+
# there are unrecognized variables, print warnings for them.
|
|
7
|
+
class VariablesDoctor
|
|
8
|
+
# These are keys that are recognized by Capistrano, but do not have values
|
|
9
|
+
# set by default.
|
|
10
|
+
WHITELIST = %i(
|
|
11
|
+
application
|
|
12
|
+
current_directory
|
|
13
|
+
linked_dirs
|
|
14
|
+
linked_files
|
|
15
|
+
releases_directory
|
|
16
|
+
repo_url
|
|
17
|
+
repo_tree
|
|
18
|
+
shared_directory
|
|
19
|
+
).freeze
|
|
20
|
+
private_constant :WHITELIST
|
|
21
|
+
|
|
22
|
+
include Capistrano::Doctor::OutputHelpers
|
|
23
|
+
|
|
24
|
+
def initialize(env=Capistrano::Configuration.env)
|
|
25
|
+
@env = env
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def call
|
|
29
|
+
title("Variables")
|
|
30
|
+
values = inspect_all_values
|
|
31
|
+
|
|
32
|
+
table(variables.keys.sort_by(&:to_s)) do |key, row|
|
|
33
|
+
row.yellow if suspicious_keys.include?(key)
|
|
34
|
+
row << key.inspect
|
|
35
|
+
row << values[key]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
puts if suspicious_keys.any?
|
|
39
|
+
|
|
40
|
+
suspicious_keys.sort_by(&:to_s).each do |key|
|
|
41
|
+
warning("#{key.inspect} is not a recognized Capistrano setting "\
|
|
42
|
+
"(#{location(key)})")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
attr_reader :env
|
|
49
|
+
|
|
50
|
+
def variables
|
|
51
|
+
env.variables
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def inspect_all_values
|
|
55
|
+
variables.keys.each_with_object({}) do |key, inspected|
|
|
56
|
+
inspected[key] = if env.is_question?(key)
|
|
57
|
+
"<ask>"
|
|
58
|
+
else
|
|
59
|
+
variables.peek(key).inspect
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def suspicious_keys
|
|
65
|
+
(variables.untrusted_keys & variables.unused_keys) - WHITELIST
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def location(key)
|
|
69
|
+
loc = variables.source_locations(key).first
|
|
70
|
+
loc && loc.sub(/^#{Regexp.quote(Dir.pwd)}/, "").sub(/:in.*/, "")
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require "forwardable"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module DSL
|
|
5
|
+
module Env
|
|
6
|
+
extend Forwardable
|
|
7
|
+
def_delegators :env,
|
|
8
|
+
:configure_backend, :fetch, :set, :set_if_empty, :delete,
|
|
9
|
+
:ask, :role, :server, :primary, :validate, :append,
|
|
10
|
+
:remove, :dry_run?, :install_plugin, :any?, :is_question?,
|
|
11
|
+
:configure_scm, :scm_plugin_installed?
|
|
12
|
+
|
|
13
|
+
def roles(*names)
|
|
14
|
+
env.roles_for(names.flatten)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def role_properties(*names, &block)
|
|
18
|
+
env.role_properties_for(names, &block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def release_roles(*names)
|
|
22
|
+
if names.last.is_a? Hash
|
|
23
|
+
names.last[:exclude] = :no_release
|
|
24
|
+
else
|
|
25
|
+
names << { exclude: :no_release }
|
|
26
|
+
end
|
|
27
|
+
roles(*names)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def env
|
|
31
|
+
Configuration.env
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def release_timestamp
|
|
35
|
+
env.timestamp.strftime("%Y%m%d%H%M%S")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def asset_timestamp
|
|
39
|
+
env.timestamp.strftime("%Y%m%d%H%M.%S")
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require "pathname"
|
|
2
|
+
module Capistrano
|
|
3
|
+
module DSL
|
|
4
|
+
module Paths
|
|
5
|
+
def deploy_to
|
|
6
|
+
fetch(:deploy_to)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def deploy_path
|
|
10
|
+
Pathname.new(deploy_to)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def current_path
|
|
14
|
+
deploy_path.join(fetch(:current_directory, "current"))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def releases_path
|
|
18
|
+
deploy_path.join(fetch(:releases_directory, "releases"))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def release_path
|
|
22
|
+
fetch(:release_path) { current_path }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def set_release_path(timestamp=now)
|
|
26
|
+
set(:release_timestamp, timestamp)
|
|
27
|
+
set(:release_path, releases_path.join(timestamp))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def stage_config_path
|
|
31
|
+
Pathname.new fetch(:stage_config_path, "config/deploy")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def deploy_config_path
|
|
35
|
+
Pathname.new fetch(:deploy_config_path, "config/deploy.rb")
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def repo_url
|
|
39
|
+
fetch(:repo_url)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def repo_path
|
|
43
|
+
Pathname.new(fetch(:repo_path, ->() { deploy_path.join("repo") }))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def shared_path
|
|
47
|
+
deploy_path.join(fetch(:shared_directory, "shared"))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def revision_log
|
|
51
|
+
deploy_path.join("revisions.log")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def now
|
|
55
|
+
env.timestamp.strftime("%Y%m%d%H%M%S")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def asset_timestamp
|
|
59
|
+
env.timestamp.strftime("%Y%m%d%H%M.%S")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def linked_dirs(parent)
|
|
63
|
+
paths = fetch(:linked_dirs)
|
|
64
|
+
join_paths(parent, paths)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def linked_files(parent)
|
|
68
|
+
paths = fetch(:linked_files)
|
|
69
|
+
join_paths(parent, paths)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def linked_file_dirs(parent)
|
|
73
|
+
map_dirnames(linked_files(parent))
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def linked_dir_parents(parent)
|
|
77
|
+
map_dirnames(linked_dirs(parent))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def join_paths(parent, paths)
|
|
81
|
+
paths.map { |path| parent.join(path) }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def map_dirnames(paths)
|
|
85
|
+
paths.map(&:dirname).uniq
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Capistrano
|
|
2
|
+
module DSL
|
|
3
|
+
module Stages
|
|
4
|
+
RESERVED_NAMES = %w(deploy doctor install).freeze
|
|
5
|
+
private_constant :RESERVED_NAMES
|
|
6
|
+
|
|
7
|
+
def stages
|
|
8
|
+
names = Dir[stage_definitions].map { |f| File.basename(f, ".rb") }
|
|
9
|
+
assert_valid_stage_names(names)
|
|
10
|
+
names
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def stage_definitions
|
|
14
|
+
stage_config_path.join("*.rb")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def stage_set?
|
|
18
|
+
!!fetch(:stage, false)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def assert_valid_stage_names(names)
|
|
24
|
+
invalid = names.find { |n| RESERVED_NAMES.include?(n) }
|
|
25
|
+
return if invalid.nil?
|
|
26
|
+
|
|
27
|
+
raise t("error.invalid_stage_name", name: invalid, path: stage_config_path.join("#{invalid}.rb"))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require "capistrano/upload_task"
|
|
2
|
+
|
|
3
|
+
module Capistrano
|
|
4
|
+
module TaskEnhancements
|
|
5
|
+
def before(task, prerequisite, *args, &block)
|
|
6
|
+
prerequisite = Rake::Task.define_task(prerequisite, *args, &block) if block_given?
|
|
7
|
+
Rake::Task[task].enhance [prerequisite]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def after(task, post_task, *args, &block)
|
|
11
|
+
Rake::Task.define_task(post_task, *args, &block) if block_given?
|
|
12
|
+
task = Rake::Task[task]
|
|
13
|
+
task.enhance do
|
|
14
|
+
post = Rake.application.lookup(post_task, task.scope)
|
|
15
|
+
raise ArgumentError, "Task #{post_task.inspect} not found" unless post
|
|
16
|
+
post.invoke
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def define_remote_file_task(task, target_roles)
|
|
21
|
+
Capistrano::UploadTask.define_task(task) do |t|
|
|
22
|
+
prerequisite_file = t.prerequisites.first
|
|
23
|
+
file = shared_path.join(t.name)
|
|
24
|
+
|
|
25
|
+
on roles(target_roles) do
|
|
26
|
+
unless test "[ -f #{file.to_s.shellescape} ]"
|
|
27
|
+
info "Uploading #{prerequisite_file} to #{file}"
|
|
28
|
+
upload! File.open(prerequisite_file), file
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def ensure_stage
|
|
35
|
+
Rake::Task.define_task(:ensure_stage) do
|
|
36
|
+
unless stage_set?
|
|
37
|
+
puts t(:stage_not_set)
|
|
38
|
+
exit 1
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def tasks_without_stage_dependency
|
|
44
|
+
stages + default_tasks
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def default_tasks
|
|
48
|
+
%w{install}
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def exit_deploy_because_of_exception(ex)
|
|
52
|
+
warn t(:deploy_failed, ex: ex.message)
|
|
53
|
+
invoke "deploy:failed"
|
|
54
|
+
exit(false)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def deploying?
|
|
58
|
+
fetch(:deploying, false)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require "capistrano/dsl/task_enhancements"
|
|
2
|
+
require "capistrano/dsl/paths"
|
|
3
|
+
require "capistrano/dsl/stages"
|
|
4
|
+
require "capistrano/dsl/env"
|
|
5
|
+
require "capistrano/configuration/filter"
|
|
6
|
+
|
|
7
|
+
module Capistrano
|
|
8
|
+
module DSL
|
|
9
|
+
include TaskEnhancements
|
|
10
|
+
include Env
|
|
11
|
+
include Paths
|
|
12
|
+
include Stages
|
|
13
|
+
|
|
14
|
+
def invoke(task_name, *args)
|
|
15
|
+
task = Rake::Task[task_name]
|
|
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)
|
|
18
|
+
file, line, = caller.first.split(":")
|
|
19
|
+
colors = SSHKit::Color.new($stderr)
|
|
20
|
+
$stderr.puts colors.colorize("Skipping task `#{task_name}'.", :yellow)
|
|
21
|
+
$stderr.puts "Capistrano tasks may only be invoked once. Since task `#{task}' was previously invoked, invoke(\"#{task_name}\") at #{file}:#{line} will be skipped."
|
|
22
|
+
$stderr.puts "If you really meant to run this task again, use invoke!(\"#{task_name}\")"
|
|
23
|
+
$stderr.puts colors.colorize("THIS BEHAVIOR MAY CHANGE IN A FUTURE VERSION OF CAPISTRANO. Please join the conversation here if this affects you.", :red)
|
|
24
|
+
$stderr.puts colors.colorize("https://github.com/capistrano/capistrano/issues/1686", :red)
|
|
25
|
+
end
|
|
26
|
+
task.invoke(*args)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def invoke!(task_name, *args)
|
|
30
|
+
task = Rake::Task[task_name]
|
|
31
|
+
task.reenable
|
|
32
|
+
task.invoke(*args)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def t(key, options={})
|
|
36
|
+
I18n.t(key, **options.merge(scope: :capistrano))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def scm
|
|
40
|
+
fetch(:scm)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sudo(*args)
|
|
44
|
+
execute :sudo, *args
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def revision_log_message
|
|
48
|
+
fetch(:revision_log_message,
|
|
49
|
+
t(:revision_log_message,
|
|
50
|
+
branch: fetch(:branch),
|
|
51
|
+
user: local_user,
|
|
52
|
+
sha: fetch(:current_revision),
|
|
53
|
+
release: fetch(:release_timestamp)))
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def rollback_log_message
|
|
57
|
+
t(:rollback_log_message, user: local_user, release: fetch(:rollback_timestamp))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def local_user
|
|
61
|
+
fetch(:local_user)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def lock(locked_version)
|
|
65
|
+
VersionValidator.new(locked_version).verify
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# rubocop:disable Security/MarshalLoad
|
|
69
|
+
def on(hosts, options={}, &block)
|
|
70
|
+
subset_copy = Marshal.dump(Configuration.env.filter(hosts))
|
|
71
|
+
SSHKit::Coordinator.new(Marshal.load(subset_copy)).each(options, &block)
|
|
72
|
+
end
|
|
73
|
+
# rubocop:enable Security/MarshalLoad
|
|
74
|
+
|
|
75
|
+
def run_locally(&block)
|
|
76
|
+
SSHKit::Backend::Local.new(&block).run
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Catch common beginner mistake and give a helpful error message on stderr
|
|
80
|
+
def execute(*)
|
|
81
|
+
file, line, = caller.first.split(":")
|
|
82
|
+
colors = SSHKit::Color.new($stderr)
|
|
83
|
+
$stderr.puts colors.colorize("Warning: `execute' should be wrapped in an `on' scope in #{file}:#{line}.", :red)
|
|
84
|
+
$stderr.puts
|
|
85
|
+
$stderr.puts " task :example do"
|
|
86
|
+
$stderr.puts colors.colorize(" on roles(:app) do", :yellow)
|
|
87
|
+
$stderr.puts " execute 'whoami'"
|
|
88
|
+
$stderr.puts colors.colorize(" end", :yellow)
|
|
89
|
+
$stderr.puts " end"
|
|
90
|
+
$stderr.puts
|
|
91
|
+
raise NoMethodError, "undefined method `execute' for main:Object"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
extend Capistrano::DSL
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require "i18n"
|
|
2
|
+
|
|
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}: ",
|
|
14
|
+
question_default: "Please enter %{key} (%{default_value}): ",
|
|
15
|
+
question_prompt: "%{key}: ",
|
|
16
|
+
question_prompt_default: "%{key} (%{default_value}): ",
|
|
17
|
+
keeping_releases: "Keeping %{keep_releases} of %{releases} deployed releases on %{host}",
|
|
18
|
+
skip_cleanup: "Skipping cleanup of invalid releases on %{host}; unexpected foldername found (should be timestamp)",
|
|
19
|
+
wont_delete_current_release: "Current release was marked for being removed but it's going to be skipped on %{host}",
|
|
20
|
+
no_current_release: "There is no current release present on %{host}",
|
|
21
|
+
no_old_releases: "No old releases (keeping newest %{keep_releases}) on %{host}",
|
|
22
|
+
linked_file_does_not_exist: "linked file %{file} does not exist on %{host}",
|
|
23
|
+
cannot_rollback: "There are no older releases to rollback to",
|
|
24
|
+
cannot_found_rollback_release: "Cannot rollback because release %{release} does not exist",
|
|
25
|
+
mirror_exists: "The repository mirror is at %{at}",
|
|
26
|
+
revision_log_message: "Branch %{branch} (at %{sha}) deployed as release %{release} by %{user}",
|
|
27
|
+
rollback_log_message: "%{user} rolled back to release %{release}",
|
|
28
|
+
deploy_failed: "The deploy has failed with an error: %{ex}",
|
|
29
|
+
console: {
|
|
30
|
+
welcome: "capistrano console - enter command to execute on %{stage}",
|
|
31
|
+
bye: "bye"
|
|
32
|
+
},
|
|
33
|
+
error: {
|
|
34
|
+
invalid_stage_name: '"%{name}" is a reserved word and cannot be used as a stage. Rename "%{path}" to something else.',
|
|
35
|
+
user: {
|
|
36
|
+
does_not_exist: "User %{user} does not exists",
|
|
37
|
+
cannot_switch: "Cannot switch to user %{user}"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
I18n.backend.store_translations(:en, capistrano: en)
|
|
43
|
+
|
|
44
|
+
if I18n.respond_to?(:enforce_available_locales=)
|
|
45
|
+
I18n.enforce_available_locales = true
|
|
46
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
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
|
+
ERROR: #{name} has already been invoked and can no longer be modified.
|
|
21
|
+
Check that you haven't loaded a Capistrano plugin in deploy.rb or a stage
|
|
22
|
+
(e.g. deploy/production.rb) by mistake.
|
|
23
|
+
Plugins must be loaded in the Capfile to initialize properly.
|
|
24
|
+
MESSAGE
|
|
25
|
+
|
|
26
|
+
# This will raise a frozen object error
|
|
27
|
+
super(*args, &block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
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
|