capistrano 2.12.0 → 2.13.5
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/CHANGELOG +29 -1
- data/README.mdown +3 -2
- data/bin/capify +1 -3
- data/capistrano.gemspec +3 -3
- data/lib/capistrano/command.rb +1 -0
- data/lib/capistrano/configuration.rb +6 -1
- data/lib/capistrano/configuration/actions/inspect.rb +2 -2
- data/lib/capistrano/configuration/actions/invocation.rb +7 -0
- data/lib/capistrano/configuration/callbacks.rb +22 -4
- data/lib/capistrano/configuration/execution.rb +2 -3
- data/lib/capistrano/configuration/log_formatters.rb +71 -0
- data/lib/capistrano/configuration/namespaces.rb +20 -13
- data/lib/capistrano/logger.rb +98 -4
- data/lib/capistrano/recipes/deploy.rb +45 -83
- data/lib/capistrano/recipes/deploy/assets.rb +1 -1
- data/lib/capistrano/recipes/deploy/scm/git.rb +0 -1
- data/lib/capistrano/recipes/deploy/scm/none.rb +7 -0
- data/lib/capistrano/recipes/deploy/strategy/base.rb +1 -1
- data/lib/capistrano/shell.rb +4 -4
- data/lib/capistrano/version.rb +2 -7
- data/test/command_test.rb +8 -0
- data/test/configuration/actions/inspect_test.rb +13 -2
- data/test/configuration/actions/invocation_test.rb +6 -1
- data/test/configuration/callbacks_test.rb +24 -0
- data/test/configuration/namespace_dsl_test.rb +2 -2
- data/test/configuration_test.rb +1 -1
- data/test/deploy/scm/git_test.rb +1 -1
- data/test/deploy/strategy/copy_test.rb +2 -1
- data/test/logger_formatting_test.rb +94 -0
- data/test/logger_test.rb +12 -1
- metadata +51 -19
- data/lib/capistrano/recipes/deploy/templates/maintenance.rhtml +0 -53
- data/lib/capistrano/recipes/templates/maintenance.rhtml +0 -53
data/CHANGELOG
CHANGED
@@ -1,6 +1,34 @@
|
|
1
|
+
## 2.13.5 (tentative) / October 26 2012
|
2
|
+
|
3
|
+
* Merged in `capistrano_colors` gem, and renamed to 'log_formatters', since it does much more than just colors
|
4
|
+
(@ndbroadbent)
|
5
|
+
* Use more intelligence in setting the :scm variable based on known version control directory names (@czarneckid)
|
6
|
+
* Remove the deploy:web:{disable, enable} tasks (@carsomyr)
|
7
|
+
* Group finalize_update shell commands into one command, harden shell calls with #shellescape, and separate arguments
|
8
|
+
with -- (@ndbroadbent)
|
9
|
+
|
10
|
+
## 2.13.0 / August 21 2012
|
11
|
+
|
12
|
+
This release contains multiple bugfixes and handling of exotic situations. The
|
13
|
+
`Configuration#capture` method should now work in spite of `ActiveSupport`
|
14
|
+
shenanigans. Thank you, the community, for all of your contributions:
|
15
|
+
|
16
|
+
* Close input streams when sending commands that don't read input. Dylan Smith
|
17
|
+
(dylanahsmith)
|
18
|
+
* Listen for method definition on `Kernel` and undefine on `Namespace`. Chris
|
19
|
+
Griego (cgriego)
|
20
|
+
* Fixed shell `Thread.abort_on_exception` bug. George Malamidis (nutrun)
|
21
|
+
* Adding a log method to `Capistrano::Deploy::SCM::None` to maintain
|
22
|
+
consistency with other SCM classes. Kevin Lawver (kplawver)
|
23
|
+
* Add deprecation warning if someone uses old `deploy:symlink` syntax on
|
24
|
+
callbacks. Ken Mazaika (kenmazaika)
|
25
|
+
* Simplify the `finalize_update` code by respecting the `:shared_children`
|
26
|
+
variable during removal and recreation of the parent. John Knight
|
27
|
+
(knightlabs)
|
28
|
+
|
1
29
|
## 2.12.0 / April 13 2012
|
2
30
|
|
3
|
-
This release
|
31
|
+
This release reverts the very verbose logging introduced in the previous version, it also
|
4
32
|
enables a handful of power-user features which are largely un-documented, but shouldn't be
|
5
33
|
important unless you are looking for them. Undocumented code shouldn't scare you, simply
|
6
34
|
read through deploy.rb in the Gem if you want to know how a new feature works!
|
data/README.mdown
CHANGED
@@ -17,7 +17,7 @@ of tasks designed for deploying Rails applications.
|
|
17
17
|
|
18
18
|
## Documentation
|
19
19
|
|
20
|
-
* [
|
20
|
+
* [https://github.com/capistrano/capistrano/wiki](https://github.com/capistrano/capistrano/wiki)
|
21
21
|
|
22
22
|
## DEPENDENCIES
|
23
23
|
|
@@ -26,6 +26,7 @@ of tasks designed for deploying Rails applications.
|
|
26
26
|
* [Net::SCP](http://net-ssh.rubyforge.org)
|
27
27
|
* [Net::SSH::Gateway](http://net-ssh.rubyforge.org)
|
28
28
|
* [HighLine](http://highline.rubyforge.org)
|
29
|
+
* [Ruby](http://www.ruby-lang.org/en/) ≥ 1.8.7
|
29
30
|
|
30
31
|
If you want to run the tests, you'll also need to install the dependencies with
|
31
32
|
Bundler, see the `Gemfile` within .
|
@@ -51,7 +52,7 @@ In general, you'll use Capistrano as follows:
|
|
51
52
|
|
52
53
|
Use the `cap` script as follows:
|
53
54
|
|
54
|
-
|
55
|
+
cap sometask
|
55
56
|
|
56
57
|
By default, the script will look for a file called one of `capfile` or
|
57
58
|
`Capfile`. The `someaction` text indicates which task to execute. You can do
|
data/bin/capify
CHANGED
@@ -43,15 +43,13 @@ files = {
|
|
43
43
|
# Uncomment if you are using Rails' asset pipeline
|
44
44
|
# load 'deploy/assets'
|
45
45
|
|
46
|
-
Dir['vendor/gems/*/recipes/*.rb','vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }
|
47
|
-
|
48
46
|
load 'config/deploy' # remove this line to skip loading any of the default tasks
|
49
47
|
FILE
|
50
48
|
|
51
49
|
"config/deploy.rb" => 'set :application, "set your application name here"
|
52
50
|
set :repository, "set your repository location here"
|
53
51
|
|
54
|
-
set :scm, :
|
52
|
+
# set :scm, :git # You can set :scm explicitly or Capistrano will make an intelligent guess based on known version control directory names
|
55
53
|
# Or: `accurev`, `bzr`, `cvs`, `darcs`, `git`, `mercurial`, `perforce`, `subversion` or `none`
|
56
54
|
|
57
55
|
role :web, "your web-server here" # Your HTTP server, Apache/etc
|
data/capistrano.gemspec
CHANGED
@@ -28,14 +28,14 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.add_runtime_dependency(%q<net-sftp>, [">= 2.0.0"])
|
29
29
|
s.add_runtime_dependency(%q<net-scp>, [">= 1.0.0"])
|
30
30
|
s.add_runtime_dependency(%q<net-ssh-gateway>, [">= 1.1.0"])
|
31
|
-
s.add_development_dependency(%q<mocha>, ["
|
31
|
+
s.add_development_dependency(%q<mocha>, ["0.9.12"])
|
32
32
|
else
|
33
33
|
s.add_dependency(%q<net-ssh>, [">= 2.0.14"])
|
34
34
|
s.add_dependency(%q<net-sftp>, [">= 2.0.0"])
|
35
35
|
s.add_dependency(%q<net-scp>, [">= 1.0.0"])
|
36
36
|
s.add_dependency(%q<net-ssh-gateway>, [">= 1.1.0"])
|
37
37
|
s.add_dependency(%q<highline>, [">= 0"])
|
38
|
-
s.add_dependency(%q<mocha>, ["
|
38
|
+
s.add_dependency(%q<mocha>, ["0.9.12"])
|
39
39
|
end
|
40
40
|
else
|
41
41
|
s.add_dependency(%q<net-ssh>, [">= 2.0.14"])
|
@@ -43,6 +43,6 @@ Gem::Specification.new do |s|
|
|
43
43
|
s.add_dependency(%q<net-scp>, [">= 1.0.0"])
|
44
44
|
s.add_dependency(%q<net-ssh-gateway>, [">= 1.1.0"])
|
45
45
|
s.add_dependency(%q<highline>, [">= 0"])
|
46
|
-
s.add_dependency(%q<mocha>, ["
|
46
|
+
s.add_dependency(%q<mocha>, ["0.9.12"])
|
47
47
|
end
|
48
48
|
end
|
data/lib/capistrano/command.rb
CHANGED
@@ -221,6 +221,7 @@ module Capistrano
|
|
221
221
|
|
222
222
|
ch.exec(command_line)
|
223
223
|
ch.send_data(options[:data]) if options[:data]
|
224
|
+
ch.eof! if options[:eof]
|
224
225
|
else
|
225
226
|
# just log it, don't actually raise an exception, since the
|
226
227
|
# process method will see that the status is not zero and will
|
@@ -5,6 +5,7 @@ require 'capistrano/configuration/callbacks'
|
|
5
5
|
require 'capistrano/configuration/connections'
|
6
6
|
require 'capistrano/configuration/execution'
|
7
7
|
require 'capistrano/configuration/loading'
|
8
|
+
require 'capistrano/configuration/log_formatters'
|
8
9
|
require 'capistrano/configuration/namespaces'
|
9
10
|
require 'capistrano/configuration/roles'
|
10
11
|
require 'capistrano/configuration/servers'
|
@@ -34,12 +35,16 @@ module Capistrano
|
|
34
35
|
|
35
36
|
# The includes must come at the bottom, since they may redefine methods
|
36
37
|
# defined in the base class.
|
37
|
-
include AliasTask, Connections, Execution, Loading, Namespaces, Roles, Servers, Variables
|
38
|
+
include AliasTask, Connections, Execution, Loading, LogFormatters, Namespaces, Roles, Servers, Variables
|
38
39
|
|
39
40
|
# Mix in the actions
|
40
41
|
include Actions::FileTransfer, Actions::Inspect, Actions::Invocation
|
41
42
|
|
42
43
|
# Must mix last, because it hooks into previously defined methods
|
43
44
|
include Callbacks
|
45
|
+
|
46
|
+
((self.instance_methods & Kernel.methods) - Namespaces::Namespace.instance_methods).each do |name|
|
47
|
+
Namespaces::Namespace.send(:undef_method, name)
|
48
|
+
end
|
44
49
|
end
|
45
50
|
end
|
@@ -20,7 +20,7 @@ module Capistrano
|
|
20
20
|
# stream "tail -f #{shared_path}/log/fastcgi.crash.log"
|
21
21
|
# end
|
22
22
|
def stream(command, options={})
|
23
|
-
invoke_command(command, options) do |ch, stream, out|
|
23
|
+
invoke_command(command, options.merge(:eof => !command.include?(sudo))) do |ch, stream, out|
|
24
24
|
puts out if stream == :out
|
25
25
|
warn "[err :: #{ch[:server]}] #{out}" if stream == :err
|
26
26
|
end
|
@@ -31,7 +31,7 @@ module Capistrano
|
|
31
31
|
# string. The command is invoked via #invoke_command.
|
32
32
|
def capture(command, options={})
|
33
33
|
output = ""
|
34
|
-
invoke_command(command, options.merge(:once => true)) do |ch, stream, data|
|
34
|
+
invoke_command(command, options.merge(:once => true, :eof => !command.include?(sudo))) do |ch, stream, data|
|
35
35
|
case stream
|
36
36
|
when :out then output << data
|
37
37
|
when :err then warn "[err :: #{ch[:server]}] #{data}"
|
@@ -138,11 +138,18 @@ module Capistrano
|
|
138
138
|
# and the values should be their corresponding values. The default is
|
139
139
|
# empty, but may be modified by changing the +default_environment+
|
140
140
|
# Capistrano variable.
|
141
|
+
# * :eof - if true, the standard input stream will be closed after sending
|
142
|
+
# any data specified in the :data option. If false, the input stream is
|
143
|
+
# left open. The default is to close the input stream only if no block is
|
144
|
+
# passed.
|
141
145
|
#
|
142
146
|
# Note that if you set these keys in the +default_run_options+ Capistrano
|
143
147
|
# variable, they will apply for all invocations of #run, #invoke_command,
|
144
148
|
# and #parallel.
|
145
149
|
def run(cmd, options={}, &block)
|
150
|
+
if options[:eof].nil? && !cmd.include?(sudo)
|
151
|
+
options = options.merge(:eof => !block_given?)
|
152
|
+
end
|
146
153
|
block ||= self.class.default_io_proc
|
147
154
|
tree = Command::Tree.new(self) { |t| t.else(cmd, &block) }
|
148
155
|
run_tree(tree, options)
|
@@ -19,7 +19,7 @@ module Capistrano
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def invoke_task_directly_with_callbacks(task) #:nodoc:
|
22
|
-
|
22
|
+
|
23
23
|
trigger :before, task
|
24
24
|
|
25
25
|
result = invoke_task_directly_without_callbacks(task)
|
@@ -106,12 +106,30 @@ module Capistrano
|
|
106
106
|
elsif block
|
107
107
|
callbacks[event] << ProcCallback.new(block, options)
|
108
108
|
else
|
109
|
-
args
|
110
|
-
|
111
|
-
|
109
|
+
args = filter_deprecated_tasks(args)
|
110
|
+
options[:only] = filter_deprecated_tasks(options[:only])
|
111
|
+
options[:except] = filter_deprecated_tasks(options[:except])
|
112
|
+
|
113
|
+
callbacks[event].concat(args.map { |name| TaskCallback.new(self, name, options) })
|
112
114
|
end
|
113
115
|
end
|
114
116
|
|
117
|
+
# Filters the given task name or names and attempts to replace deprecated tasks with their equivalents.
|
118
|
+
def filter_deprecated_tasks(names)
|
119
|
+
deprecation_msg = "[Deprecation Warning] This API has changed, please hook `deploy:create_symlink` instead of" \
|
120
|
+
" `deploy:symlink`."
|
121
|
+
|
122
|
+
if names == "deploy:symlink"
|
123
|
+
warn deprecation_msg
|
124
|
+
names = "deploy:create_symlink"
|
125
|
+
elsif names.is_a?(Array) && names.include?("deploy:symlink")
|
126
|
+
warn deprecation_msg
|
127
|
+
names = names.map { |name| name == "deploy:symlink" ? "deploy:create_symlink" : name }
|
128
|
+
end
|
129
|
+
|
130
|
+
names
|
131
|
+
end
|
132
|
+
|
115
133
|
# Trigger the named event for the named task. All associated callbacks
|
116
134
|
# will be fired, in the order they were defined.
|
117
135
|
def trigger(event, task=nil)
|
@@ -59,7 +59,7 @@ module Capistrano
|
|
59
59
|
rollback!
|
60
60
|
raise
|
61
61
|
ensure
|
62
|
-
self.rollback_requests = nil
|
62
|
+
self.rollback_requests = nil
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
@@ -108,8 +108,7 @@ module Capistrano
|
|
108
108
|
|
109
109
|
def rollback!
|
110
110
|
return if Thread.current[:rollback_requests].nil?
|
111
|
-
|
112
|
-
|
111
|
+
|
113
112
|
# throw the task back on the stack so that roles are properly
|
114
113
|
# interpreted in the scope of the task in question.
|
115
114
|
rollback_requests.reverse.each do |frame|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Add custom log formatters
|
2
|
+
#
|
3
|
+
# Passing a hash or a array of hashes with custom log formatters.
|
4
|
+
#
|
5
|
+
# Add the following to your deploy.rb or in your ~/.caprc
|
6
|
+
#
|
7
|
+
# == Example:
|
8
|
+
#
|
9
|
+
# capistrano_log_formatters = [
|
10
|
+
# { :match => /command finished/, :color => :hide, :priority => 10, :prepend => "$$$" },
|
11
|
+
# { :match => /executing command/, :color => :blue, :priority => 10, :style => :underscore, :timestamp => true },
|
12
|
+
# { :match => /^transaction: commit$/, :color => :magenta, :priority => 10, :style => :blink },
|
13
|
+
# { :match => /git/, :color => :white, :priority => 20, :style => :reverse }
|
14
|
+
# ]
|
15
|
+
#
|
16
|
+
# format_logs capistrano_log_formatters
|
17
|
+
#
|
18
|
+
# You can call format_logs multiple times, with either a hash or an array of hashes.
|
19
|
+
#
|
20
|
+
# == Colors:
|
21
|
+
#
|
22
|
+
# :color can have the following values:
|
23
|
+
#
|
24
|
+
# * :hide (hides the row completely)
|
25
|
+
# * :none
|
26
|
+
# * :black
|
27
|
+
# * :red
|
28
|
+
# * :green
|
29
|
+
# * :yellow
|
30
|
+
# * :blue
|
31
|
+
# * :magenta
|
32
|
+
# * :cyan
|
33
|
+
# * :white
|
34
|
+
#
|
35
|
+
# == Styles:
|
36
|
+
#
|
37
|
+
# :style can have the following values:
|
38
|
+
#
|
39
|
+
# * :bright
|
40
|
+
# * :dim
|
41
|
+
# * :underscore
|
42
|
+
# * :blink
|
43
|
+
# * :reverse
|
44
|
+
# * :hidden
|
45
|
+
#
|
46
|
+
#
|
47
|
+
# == Text alterations
|
48
|
+
#
|
49
|
+
# :prepend gives static text to be prepended to the output
|
50
|
+
# :replace replaces the matched text in the output
|
51
|
+
# :timestamp adds the current time before the output
|
52
|
+
|
53
|
+
module Capistrano
|
54
|
+
class Configuration
|
55
|
+
module LogFormatters
|
56
|
+
def log_formatter(options)
|
57
|
+
if options.class == Array
|
58
|
+
options.each do |option|
|
59
|
+
Capistrano::Logger.add_formatter(option)
|
60
|
+
end
|
61
|
+
else
|
62
|
+
Capistrano::Logger.add_formatter(options)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def disable_log_formatters
|
67
|
+
@logger.disable_formatters = true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -176,8 +176,6 @@ module Capistrano
|
|
176
176
|
def initialize(name, parent)
|
177
177
|
@parent = parent
|
178
178
|
@name = name
|
179
|
-
|
180
|
-
explicitly_define_clashing_kernel_methods
|
181
179
|
end
|
182
180
|
|
183
181
|
def role(*args)
|
@@ -199,18 +197,27 @@ module Capistrano
|
|
199
197
|
include Capistrano::Configuration::AliasTask
|
200
198
|
include Capistrano::Configuration::Namespaces
|
201
199
|
undef :desc, :next_description
|
202
|
-
|
203
|
-
protected
|
204
|
-
def explicitly_define_clashing_kernel_methods
|
205
|
-
(parent.public_methods & Kernel.methods).each do |m|
|
206
|
-
next if self.method(m).owner == self.class
|
207
|
-
if parent.method(m).owner == parent.class
|
208
|
-
metaclass = class << self; self; end
|
209
|
-
metaclass.send(:define_method, m) {|*args, &block| parent.send(m, *args, &block)}
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
200
|
end
|
214
201
|
end
|
215
202
|
end
|
216
203
|
end
|
204
|
+
|
205
|
+
module Kernel
|
206
|
+
class << self
|
207
|
+
alias_method :method_added_without_capistrano, :method_added
|
208
|
+
|
209
|
+
# Detect method additions to Kernel and remove them in the Namespace class
|
210
|
+
def method_added(name)
|
211
|
+
result = method_added_without_capistrano(name)
|
212
|
+
return result if self != Kernel
|
213
|
+
|
214
|
+
namespace = Capistrano::Configuration::Namespaces::Namespace
|
215
|
+
|
216
|
+
if namespace.method_defined?(name) && namespace.method(name).owner == Kernel
|
217
|
+
namespace.send :undef_method, name
|
218
|
+
end
|
219
|
+
|
220
|
+
result
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
data/lib/capistrano/logger.rb
CHANGED
@@ -1,15 +1,67 @@
|
|
1
1
|
module Capistrano
|
2
2
|
class Logger #:nodoc:
|
3
|
-
attr_accessor :level
|
4
|
-
attr_reader :device
|
3
|
+
attr_accessor :level, :device, :disable_formatters
|
5
4
|
|
6
5
|
IMPORTANT = 0
|
7
6
|
INFO = 1
|
8
7
|
DEBUG = 2
|
9
8
|
TRACE = 3
|
10
|
-
|
9
|
+
|
11
10
|
MAX_LEVEL = 3
|
12
11
|
|
12
|
+
COLORS = {
|
13
|
+
:none => "0",
|
14
|
+
:black => "30",
|
15
|
+
:red => "31",
|
16
|
+
:green => "32",
|
17
|
+
:yellow => "33",
|
18
|
+
:blue => "34",
|
19
|
+
:magenta => "35",
|
20
|
+
:cyan => "36",
|
21
|
+
:white => "37"
|
22
|
+
}
|
23
|
+
|
24
|
+
STYLES = {
|
25
|
+
:bright => 1,
|
26
|
+
:dim => 2,
|
27
|
+
:underscore => 4,
|
28
|
+
:blink => 5,
|
29
|
+
:reverse => 7,
|
30
|
+
:hidden => 8
|
31
|
+
}
|
32
|
+
|
33
|
+
# Set up default formatters
|
34
|
+
@formatters = [
|
35
|
+
# TRACE
|
36
|
+
{ :match => /command finished/, :color => :white, :style => :dim, :level => 3, :priority => -10 },
|
37
|
+
{ :match => /executing locally/, :color => :yellow, :level => 3, :priority => -20 },
|
38
|
+
|
39
|
+
# DEBUG
|
40
|
+
{ :match => /executing `.*/, :color => :green, :level => 2, :priority => -10, :timestamp => true },
|
41
|
+
{ :match => /.*/, :color => :yellow, :level => 2, :priority => -30 },
|
42
|
+
|
43
|
+
# INFO
|
44
|
+
{ :match => /.*out\] (fatal:|ERROR:).*/, :color => :red, :level => 1, :priority => -10 },
|
45
|
+
{ :match => /Permission denied/, :color => :red, :level => 1, :priority => -20 },
|
46
|
+
{ :match => /sh: .+: command not found/, :color => :magenta, :level => 1, :priority => -30 },
|
47
|
+
|
48
|
+
# IMPORTANT
|
49
|
+
{ :match => /^err ::/, :color => :red, :level => 0, :priority => -10 },
|
50
|
+
{ :match => /.*/, :color => :blue, :level => 0, :priority => -20 }
|
51
|
+
]
|
52
|
+
|
53
|
+
class << self
|
54
|
+
def add_formatter(options) #:nodoc:
|
55
|
+
@formatters.push(options)
|
56
|
+
@sorted_formatters = nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def sorted_formatters
|
60
|
+
# Sort matchers in reverse order so we can break if we found a match.
|
61
|
+
@sorted_formatters ||= @formatters.sort_by { |i| -(i[:priority] || i[:prio] || 0) }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
13
65
|
def initialize(options={})
|
14
66
|
output = options[:output] || $stderr
|
15
67
|
if output.respond_to?(:puts)
|
@@ -20,7 +72,8 @@ module Capistrano
|
|
20
72
|
end
|
21
73
|
|
22
74
|
@options = options
|
23
|
-
@level = 0
|
75
|
+
@level = options[:level] || 0
|
76
|
+
@disable_formatters = options[:disable_formatters]
|
24
77
|
end
|
25
78
|
|
26
79
|
def close
|
@@ -29,6 +82,42 @@ module Capistrano
|
|
29
82
|
|
30
83
|
def log(level, message, line_prefix=nil)
|
31
84
|
if level <= self.level
|
85
|
+
# Only format output if device is a TTY or formatters are not disabled
|
86
|
+
if device.tty? && !@disable_formatters
|
87
|
+
color = :none
|
88
|
+
style = nil
|
89
|
+
|
90
|
+
Logger.sorted_formatters.each do |formatter|
|
91
|
+
if (formatter[:level] == level || formatter[:level].nil?)
|
92
|
+
if message =~ formatter[:match] || line_prefix =~ formatter[:match]
|
93
|
+
color = formatter[:color] if formatter[:color]
|
94
|
+
style = formatter[:style] || formatter[:attribute] # (support original cap colors)
|
95
|
+
message.gsub!(formatter[:match], formatter[:replace]) if formatter[:replace]
|
96
|
+
message = formatter[:prepend] + message unless formatter[:prepend].nil?
|
97
|
+
message = message + formatter[:append] unless formatter[:append].nil?
|
98
|
+
message = Time.now.strftime('%Y-%m-%d %T') + ' ' + message if formatter[:timestamp]
|
99
|
+
break unless formatter[:replace]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
if color == :hide
|
105
|
+
# Don't do anything if color is set to :hide
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
term_color = COLORS[color]
|
110
|
+
term_style = STYLES[style]
|
111
|
+
|
112
|
+
# Don't format message if no color or style
|
113
|
+
unless color == :none and style.nil?
|
114
|
+
unless line_prefix.nil?
|
115
|
+
line_prefix = format(line_prefix, term_color, term_style, nil)
|
116
|
+
end
|
117
|
+
message = format(message, term_color, term_style)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
32
121
|
indent = "%*s" % [MAX_LEVEL, "*" * (MAX_LEVEL - level)]
|
33
122
|
(RUBY_VERSION >= "1.9" ? message.lines : message).each do |line|
|
34
123
|
if line_prefix
|
@@ -55,5 +144,10 @@ module Capistrano
|
|
55
144
|
def trace(message, line_prefix=nil)
|
56
145
|
log(TRACE, message, line_prefix)
|
57
146
|
end
|
147
|
+
|
148
|
+
def format(message, color, style, nl = "\n")
|
149
|
+
style = "#{style};" if style
|
150
|
+
"\e[#{style}#{color}m" + message.to_s.strip + "\e[0m#{nl}"
|
151
|
+
end
|
58
152
|
end
|
59
153
|
end
|