summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2001-09-24 14:16:04 (GMT)
committerSteven Knight <knight@baldmt.com>2001-09-24 14:16:04 (GMT)
commitcf97a90442df5f8b835bb81aa5139e142baaf446 (patch)
tree38b6a16f2ac93941a08d32dc22c6991a15bc0bc8
parent6d2e37c6e4552fc39dc01fd69d0e4dd8d8edf356 (diff)
downloadSCons-cf97a90442df5f8b835bb81aa5139e142baaf446.zip
SCons-cf97a90442df5f8b835bb81aa5139e142baaf446.tar.gz
SCons-cf97a90442df5f8b835bb81aa5139e142baaf446.tar.bz2
Enhance Builders to take any type of node as input.
-rw-r--r--src/engine/SCons/Builder.py31
-rw-r--r--src/engine/SCons/BuilderTests.py26
-rw-r--r--src/engine/SCons/Node/FS.py6
-rw-r--r--src/engine/SCons/Node/FSTests.py5
-rw-r--r--src/engine/SCons/Node/__init__.py10
-rw-r--r--src/engine/SCons/Sig/SigTests.py23
-rw-r--r--src/engine/SCons/Sig/__init__.py2
-rw-r--r--src/engine/SCons/Util.py12
-rw-r--r--src/engine/SCons/UtilTests.py9
-rw-r--r--test/Depends.py35
10 files changed, 107 insertions, 52 deletions
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 0d1d274..72b01cf 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -10,6 +10,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
import SCons.Node.FS
+import SCons.Util
import string
import types
@@ -39,25 +40,17 @@ class Builder:
return cmp(self.__dict__, other.__dict__)
def __call__(self, env, target = None, source = None):
- node = self.node_factory(target)
- node.builder_set(self)
- node.env_set(self)
-
- # XXX REACHING INTO ANOTHER OBJECT (this is only temporary):
- assert type(source) is type("")
- node.sources = source
- node.derived = 1
- sources = string.split(source, " ")
- sources = filter(lambda x: x, sources)
- source_nodes = []
- for source in sources:
- source_node = self.node_factory(source)
- source_node.derived = 0
- source_node.source_nodes = []
- source_nodes.append(source_node)
- node.source_nodes = source_nodes
-
- return node
+ tlist = SCons.Util.scons_str2nodes(target)
+ slist = SCons.Util.scons_str2nodes(source)
+ for t in tlist:
+ t.builder_set(self)
+ t.env_set(env)
+ t.derived = 1
+ t.add_source(slist)
+
+ if len(tlist) == 1:
+ tlist = tlist[0]
+ return tlist
def execute(self, **kw):
"""Execute a builder's action to create an output object.
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index ab7e122..0ea81f0 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -29,6 +29,32 @@ outfile = test.workpath('outfile')
class BuilderTestCase(unittest.TestCase):
+ def test__call__(self):
+ """Test calling a builder to establish source dependencies
+ """
+ class Environment:
+ pass
+ env = Environment()
+ class Node:
+ def __init__(self, name):
+ self.name = name
+ self.sources = []
+ self.derived = 0
+ def builder_set(self, builder):
+ self.builder = builder
+ def env_set(self, env):
+ self.env = env
+ def add_source(self, source):
+ self.sources.extend(source)
+ builder = SCons.Builder.Builder(action = "foo")
+ n1 = Node("n1");
+ n2 = Node("n2");
+ builder(env, target = n1, source = n2)
+ assert n1.env == env
+ assert n1.builder == builder
+ assert n1.sources == [n2]
+ assert n1.derived == 1
+
def test_action(self):
"""Test Builder creation
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index ee06089..2595766 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -214,6 +214,9 @@ class Dir(Node):
self.abspath = self.path = name
self.entries['..'] = None
+ def __str__(self):
+ return self.path
+
def up(self):
return self.entries['..']
@@ -258,6 +261,9 @@ class File(Node):
self.path = os.path.join(directory.path, name)
self.parent = directory
+ def __str__(self):
+ return self.path
+
def root(self):
return self.parent.root()
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 87c6ed8..94ec5b0 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -41,6 +41,8 @@ class FSTestCase(unittest.TestCase):
dir = fileSys.Dir(lpath)
assert dir.path == path, "Dir.path %s != expected path %s" % \
(dir.path, path)
+ assert str(dir) == path, "str(dir) %s != expected path %s" % \
+ (str(dir), path)
assert dir.abspath == abspath, "Dir.abspath %s != expected abs. path %s" % \
(dir.abspath, path)
assert dir.up().path == up_path, "Dir.up().path %s != expected parent path %s" % \
@@ -62,12 +64,14 @@ class FSTestCase(unittest.TestCase):
f1 = fs.File('f1', directory = d1)
assert f1.path == 'd1/f1', "f1.path %s != d1/f1" % f1.path
+ assert str(f1) == 'd1/f1', "str(f1) %s != d1/f1" % str(f1)
try:
f2 = fs.File('f1/f2', directory = d1)
except TypeError, x:
node = x.args[0]
assert node.path == 'd1/f1', "node.path %s != d1/f1" % node.path
+ assert str(node) == 'd1/f1', "str(node) %s != d1/f1" % str(node)
assert node.__class__.__name__ == 'File'
except:
raise
@@ -77,6 +81,7 @@ class FSTestCase(unittest.TestCase):
except TypeError, x:
node = x.args[0]
assert node.path == 'd1/f1', "node.path %s != d1/f1" % node.path
+ assert str(node) == 'd1/f1', "str(node) %s != d1/f1" % str(node)
assert node.__class__.__name__ == 'File'
except:
raise
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index ce8e225..8609c57 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -8,18 +8,24 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import string
+
+
+
class Node:
"""The base Node class, for entities that we know how to
build, or use to build other Nodes.
"""
def __init__(self):
- self.depends = []
self.sources = []
+ self.depends = []
+ self.derived = 0
self.env = None
def build(self):
- self.builder.execute(target = self.path, source = self.sources)
+ sources_str = string.join(map(lambda x: str(x), self.sources))
+ self.builder.execute(target = str(self), source = sources_str)
def builder_set(self, builder):
self.builder = builder
diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py
index 7fae807..3a8e0b3 100644
--- a/src/engine/SCons/Sig/SigTests.py
+++ b/src/engine/SCons/Sig/SigTests.py
@@ -27,6 +27,7 @@ class DummyNode:
self.file = file
self.path = file.path
self.derived = file.derived
+ self.depends = []
def get_contents(self):
# a file that doesn't exist has no contents:
@@ -73,17 +74,17 @@ def create_files(test):
def create_nodes(files):
nodes = map(DummyNode, files)
- nodes[0].source_nodes = []
- nodes[1].source_nodes = [nodes[0]]
- nodes[2].source_nodes = [nodes[3]]
- nodes[3].source_nodes = []
- nodes[4].source_nodes = [nodes[5]]
- nodes[5].source_nodes = [nodes[6]]
- nodes[6].source_nodes = [nodes[5]]
- nodes[7].source_nodes = [nodes[2], nodes[4]]
- nodes[8].source_nodes = []
- nodes[9].source_nodes = [nodes[8]]
- nodes[10].source_nodes = [nodes[9]]
+ nodes[0].sources = []
+ nodes[1].sources = [nodes[0]]
+ nodes[2].sources = [nodes[3]]
+ nodes[3].sources = []
+ nodes[4].sources = [nodes[5]]
+ nodes[5].sources = [nodes[6]]
+ nodes[6].sources = [nodes[5]]
+ nodes[7].sources = [nodes[2], nodes[4]]
+ nodes[8].sources = []
+ nodes[9].sources = [nodes[8]]
+ nodes[10].sources = [nodes[9]]
return nodes
diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py
index ea1820e..a2c36b8 100644
--- a/src/engine/SCons/Sig/__init__.py
+++ b/src/engine/SCons/Sig/__init__.py
@@ -91,7 +91,7 @@ class Calculator:
signatures - the dictionary that the signatures will be
gathered into.
"""
- for source_node in node.source_nodes:
+ for source_node in node.sources + node.depends:
if not signatures.has_key(source_node):
signature = self.signature(source_node)
signatures[source_node] = signature
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 0167260..0828db3 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -32,9 +32,15 @@ def scons_str2nodes(arg, fs=SCons.Node.FS.default_fs):
for v in narg:
if type(v) is types.StringType:
nodes.append(fs.File(v))
- elif issubclass(v.__class__, SCons.Node.Node):
- nodes.append(v)
+ # Do we enforce the following restriction? Maybe, but it
+ # also restricts what we can do for allowing people to
+ # use the engine with alternate Node implementations...
+ # Perhaps this should be split in two, with the SCons.Node
+ # logic in a wrapper somewhere under SCons.Node, and the
+ # string-parsing logic here...?
+ #elif not issubclass(v.__class__, SCons.Node.Node):
+ # raise TypeError
else:
- raise TypeError
+ nodes.append(v)
return nodes
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
index 0e13047..cb19c15 100644
--- a/src/engine/SCons/UtilTests.py
+++ b/src/engine/SCons/UtilTests.py
@@ -2,6 +2,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import unittest
+import SCons.Node
import SCons.Node.FS
from SCons.Util import scons_str2nodes
@@ -38,6 +39,14 @@ class UtilTestCase(unittest.TestCase):
assert nodes[0].path == "Util.py"
assert nodes[1].path == "UtilTests.py"
+ class SConsNode(SCons.Node.Node):
+ pass
+ node = scons_str2nodes(SConsNode())
+
+ class OtherNode:
+ pass
+ node = scons_str2nodes(OtherNode())
+
if __name__ == "__main__":
suite = unittest.makeSuite(UtilTestCase, 'test_')
diff --git a/test/Depends.py b/test/Depends.py
index 5c6c4f1..ccbcf26 100644
--- a/test/Depends.py
+++ b/test/Depends.py
@@ -6,8 +6,6 @@ import TestSCons
test = TestSCons.TestSCons()
-test.pass_test() #XXX Short-circuit until this is implemented.
-
test.subdir('subdir')
test.write('build.py', r"""
@@ -24,16 +22,16 @@ Foo = Builder(name = "Foo",
Bar = Builder(name = "Bar",
action = "python build.py %(target)s %(source)s subdir/bar.dep")
env = Environment(BUILDERS = [Foo, Bar])
-env.Depends(target = ['f1.out', 'f2.out'], source = 'subdir/foo.dep')
-env.Depends(target = 'f3.out', source = 'subdir/bar.dep')
+env.Depends(target = ['f1.out', 'f2.out'], dependency = 'subdir/foo.dep')
+env.Depends(target = 'f3.out', dependency = 'subdir/bar.dep')
env.Foo(target = 'f1.out', source = 'f1.in')
env.Foo(target = 'f2.out', source = 'f2.in')
env.Bar(target = 'f3.out', source = 'f3.in')
-SConscript('subdir/SConscript')
+Conscript('subdir/SConscript')
""")
test.write(['subdir', 'SConscript'], """
-env.Depends(target = 'f4.out', source = 'bar.dep')
+env.Depends(target = 'f4.out', dependency = 'bar.dep')
env.Foo(target = 'f4.out', source = 'f4.in')
""")
@@ -41,40 +39,45 @@ test.write('f1.in', "f1.in\n")
test.write('f2.in', "f2.in\n")
+test.write('f3.in', "f3.in\n")
+
test.write(['subdir', 'f4.in'], "subdir/f4.in\n")
test.write(['subdir', 'foo.dep'], "subdir/foo.dep 1\n")
test.write(['subdir', 'bar.dep'], "subdir/bar.dep 1\n")
-test.run(arguments = '.')
+#XXXtest.run(arguments = '.')
+test.run(arguments = 'f1.out f2.out f3.out subdir/f4.out')
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 1\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 1\n")
test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 1\n")
-test.fail_test(test.read('subdir', 'f4.out') !=
- "subdir/f4.in\nsubdir/bar.dep 1\n")
+#XXXtest.fail_test(test.read(['subdir', 'f4.out']) !=
+#XXX "subdir/f4.in\nsubdir/bar.dep 1\n")
test.write(['subdir', 'foo.dep'], "subdir/foo.dep 2\n")
test.write(['subdir', 'bar.dep'], "subdir/bar.dep 2\n")
-test.run(arguments = '.')
+#XXXtest.run(arguments = '.')
+test.run(arguments = 'f1.out f2.out f3.out subdir/f4.out')
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 2\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 2\n")
test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 2\n")
-test.fail_test(test.read('subdir', 'f4.out') !=
- "subdir/f4.in\nsubdir/bar.dep 2\n")
+#XXXtest.fail_test(test.read(['subdir', 'f4.out']) !=
+#XXX "subdir/f4.in\nsubdir/bar.dep 2\n")
test.write(['subdir', 'bar.dep'], "subdir/bar.dep 3\n")
-test.run(arguments = '.')
+#XXXtest.run(arguments = '.')
+test.run(arguments = 'f1.out f2.out f3.out subdir/f4.out')
test.fail_test(test.read('f1.out') != "f1.in\nsubdir/foo.dep 2\n")
test.fail_test(test.read('f2.out') != "f2.in\nsubdir/foo.dep 2\n")
-test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 2\n")
-test.fail_test(test.read('subdir', 'f4.out') !=
- "subdir/f4.in\nsubdir/bar.dep 3\n")
+test.fail_test(test.read('f3.out') != "f3.in\nsubdir/bar.dep 3\n")
+#XXXtest.fail_test(test.read(['subdir', 'f4.out']) !=
+#XXX "subdir/f4.in\nsubdir/bar.dep 3\n")
test.pass_test()