Fix the execute-Mkdir-once patch so that it doesn't treat the directory as up-to...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 22 Oct 2004 17:42:35 +0000 (17:42 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Fri, 22 Oct 2004 17:42:35 +0000 (17:42 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1134 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Executor.py
src/engine/SCons/ExecutorTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
test/Mkdir.py

index 47a72de2e4bcd731ae08ede55621477c0067164a..6767cc874693f002d1a5567fe443ecaa78696a37 100644 (file)
@@ -105,6 +105,9 @@ class Executor:
         except AttributeError:
             return al
 
+    def do_nothing(self, target, errfunc, **kw):
+        pass
+
     def __call__(self, target, errfunc, **kw):
         """Actually execute the action list."""
         action_list = self.get_action_list(target)
@@ -159,6 +162,11 @@ class Executor:
                                                    build_env)
             return self._strfunc
 
+    def nullify(self):
+        self.__call__ = self.do_nothing
+        self.string = None
+        self._strfunc = None
+
     def get_raw_contents(self):
         """Fetch the raw signature contents.  This, along with
         get_contents(), is the real reason this class exists, so we can
index e259012c8b8908bfaebddd13c03e8e3bebbcf6d6..d52853c903e96fcf01002a16488ab9fb1cd2b167 100644 (file)
@@ -50,9 +50,9 @@ class MyAction:
         for action in self.actions:
             action(target, source, env, errfunc)
     def strfunction(self, target, source, env):
-        return string.join(['STRFUNCTION'] + self.actions + target + source)
+        return string.join(['STRFUNCTION'] + map(str, self.actions) + target + source)
     def genstring(self, target, source, env):
-        return string.join(['GENSTRING'] + self.actions + target + source)
+        return string.join(['GENSTRING'] + map(str, self.actions) + target + source)
     def get_raw_contents(self, target, source, env):
         return string.join(['RAW'] + self.actions + target + source)
     def get_contents(self, target, source, env):
@@ -212,6 +212,35 @@ class ExecutorTestCase(unittest.TestCase):
         s = x.strfunction()
         assert s == 'STRFUNCTION action1 action2 t s', s
 
+    def test_nullify(self):
+        """Test the nullify() method"""
+        env = MyEnvironment(S='string')
+
+        result = []
+        def action1(target, source, env, errfunc, result=result, **kw):
+            result.append('action1')
+
+        env = MyEnvironment()
+        a = MyAction([action1])
+        x = SCons.Executor.Executor(a, env, [], ['t1', 't2'], ['s1', 's2'])
+
+        x(MyNode([], []), None)
+        assert result == ['action1'], result
+        s = str(x)
+        assert s[:10] == 'GENSTRING ', s
+        s = x.strfunction()
+        assert s[:12] == 'STRFUNCTION ', s
+
+        del result[:]
+        x.nullify()
+
+        x(MyNode([], []), None)
+        assert result == [], result
+        s = str(x)
+        assert s == None, s
+        s = x.strfunction()
+        assert s == None, s
+
     def test_get_raw_contents(self):
         """Test fetching the raw signatures contents"""
         env = MyEnvironment(RC='raw contents')
index 1e24be0722e90da3ca93982a972b77158a951d8e..49cbe7d7eabf86f04b5a1d6c2a5f01adcb3c7c5f 100644 (file)
@@ -1111,21 +1111,6 @@ class FS(LocalFS):
             message = "building associated BuildDir targets: %s" % string.join(map(str, targets))
         return targets, message
 
-class DummyExecutor:
-    """Dummy executor class returned by Dir nodes to bamboozle SCons
-    into thinking we are an actual derived node, where our sources are
-    our directory entries."""
-    def cleanup(self):
-        pass
-    def get_raw_contents(self):
-        return ''
-    def get_contents(self):
-        return ''
-    def get_timestamp(self):
-        return 0
-    def get_build_env(self):
-        return None
-
 class Dir(Base):
     """A class for directories in a file system.
     """
@@ -1507,7 +1492,7 @@ class File(Base):
 
         return includes
 
-    def _createDir(self, update=None):
+    def _createDir(self):
         # ensure that the directories for this node are
         # created.
 
@@ -1529,11 +1514,7 @@ class File(Base):
                 # directory.  The dirnode.build() method will suppress
                 # the build if it's the default builder.
                 SCons.Node.Node.build(dirnode)
-                if update:
-                    # Mark this directory as built so we don't try to build
-                    # it again if it has an explicit user-defined Builder.
-                    dirnode.set_state(SCons.Node.executed)
-                    dirnode.built()
+                dirnode.get_executor().nullify()
                 # The build() action may or may not have actually
                 # created the directory, depending on whether the -n
                 # option was used or not.  Delete the _exists and
@@ -1672,7 +1653,7 @@ class File(Base):
                         pass
             else:
                 try:
-                    self._createDir(update=1)
+                    self._createDir()
                 except SCons.Errors.StopError, drive:
                     desc = "No drive `%s' for target `%s'." % (drive, self)
                     raise SCons.Errors.StopError, desc
index 67c4ffec7271384181cf0472c75f8de9992149d6..c47435f577d15cf5d531ca49bc792183afe34521 100644 (file)
@@ -1533,14 +1533,10 @@ class prepareTestCase(unittest.TestCase):
         xyz.set_state(SCons.Node.up_to_date)
         xyz.prepare()
         assert dir_made == [], dir_made
-        state = new_dir.get_state()
-        assert state != SCons.Node.executed, state
 
         xyz.set_state(0)
         xyz.prepare()
         assert dir_made[0].path == "new_dir", dir_made[0]
-        state = new_dir.get_state()
-        assert state == SCons.Node.executed, state
 
         dir = fs.Dir("dir")
         dir.prepare()
index a198571bc76079fd48ab59b1627bd6352bb50330..cbf465ec1e25408dc8c0151e6347a0c069752794 100644 (file)
@@ -34,7 +34,9 @@ import TestSCons
 
 test = TestSCons.TestSCons()
 
-test.write('SConstruct', """
+test.subdir('work1', 'work2')
+
+test.write(['work1', 'SConstruct'], """
 Execute(Mkdir('d1'))
 def cat(env, source, target):
     target = str(target[0])
@@ -58,9 +60,9 @@ env.Command(Dir('hello'), None, [Mkdir('$TARGET')])
 env.Command('hello/world', None, [Touch('$TARGET')])
 """)
 
-test.write('f2.in', "f2.in\n")
-test.write('f5.in', "f5.in\n")
-test.write('f6.in', "f6.in\n")
+test.write(['work1', 'f2.in'], "f2.in\n")
+test.write(['work1', 'f5.in'], "f5.in\n")
+test.write(['work1', 'f6.in'], "f6.in\n")
 
 expect = test.wrap_stdout(read_str = 'Mkdir("d1")\n',
                           build_str = """\
@@ -74,34 +76,66 @@ Mkdir("f6.out-Mkdir")
 Mkdir("hello")
 Touch("%s")
 """ % (os.path.join('hello', 'world')))
-test.run(options = '-n', arguments = '.', stdout = expect)
-
-test.must_not_exist('d1')
-test.must_not_exist('f2.out')
-test.must_not_exist('d3')
-test.must_not_exist('d4')
-test.must_not_exist('f5.out')
-test.must_not_exist('f6.out')
-test.must_not_exist('Mkdir-f6.in')
-test.must_not_exist('f6.out-Mkdir')
-
-test.run()
-
-test.must_exist('d1')
-test.must_match('f2.out', "f2.in\n")
-test.must_exist('d3')
-test.must_exist('d4')
-test.must_match('f5.out', "f5.in\n")
-test.must_exist('f6.out')
-test.must_exist('Mkdir-f6.in')
-test.must_exist('f6.out-Mkdir')
-test.must_exist('hello')
-test.must_exist('hello/world')
-
-test.write(['d1', 'file'], "d1/file\n")
-test.write(['d3', 'file'], "d3/file\n")
-test.write(['Mkdir-f6.in', 'file'], "Mkdir-f6.in/file\n")
-test.write(['f6.out-Mkdir', 'file'], "f6.out-Mkdir/file\n")
-test.write(['hello', 'file'], "hello/file\n")
+test.run(chdir = 'work1', options = '-n', arguments = '.', stdout = expect)
+
+test.must_not_exist(['work1', 'd1'])
+test.must_not_exist(['work1', 'f2.out'])
+test.must_not_exist(['work1', 'd3'])
+test.must_not_exist(['work1', 'd4'])
+test.must_not_exist(['work1', 'f5.out'])
+test.must_not_exist(['work1', 'f6.out'])
+test.must_not_exist(['work1', 'Mkdir-f6.in'])
+test.must_not_exist(['work1', 'f6.out-Mkdir'])
+
+test.run(chdir = 'work1')
+
+test.must_exist(['work1', 'd1'])
+test.must_match(['work1', 'f2.out'], "f2.in\n")
+test.must_exist(['work1', 'd3'])
+test.must_exist(['work1', 'd4'])
+test.must_match(['work1', 'f5.out'], "f5.in\n")
+test.must_exist(['work1', 'f6.out'])
+test.must_exist(['work1', 'Mkdir-f6.in'])
+test.must_exist(['work1', 'f6.out-Mkdir'])
+test.must_exist(['work1', 'hello'])
+test.must_exist(['work1', 'hello/world'])
+
+test.write(['work1', 'd1', 'file'], "d1/file\n")
+test.write(['work1', 'd3', 'file'], "d3/file\n")
+test.write(['work1', 'Mkdir-f6.in', 'file'], "Mkdir-f6.in/file\n")
+test.write(['work1', 'f6.out-Mkdir', 'file'], "f6.out-Mkdir/file\n")
+test.write(['work1', 'hello', 'file'], "hello/file\n")
+
+
+
+
+test.write(['work2', 'SConstruct'], """\
+import os
+def catdir(env, source, target):
+    target = str(target[0])
+    source = map(str, source)
+    outfp = open(target, "wb")
+    for src in source:
+        l = os.listdir(src)
+        l.sort()
+        for f in l:
+            f = os.path.join(src, f)
+            if os.path.isfile(f):
+                outfp.write(open(f, "rb").read())
+    outfp.close()
+CatDir = Builder(action = catdir)
+env = Environment(BUILDERS = {'CatDir' : CatDir})
+env.Command(Dir('hello'), None, [Mkdir('$TARGET')])
+env.Command('hello/file1.out', 'file1.in', [Copy('$TARGET', '$SOURCE')])
+env.Command('hello/file2.out', 'file2.in', [Copy('$TARGET', '$SOURCE')])
+env.CatDir('output', Dir('hello'))
+""")
+
+test.write(['work2', 'file1.in'], "work2/file1.in\n")
+test.write(['work2', 'file2.in'], "work2/file2.in\n")
+
+test.run(chdir = 'work2', arguments = 'hello/file2.out output')
+
+test.must_match(['work2', 'output'], "work2/file1.in\nwork2/file2.in\n")
 
 test.pass_test()