Bee C0 Coverage Information - RCov

lib/bee_target.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/bee_target.rb 304 207
100.00%
100.00%

Key

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.

Coverage Details

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_util'
17 
18 module Bee
19   
20   # Class for a target. It is built from the YAML build file and manages a
21   # target, in particular, tasks execution.
22   class Target
23     
24     include Bee::Util::BuildErrorMixin
25     include Bee::Util::HashCheckerMixin
26 
27     # Target key.
28     KEY = 'target'
29     # Target entry description.
30     DESCRIPTION = {
31       'target'      => :mandatory,
32       'depends'     => :optional,
33       'description' => :optional,
34       'script'      => :optional}
35 
36     # Targets for build.
37     attr_accessor :targets
38     # Name of the target.
39     attr_reader :name
40     # Target dependencies.
41     attr_accessor :depends
42     # Target description.
43     attr_accessor :description
44     # Script that run in the target.
45     attr_reader :script
46     
47     # Constructor.
48     # - object: object for target, resulting from YAML parsing.
49     # - targets: build targets.
50     def initialize(object, targets)
51       check_hash(object, Target::DESCRIPTION)
52       @targets = targets
53       @name = object[Target::KEY]
54       error "Target name cannot be 'null'" if @name == nil
55       @depends = Array(object['depends']||[])
56       @description = object['description']
57       @script = Array(object['script']||[])
58     end
59     
60     # Run target.
61     # - dry: tells if we run in dry mode. Defaults to false.
62     def run(dry=false)
63       current_dir = Dir.pwd
64       begin
65         for depend in @depends
66           @targets.run_target(depend, dry)
67         end
68         @targets.build.listener.target(self) if 
69           @targets.build.listener and @targets.is_last(self)
70         run_block(@script, dry)
71       ensure
72         Dir.chdir(current_dir)
73       end
74     end
75     
76     private
77     
78     # Run a task.
79     # - task: the task to run.
80     # - dry: whether to just print.
81     def run_task(task, dry=false)
82       @targets.build.listener.task(task) if @targets.build.listener
83       case task
84       when String
85         # shell script
86         run_shell(task, dry)
87       when Hash
88         if task.keys.length > 1
89           # construct
90           run_construct(task, dry)
91         else
92           if task.key?('rb')
93             # ruby script
94             script = task['rb']
95             run_ruby(script, dry)
96           elsif task.key?('sh')
97             # shell script
98             script = task['sh']
99             run_shell(script, dry)
100           elsif task.key?('super')
101             # call super target
102             targets.call_super(self, dry)
103           else
104             # bee task
105             run_bee_task(task, dry)
106           end
107         end
108       else
109         raise "Task must be a string or a hash"
110       end
111     end
112     
113     # Run a given shell script.
114     # - script: the scrip to run.
115     def run_shell(script, dry=false)
116       @listener.task(script) if @listener
117       return if dry
118       evaluated_script = @targets.build.context.evaluate_object(script)
119       if evaluated_script != ''
120         system(evaluated_script)
121         error "Script exited with value #{$?}" if $? != 0
122       end
123     end
124     
125     # Run a given shell script.
126     # - script: the scrip to run.
127     # - dry: tells if we run in dry mode.
128     def run_ruby(script, dry=false)
129       @listener.task(script) if @listener
130       return if dry
131       begin
132         @targets.build.context.evaluate_script(script)
133       rescue Interrupt
134         raise $!
135       rescue Exception
136         error "Error running Ruby script: #{$!}"
137       end
138     end
139     
140     # Run a given bee task.
141     # - task: task to run as a Hash.
142     def run_bee_task(task, dry=false)
143       @listener.task(task) if @listener
144       return if dry
145       @targets.build.package_manager.run_task(task)
146     end
147 
148     # Run a given construct.
149     # - construct: construct to run as a Hash.
150     # - dry: tells if we are running in dry mode. Defaults to false.
151     def run_construct(construct, dry=false)
152       @listener.task(construct) if @listener
153       return if dry
154       # if construct
155       if construct.keys.include?('if')
156         construct_if(construct, dry)
157       # while construct
158       elsif construct.keys.include?('while')
159         construct_while(construct, dry)
160       # for construct
161       elsif construct.keys.include?('for')
162         construct_for(construct, dry)
163       # try construct
164       elsif construct.keys.include?('try')
165         construct_try(construct, dry)
166       else
167         error "Unknown construct '#{construct.keys.join('-')}'"
168       end
169     end
170 
171     # Run if construct.
172     # - task: the construct as a hash.
173     # - dry: tells if we run in dry mode.
174     def construct_if(task, dry)
175       # test entries
176       error "If-then-else construct must include 'then' entry" if
177         not task.keys.include?('then')
178       unknown_keys = task.keys - ['if', 'then', 'else']
179       error "If-then-else construct may only include 'if', 'then' and 'else' entries" if
180         unknown_keys.length > 0
181       error "If entry in if-then-else construct must be a string, a symbol or a boolean" if
182         not task['if'].kind_of?(String) and
183         not task['if'].kind_of?(Symbol) and
184         not (task['if'].kind_of?(TrueClass) or task['if'].kind_of?(FalseClass))
185       error "Then entry in if-then-else construct must be a list" if
186         not task['then'].kind_of?(Array)
187       error "Else entry in if-then-else construct must be a list" if
188         task['else'] and not task['else'].kind_of?(Array)
189       # evaluate condition in the build context
190       if evaluate(task['if'])
191         run_block(task['then'], dry)
192       else
193         run_block(task['else'], dry) if task['else']
194       end
195     end
196 
197     # Run while construct.
198     # - task: the construct as a hash.
199     # - dry: tells if we run in dry mode.
200     def construct_while(task, dry)
201       # test entries
202       error "While-do construct must include 'do' entry" if
203         not task.keys.include?('do')
204       unknown_keys = task.keys - ['while', 'do']
205       error "While-do construct may only include 'while' and 'do' entries" if
206         unknown_keys.length > 0
207       error "While entry in while-do construct must be a string" if
208         not task['while'].kind_of?(String)
209       error "Do entry in while-do construct must be a list" if
210         not task['do'].kind_of?(Array)
211       # evaluate condition in the build context
212       while evaluate(task['while'])
213         run_block(task['do'], dry)
214       end
215     end
216 
217     # Run for construct.
218     # - task: the construct as a hash.
219     # - dry: tells if we run in dry mode.
220     def construct_for(task, dry)
221       # test entries
222       error "For-in-do construct must include 'in' and 'do' entries" if
223         not task.keys.include?('in') or
224         not task.keys.include?('do')
225       unknown_keys = task.keys - ['for', 'in', 'do']
226       error "For-in-do construct may only include 'for', 'in' and 'do' entries" if
227         unknown_keys.length > 0
228       error "For entry in for-in-do construct must be a string" if
229         not task['for'].kind_of?(String)
230       error "In entry in for-in-do construct must be a list, a string or a symbol" if
231         not task['in'].kind_of?(Enumerable) and
232         not task['in'].kind_of?(String) and
233         not task['in'].kind_of?(Symbol)
234       error "Do entry in for-in-do construct must be a list" if
235         not task['do'].kind_of?(Array)
236       # iterate over list
237       if task['in'].kind_of?(String) or task['in'].kind_of?(Symbol)
238         enumerable = evaluate(task['in'])
239         error "In entry in for-in-do construct must result in an enumerable" if
240           not enumerable.kind_of?(Enumerable)
241       else
242         enumerable = task['in']
243       end
244       for element in enumerable
245         begin
246           @targets.build.context.set_property(task['for'], element)
247         rescue
248           error "Error setting property '#{task['for']}'"
249         end
250         run_block(task['do'], dry)
251       end
252     end
253 
254     # Run try-catch construct.
255     # - task: the construct as a hash.
256     # - dry: tells if we run in dry mode.
257     def construct_try(task, dry)
258       # test entries
259       error "Try-catch construct must include 'catch' entry" if
260         not task.keys.include?('catch')
261       unknown_keys = task.keys - ['try', 'catch']
262       error "Try-catch construct may only include 'try' and 'catch' entries" if
263         unknown_keys.length > 0
264       error "Try entry in try-catch construct must be a list" if
265         not task['try'].kind_of?(Array)
266       error "Catch entry in try-catch construct must be a list" if
267         task['catch'] and not task['catch'].kind_of?(Array)
268       # try and catch errors
269       begin
270         run_block(task['try'], dry)
271       rescue
272         @targets.build.listener.recover if @targets.build.listener
273         run_block(task['catch'], dry) if task['catch']
274 
275       end
276     end
277 
278     # Run a block, that is a list of tasks.
279     # - block: the block to run as a list of tasks.
280     # - dry: tells if we run in dry mode.
281     def run_block(block, dry)
282       for task in block
283         run_task(task, dry)
284       end   
285     end
286 
287     # Evaluate a given expression and raise a BuildError if an error happens.
288     def evaluate(expression)
289       begin
290         if expression.kind_of?(String)
291           return @targets.build.context.evaluate_script(expression)
292         elsif (expression.kind_of?(TrueClass) or expression.kind_of?(FalseClass))
293           return expression
294         else
295           return @targets.build.context.evaluate_object(expression)
296         end
297       rescue
298         error "Error evaluating expression: #{$!}"
299       end
300     end
301 
302   end
303 
304 end

Generated on Fri Oct 09 02:07:49 +0200 2015 with rcov 1.0.0