calas-capitate 0.3.6
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.
- data/Capfile +13 -0
- data/History.txt +167 -0
- data/License.txt +20 -0
- data/Manifest.txt +121 -0
- data/README.txt +8 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +72 -0
- data/config/requirements.rb +17 -0
- data/lib/capitate.rb +56 -0
- data/lib/capitate/cap_ext/connections.rb +105 -0
- data/lib/capitate/cap_ext/docs.rb +26 -0
- data/lib/capitate/cap_ext/namespace.rb +34 -0
- data/lib/capitate/cap_ext/run_via.rb +16 -0
- data/lib/capitate/cap_ext/task_definition.rb +22 -0
- data/lib/capitate/cap_ext/variables.rb +132 -0
- data/lib/capitate/plugins/base.rb +140 -0
- data/lib/capitate/plugins/build.rb +71 -0
- data/lib/capitate/plugins/gem.rb +24 -0
- data/lib/capitate/plugins/prompt.rb +109 -0
- data/lib/capitate/plugins/rake.rb +25 -0
- data/lib/capitate/plugins/script.rb +96 -0
- data/lib/capitate/plugins/templates.rb +113 -0
- data/lib/capitate/plugins/utils.rb +151 -0
- data/lib/capitate/plugins/yum.rb +76 -0
- data/lib/capitate/recipes.rb +5 -0
- data/lib/capitate/task_node.rb +262 -0
- data/lib/capitate/version.rb +9 -0
- data/lib/deployment/centos-5.1-64-web/install.rb +196 -0
- data/lib/recipes/active_record.rb +36 -0
- data/lib/recipes/apache.rb +47 -0
- data/lib/recipes/backgroundrb.rb +29 -0
- data/lib/recipes/centos/backgroundjob.rb +27 -0
- data/lib/recipes/centos/backgroundrb.rb +23 -0
- data/lib/recipes/centos/centos.rb +45 -0
- data/lib/recipes/centos/imagemagick.rb +29 -0
- data/lib/recipes/centos/memcached.rb +45 -0
- data/lib/recipes/centos/merb.rb +23 -0
- data/lib/recipes/centos/mongrel_cluster.rb +54 -0
- data/lib/recipes/centos/monit.rb +62 -0
- data/lib/recipes/centos/mysql.rb +25 -0
- data/lib/recipes/centos/nginx.rb +64 -0
- data/lib/recipes/centos/ruby.rb +40 -0
- data/lib/recipes/centos/sphinx.rb +59 -0
- data/lib/recipes/docs.rb +24 -0
- data/lib/recipes/logrotate/backgroundjob.rb +26 -0
- data/lib/recipes/logrotate/backgroundrb.rb +26 -0
- data/lib/recipes/logrotate/merb.rb +25 -0
- data/lib/recipes/logrotate/mongrel_cluster.rb +29 -0
- data/lib/recipes/logrotate/monit.rb +28 -0
- data/lib/recipes/logrotate/mysql.rb +26 -0
- data/lib/recipes/logrotate/nginx.rb +37 -0
- data/lib/recipes/logrotate/rails.rb +21 -0
- data/lib/recipes/logrotate/sphinx.rb +21 -0
- data/lib/recipes/logrotated.rb +61 -0
- data/lib/recipes/memcached.rb +26 -0
- data/lib/recipes/merb.rb +32 -0
- data/lib/recipes/monit.rb +35 -0
- data/lib/recipes/monit/backgroundjob.rb +38 -0
- data/lib/recipes/monit/backgroundrb.rb +38 -0
- data/lib/recipes/monit/database.rb +25 -0
- data/lib/recipes/monit/memcached.rb +22 -0
- data/lib/recipes/monit/merb.rb +58 -0
- data/lib/recipes/monit/mongrel_cluster.rb +85 -0
- data/lib/recipes/monit/mysql.rb +20 -0
- data/lib/recipes/monit/nginx.rb +37 -0
- data/lib/recipes/monit/sphinx.rb +38 -0
- data/lib/recipes/monit/sshd.rb +27 -0
- data/lib/recipes/mysql.rb +42 -0
- data/lib/recipes/nginx.rb +29 -0
- data/lib/recipes/rails.rb +71 -0
- data/lib/recipes/redmine.rb +38 -0
- data/lib/recipes/sphinx.rb +60 -0
- data/lib/recipes/sshd.rb +47 -0
- data/lib/recipes/syslogd.rb +21 -0
- data/lib/templates/apache/vhost.mongrel_cluster.conf.erb +46 -0
- data/lib/templates/backgroundjob/backgroundjob.initd.centos.erb +54 -0
- data/lib/templates/backgroundjob/backgroundjob.monitrc.erb +3 -0
- data/lib/templates/backgroundrb/backgroundrb.initd.centos.erb +58 -0
- data/lib/templates/backgroundrb/backgroundrb.monitrc.erb +3 -0
- data/lib/templates/backgroundrb/backgroundrb.yml.erb +14 -0
- data/lib/templates/capistrano/Capfile +22 -0
- data/lib/templates/logrotated/conf.erb +3 -0
- data/lib/templates/memcached/memcached.initd.centos.erb +58 -0
- data/lib/templates/memcached/memcached.monitrc.erb +4 -0
- data/lib/templates/memcached/memcached.yml.erb +14 -0
- data/lib/templates/merb/merb-no-http.monitrc.erb +13 -0
- data/lib/templates/merb/merb.initd.centos.erb +123 -0
- data/lib/templates/merb/merb.monitrc.erb +15 -0
- data/lib/templates/mongrel/mongrel_cluster.initd.centos.erb +94 -0
- data/lib/templates/mongrel/mongrel_cluster.monitrc.erb +15 -0
- data/lib/templates/mongrel/mongrel_cluster.yml.erb +11 -0
- data/lib/templates/monit/monit.cnf +34 -0
- data/lib/templates/monit/monit.initd.centos.erb +68 -0
- data/lib/templates/monit/monitrc.erb +18 -0
- data/lib/templates/mysql/install_db.sql.erb +6 -0
- data/lib/templates/mysql/my.cnf.innodb_1024.erb +122 -0
- data/lib/templates/mysql/my.cnf.innodb_512.erb +127 -0
- data/lib/templates/mysql/mysql.monitrc.erb +6 -0
- data/lib/templates/nginx/nginx.conf.erb +97 -0
- data/lib/templates/nginx/nginx.initd.centos.erb +69 -0
- data/lib/templates/nginx/nginx.monitrc.erb +4 -0
- data/lib/templates/nginx/nginx_vhost.conf.erb +101 -0
- data/lib/templates/nginx/nginx_vhost_generic.conf.erb +99 -0
- data/lib/templates/rails/database.yml.erb +7 -0
- data/lib/templates/redmine/email.yml.erb +10 -0
- data/lib/templates/ruby/fix_openssl.sh +12 -0
- data/lib/templates/sphinx/sphinx.conf.erb +157 -0
- data/lib/templates/sphinx/sphinx.monitrc.erb +4 -0
- data/lib/templates/sphinx/sphinx_app.initd.centos.erb +90 -0
- data/lib/templates/sshd/sshd.monitrc.erb +5 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +80 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +23 -0
- data/test/test_helper.rb +2 -0
- data/test/test_plugin_upload.rb +32 -0
- data/test/test_recipes.rb +37 -0
- data/test/test_templates.rb +29 -0
- metadata +198 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Patch to add ability to clear sessions/connections.
|
|
2
|
+
module Capitate
|
|
3
|
+
module CapExt
|
|
4
|
+
module Connections
|
|
5
|
+
|
|
6
|
+
# Set the user to something new (but save the old user; reset_user will set it back).
|
|
7
|
+
# Takes care of invalidating current connections. Will force a re-login.
|
|
8
|
+
#
|
|
9
|
+
# ==== Options
|
|
10
|
+
# +new_user+:: User to become
|
|
11
|
+
#
|
|
12
|
+
# ==== Examples
|
|
13
|
+
# set_user("nginx")
|
|
14
|
+
# # Do something as user nginx
|
|
15
|
+
#
|
|
16
|
+
def set_user(new_user)
|
|
17
|
+
previous_user = fetch(:user)
|
|
18
|
+
|
|
19
|
+
return if previous_user == new_user
|
|
20
|
+
set :previous_user, previous_user
|
|
21
|
+
|
|
22
|
+
set :user, new_user
|
|
23
|
+
clear_sessions
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Reset to the old user.
|
|
27
|
+
# Takes care of invalidating current connections. Will force a re-login.
|
|
28
|
+
#
|
|
29
|
+
# ==== Examples
|
|
30
|
+
# # User is "root"
|
|
31
|
+
# set_user("nginx")
|
|
32
|
+
# # Do something as user nginx
|
|
33
|
+
# reset_user
|
|
34
|
+
# # User is now root
|
|
35
|
+
#
|
|
36
|
+
def reset_user
|
|
37
|
+
return unless exists?(:previous_user)
|
|
38
|
+
set :user, fetch(:previous_user)
|
|
39
|
+
unset :previous_user
|
|
40
|
+
clear_sessions
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Perform action as a different user. Yields the previous user to the block.
|
|
44
|
+
#
|
|
45
|
+
# ==== Options
|
|
46
|
+
# +new_user+:: User to become
|
|
47
|
+
#
|
|
48
|
+
# ==== Examples
|
|
49
|
+
# new_user("nginx") do |old_user|
|
|
50
|
+
# # Do something as user nginx
|
|
51
|
+
# end
|
|
52
|
+
# # Now as user old_user
|
|
53
|
+
#
|
|
54
|
+
def with_user(new_user, &block)
|
|
55
|
+
begin
|
|
56
|
+
set_user(new_user)
|
|
57
|
+
yield exists?(:previous_user) ? fetch(:previous_user) : nil
|
|
58
|
+
ensure
|
|
59
|
+
reset_user
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
clear_sessions
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Close all open sessions, and will force user to re-login.
|
|
66
|
+
def clear_sessions
|
|
67
|
+
sessions.each do |key, session|
|
|
68
|
+
logger.info "Closing: #{key}"
|
|
69
|
+
session.close
|
|
70
|
+
end
|
|
71
|
+
sessions.clear
|
|
72
|
+
reset_password
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Reset the password.
|
|
76
|
+
# Display the current user that is asking for the password.
|
|
77
|
+
def reset_password
|
|
78
|
+
set :password, Proc.new {
|
|
79
|
+
Capistrano::CLI.password_prompt("Password (for user: #{user}): ")
|
|
80
|
+
}
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Debug connections
|
|
88
|
+
class Capistrano::SSH
|
|
89
|
+
|
|
90
|
+
class << self
|
|
91
|
+
|
|
92
|
+
def connect_with_logging(server, options={}, &block)
|
|
93
|
+
@connect_mutex ||= Mutex.new
|
|
94
|
+
|
|
95
|
+
@connect_mutex.synchronize do
|
|
96
|
+
puts "--- Connecting to #{server} with user: #{server.user || options[:user]}"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
connect_without_logging(server, options, &block)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
alias_method_chain :connect, :logging
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module Capitate
|
|
2
|
+
|
|
3
|
+
module CapExt
|
|
4
|
+
|
|
5
|
+
module Docs
|
|
6
|
+
|
|
7
|
+
# Get link to github source, so we can refer to recipe code.
|
|
8
|
+
#
|
|
9
|
+
# ==== Options
|
|
10
|
+
# +recipe+:: Recipe path, probably use __FILE__
|
|
11
|
+
#
|
|
12
|
+
# ==== Examples
|
|
13
|
+
# # In a lib/recipes/foo/foo.rb
|
|
14
|
+
# link_to_source(__FILE__) => "http://github.com/gabriel/capitate/tree/master/lib/recipes/foo/foo.rb"
|
|
15
|
+
#
|
|
16
|
+
def link_to_source(recipe_path)
|
|
17
|
+
full_path = File.expand_path(recipe_path)
|
|
18
|
+
project_path = File.expand_path(File.dirname(__FILE__) + "/../../../")
|
|
19
|
+
"http://github.com/gabriel/capitate/tree/master#{full_path.sub(project_path, "")}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module Capitate
|
|
2
|
+
|
|
3
|
+
module CapExt
|
|
4
|
+
|
|
5
|
+
module Namespace
|
|
6
|
+
|
|
7
|
+
def self.included(base) #:nodoc:
|
|
8
|
+
unless base.method_defined?(:task_without_capitate)
|
|
9
|
+
base.send :alias_method, :task_without_capitate, :task
|
|
10
|
+
base.send :alias_method, :task, :task_with_capitate
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def task_arg(name, desc, options = {})
|
|
15
|
+
@next_task_arguments ||= []
|
|
16
|
+
@next_task_arguments << options.merge({ :name => name, :desc => desc })
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def task_with_capitate(name, options={}, &block)
|
|
20
|
+
task_without_capitate(name, options) do
|
|
21
|
+
find_task(name).setup_defaults
|
|
22
|
+
block.call
|
|
23
|
+
end
|
|
24
|
+
task_def = find_task(name)
|
|
25
|
+
task_def.arguments = @next_task_arguments
|
|
26
|
+
@next_task_arguments = nil
|
|
27
|
+
task_def
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Capitate::CapExt::RunVia
|
|
2
|
+
|
|
3
|
+
# Invoke command with current run_method setting.
|
|
4
|
+
#
|
|
5
|
+
# Chooses +sudo+ or +run+ based on <tt>:run_method</tt> setting.
|
|
6
|
+
#
|
|
7
|
+
# ==== Options
|
|
8
|
+
# +cmd+:: Command to run
|
|
9
|
+
# +options+:: Options (see invoke_command options)
|
|
10
|
+
#
|
|
11
|
+
def run_via(cmd, options = {}, &block)
|
|
12
|
+
options[:via] = fetch(:run_method, :sudo) unless options.has_key?(:via)
|
|
13
|
+
invoke_command(cmd, options, &block)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Capitate
|
|
2
|
+
|
|
3
|
+
module CapExt
|
|
4
|
+
|
|
5
|
+
module TaskDefinition
|
|
6
|
+
|
|
7
|
+
attr_accessor :arguments
|
|
8
|
+
|
|
9
|
+
def setup_defaults
|
|
10
|
+
return if arguments.blank?
|
|
11
|
+
|
|
12
|
+
arguments.each do |arg|
|
|
13
|
+
namespace.fetch_or_default(arg[:name], arg[:default]) if arg.has_key?(:default)
|
|
14
|
+
namespace.fetch_or_set(arg[:name], arg[:set]) if arg.has_key?(:set)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
module Capitate
|
|
2
|
+
module CapExt
|
|
3
|
+
module Variables
|
|
4
|
+
|
|
5
|
+
def self.included(base) #:nodoc:
|
|
6
|
+
base.send :alias_method, :fetch_without_capitate, :fetch
|
|
7
|
+
base.send :alias_method, :fetch, :fetch_with_capitate
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Fetch.
|
|
11
|
+
# Displays usage message from recipe docs if variable not found.
|
|
12
|
+
#
|
|
13
|
+
# See capistrano fetch for usage info.
|
|
14
|
+
#
|
|
15
|
+
def fetch_with_capitate(variable, *args)
|
|
16
|
+
begin
|
|
17
|
+
fetch_without_capitate(variable, *args)
|
|
18
|
+
rescue IndexError
|
|
19
|
+
message = capitate.usage(variable)
|
|
20
|
+
|
|
21
|
+
if message.blank?
|
|
22
|
+
message = <<-EOS
|
|
23
|
+
|
|
24
|
+
Please set :#{variable} variable in your Capfile or deploy.rb
|
|
25
|
+
|
|
26
|
+
EOS
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
raise IndexError, "\n#{message}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Fetch or set and return default.
|
|
34
|
+
#
|
|
35
|
+
# ==== Options
|
|
36
|
+
# +variable+:: Variable to fetch
|
|
37
|
+
# +default+:: Default value if not set
|
|
38
|
+
# +args+:: ?
|
|
39
|
+
#
|
|
40
|
+
# ==== Examples
|
|
41
|
+
# fetch_or_default(:memcached_port, 11211) => 11211
|
|
42
|
+
# # Any calls to fetch(memcached_port) in the future will return this value 11211 (unless overriden)
|
|
43
|
+
#
|
|
44
|
+
def fetch_or_default(variable, default, *args)
|
|
45
|
+
if exists?(variable)
|
|
46
|
+
fetch(variable, *args)
|
|
47
|
+
else
|
|
48
|
+
set variable, default
|
|
49
|
+
default
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Fetch or set and fetch any default variable listed.
|
|
54
|
+
#
|
|
55
|
+
# ==== Options
|
|
56
|
+
# +variable+:: Variable to fetch
|
|
57
|
+
# +variables+:: List if variables to try in order
|
|
58
|
+
#
|
|
59
|
+
# ==== Examples
|
|
60
|
+
# fetch_or_set(:sphinx_db_host, :db_host)
|
|
61
|
+
#
|
|
62
|
+
def fetch_or_set(variable, *default_variables)
|
|
63
|
+
return fetch(variable) if exists?(variable)
|
|
64
|
+
|
|
65
|
+
default_variables.each do |default_variable|
|
|
66
|
+
if exists?(default_variable)
|
|
67
|
+
value = fetch(default_variable)
|
|
68
|
+
set variable, value
|
|
69
|
+
return value
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
nil
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Fetch roles with name and options.
|
|
76
|
+
# I don't actually use this.
|
|
77
|
+
#
|
|
78
|
+
# ==== Options
|
|
79
|
+
# +name+:: Role name to look for
|
|
80
|
+
# +options+:: Options to match on, e.g. :primary => true
|
|
81
|
+
#
|
|
82
|
+
# ==== Examples
|
|
83
|
+
# fetch_roles(:db) => [ "10.0.6.71", "10.0.6.72" ]
|
|
84
|
+
# fetch_roles(:db, :primary => true) => [ "10.0.6.71" ]
|
|
85
|
+
#
|
|
86
|
+
def fetch_roles(name, options = {})
|
|
87
|
+
matched_roles = Set.new
|
|
88
|
+
|
|
89
|
+
roles.each do |role_info|
|
|
90
|
+
role_name = role_info.first
|
|
91
|
+
|
|
92
|
+
next unless role_name == name
|
|
93
|
+
|
|
94
|
+
role = role_info.last
|
|
95
|
+
role.each do |server|
|
|
96
|
+
|
|
97
|
+
abort = false
|
|
98
|
+
options.each do |k, v|
|
|
99
|
+
unless server.options[k] == v
|
|
100
|
+
abort = true
|
|
101
|
+
break
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
next if abort
|
|
105
|
+
|
|
106
|
+
matched_roles << server
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
matched_roles.to_a
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Fetch first role with name and options.
|
|
113
|
+
#
|
|
114
|
+
# ==== Options
|
|
115
|
+
# +name+:: Role name to look for
|
|
116
|
+
# +options+:: Options to match on, e.g. :primary => true
|
|
117
|
+
#
|
|
118
|
+
# ==== Examples
|
|
119
|
+
# fetch_roles(:db) => [ "10.0.6.71", "10.0.6.72" ]
|
|
120
|
+
# fetch_roles(:db, :primary => true) => [ "10.0.6.71" ]
|
|
121
|
+
#
|
|
122
|
+
def fetch_role(name, options = {})
|
|
123
|
+
matched = fetch_roles(name, options)
|
|
124
|
+
return matched.first if matched
|
|
125
|
+
nil
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
end
|
|
132
|
+
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
|
|
4
|
+
# Capitate base capistrano plugin
|
|
5
|
+
module Capitate::Plugins::Base
|
|
6
|
+
|
|
7
|
+
# Project root. Fetch from :project_root, or fall back to RAILS_ROOT.
|
|
8
|
+
def root
|
|
9
|
+
return fetch(:project_root) if exists?(:project_root)
|
|
10
|
+
RAILS_ROOT
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Path relative to project root.
|
|
14
|
+
#
|
|
15
|
+
# To set the project root:
|
|
16
|
+
#
|
|
17
|
+
# set :project_root, "path/to/project" in Capfile.
|
|
18
|
+
#
|
|
19
|
+
# ==== Options
|
|
20
|
+
# +path+:: Relative path
|
|
21
|
+
# +check_exist+:: Whether to check its existence and throw error if not found
|
|
22
|
+
#
|
|
23
|
+
# ==== Examples
|
|
24
|
+
# relative_to_root("config/foo.yml") => "path/to/project/config/foo.yml"
|
|
25
|
+
#
|
|
26
|
+
def relative_to_root(path = nil, check_exist = false)
|
|
27
|
+
if path
|
|
28
|
+
root_path = File.join(root, path)
|
|
29
|
+
else
|
|
30
|
+
root_path = root
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Check for file existance
|
|
34
|
+
if check_exist and !File.exist?(root_path)
|
|
35
|
+
raise <<-EOS
|
|
36
|
+
|
|
37
|
+
File not found: #{File.expand_path(root_path)}
|
|
38
|
+
|
|
39
|
+
This is loaded for the capitate plugin. View the README in:
|
|
40
|
+
#{File.expand_path(File.dirname(__FILE__) + "/../doc/README")}
|
|
41
|
+
EOS
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
root_path
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Usage for current task.
|
|
48
|
+
#
|
|
49
|
+
# ==== Options
|
|
50
|
+
# +variable+:: Missing variable setting (to display as not set)
|
|
51
|
+
#
|
|
52
|
+
# ==== Examples
|
|
53
|
+
# usage(:gem_list) => "Description from task definition."
|
|
54
|
+
#
|
|
55
|
+
def usage(variable = nil)
|
|
56
|
+
message = ""
|
|
57
|
+
|
|
58
|
+
if variable
|
|
59
|
+
message += <<-EOS
|
|
60
|
+
|
|
61
|
+
Error: :#{variable} not set.
|
|
62
|
+
EOS
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if current_task
|
|
66
|
+
message += <<-EOS
|
|
67
|
+
|
|
68
|
+
Usage:
|
|
69
|
+
|
|
70
|
+
#{indent_doc(current_task.desc)}
|
|
71
|
+
|
|
72
|
+
EOS
|
|
73
|
+
end
|
|
74
|
+
message
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Indent string block.
|
|
78
|
+
#
|
|
79
|
+
# ==== Options
|
|
80
|
+
# +s+:: String block
|
|
81
|
+
# +amount+:: Amount to indent
|
|
82
|
+
#
|
|
83
|
+
def indent_doc(s, amount = 4)
|
|
84
|
+
return nil if s.blank?
|
|
85
|
+
indentation = (0..amount).collect { |n| " " }.join
|
|
86
|
+
s.split("\n").collect { |sp| "#{indentation}#{sp}"}.join("\n")
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Unindent.
|
|
90
|
+
#
|
|
91
|
+
# Lifted from capistrano bin/capify
|
|
92
|
+
#
|
|
93
|
+
# ==== Options
|
|
94
|
+
# +string+:: String to unindent
|
|
95
|
+
#
|
|
96
|
+
def unindent(string)
|
|
97
|
+
return "" if string.blank?
|
|
98
|
+
if string =~ /\A(\s*)/
|
|
99
|
+
amount = $1.length
|
|
100
|
+
return string.strip.gsub(/^#{$1}/, "")
|
|
101
|
+
end
|
|
102
|
+
string
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Load all tasks into an array.
|
|
106
|
+
def load_all_tasks
|
|
107
|
+
tasks = []
|
|
108
|
+
top.namespaces.each do |namespace|
|
|
109
|
+
load_tasks(namespace, tasks)
|
|
110
|
+
end
|
|
111
|
+
tasks
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Build a task tree, consisting of task nodes.
|
|
115
|
+
def task_tree
|
|
116
|
+
top_node = Capitate::TaskNode.new("top")
|
|
117
|
+
|
|
118
|
+
load_all_tasks.each do |task|
|
|
119
|
+
Capitate::TaskNode.populate_with_task(top_node, task)
|
|
120
|
+
end
|
|
121
|
+
top_node
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
protected
|
|
125
|
+
|
|
126
|
+
def load_tasks(namespace, tasks = [])
|
|
127
|
+
recipe = namespace.last
|
|
128
|
+
|
|
129
|
+
recipe.namespaces.each do |nested_namespace|
|
|
130
|
+
load_tasks(nested_namespace, tasks)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
recipe.task_list.each do |task|
|
|
134
|
+
tasks << task
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
Capistrano.plugin :capitate, Capitate::Plugins::Base
|