diff options
| author | Steven Knight <knight@baldmt.com> | 2004-06-25 04:10:24 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2004-06-25 04:10:24 (GMT) |
| commit | c2bb425dcb2907f50a485469b69e83884fed6fb4 (patch) | |
| tree | eec003c4e6e332651cf70c8896612b17b7acb290 /src/engine/SCons/Node | |
| parent | 5f1ca10deda557947d8669098fdce1852b38b81f (diff) | |
| download | SCons-c2bb425dcb2907f50a485469b69e83884fed6fb4.zip SCons-c2bb425dcb2907f50a485469b69e83884fed6fb4.tar.gz SCons-c2bb425dcb2907f50a485469b69e83884fed6fb4.tar.bz2 | |
Officially support target_factory and source_factory when creating a Builder.
Diffstat (limited to 'src/engine/SCons/Node')
| -rw-r--r-- | src/engine/SCons/Node/FS.py | 48 | ||||
| -rw-r--r-- | src/engine/SCons/Node/FSTests.py | 82 | ||||
| -rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 8 | ||||
| -rw-r--r-- | src/engine/SCons/Node/__init__.py | 2 |
4 files changed, 85 insertions, 55 deletions
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 2f115c9..52a75ce 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -176,10 +176,24 @@ Unlink = SCons.Action.Action(UnlinkFunc, None) def MkdirFunc(target, source, env): t = target[0] - t.fs.mkdir(t.path) + if not t.fs.exists(t.path): + t.fs.mkdir(t.path) return 0 -Mkdir = SCons.Action.Action(MkdirFunc, None) +Mkdir = SCons.Action.Action(MkdirFunc, None, presub=None) + +MkdirBuilder = None + +def get_MkdirBuilder(): + global MkdirBuilder + if MkdirBuilder is None: + import SCons.Builder + import SCons.Defaults + env = SCons.Defaults.DefaultEnvironment() + MkdirBuilder = SCons.Builder.Builder(action = Mkdir, + env = env, + explain = None) + return MkdirBuilder def CacheRetrieveFunc(target, source, env): t = target[0] @@ -1118,7 +1132,7 @@ class Dir(Base): self.entries['.'] = self self.entries['..'] = self.dir self.cwd = self - self.builder = 1 + self.builder = get_MkdirBuilder() self.searched = 0 self._sconsign = None self.build_dirs = [] @@ -1238,7 +1252,13 @@ class Dir(Base): def build(self, **kw): """A null "builder" for directories.""" - pass + global MkdirBuilder + if not self.builder is MkdirBuilder: + apply(SCons.Node.Node.build, [self,], kw) + + def multiple_side_effect_has_builder(self): + global MkdirBuilder + return not self.builder is MkdirBuilder and self.has_builder() def alter_targets(self): """Return any corresponding targets in a build directory. @@ -1262,6 +1282,8 @@ class Dir(Base): def current(self, calc=None): """If all of our children were up-to-date, then this directory was up-to-date, too.""" + if not self.builder is MkdirBuilder and not self.exists(): + return 0 state = 0 for kid in self.children(): s = kid.get_state() @@ -1299,16 +1321,6 @@ class Dir(Base): return self.srcdir return Base.srcnode(self) - def get_executor(self, create=1): - """Fetch the action executor for this node. Create one if - there isn't already one, and requested to do so.""" - try: - executor = self.executor - except AttributeError: - executor = DummyExecutor() - self.executor = executor - return executor - def get_timestamp(self): """Return the latest timestamp from among our children""" stamp = 0 @@ -1482,8 +1494,12 @@ class File(Base): listDirs.reverse() for dirnode in listDirs: try: - Mkdir(dirnode, [], None) - # The Mkdir() action may or may not have actually + # Don't call dirnode.build(), call the base Node method + # directly because we definitely *must* create this + # directory. The dirnode.build() method will suppress + # the build if it's the default builder. + SCons.Node.Node.build(dirnode) + # 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 # _rexists attributes so they can be reevaluated. diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index d4137c1..bbc64ef 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -281,8 +281,33 @@ class BuildDirTestCase(unittest.TestCase): f8.rfile().path # Verify the Mkdir and Link actions are called + d9 = fs.Dir('build/var2/new_dir') f9 = fs.File('build/var2/new_dir/test9.out') + class MkdirAction(Action): + def __init__(self, dir_made): + self.dir_made = dir_made + def __call__(self, target, source, env, errfunc): + self.dir_made.extend(target) + + save_Link = SCons.Node.FS.Link + link_made = [] + def link_func(target, source, env, link_made=link_made): + link_made.append(target) + SCons.Node.FS.Link = link_func + + try: + dir_made = [] + d9.builder = Builder(fs.Dir, action=MkdirAction(dir_made)) + f9.exists() + expect = os.path.join('build', 'var2', 'new_dir') + assert dir_made[0].path == expect, dir_made[0].path + expect = os.path.join('build', 'var2', 'new_dir', 'test9.out') + assert link_made[0].path == expect, link_made[0].path + assert f9.linked + finally: + SCons.Node.FS.Link = save_Link + # Test for an interesting pathological case...we have a source # file in a build path, but not in a source path. This can # happen if you switch from duplicate=1 to duplicate=0, then @@ -312,29 +337,6 @@ class BuildDirTestCase(unittest.TestCase): var2_new_dir = os.path.normpath('build/var2/new_dir') assert bdt == [var1_new_dir, var2_new_dir], bdt - save_Mkdir = SCons.Node.FS.Mkdir - dir_made = [] - def mkdir_func(target, source, env, dir_made=dir_made): - dir_made.append(target) - SCons.Node.FS.Mkdir = mkdir_func - - save_Link = SCons.Node.FS.Link - link_made = [] - def link_func(target, source, env, link_made=link_made): - link_made.append(target) - SCons.Node.FS.Link = link_func - - try: - f9.exists() - expect = os.path.join('build', 'var2', 'new_dir') - assert dir_made[0].path == expect, dir_made[0].path - expect = os.path.join('build', 'var2', 'new_dir', 'test9.out') - assert link_made[0].path == expect, link_made[0].path - assert f9.linked - finally: - SCons.Node.FS.Mkdir = save_Mkdir - SCons.Node.FS.Link = save_Link - # Test that an IOError trying to Link a src file # into a BuildDir ends up throwing a StopError. fIO = fs.File("build/var2/IOError") @@ -754,7 +756,7 @@ class FSTestCase(unittest.TestCase): d1.builder_set(Builder(fs.File)) d1.env_set(Environment()) d1.build() - assert not built_it + assert built_it built_it = None assert not built_it @@ -1497,22 +1499,24 @@ class prepareTestCase(unittest.TestCase): exc_caught = 1 assert exc_caught, "Should have caught a StopError." - save_Mkdir = SCons.Node.FS.Mkdir - dir_made = [] - def mkdir_func(target, source, env, dir_made=dir_made): - dir_made.append(target) - SCons.Node.FS.Mkdir = mkdir_func + class MkdirAction(Action): + def __init__(self, dir_made): + self.dir_made = dir_made + def __call__(self, target, source, env, errfunc): + self.dir_made.extend(target) - file = fs.File(os.path.join("new_dir", "xyz")) - try: - file.set_state(SCons.Node.up_to_date) - file.prepare() - assert dir_made == [], dir_made - file.set_state(0) - file.prepare() - assert dir_made[0].path == "new_dir", dir_made[0].path - finally: - SCons.Node.FS.Mkdir = save_Mkdir + dir_made = [] + new_dir = fs.Dir("new_dir") + new_dir.builder = Builder(fs.Dir, action=MkdirAction(dir_made)) + xyz = fs.File(os.path.join("new_dir", "xyz")) + + xyz.set_state(SCons.Node.up_to_date) + xyz.prepare() + assert dir_made == [], dir_made + xyz.set_state(0) + xyz.prepare() + print "dir_made[0] =", dir_made[0] + assert dir_made[0].path == "new_dir", dir_made[0] dir = fs.Dir("dir") dir.prepare() diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index cd7aa18..72ddd74 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -304,6 +304,14 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder()) assert n1.has_builder() == 1 + def test_multiple_side_effect_has_builder(self): + """Test the multiple_side_effect_has_builder() method + """ + n1 = SCons.Node.Node() + assert n1.multiple_side_effect_has_builder() == 0 + n1.builder_set(Builder()) + assert n1.multiple_side_effect_has_builder() == 1 + def test_is_derived(self): """Test the is_derived() method """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 51e6628..603762e 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -299,6 +299,8 @@ class Node: b = self.builder return not b is None + multiple_side_effect_has_builder = has_builder + def is_derived(self): """ Returns true iff this node is derived (i.e. built). |
