diff options
| author | Steven Knight <knight@baldmt.com> | 2004-11-13 21:56:57 (GMT) |
|---|---|---|
| committer | Steven Knight <knight@baldmt.com> | 2004-11-13 21:56:57 (GMT) |
| commit | 09cad6ed1ffb436742adbbf6608bb094b4a236e2 (patch) | |
| tree | b6c4b1f529c82d39dab94b26fb1440980955c8fe /src/engine/SCons | |
| parent | 206adf4366654b0c3fcf8c9131140f0c11ae0a5f (diff) | |
| download | SCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.zip SCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.tar.gz SCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.tar.bz2 | |
Allow Alias Nodes to have Actions.
Diffstat (limited to 'src/engine/SCons')
| -rw-r--r-- | src/engine/SCons/Environment.py | 72 | ||||
| -rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 19 | ||||
| -rw-r--r-- | src/engine/SCons/Node/Alias.py | 45 | ||||
| -rw-r--r-- | src/engine/SCons/Node/AliasTests.py | 14 | ||||
| -rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 13 | ||||
| -rw-r--r-- | src/engine/SCons/Node/__init__.py | 7 |
6 files changed, 124 insertions, 46 deletions
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 443c6b0..ef3b2d0 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -96,6 +96,7 @@ AliasBuilder = SCons.Builder.Builder(action = alias_builder, target_factory = SCons.Node.Alias.default_ans.Alias, source_factory = SCons.Node.FS.default_fs.Entry, multi = 1, + is_explicit = None, name='AliasBuilder') def our_deepcopy(x): @@ -1036,29 +1037,56 @@ class Base: n.add_post_action(action) return nodes - def Alias(self, target, *source, **kw): - if not SCons.Util.is_List(target): - target = [target] - tlist = [] - for t in target: - if not isinstance(t, SCons.Node.Alias.Alias): - t = self.arg2nodes(self.subst(t), self.ans.Alias)[0] - tlist.append(t) - try: - s = kw['source'] - except KeyError: - try: - s = source[0] - except IndexError: - s = None - if s: - if not SCons.Util.is_List(s): - s = [s] - s = filter(None, s) - s = self.arg2nodes(s, self.fs.Entry) + def Alias(self, target, source=[], action=None, **kw): + tlist = self.arg2nodes(target, self.ans.Alias) + if not SCons.Util.is_List(source): + source = [source] + source = filter(None, source) + + if not action: + if not source: + # There are no source files and no action, so just + # return a target list of classic Alias Nodes, without + # any builder. The externally visible effect is that + # this will make the wrapping Script.BuildTask class + # say that there's "Nothing to be done" for this Alias, + # instead of that it's "up to date." + return tlist + + # No action, but there are sources. Re-call all the target + # builders to add the sources to each target. + result = [] for t in tlist: - AliasBuilder(self, t, s) - return tlist + bld = t.get_builder(AliasBuilder) + result.extend(bld(self, t, source)) + return result + + action = SCons.Action.Action(action) + nkw = self.subst_kw(kw) + nkw['source_factory'] = self.fs.Entry + nkw['multi'] = 1 + nkw['action'] = action + bld = apply(SCons.Builder.Builder, (), nkw) + + # Apply the Builder separately to each target so that the Aliases + # stay separate. If we did one "normal" Builder call with the + # whole target list, then all of the target Aliases would be + # associated under a single Executor. + result = [] + for t in tlist: + # Calling the convert() method will cause a new Executor to be + # created from scratch, so we have to explicitly initialize + # it with the target's existing sources, plus our new ones, + # so nothing gets lost. + b = t.get_builder() + if b is None or b is AliasBuilder: + b = bld + else: + nkw['action'] = b.action + action + b = apply(SCons.Builder.Builder, (), nkw) + t.convert() + result.extend(b(self, t, t.sources + source)) + return result def AlwaysBuild(self, *targets): tlist = [] diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 0a0f260..9b84f3c 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -1797,6 +1797,7 @@ f5: \ tgt = env.Alias('new_alias')[0] assert str(tgt) == 'new_alias', tgt assert tgt.sources == [], tgt.sources + assert not hasattr(tgt, 'builder'), tgt.builder tgt = env.Alias('None_alias', None)[0] assert str(tgt) == 'None_alias', tgt @@ -1833,6 +1834,24 @@ f5: \ assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources) assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources) + tgt = env.Alias('add', 's1') + tgt = env.Alias('add', 's2')[0] + s = map(str, tgt.sources) + assert s == ['s1', 's2'], s + tgt = env.Alias(tgt, 's3')[0] + s = map(str, tgt.sources) + assert s == ['s1', 's2', 's3'], s + + tgt = env.Alias('act', None, "action1")[0] + s = str(tgt.builder.action) + assert s == "action1", s + tgt = env.Alias('act', None, "action2")[0] + s = str(tgt.builder.action) + assert s == "action1\naction2", s + tgt = env.Alias(tgt, None, "action3")[0] + s = str(tgt.builder.action) + assert s == "action1\naction2\naction3", s + def test_AlwaysBuild(self): """Test the AlwaysBuild() method""" env = Environment(FOO='fff', BAR='bbb') diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py index 89127a3..c361838 100644 --- a/src/engine/SCons/Node/Alias.py +++ b/src/engine/SCons/Node/Alias.py @@ -39,11 +39,15 @@ import SCons.Node import SCons.Util class AliasNameSpace(UserDict.UserDict): - def Alias(self, name): - if self.has_key(name): - raise SCons.Errors.UserError - self[name] = SCons.Node.Alias.Alias(name) - return self[name] + def Alias(self, name, **kw): + if isinstance(name, SCons.Node.Alias.Alias): + return name + try: + a = self[name] + except KeyError: + a = apply(SCons.Node.Alias.Alias, (name,), kw) + self[name] = a + return a def lookup(self, name): try: @@ -59,18 +63,11 @@ class Alias(SCons.Node.Node): def __str__(self): return self.name - def build(self): - """A "builder" for aliases.""" - pass - + really_build = SCons.Node.Node.build current = SCons.Node.Node.children_are_up_to_date - def sconsign(self): - """An Alias is not recorded in .sconsign files""" - pass - def is_under(self, dir): - # Make Alias nodes get built regardless of + # Make Alias nodes get built regardless of # what directory scons was run from. Alias nodes # are outside the filesystem: return 1 @@ -82,7 +79,25 @@ class Alias(SCons.Node.Node): for kid in self.children(None): contents = contents + kid.get_contents() return contents - + + def sconsign(self): + """An Alias is not recorded in .sconsign files""" + pass + + # + # + # + + def build(self): + """A "builder" for aliases.""" + pass + + def convert(self): + try: del self.builder + except AttributeError: pass + self.reset_executor() + self.build = self.really_build + default_ans = AliasNameSpace() SCons.Node.arg2nodes_lookups.append(default_ans.lookup) diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py index afae46b..417cc2b 100644 --- a/src/engine/SCons/Node/AliasTests.py +++ b/src/engine/SCons/Node/AliasTests.py @@ -42,15 +42,11 @@ class AliasTestCase(unittest.TestCase): """ ans = SCons.Node.Alias.AliasNameSpace() - a = ans.Alias('a1') - assert a.name == 'a1', a.name - - try: - ans.Alias('a1') - except SCons.Errors.UserError: - pass - else: - raise TestFailed, "did not catch expected UserError" + a1 = ans.Alias('a1') + assert a1.name == 'a1', a1.name + + a2 = ans.Alias('a1') + assert a1 is a2, (a1, a2) def test_lookup(self): """Test the lookup() method diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 657ac9b..e0956e1 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -390,6 +390,19 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder(is_explicit=None)) assert not n1.has_explicit_builder() + def test_get_builder(self): + """Test the get_builder() method""" + n1 = SCons.Node.Node() + b = n1.get_builder() + assert b is None, b + b = n1.get_builder(777) + assert b == 777, b + n1.builder_set(888) + b = n1.get_builder() + assert b == 888, b + b = n1.get_builder(999) + assert b == 888, b + def test_multiple_side_effect_has_builder(self): """Test the multiple_side_effect_has_builder() method """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 36b0aed..fc3d7ec 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -329,6 +329,13 @@ class Node: directories).""" return self.has_builder() and self.builder.is_explicit + def get_builder(self, default_builder=None): + """Return the set builder, or a specified default value""" + try: + return self.builder + except AttributeError: + return default_builder + multiple_side_effect_has_builder = has_builder def is_derived(self): |
