diff options
| author | Steven Knight <knight@baldmt.com> | 2001-10-24 14:18:02 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2001-10-24 14:18:02 (GMT) |
| commit | 6a98a941a75eab2e4c22fa3e19cb973046f613b6 (patch) | |
| tree | fbedd2a2caa8c7d0e4a1e4b774adc6e1b1ed6d8e /src/engine/SCons/Node | |
| parent | 908b74a3a3ecba5eccc6fd1f844505050d9dad2f (diff) | |
| download | SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.zip SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.tar.gz SCons-6a98a941a75eab2e4c22fa3e19cb973046f613b6.tar.bz2 | |
Add -k support and more
Diffstat (limited to 'src/engine/SCons/Node')
| -rw-r--r-- | src/engine/SCons/Node/FSTests.py | 6 | ||||
| -rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 127 | ||||
| -rw-r--r-- | src/engine/SCons/Node/__init__.py | 60 |
3 files changed, 154 insertions, 39 deletions
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index 6f2a5a7..044f83f 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -160,15 +160,17 @@ class FSTestCase(unittest.TestCase): built_it = None assert not built_it - d1.add_source(["d"]) # XXX FAKE SUBCLASS ATTRIBUTE + d1.add_source([SCons.Node.Node()]) # XXX FAKE SUBCLASS ATTRIBUTE d1.builder_set(Builder()) d1.env_set(Environment()) d1.build() assert built_it + assert d1.get_parents() == [] + built_it = None assert not built_it - f1.add_source(["f"]) # XXX FAKE SUBCLASS ATTRIBUTE + f1.add_source([SCons.Node.Node()]) # XXX FAKE SUBCLASS ATTRIBUTE f1.builder_set(Builder()) f1.env_set(Environment()) f1.build() diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 02b34b5..b8015c2 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -128,42 +128,96 @@ class NodeTestCase(unittest.TestCase): """ node = SCons.Node.Node() assert node.depends == [] - try: - node.add_dependency('zero') + + zero = SCons.Node.Node() + try: + node.add_dependency(zero) except TypeError: pass - node.add_dependency(['one']) - assert node.depends == ['one'] - node.add_dependency(['two', 'three']) - assert node.depends == ['one', 'two', 'three'] - node.add_dependency(['three', 'four', 'one']) - assert node.depends == ['one', 'two', 'three', 'four'] + else: + assert 0 + + one = SCons.Node.Node() + two = SCons.Node.Node() + three = SCons.Node.Node() + four = SCons.Node.Node() + + node.add_dependency([one]) + assert node.depends == [one] + node.add_dependency([two, three]) + assert node.depends == [one, two, three] + node.add_dependency([three, four, one]) + assert node.depends == [one, two, three, four] + + assert zero.get_parents() == [] + assert one.get_parents() == [node] + assert two.get_parents() == [node] + assert three.get_parents() == [node] + assert four.get_parents() == [node] + def test_add_source(self): """Test adding sources to a Node's list. """ node = SCons.Node.Node() assert node.sources == [] + + zero = SCons.Node.Node() try: - node.add_source('zero') + node.add_source(zero) except TypeError: pass - node.add_source(['one']) - assert node.sources == ['one'] - node.add_source(['two', 'three']) - assert node.sources == ['one', 'two', 'three'] - node.add_source(['three', 'four', 'one']) - assert node.sources == ['one', 'two', 'three', 'four'] + else: + assert 0 + + one = SCons.Node.Node() + two = SCons.Node.Node() + three = SCons.Node.Node() + four = SCons.Node.Node() + + node.add_source([one]) + assert node.sources == [one] + node.add_source([two, three]) + assert node.sources == [one, two, three] + node.add_source([three, four, one]) + assert node.sources == [one, two, three, four] + + assert zero.get_parents() == [] + assert one.get_parents() == [node] + assert two.get_parents() == [node] + assert three.get_parents() == [node] + assert four.get_parents() == [node] def test_children(self): """Test fetching the "children" of a Node. """ node = SCons.Node.Node() - node.add_source(['one', 'two', 'three']) - node.add_dependency(['four', 'five', 'six']) - kids = node.children() - kids.sort() - assert kids == ['five', 'four', 'one', 'six', 'three', 'two'] + one = SCons.Node.Node() + two = SCons.Node.Node() + three = SCons.Node.Node() + four = SCons.Node.Node() + five = SCons.Node.Node() + six = SCons.Node.Node() + + node.add_source([one, two, three]) + node.add_dependency([four, five, six]) + kids = node.children() + assert len(kids) == 6 + assert one in kids + assert two in kids + assert three in kids + assert four in kids + assert five in kids + assert six in kids + + def test_add_parent(self): + """Test adding parents to a Node.""" + node = SCons.Node.Node() + parent = SCons.Node.Node() + node._add_parent(parent) + assert node.get_parents() == [parent] + node._add_parent(parent) + assert node.get_parents() == [parent] def test_state(self): """Test setting and getting the state of a node @@ -217,6 +271,39 @@ class NodeTestCase(unittest.TestCase): assert nw.next().name == "n1" assert nw.next() == None + def test_children_are_executed(self): + n1 = SCons.Node.Node() + n2 = SCons.Node.Node() + n3 = SCons.Node.Node() + n4 = SCons.Node.Node() + + n4.add_source([n3]) + n3.add_source([n1, n2]) + + assert not n4.children_are_executed() + assert not n3.children_are_executed() + assert n2.children_are_executed() + assert n1.children_are_executed() + + n1.set_state(SCons.Node.executed) + assert not n4.children_are_executed() + assert not n3.children_are_executed() + assert n2.children_are_executed() + assert n1.children_are_executed() + + n2.set_state(SCons.Node.executed) + assert not n4.children_are_executed() + assert n3.children_are_executed() + assert n2.children_are_executed() + assert n1.children_are_executed() + + n3.set_state(SCons.Node.executed) + assert n4.children_are_executed() + assert n3.children_are_executed() + assert n2.children_are_executed() + assert n1.children_are_executed() + + if __name__ == "__main__": diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 265071e..b7bdecf 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -41,7 +41,7 @@ executing = 1 executed = 2 up_to_date = 3 failed = 4 - +pending = 5 class Node: """The base Node class, for entities that we know how to @@ -51,6 +51,7 @@ class Node: def __init__(self): self.sources = [] self.depends = [] + self.parents = [] self.builder = None self.env = None self.state = None @@ -82,24 +83,35 @@ class Node: return self.signature def add_dependency(self, depend): - """Adds dependencies. The depends argument must be a list.""" - if type(depend) is not type([]): - raise TypeError("depend must be a list") - depend = filter(lambda x, d=self.depends: x not in d, depend) - if len(depend): - self.depends.extend(depend) + """Adds dependencies. The depend argument must be a list.""" + self._add_child(self.depends, depend) def add_source(self, source): """Adds sources. The source argument must be a list.""" - if type(source) is not type([]): - raise TypeError("source must be a list") - source = filter(lambda x, s=self.sources: x not in s, source) - if len(source): - self.sources.extend(source) + self._add_child(self.sources, source) + + def _add_child(self, collection, child): + """Adds 'child' to 'collection'. The 'child' argument must be a list""" + if type(child) is not type([]): + raise TypeError("child must be a list") + child = filter(lambda x, s=collection: x not in s, child) + if child: + collection.extend(child) + + for c in child: + c._add_parent(self) + + def _add_parent(self, parent): + """Adds 'parent' to the list of parents of this node""" + + if parent not in self.parents: self.parents.append(parent) def children(self): return self.sources + self.depends + def get_parents(self): + return self.parents + def set_state(self, state): self.state = state @@ -109,10 +121,20 @@ class Node: def current(self): return None + def children_are_executed(self): + return reduce(lambda x,y: ((y.get_state() == executed + or y.get_state() == up_to_date) + and x), + self.children(), + 1) + +def get_children(node): return node.children() + class Wrapper: - def __init__(self, node): + def __init__(self, node, kids_func): self.node = node - self.kids = copy.copy(node.children()) + self.kids = copy.copy(kids_func(node)) + # XXX randomize kids here, if requested class Walker: @@ -121,9 +143,12 @@ class Walker: This is depth-first, children are visited before the parent. The Walker object can be initialized with any node, and returns the next node on the descent with each next() call. + 'kids_func' is an optional function that will be called to + get the children of a node instead of calling 'children'. """ - def __init__(self, node): - self.stack = [Wrapper(node)] + def __init__(self, node, kids_func=get_children): + self.kids_func = kids_func + self.stack = [Wrapper(node, self.kids_func)] def next(self): """Return the next node for this walk of the tree. @@ -134,7 +159,8 @@ class Walker: while self.stack: if self.stack[-1].kids: - self.stack.append(Wrapper(self.stack[-1].kids.pop(0))) + self.stack.append(Wrapper(self.stack[-1].kids.pop(0), + self.kids_func)) else: return self.stack.pop().node |
