Create all of the directories for a target list before trying to build the targets.
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 10 Feb 2002 07:03:00 +0000 (07:03 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sun, 10 Feb 2002 07:03:00 +0000 (07:03 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@251 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Builder.py
src/engine/SCons/BuilderTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Node/NodeTests.py
src/engine/SCons/Node/__init__.py
src/engine/SCons/Script/__init__.py
src/engine/SCons/Taskmaster.py
src/engine/SCons/TaskmasterTests.py

index 29f99f6a2af1e0c2ccf824bc8c520760911f6708..4b4256f84f89ff37fed7e89a523029f5ad9c6f9d 100644 (file)
@@ -25,6 +25,9 @@ RELEASE 0.05 -
   - More performance optimizations:  cache #include lines from files,
     eliminate unnecessary calls.
 
+  - If a prefix or suffix contains white space, treat the resulting
+    concatenation as separate arguments.
+
   - Fix irregularities in the way we fetch DevStudio information from
     the Windows registry, and in our registry error handling.
 
@@ -42,6 +45,9 @@ RELEASE 0.05 -
   - Make writing .sconsign files more robust by first trying to write
     to a temp file that we rename.
 
+  - Create all of the directories for a list of targets before trying
+    to build any of the targets.
+
   From Anthony Roach:
 
   - Make the scons script return an error code on failures.
index 130a9e2c58f93c6a225611e6435158a40d513b55..347a6525058a8ce19acb596ec20cb7d70fdf553b 100644 (file)
@@ -190,8 +190,9 @@ class ListBuilder:
         if hasattr(self, 'status'):
             return self.status
         for t in self.tlist:
-            # unlink all targets before building any
-            t.remove()
+            # unlink all targets and make all directories
+            # before building anything
+            t.prepare()
         kw['target'] = self.tlist[0]
         self.status = apply(self.builder.execute, (), kw)
         for t in self.tlist:
index 5fb273b8f5b96190f286437570dfa41225d9ba91..3b44672306e8c78ce47db8d7bd413b70b9d6379e 100644 (file)
@@ -61,7 +61,7 @@ sys.exit(0)
 
 act_py = test.workpath('act.py')
 outfile = test.workpath('outfile')
-outfile2 = test.workpath('outfile')
+outfile2 = test.workpath('outfile2')
 
 show_string = None
 instanced = None
@@ -259,7 +259,10 @@ class BuilderTestCase(unittest.TestCase):
            return 1
 
        builder = MyBuilder(action = function1, name = "function1")
-        r = builder.execute(target = [outfile, outfile2])
+        try:
+            r = builder.execute(target = [outfile, outfile2])
+        except SCons.Errors.BuildError:
+            pass
         assert r == 1
         assert count == 1
         c = test.read(outfile, 'r')
@@ -462,19 +465,24 @@ class BuilderTestCase(unittest.TestCase):
         """Testing ListBuilder class."""
         global count
         count = 0
-        def function2(**kw):
+        def function2(tlist = [outfile, outfile2], **kw):
             global count
             count = count + 1
             if not type(kw['target']) is type([]):
                 kw['target'] = [ kw['target'] ]
             for t in kw['target']:
                 open(t, 'w').write("function2\n")
+            for t in tlist:
+                if not t in kw['target']:
+                    open(t, 'w').write("function2\n")
             return 1
 
         builder = SCons.Builder.Builder(action = function2, name = "function2")
         tgts = builder(env, target = [outfile, outfile2], source = 'foo')
-        r = tgts[0].builder.execute(target = tgts[0])
-        assert r == 1, r
+       try:
+            r = tgts[0].builder.execute(target = tgts)
+       except SCons.Errors.BuildError:
+            pass
         c = test.read(outfile, 'r')
         assert c == "function2\n", c
         c = test.read(outfile2, 'r')
@@ -483,6 +491,36 @@ class BuilderTestCase(unittest.TestCase):
         assert r == 1, r
         assert count == 1, count
 
+        sub1_out = test.workpath('sub1', 'out')
+        sub2_out = test.workpath('sub2', 'out')
+
+        count = 0
+        def function3(tlist = [sub1_out, sub2_out], **kw):
+            global count
+            count = count + 1
+            if not type(kw['target']) is type([]):
+                kw['target'] = [ kw['target'] ]
+            for t in kw['target']:
+                open(t, 'w').write("function3\n")
+            for t in tlist:
+                if not t in kw['target']:
+                    open(t, 'w').write("function3\n")
+            return 1
+
+        builder = SCons.Builder.Builder(action = function3, name = "function3")
+        tgts = builder(env, target = [sub1_out, sub2_out], source = 'foo')
+        try:
+            r = tgts[0].builder.execute(target = tgts)
+        except:
+            pass
+        assert r == 1, r
+        c = test.read(sub1_out, 'r')
+        assert c == "function3\n", c
+        c = test.read(sub2_out, 'r')
+        assert c == "function3\n", c
+        assert os.path.exists(test.workpath('sub1'))
+        assert os.path.exists(test.workpath('sub2'))
+
     def test_MultiStepBuilder(self):
         """Testing MultiStepBuilder class."""
         builder1 = SCons.Builder.Builder(name = "builder1",
index 55084364e33c5efe39c545d0710185c5ae3ef3d4..3167005d673a73a5299dc0d5ce042ff65b70400f 100644 (file)
@@ -562,14 +562,16 @@ class File(Entry):
                 pass
 
     def build(self):
-        self.__createDir()
         Entry.build(self)
         self.exists_flag = self.exists()
 
-    def remove(self):
-        """Remove this file."""
+    def prepare(self):
+        """Prepare for this file to be created."""
         if self.exists():
-            os.unlink(self.path)
+            if not self.precious:
+                os.unlink(self.path)
+        else:
+            self.__createDir()
 
 default_fs = FS()
 
index f20c2fb922c03f826b3e344d649da22065621468..94f81fdfb33963a61de7d3d8ca8ffd7dde33d013 100644 (file)
@@ -397,6 +397,7 @@ class FSTestCase(unittest.TestCase):
         # Test building a file whose directory is not there yet...
         f1 = fs.File(test.workpath("foo/bar/baz/ack"))
         assert not f1.dir.exists()
+        f1.prepare()
         f1.build()
         assert f1.dir.exists()
 
@@ -448,7 +449,7 @@ class FSTestCase(unittest.TestCase):
         test.write("remove_me", "\n")
         assert os.path.exists(test.workpath("remove_me"))
         f1 = fs.File(test.workpath("remove_me"))
-        f1.remove()
+        f1.prepare()
         assert not os.path.exists(test.workpath("remove_me"))
 
         #XXX test current() for directories
index abe5e008d8e69b545aea33728607cbc33b84510b..4e518603bfd5f9548b97f9b04588b646927f4c66 100644 (file)
@@ -59,7 +59,7 @@ class ListBuilder(Builder):
         if hasattr(self, 'status'):
             return self.status
         for n in self.nodes:
-            n.remove()
+            n.prepare()
         kw['target'] = self.nodes[0]
         self.status = apply(Builder.execute, (self,), kw)
 
@@ -130,11 +130,11 @@ class NodeTestCase(unittest.TestCase):
         class MyNode(SCons.Node.Node):
             def __init__(self, **kw):
                 apply(SCons.Node.Node.__init__, (self,), kw)
-                self.remove_count = 0
+                self.prepare_count = 0
             def __str__(self):
                 return self.path
-            def remove(self):
-                self.remove_count= self.remove_count+ 1
+            def prepare(self):
+                self.prepare_count = self.prepare_count+ 1
        # Make sure it doesn't blow up if no builder is set.
         node = MyNode()
        node.build()
@@ -180,20 +180,20 @@ class NodeTestCase(unittest.TestCase):
         fff.build()
         assert built_it
         ggg.build()
-        assert ggg.remove_count== 1, ggg.remove_count
+        assert ggg.prepare_count== 1, ggg.prepare_count
         assert type(built_target) == type(MyNode()), type(built_target)
         assert str(built_target) == "fff", str(built_target)
         assert built_source == ["hhh", "iii"], built_source
 
         delattr(lb, 'status')
-        fff.remove_count = 0
-        ggg.remove_count = 0
+        fff.prepare_count = 0
+        ggg.prepare_count = 0
 
         built_it = None
         ggg.build()
         #assert built_it
         fff.build()
-        assert fff.remove_count== 1, fff.remove_count
+        assert fff.prepare_count== 1, fff.prepare_count
         assert type(built_target) == type(MyNode()), type(built_target)
         assert str(built_target) == "fff", str(built_target)
         assert built_source == ["hhh", "iii"], built_source
index 1222b1e9b6c9d1f660ed041cc3f10aaf5f52ffd4..1d09b20bb74db6b8c9b62f95ab8921a48c75a990 100644 (file)
@@ -82,8 +82,6 @@ class Node:
             # there will already be an associated status.
             stat = self.builder.status
         except AttributeError:
-            if not self.precious:
-                self.remove()
             try:
                 stat = self.builder.execute(env = self.env.Dictionary(),
                                             target = self,
@@ -185,8 +183,8 @@ class Node:
         """Set the Node's precious value."""
         self.precious = precious
 
-    def remove(self):
-        """Remove this Node's external object:  no-op by default."""
+    def prepare(self):
+        """Prepare for this Node to be created:  no-op by default."""
         pass
 
     def add_dependency(self, depend):
index 2b907a0ed93c1275a875d37624237de759ebe171..a34814ed70ab2a3e80d1dc6e45c485ba3759de07 100644 (file)
@@ -73,6 +73,7 @@ class BuildTask(SCons.Taskmaster.Task):
                 print 'scons: "%s" is up to date.' % str(self.targets[0])
         else:
             try:
+                self.targets[0].prepare()
                 self.targets[0].build()
             except BuildError, e:
                 sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
index a88fe63b9f039c85035c2f651333131b5424e917..558845db035f0687bee54ad498cc511f8bb667f1 100644 (file)
@@ -61,6 +61,7 @@ class Task:
 
     def execute(self):
         if self.targets[0].get_state() != SCons.Node.up_to_date:
+            self.targets[0].prepare()
             self.targets[0].build()
 
     def get_target(self):
index 5beb9b2dd19dae279dcc8f2de03d903fdf703946..0d7a7ad423be8ba9d97356b964ec038d8b0f08d9 100644 (file)
@@ -51,6 +51,9 @@ class Node:
         global built
         built = self.name + " built"
 
+    def prepare(self):
+        pass
+
     def children(self):
        return self.kids