comparison piecrust/processing/tree.py @ 120:133845647083

Better error management and removal support in baking/processing. * Baker and processor pipeline now store errors in their records. * They also support deleting output files that are no longer valid. * The basic transitional record class implements more boilerplate code. * The processor pipeline is run from the `bake` command directly. * New unit tests. * Unit test mocking now mocks `os.remove` too.
author Ludovic Chabant <ludovic@chabant.com>
date Sun, 09 Nov 2014 14:46:23 -0800
parents 6827dcc9d3fb
children 3834e2ef0cf2
comparison
equal deleted inserted replaced
119:0811f92cbdc7 120:133845647083
1 import os 1 import os
2 import time 2 import time
3 import os.path 3 import os.path
4 import logging 4 import logging
5 from piecrust.chefutil import format_timed
5 6
6 7
7 logger = logging.getLogger(__name__) 8 logger = logging.getLogger(__name__)
8 9
9 10
148 node, 149 node,
149 format_timed( 150 format_timed(
150 start_time, "(bypassing structured processing)")) 151 start_time, "(bypassing structured processing)"))
151 return True 152 return True
152 except Exception as e: 153 except Exception as e:
153 raise Exception("Error processing: %s" % node.path) from e 154 raise ProcessingTreeError("Error processing: %s" %
155 node.path) from e
154 156
155 # All outputs of a node must go to the same directory, so we can get 157 # All outputs of a node must go to the same directory, so we can get
156 # the output directory off of the first output. 158 # the output directory off of the first output.
157 base_out_dir = self._getNodeBaseDir(node.outputs[0]) 159 base_out_dir = self._getNodeBaseDir(node.outputs[0])
158 rel_out_dir = os.path.dirname(node.path) 160 rel_out_dir = os.path.dirname(node.path)
237 print_node(node, message) 239 print_node(node, message)
238 else: 240 else:
239 node.setState(STATE_CLEAN, False) 241 node.setState(STATE_CLEAN, False)
240 242
241 state = "dirty" if node.state == STATE_DIRTY else "clean" 243 state = "dirty" if node.state == STATE_DIRTY else "clean"
242 logger.debug(format_timed(start_time, "Computed node dirtyness: %s" % state, node.level)) 244 logger.debug(format_timed(start_time,
245 "Computed node dirtyness: %s" % state,
246 indent_level=node.level))
243 247
244 def _getNodeBaseDir(self, node): 248 def _getNodeBaseDir(self, node):
245 if node.level == 0: 249 if node.level == 0:
246 return self.base_dir 250 return self.base_dir
247 if node.is_leaf: 251 if node.is_leaf:
265 269
266 if recursive: 270 if recursive:
267 for o in node.outputs: 271 for o in node.outputs:
268 print_node(o, None, True) 272 print_node(o, None, True)
269 273
270
271 def format_timed(start_time, message, indent_level=0):
272 end_time = time.clock()
273 indent = indent_level * ' '
274 build_time = '{0:8.1f} ms'.format((end_time - start_time) / 1000.0)
275 return "%s[%s] %s" % (indent, build_time, message)
276