another experimental module for stopping as early as possible when errors occur with -k

This commit is contained in:
Thomas Nagy 2011-11-05 23:57:17 +01:00
parent 742ca78276
commit f9754ac7d5
3 changed files with 101 additions and 0 deletions

16
TODO
View File

@ -4,3 +4,19 @@ Waf 1.6.x
* fix the remaining bugs
* provide more extensions
Can be useful:
def bld_command(*k):
fun = k[0]
name = fun.__name__
from waflib.Build import BuildContext
class tmp(BuildContext):
cmd = name
fun = name
return fun
@bld_command
def foo(ctx):
print ctx.env

View File

@ -312,6 +312,7 @@ class Parallel(object):
st = tsk.runnable_status()
except Exception:
self.processed += 1
# TODO waf 1.7 this piece of code should go in the error_handler
tsk.err_msg = Utils.ex_stack()
if not self.stop and self.bld.keep:
tsk.hasrun = Task.SKIPPED
@ -320,6 +321,9 @@ class Parallel(object):
if Logs.verbose > 1 or not self.error:
self.error.append(tsk)
self.stop = True
else:
if Logs.verbose > 1:
self.error.append(tsk)
continue
tsk.hasrun = Task.EXCEPTION
self.error_handler(tsk)

View File

@ -0,0 +1,81 @@
#! /usr/bin/env python
# Thomas Nagy, 2011
# Try to cancel the tasks that cannot run with the option -k when an error occurs:
# 1 direct file dependencies
# 2 tasks listed in the before/after/ext_in/ext_out attributes
from waflib import Task, Runner
Task.CANCELED = 4
def cancel_next(self, tsk):
if not isinstance(tsk, Task.TaskBase):
return
if tsk.hasrun >= Task.SKIPPED:
# normal execution, no need to do anything here
return
try:
canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes
except AttributeError:
canceled_tasks = self.canceled_tasks = set([])
canceled_nodes = self.canceled_nodes = set([])
try:
canceled_nodes.update(tsk.outputs)
except AttributeError:
pass
try:
canceled_tasks.add(tsk)
except AttributeError:
pass
def get_out(self):
tsk = self.out.get()
if not self.stop:
self.add_more_tasks(tsk)
self.count -= 1
self.dirty = True
self.cancel_next(tsk) # new code
def error_handler(self, tsk):
if not self.bld.keep:
self.stop = True
self.error.append(tsk)
self.cancel_next(tsk) # new code
Runner.Parallel.cancel_next = cancel_next
Runner.Parallel.get_out = get_out
Runner.Parallel.error_handler = error_handler
def get_next_task(self):
tsk = self.get_next_task_smart_continue()
if not tsk:
return tsk
try:
canceled_tasks, canceled_nodes = self.canceled_tasks, self.canceled_nodes
except AttributeError:
pass
else:
# look in the tasks that this one is waiting on
# if one of them was canceled, cancel this one too
for x in tsk.run_after:
if x in canceled_tasks:
tsk.hasrun = Task.CANCELED
self.cancel_next(tsk)
break
else:
# so far so good, now consider the nodes
for x in getattr(tsk, 'inputs', []) + getattr(tsk, 'deps', []):
if x in canceled_nodes:
tsk.hasrun = Task.CANCELED
self.cancel_next(tsk)
break
return tsk
Runner.Parallel.get_next_task_smart_continue = Runner.Parallel.get_next_task
Runner.Parallel.get_next_task = get_next_task