diff python/ppci/tasks.py @ 342:86b02c98a717 devel

Moved target directory
author Windel Bouwman
date Sat, 01 Mar 2014 15:40:31 +0100
parents 6f4753202b9a
children 3bb7dcfe5529
line wrap: on
line diff
--- a/python/ppci/tasks.py	Fri Feb 28 18:07:14 2014 +0100
+++ b/python/ppci/tasks.py	Sat Mar 01 15:40:31 2014 +0100
@@ -1,3 +1,7 @@
+"""
+    This module defines tasks and a runner for these tasks. Tasks can
+    have dependencies and it can be determined if they need to be run.
+"""
 
 import logging
 
@@ -9,31 +13,49 @@
     """ Task that can run, and depend on other tasks """
     def __init__(self, name):
         self.name = name
-        self.subtasks = []
         self.completed = False
-        self.dependencies = []
+        self.dependencies = set()
         self.duration = 1
 
     def run(self):
         raise NotImplementedError("Implement this abstract method!")
 
     def fire(self):
+        """ Wrapper around run that marks the task as done """
         assert all(t.completed for t in self.dependencies)
         self.run()
         self.completed = True
 
-    def addSubTask(self, tsk):
-        self.subtasks.append(tsk)
-        return tsk
+    def add_dependency(self, task):
+        """ Add another task as a dependency for this task """
+        if task is self:
+            raise TaskError('Can not add dependency on task itself!')
+        if self in task.down_stream_tasks:
+            raise TaskError('Can not introduce circular task')
+        self.dependencies.add(task)
+        return task
 
-    def addDependency(self, task):
-        self.dependencies.append(task)
-        return task
+    @property
+    def down_stream_tasks(self):
+        """ Return a set of all tasks that follow this task """
+        # TODO: is this upstream or downstream???
+        cdst = list(dep.down_stream_tasks for dep in self.dependencies)
+        cdst.append(self.dependencies)
+        return set.union(*cdst)
+
+    def __gt__(self, other):
+        return other in self.down_stream_tasks
 
     def __repr__(self):
         return 'Task "{}"'.format(self.name)
 
 
+class EmptyTask(Task):
+    """ Basic task that does nothing """
+    def run(self):
+        pass
+
+
 class TaskRunner:
     """ Basic task runner that can run some tasks in sequence """
     def __init__(self):
@@ -48,6 +70,10 @@
         return sum(t.duration for t in self.task_list)
 
     def run_tasks(self):
+        # First sort tasks:
+        self.task_list.sort()
+
+        # Run tasks:
         passed_time = 0.0
         total_time = self.total_duration
         try:
@@ -56,7 +82,7 @@
                 t.fire()
                 passed_time += t.duration
         except TaskError as e:
-            print('Error: {}'.format(e))
+            self.logger.error(str(e.msg))
             return 1
         self.report_progress(1, 'OK')
         return 0