diff options
| author | Steven Knight <knight@baldmt.com> | 2001-10-05 17:37:48 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2001-10-05 17:37:48 (GMT) |
| commit | a86827b3933c2861d2e5b9df319630ce04559fe0 (patch) | |
| tree | 4172953c924c5d23c8b1622fd0d9d5e980f79cc3 /src/engine | |
| parent | a0e380faef8af1b62213a0ea1840b38fa0ecf6e4 (diff) | |
| download | SCons-a86827b3933c2861d2e5b9df319630ce04559fe0.zip SCons-a86827b3933c2861d2e5b9df319630ce04559fe0.tar.gz SCons-a86827b3933c2861d2e5b9df319630ce04559fe0.tar.bz2 | |
Use the Node Walker to build dependencies in order.
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/MANIFEST | 1 | ||||
| -rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 5 | ||||
| -rw-r--r-- | src/engine/SCons/Node/__init__.py | 2 | ||||
| -rw-r--r-- | src/engine/SCons/Taskmaster.py | 106 | ||||
| -rw-r--r-- | src/engine/SCons/TaskmasterTests.py | 154 |
5 files changed, 268 insertions, 0 deletions
diff --git a/src/engine/MANIFEST b/src/engine/MANIFEST index e085755..af9d531 100644 --- a/src/engine/MANIFEST +++ b/src/engine/MANIFEST @@ -14,5 +14,6 @@ SCons/Scanner/C.py SCons/Sig/__init__.py SCons/Sig/MD5.py SCons/Sig/TimeStamp.py +SCons/Taskmaster.py SCons/Util.py setup.py diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 309229e..7dfa23e 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -68,6 +68,11 @@ class NodeTestCase(unittest.TestCase): def test_build(self): """Test building a node """ + # Make sure it doesn't blow up if no builder is set. + node = SCons.Node.Node() + node.build() + assert built_it == None + node = SCons.Node.Node() node.builder_set(Builder()) node.env_set(Environment()) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 8e1760d..b6922dc 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -48,6 +48,8 @@ class Node: self.env = None def build(self): + if not hasattr(self, "builder"): + return None sources_str = string.join(map(lambda x: str(x), self.sources)) stat = self.builder.execute(ENV = self.env.Dictionary('ENV'), target = str(self), source = sources_str) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py new file mode 100644 index 0000000..651769d --- /dev/null +++ b/src/engine/SCons/Taskmaster.py @@ -0,0 +1,106 @@ +"""SCons.Taskmaster + +Generic Taskmaster. + +""" + +# +# Copyright (c) 2001 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + + + + +import SCons.Node + + + +class Task: + """Default SCons build engine task.""" + def __init__(self,target): + self.target = target + + def execute(self): + self.target.build() + + + +def current(node): + """Default SCons build engine is-it-current function. + + This returns "always out of date," so every node is always + built/visited. + """ + return None + + + +class Taskmaster: + """A generic Taskmaster for handling a bunch of targets. + """ + + def __init__(self, targets=[], tasker=Task, current=current): + self.targets = 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 + + def next_task(self): + n, top = self.next_node() + while n != None: + if self.current(n): + self.up_to_date(n) + else: + return self.tasker(n) + n, top = self.next_node() + return None + + def is_blocked(self): + return 0 + + def up_to_date(self, node): + pass + + def executed(self, task): + pass + + def failed(self, task): + self.walker = None + self.num_iterated = len(self.targets) diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py new file mode 100644 index 0000000..2af65f6 --- /dev/null +++ b/src/engine/SCons/TaskmasterTests.py @@ -0,0 +1,154 @@ +# +# Copyright (c) 2001 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import SCons.Taskmaster + + + +built = None + +class Node: + def __init__(self, name, kids = []): + self.name = name + self.kids = kids + + def build(self): + global built + built = self.name + " built" + + def children(self): + return self.kids + + + +class TaskmasterTestCase(unittest.TestCase): + + def test_next_node(self): + """Test fetching the next node + """ + n1 = Node("n1") + n2 = Node("n2") + n3 = Node("n3", [n1, n2]) + + 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 + + def test_next_task(self): + """Test fetching the next task + """ + global built + + n1 = Node("n1") + n2 = Node("n2") + n3 = Node("n3", [n1, n2]) + + tm = SCons.Taskmaster.Taskmaster([n3]) + tm.next_task().execute() + assert built == "n1 built" + + tm.next_task().execute() + assert built == "n2 built" + + tm.next_task().execute() + assert built == "n3 built" + + def current(node): + return 1 + + built = "up to date: " + + class MyTM(SCons.Taskmaster.Taskmaster): + def up_to_date(self, node): + global built + built = built + " " + node.name + + tm = MyTM(targets = [n3], current = current) + assert tm.next_task() == None + assert built == "up to date: n1 n2 n3" + + def test_is_blocked(self): + """Test whether a task is blocked + + Both default and overridden in a subclass. + """ + tm = SCons.Taskmaster.Taskmaster() + assert tm.is_blocked() == 0 + + class MyTM(SCons.Taskmaster.Taskmaster): + def is_blocked(self): + return 1 + tm = MyTM() + assert tm.is_blocked() == 1 + + def test_executed(self): + """Test the executed() method + + Both default and overridden in a subclass. + """ + tm = SCons.Taskmaster.Taskmaster() + tm.executed('foo') + + class MyTM(SCons.Taskmaster.Taskmaster): + def executed(self, task): + return 'x' + task + tm = MyTM() + assert tm.executed('foo') == 'xfoo' + + def test_failed(self): + """Test the failed() method + + Both default and overridden in a subclass. + """ + tm = SCons.Taskmaster.Taskmaster() + #XXX + tm.failed('foo') + + class MyTM(SCons.Taskmaster.Taskmaster): + def failed(self, task): + return 'y' + task + tm = MyTM() + assert tm.failed('foo') == 'yfoo' + + + + +if __name__ == "__main__": + suite = unittest.makeSuite(TaskmasterTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) |
