Implement the Depends() method.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 24 Sep 2001 13:44:50 +0000 (13:44 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 24 Sep 2001 13:44:50 +0000 (13:44 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@67 fdb21ef1-2011-0410-befe-b5e4ea1792b1

config
src/engine/MANIFEST
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/Util.py [new file with mode: 0644]
src/engine/SCons/UtilTests.py [new file with mode: 0644]

diff --git a/config b/config
index 9618a967103c649ddfa589fbac7792cc7f48409b..9ecf0137f7957b7626870f9a0f76529bd0b7f270 100644 (file)
--- a/config
+++ b/config
@@ -252,15 +252,15 @@ new_test_filename = "test/CHANGETHIS.py";
 file_template =
 [
        {
-               pattern = [ "src/scons/*__init__.py" ];
+               pattern = [ "src/engine/*__init__.py" ];
                body = "${read_file ${source template/__init__.py abs}}";
        },
        {
-               pattern = [ "src/scons/*Tests.py" ];
+               pattern = [ "src/engine/*Tests.py" ];
                body = "${read_file ${source template/Tests.py abs}}";
        },
        {
-               pattern = [ "src/scons/*.py" ];
+               pattern = [ "src/engine/*.py" ];
                body = "${read_file ${source template/file.py abs}}";
        },
        {
index 51c68221285c77c18d320dc68a31ebdf65b9f8f7..1d04e409e2940ea0be71e67f83d56e83a46a8bff 100644 (file)
@@ -13,4 +13,5 @@ SCons/Scanner/C.py
 SCons/Sig/__init__.py
 SCons/Sig/MD5.py
 SCons/Sig/TimeStamp.py
+SCons/Util.py
 setup.py
index a7e02a2443323e42116b353bd33109ca4ce75892..5561cceda91ee15de74565309d5ded06422ffeb7 100644 (file)
@@ -11,6 +11,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import copy
 import re
 import types
+import SCons.Util
 
 
 
@@ -26,7 +27,6 @@ def InstallAs():
 
 
 _cv = re.compile(r'%([_a-zA-Z]\w*|{[_a-zA-Z]\w*})')
-_self = None
 
 
 
@@ -109,6 +109,17 @@ class Environment:
        """
        self.Dictionary.update(copy.deepcopy(kw))
 
+    def        Depends(self, target, dependency):
+       """Explicity specify that 'target's depend on 'dependency'."""
+       tlist = SCons.Util.scons_str2nodes(target)
+       dlist = SCons.Util.scons_str2nodes(dependency)
+       for t in tlist:
+           t.add_dependency(dlist)
+
+       if len(tlist) == 1:
+           tlist = tlist[0]
+       return tlist
+
     def subst(self, string):
        """Recursively interpolates construction variables from the
        Environment into the specified string, returning the expanded
@@ -119,9 +130,7 @@ class Environment:
        may be surrounded by curly braces to separate the name from
        trailing characters.
        """
-       global _self
-       _self = self    # XXX NOT THREAD SAFE, BUT HOW ELSE DO WE DO THIS?
-       def repl(m):
+       def repl(m, _self=self):
            key = m.group(1)
            if key[:1] == '{' and key[-1:] == '}':
                key = key[1:-1]
index 885e36546482afaede6c6d3572543f72ba7a41a3..149ba74813dab0a7b642f87f490700e22a0f15db 100644 (file)
@@ -120,6 +120,17 @@ class EnvironmentTestCase(unittest.TestCase):
        env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'c')
        assert env1 != env2
 
+    def test_Depends(self):
+       """Test the explicit Depends method."""
+       env = Environment()
+       t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
+       assert t.__class__.__name__ == 'File'
+       assert t.path == 'EnvironmentTest.py'
+       assert len(t.depends) == 1
+       d = t.depends[0]
+       assert d.__class__.__name__ == 'File'
+       assert d.path == 'Environment.py'
+
     def test_subst(self):
        """Test substituting construction variables within strings
        
index fc7b042c839f9354e0fd97e3ff3633dd3179e37d..ee06089ac35e1b3782a217b586f466c6aaa4f1ed 100644 (file)
@@ -198,6 +198,8 @@ class Dir(Node):
     """
 
     def __init__(self, name, directory = None):
+        Node.__init__(self)
+
         self.entries = PathDict()
         self.entries['.'] = self
 
@@ -247,6 +249,8 @@ class File(Node):
     """
 
     def __init__(self, name, directory):
+        Node.__init__(self)
+
         self.abspath = os.path.join(directory.abspath, name)
         if str(directory.path) == '.':
             self.path = name
index f95837fbde55a062a09404d05eddcf6cbce60158..87c6ed870bac124afc6f4c71f8e5adef27bf669d 100644 (file)
@@ -87,7 +87,7 @@ class FSTestCase(unittest.TestCase):
         built_it = None
         assert not built_it
         d1.path = "d"           # XXX FAKE SUBCLASS ATTRIBUTE
-        d1.sources = "d"        # XXX FAKE SUBCLASS ATTRIBUTE
+        d1.add_source(["d"])    # XXX FAKE SUBCLASS ATTRIBUTE
         d1.builder_set(Builder())
         d1.build()
         assert built_it
@@ -95,7 +95,7 @@ class FSTestCase(unittest.TestCase):
         built_it = None
         assert not built_it
         f1.path = "f"           # XXX FAKE SUBCLASS ATTRIBUTE
-        f1.sources = "f"        # XXX FAKE SUBCLASS ATTRIBUTE
+        f1.add_source(["f"])    # XXX FAKE SUBCLASS ATTRIBUTE
         f1.builder_set(Builder())
         f1.build()
         assert built_it
index 8e5aab1a2e2aa743482d3fca8a6d0fceac046db7..ce8e225b04dd79113aaab2221ee8b5740d2e0a71 100644 (file)
@@ -12,6 +12,12 @@ 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.env = None
+
     def build(self):
        self.builder.execute(target = self.path, source = self.sources)
 
@@ -30,3 +36,10 @@ class Node:
     def get_signature(self):
         return self.signature
 
+    def add_dependency(self, depend):
+       """Adds dependencies. The depends argument must be a list."""
+       self.depends.extend(depend)
+
+    def add_source(self, source):
+       """Adds sources. The source argument must be a list."""
+       self.sources.extend(source)
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
new file mode 100644 (file)
index 0000000..0167260
--- /dev/null
@@ -0,0 +1,40 @@
+"""SCons.Util
+
+Various utility functions go here.
+
+"""
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+
+import types
+import string
+import SCons.Node.FS
+
+def scons_str2nodes(arg, fs=SCons.Node.FS.default_fs):
+    """This function converts a string or list into a list of Node instances.
+    It follows the rules outlined in the SCons design document by accepting
+    any of the following inputs:
+       - A single string containing names separated by spaces. These will be
+         split apart at the spaces.
+       - A single Node instance,
+       - A list containingg either strings or Node instances. Any strings
+         in the list are not split at spaces.
+    In all cases, the function returns a list of Node instances."""
+
+    narg = arg
+    if type(arg) is types.StringType:
+       narg = string.split(arg)
+    elif type(arg) is not types.ListType:
+       narg = [arg]
+
+    nodes = []
+    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)
+       else:
+           raise TypeError
+
+    return nodes
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
new file mode 100644 (file)
index 0000000..0e13047
--- /dev/null
@@ -0,0 +1,45 @@
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import unittest
+import SCons.Node.FS
+from SCons.Util import scons_str2nodes
+
+
+class UtilTestCase(unittest.TestCase):
+    def test_str2nodes(self):
+       """Test the str2nodes function."""
+       nodes = scons_str2nodes("Util.py UtilTests.py")
+       assert len(nodes) == 2
+       assert isinstance(nodes[0], SCons.Node.FS.File)
+       assert isinstance(nodes[1], SCons.Node.FS.File)
+       assert nodes[0].path == "Util.py"
+       assert nodes[1].path == "UtilTests.py"
+
+       nodes = scons_str2nodes("Util.py UtilTests.py", SCons.Node.FS.FS())
+       assert len(nodes) == 2
+       assert isinstance(nodes[0], SCons.Node.FS.File)
+       assert isinstance(nodes[1], SCons.Node.FS.File)
+       assert nodes[0].path == "Util.py"
+       assert nodes[1].path == "UtilTests.py"
+
+       nodes = scons_str2nodes(["Util.py", "UtilTests.py"])
+       assert len(nodes) == 2
+       assert isinstance(nodes[0], SCons.Node.FS.File)
+       assert isinstance(nodes[1], SCons.Node.FS.File)
+       assert nodes[0].path == "Util.py"
+       assert nodes[1].path == "UtilTests.py"
+
+       n1 = SCons.Node.FS.default_fs.File("Util.py")
+       nodes = scons_str2nodes([n1, "UtilTests.py"])
+       assert len(nodes) == 2
+       assert isinstance(nodes[0], SCons.Node.FS.File)
+       assert isinstance(nodes[1], SCons.Node.FS.File)
+       assert nodes[0].path == "Util.py"
+       assert nodes[1].path == "UtilTests.py"
+
+
+if __name__ == "__main__":
+    suite = unittest.makeSuite(UtilTestCase, 'test_')
+    if not unittest.TextTestRunner().run(suite).wasSuccessful():
+       sys.exit(1)