Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
---|---|---|---|---|
lib/bee_console_formatter.rb | 348 | 230 | 93.68%
|
92.17%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
1 # Copyright 2006-2012 Michel Casabianca <michel.casabianca@gmail.com> |
2 # |
3 # Licensed under the Apache License, Version 2.0 (the "License"); |
4 # you may not use this file except in compliance with the License. |
5 # You may obtain a copy of the License at |
6 # |
7 # http://www.apache.org/licenses/LICENSE-2.0 |
8 # |
9 # Unless required by applicable law or agreed to in writing, software |
10 # distributed under the License is distributed on an "AS IS" BASIS, |
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 # See the License for the specific language governing permissions and |
13 # limitations under the License. |
14 |
15 require 'rubygems' |
16 require 'bee_console_style' |
17 require 'syck' |
18 require 'yaml' |
19 |
20 module Bee |
21 |
22 module Console |
23 |
24 # Class to format build output on console. |
25 class Formatter |
26 |
27 include Bee::Util::BuildErrorMixin |
28 |
29 # Minimum duration to print on console even if not verbose (in seconds) |
30 AUTO_DURATION = 60 |
31 |
32 # Construct formatting order |
33 CONSTRUCT_FORMATS = { |
34 'if' => ['if', 'then', 'else'], |
35 'while' => ['while', 'do'], |
36 'for' => ['for', 'in', 'do'], |
37 'try' => ['try', 'catch'], |
38 } |
39 |
40 # Verbosity indicator |
41 attr_reader :verbose |
42 |
43 # Constructor. |
44 # - style: style as a Hash or a String. |
45 # - color: tells if we use default color scheme. Defaults to false. |
46 # - verbose: tells if build is verbose. Defaults to false. |
47 # - outputer: object on which we call print and puts for outputs. |
48 # Defaults to Kernel. |
49 def initialize(style, color=false, verbose=false, outputer=Kernel) |
50 @style = Bee::Console::Style.new(style, color) |
51 @verbose = verbose |
52 @outputer = outputer |
53 end |
54 |
55 ########################################################################## |
56 # LOW LEVEL OUTPUT METHODS # |
57 ########################################################################## |
58 |
59 # Print a given message on console: |
60 # - message: the message to print. |
61 def print(message) |
62 @outputer.print(message) |
63 end |
64 |
65 # Puts a given message on console: |
66 # - message: the message to put. |
67 def puts(message) |
68 @outputer.puts(message) |
69 end |
70 |
71 ########################################################################## |
72 # METHODS CALLED BY LISTENER # |
73 ########################################################################## |
74 |
75 # Print build start message: |
76 # - build: the started build. |
77 # - dry_run: tells if we are running in dry mode. |
78 def print_build_started(build, dry_run) |
79 if @verbose |
80 build_type = dry_run ? "dry run of" : "build" |
81 puts "Starting #{build_type} '#{build.file}'..." |
82 end |
83 end |
84 |
85 # Print message when build finished: |
86 # - duration: the build duration in seconds. |
87 # - success: tells if build was a success. |
88 # - exception : exception raised, if any. |
89 # - last_target: last met target, if any. |
90 # - last_task: last met task, if any. |
91 def print_build_finished(duration) |
92 puts "Built in #{duration} s" if @verbose or duration >= AUTO_DURATION |
93 end |
94 |
95 # Print target: |
96 # - target: the target we are running. |
97 def print_target(target) |
98 puts format_target(target) |
99 end |
100 |
101 # Print task: |
102 # - task: the task we are running. |
103 def print_task(task) |
104 puts format_task(task) if @verbose |
105 end |
106 |
107 ########################################################################## |
108 # FORMATTING METHODS # |
109 ########################################################################## |
110 |
111 # Format a target. |
112 # - target: target to format. |
113 def format_target(target) |
114 name = target.name |
115 return format_title(name) |
116 end |
117 |
118 # Format a task. |
119 # - task: task to format. |
120 def format_task(task) |
121 if task.kind_of?(String) |
122 source = task |
123 elsif task.kind_of?(Hash) |
124 if task.key?('rb') |
125 source = "rb: #{task['rb']}" |
126 else |
127 if task.keys.length == 1 |
128 source = format_entry(task) |
129 else |
130 source = format_construct(task) |
131 end |
132 end |
133 end |
134 formatted = '- ' + source.strip.gsub(/\n/, "\n. ") |
135 styled = @style.style(formatted, :task) |
136 return styled |
137 end |
138 |
139 # Format a success string. |
140 # - string: string to format. |
141 def format_success(string) |
142 string = @style.style(string, :success) |
143 return string |
144 end |
145 |
146 # Format an error string. |
147 # - string: string to format. |
148 def format_error(string) |
149 string = @style.style(string, :error) |
150 return string |
151 end |
152 |
153 # Format error message: |
154 # - exception: raised exception. |
155 def format_error_message(exception) |
156 message = format_error('ERROR') |
157 message << ": " |
158 message << exception.to_s |
159 if exception.kind_of?(Bee::Util::BuildError) |
160 message << "\nIn target '#{exception.target.name}'" if exception.target |
161 message << ", in task:\n#{format_task(exception.task)}" if exception.task |
162 end |
163 return message |
164 end |
165 |
166 # Format a description. |
167 # - title: description title (project, property or target name). |
168 # - text: description text. |
169 # - indent: indentation width. |
170 # - bullet: tells if we must put a bullet. |
171 def format_description(title, text=nil, indent=0, bullet=true) |
172 string = ' '*indent |
173 string << '- ' if bullet |
174 string << title |
175 if text and !text.empty? |
176 string << ": " |
177 if text.split("\n").length > 1 |
178 string << "\n" |
179 text.split("\n").each do |line| |
180 string << ' '*(indent+2) + line.strip + "\n" |
181 end |
182 else |
183 string << text.strip + "\n" |
184 end |
185 else |
186 string << "\n" |
187 end |
188 return string |
189 end |
190 |
191 # Format a title. |
192 # - title: title to format. |
193 def format_title(title) |
194 length = @style.line_length || Bee::Util::term_width |
195 right = ' ' + @style.line_character*2 |
196 size = length - (title.length + 4) |
197 size = 2 if size <= 0 |
198 left = @style.line_character*size + ' ' |
199 line = left + title + right |
200 # apply style |
201 formatted = @style.style(line, :target) |
202 return formatted |
203 end |
204 |
205 ########################################################################## |
206 # HELP FORMATTING METHODS # |
207 ########################################################################## |
208 |
209 # Return help about build. |
210 # - build: running build. |
211 def help_build(build) |
212 build.context.evaluate |
213 help = '' |
214 # print build name and description |
215 if build.name |
216 help << "build: #{build.name}\n" |
217 end |
218 if build.extends |
219 help << "extends: #{format_list(build.extends.map{|b| b.name})}\n" |
220 end |
221 if build.description |
222 help << format_description('description', build.description, 0, false) |
223 end |
224 # print build properties |
225 if build.context.properties.length > 0 |
226 help << "properties:\n" |
227 for property in build.context.properties.sort |
228 help << "- #{property}: " + |
229 "#{format_property_value(build.context.get_property(property))}\n" |
230 end |
231 end |
232 # print build targets |
233 description = build.targets.description |
234 if description.length > 0 |
235 help << "targets:\n" |
236 for name in description.keys.sort |
237 help << format_description(name, description[name], 0) |
238 end |
239 end |
240 # print default target |
241 help << "default: #{format_list(build.targets.default)}\n" if |
242 build.targets.default |
243 # print alias for targets |
244 if build.targets.alias and build.targets.alias.keys.length > 0 |
245 help << "alias:\n" |
246 for name in build.targets.alias.keys.sort |
247 help << " #{name}: #{format_list(build.targets.alias[name])}\n" |
248 end |
249 end |
250 return help.strip |
251 end |
252 |
253 # Return help about task(s). |
254 # - task: task to print help about (all tasks if nil). |
255 def help_task(task) |
256 task = '?' if task == nil or task.length == 0 |
257 package_manager = Bee::Task::PackageManager.new(nil) |
258 methods = package_manager.help_task(task) |
259 help = '' |
260 for method in methods.keys.sort |
261 text = methods[method].strip |
262 help << format_title(method) |
263 help << "\n" |
264 help << text |
265 help << "\n" |
266 if text =~ /Alias for \w+/ |
267 alias_method = text.scan(/Alias for (\w+)/).flatten[0] |
268 help << "\n" |
269 help << package_manager.help_task(alias_method)[alias_method].strip |
270 help << "\n" |
271 end |
272 end |
273 return help |
274 end |
275 |
276 # Return help about template(s). |
277 # - template: template to print help about (all templates if nil). |
278 def help_template(template) |
279 templates = Bee::Util::search_templates(template) |
280 help = '' |
281 for name in templates.keys |
282 build = YAML::load(File.read(templates[name])) |
283 properties = nil |
284 for entry in build |
285 properties = entry['properties'] if entry['properties'] |
286 end |
287 description = 'No description found' |
288 if properties |
289 if properties['description'] |
290 description = properties['description'] |
291 end |
292 end |
293 help << format_title(name) |
294 help << "\n" |
295 help << description |
296 help << "\n" |
297 end |
298 return help |
299 end |
300 |
301 private |
302 |
303 def format_entry(entry) |
304 return YAML::dump(entry).sub(/---/, '').strip |
305 end |
306 |
307 def format_construct(construct) |
308 for key in CONSTRUCT_FORMATS.keys |
309 if construct.has_key?(key) |
310 lines = [] |
311 for entry in CONSTRUCT_FORMATS[key] |
312 lines << format_entry({entry => construct[entry]}) |
313 end |
314 return lines.join("\n") |
315 end |
316 end |
317 return "UNKNOWN CONSTRUCT" |
318 end |
319 |
320 def format_property_value(data) |
321 if data.kind_of?(Hash) |
322 pairs = [] |
323 for key in data.keys() |
324 pairs << "#{format_property_value(key)}: #{format_property_value(data[key])}" |
325 end |
326 return "{#{pairs.join(', ')}}" |
327 else |
328 return data.inspect |
329 end |
330 end |
331 |
332 def format_list(list) |
333 if list.kind_of?(Array) |
334 if list.length > 1 |
335 return "[#{list.join(', ')}]" |
336 else |
337 return list[0] |
338 end |
339 else |
340 return list |
341 end |
342 end |
343 |
344 end |
345 |
346 end |
347 |
348 end |
Generated on Fri Oct 09 02:07:49 +0200 2015 with rcov 1.0.0