Allow explicit target_factory=Dir with Builders that make a directory to override...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 20 Oct 2004 23:59:50 +0000 (23:59 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 20 Oct 2004 23:59:50 +0000 (23:59 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1130 fdb21ef1-2011-0410-befe-b5e4ea1792b1

doc/man/scons.1
src/CHANGES.txt
src/engine/SCons/Builder.py
src/engine/SCons/BuilderTests.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/NodeTests.py
src/engine/SCons/Node/__init__.py
test/Dir.py

index f21e00b8db54794443827443f140af4ff0abd9b7..b94d680e508fd09e99e3d3c77e09cf334293b889 100644 (file)
@@ -7655,7 +7655,7 @@ Example:
 MakeDirectoryBuilder = Builder(action=my_mkdir, target_factory=Dir)
 env = Environment()
 env.Append(BUILDERS = {'MakeDirectory':MakeDirectoryBuilder})
-env.MakeDirectory('new_directory')
+env.MakeDirectory('new_directory', [])
 .EE
 
 .IP source_factory
index 8e0a1ceefb6033bd55c7090ece12f8971728fbe6..5a4062fa111d5202428a5a561e206bbe12c26336 100644 (file)
@@ -97,6 +97,9 @@ RELEASE 0.97 - XXX
   - Packaging build fix:  Rebuild the files that are use to report the
     --version of SCons whenever the development version number changes.
 
+  - Fix the ability to specify a target_factory of Dir() to a Builder,
+    which the default create-a-directory Builder was interfering with.
+
   From Clive Levinson:
 
   - Make ParseConfig() recognize and add -mno-cygwin to $LINKFLAGS and
index e9d4e117ba1e0540a7efc2db59c83085f031c627..6afff589788ce06025681995e2738281779dee3b 100644 (file)
@@ -284,7 +284,7 @@ def _init_nodes(builder, env, overrides, executor_kw, tlist, slist):
     for t in tlist:
         if t.side_effect:
             raise UserError, "Multiple ways to build the same target were specified for: %s" % str(t)
-        if t.has_builder():
+        if t.has_explicit_builder():
             if not t.env is None and not t.env is env:
                 t_contents = t.builder.action.get_contents(tlist, slist, t.env)
                 contents = t.builder.action.get_contents(tlist, slist, env)
@@ -412,6 +412,7 @@ class BuilderBase:
                         single_source = 0,
                         name = None,
                         chdir = _null,
+                        is_explicit = 1,
                         **overrides):
         if __debug__: logInstanceCreation(self, 'BuilderBase')
         self.action = SCons.Action.Action(action)
@@ -453,6 +454,7 @@ class BuilderBase:
         self.executor_kw = {}
         if not chdir is _null:
             self.executor_kw['chdir'] = chdir
+        self.is_explicit = is_explicit
 
     def __nonzero__(self):
         raise InternalError, "Do not test for the Node.builder attribute directly; use Node.has_builder() instead"
index a67d22a26b45165a99cb7376eb90d24bb2d8f6e3..2075bf0e85d8bf51f0e4e480127a5a522714b8d5 100644 (file)
@@ -140,6 +140,8 @@ class MyNode_without_target_from_source:
         self.builder = builder
     def has_builder(self):
         return not self.builder is None
+    def has_explicit_builder(self):
+        return not self.builder is None and self.builder.is_explicit
     def env_set(self, env, safe=0):
         self.env = env
     def add_source(self, source):
index 2bd68e1372df680469de7c5d48713e73caa6f261..883b82c9037a600d8f81ddeefd0746bbd7e7ebbd 100644 (file)
@@ -194,6 +194,7 @@ def get_MkdirBuilder():
         MkdirBuilder = SCons.Builder.Builder(action = Mkdir,
                                              env = None,
                                              explain = None,
+                                             is_explicit = None,
                                              name = "MkdirBuilder")
     return MkdirBuilder
 
index f8cd62b7617c4250310a015998f0993f548d08f4..ce677815c006c83d07d3de7344e528895e422268 100644 (file)
@@ -93,10 +93,11 @@ class Environment:
         self._dict.update(dict)
 
 class Builder:
-    def __init__(self):
+    def __init__(self, is_explicit=1):
         self.env = Environment()
         self.overrides = {}
         self.action = MyAction()
+        self.is_explicit = is_explicit
     def targets(self, t):
         return [t]
     def get_actions(self):
@@ -314,6 +315,16 @@ class NodeTestCase(unittest.TestCase):
         n1.builder_set(Builder())
         assert n1.has_builder() == 1
 
+    def test_has_explicit_builder(self):
+        """Test the has_explicit_builder() method
+        """
+        n1 = SCons.Node.Node()
+        assert not n1.has_explicit_builder()
+        n1.builder_set(Builder(is_explicit=1))
+        assert n1.has_explicit_builder()
+        n1.builder_set(Builder(is_explicit=None))
+        assert not n1.has_explicit_builder()
+
     def test_multiple_side_effect_has_builder(self):
         """Test the multiple_side_effect_has_builder() method
         """
index 338df0783b76640b678ac1b114e7941f4939e146..38cff929751d8f17408859854cdbe49bcf80d6a3 100644 (file)
@@ -307,6 +307,15 @@ class Node:
             b = self.builder
         return not b is None
 
+    def has_explicit_builder(self):
+        """Return whether this Node has an explicit builder
+
+        This allows an internal Builder created by SCons to be marked
+        non-explicit, so that it can be overridden by an explicit
+        builder that the user supplies (the canonical example being
+        directories)."""
+        return self.has_builder() and self.builder.is_explicit
+
     multiple_side_effect_has_builder = has_builder
 
     def is_derived(self):
index 5c4eaa380a420a13996f5d67ad91f9fe2dd847f9..d7ec9ae71d3b73f72bc5faadee484517e140662d 100644 (file)
@@ -55,4 +55,20 @@ bbb_bbb
 scons: `.' is up to date.
 """))
 
+
+
+test.write('SConstruct', """\
+import os
+def my_mkdir(target=None, source=None, env=None):
+    os.mkdir(str(target[0]))
+
+MDBuilder = Builder(action=my_mkdir, target_factory=Dir)
+env = Environment()
+env.Append(BUILDERS = {'MD':MDBuilder})
+env.MD(target='sub1', source=['SConstruct'])
+env.MD(target='sub2', source=['SConstruct'], OVERRIDE='foo')
+""")
+
+test.run()
+
 test.pass_test()