diff options
author | Steven Knight <knight@baldmt.com> | 2001-10-10 21:50:55 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2001-10-10 21:50:55 (GMT) |
commit | 385aabf686d687432fb81fa2e68b77e3f11f06f8 (patch) | |
tree | 319adfb4dc23d8c7b1e55fb2e691898d8b544481 /src/engine | |
parent | f72203b4610a100fce3065f5c5c4c41e92fc5883 (diff) | |
download | SCons-385aabf686d687432fb81fa2e68b77e3f11f06f8.zip SCons-385aabf686d687432fb81fa2e68b77e3f11f06f8.tar.gz SCons-385aabf686d687432fb81fa2e68b77e3f11f06f8.tar.bz2 |
Add -i (ignore errors) support
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 10 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 50 | ||||
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 62 | ||||
-rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 55 |
4 files changed, 94 insertions, 83 deletions
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 7dfa23e..febb95a 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -157,6 +157,14 @@ class NodeTestCase(unittest.TestCase): kids.sort() assert kids == ['five', 'four', 'one', 'six', 'three', 'two'] + def test_state(self): + """Test setting and getting the state of a node + """ + node = SCons.Node.Node() + assert node.get_state() == None + node.set_state(SCons.Node.executing) + assert node.get_state() == SCons.Node.executing + def test_walker(self): """Test walking a Node tree. """ @@ -169,7 +177,9 @@ class NodeTestCase(unittest.TestCase): n1 = MyNode("n1") nw = SCons.Node.Walker(n1) + assert not nw.is_done() assert nw.next().name == "n1" + assert nw.is_done() assert nw.next() == None n2 = MyNode("n2") diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index b6922dc..c0346cc 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -34,6 +34,13 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from SCons.Errors import BuildError import string import types +import copy + +# Node states: +executing = 1 +executed = 2 +up_to_date = 3 +failed = 4 class Node: @@ -46,6 +53,7 @@ class Node: self.depends = [] self.derived = 0 self.env = None + self.state = None def build(self): if not hasattr(self, "builder"): @@ -87,26 +95,27 @@ class Node: def children(self): return self.sources + self.depends + def set_state(self, state): + self.state = state - + def get_state(self): + return self.state class Wrapper: def __init__(self, node): self.node = node - self.kids = node.children() + self.kids = copy.copy(node.children()) # XXX randomize kids here, if requested class Walker: """An iterator for walking a Node tree. - + This is depth-first, children are visited before the parent. - The Walker object can be initialized with any node, and + The Walker object can be initialized with any node, and returns the next node on the descent with each next() call. """ def __init__(self, node): - self.current = Wrapper(node) - self.stack = [] - self.top = self.current + self.stack = [Wrapper(node)] def next(self): """Return the next node for this walk of the tree. @@ -114,23 +123,12 @@ class Walker: This function is intentionally iterative, not recursive, to sidestep any issues of stack size limitations. """ - if not self.current: - return None - while 1: - if self.current.kids: - k = Wrapper(self.current.kids[0]) - self.current.kids = self.current.kids[1:] - if k.kids: - self.stack.append(self.current) - self.current = k - else: - return k.node - else: - n = self.current.node - if self.stack: - self.current = self.stack[-1] - self.stack = self.stack[0:-1] - else: - self.current = None - return n + while self.stack: + if self.stack[-1].kids: + self.stack.append(Wrapper(self.stack[-1].kids.pop(0))) + else: + return self.stack.pop().node + + def is_done(self): + return not self.stack diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 651769d..3fd787e 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -44,8 +44,9 @@ class Task: def execute(self): self.target.build() - - + def set_state(self, state): + return self.target.set_state(state) + def current(node): """Default SCons build engine is-it-current function. @@ -58,40 +59,41 @@ def current(node): class Taskmaster: """A generic Taskmaster for handling a bunch of targets. + + Classes that override methods of this class should call + the base class method, so this class can do it's thing. """ def __init__(self, targets=[], tasker=Task, current=current): - self.targets = targets + self.walkers = map(SCons.Node.Walker, targets) self.tasker = tasker self.current = current - self.num_iterated = 0 - self.walker = None - - def next_node(self): - t = None - if self.walker: - t = self.walker.next() - if t == None and self.num_iterated < len(self.targets): - t = self.targets[self.num_iterated] - self.num_iterated = self.num_iterated + 1 - t.top_target = 1 - self.walker = SCons.Node.Walker(t) - t = self.walker.next() - top = None - if hasattr(t, "top_target"): - top = 1 - return t, top + self.targets = targets def next_task(self): - n, top = self.next_node() - while n != None: - if self.current(n): - self.up_to_date(n) + while self.walkers: + n = self.walkers[0].next() + if n == None: + self.walkers.pop(0) + elif n.get_state() == SCons.Node.up_to_date: + self.up_to_date(n, self.walkers[0].is_done()) + elif n.get_state() == SCons.Node.failed: + # XXX do the right thing here + pass + elif n.get_state() == SCons.Node.executing: + # XXX do the right thing here + pass + elif n.get_state() == SCons.Node.executed: + # skip this node because it has already been executed + pass + elif self.current(n): + n.set_state(SCons.Node.up_to_date) + self.up_to_date(n, self.walkers[0].is_done()) else: + n.set_state(SCons.Node.executing) return self.tasker(n) - n, top = self.next_node() - return None - + return None + def is_blocked(self): return 0 @@ -99,8 +101,8 @@ class Taskmaster: pass def executed(self, task): - pass + task.set_state(SCons.Node.executed) def failed(self, task): - self.walker = None - self.num_iterated = len(self.targets) + self.walkers = [] + task.set_state(SCons.Node.failed) diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 2af65f6..59f62bd 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -44,30 +44,21 @@ class Node: def children(self): return self.kids + def get_state(self): + pass + def set_state(self, state): + pass -class TaskmasterTestCase(unittest.TestCase): +class Task: + def __init__(self, target): + self.target = target - def test_next_node(self): - """Test fetching the next node - """ - n1 = Node("n1") - n2 = Node("n2") - n3 = Node("n3", [n1, n2]) + def set_state(self, state): + pass - tm = SCons.Taskmaster.Taskmaster([n3]) - n, top = tm.next_node() - assert n.name == "n1" - assert top == None - n, top = tm.next_node() - assert n.name == "n2" - assert top == None - n, top = tm.next_node() - assert n.name == "n3" - assert top == 1 - n, top = tm.next_node() - assert n == None - assert top == None + +class TaskmasterTestCase(unittest.TestCase): def test_next_task(self): """Test fetching the next task @@ -76,8 +67,8 @@ class TaskmasterTestCase(unittest.TestCase): n1 = Node("n1") n2 = Node("n2") - n3 = Node("n3", [n1, n2]) - + n3 = Node("n3", [n1, n2]) + tm = SCons.Taskmaster.Taskmaster([n3]) tm.next_task().execute() assert built == "n1 built" @@ -93,15 +84,25 @@ class TaskmasterTestCase(unittest.TestCase): built = "up to date: " + global top_node + top_node = n3 class MyTM(SCons.Taskmaster.Taskmaster): - def up_to_date(self, node): - global built - built = built + " " + node.name + def up_to_date(self, node, top): + if node == top_node: + assert top + global built + built = built + " " + node.name tm = MyTM(targets = [n3], current = current) assert tm.next_task() == None + print built assert built == "up to date: n1 n2 n3" + n4 = Node("n4") + n4.get_state = lambda: SCons.Node.executed + tm = SCons.Taskmaster.Taskmaster([n4]) + assert tm.next_task() == None + def test_is_blocked(self): """Test whether a task is blocked @@ -122,7 +123,7 @@ class TaskmasterTestCase(unittest.TestCase): Both default and overridden in a subclass. """ tm = SCons.Taskmaster.Taskmaster() - tm.executed('foo') + tm.executed(Task('foo')) class MyTM(SCons.Taskmaster.Taskmaster): def executed(self, task): @@ -137,7 +138,7 @@ class TaskmasterTestCase(unittest.TestCase): """ tm = SCons.Taskmaster.Taskmaster() #XXX - tm.failed('foo') + tm.failed(Task('foo')) class MyTM(SCons.Taskmaster.Taskmaster): def failed(self, task): |