summaryrefslogtreecommitdiff
path: root/third_party/waf/waflib/extras/smart_continue.py
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/waf/waflib/extras/smart_continue.py')
-rw-r--r--third_party/waf/waflib/extras/smart_continue.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/third_party/waf/waflib/extras/smart_continue.py b/third_party/waf/waflib/extras/smart_continue.py
new file mode 100644
index 00000000000..8c171a8d96c
--- /dev/null
+++ b/third_party/waf/waflib/extras/smart_continue.py
@@ -0,0 +1,80 @@
+#! /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