summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-02-02 18:35:15 (GMT)
committerSteven Knight <knight@baldmt.com>2003-02-02 18:35:15 (GMT)
commitc7dcf9e7a31681c4a0d7043f2c4406be4e7648e9 (patch)
tree68854e66d53bf8f0bd4b3e95a842033c2d336fd2
parent8c857d116b57450227a1fe4bc822d8b2e5047f54 (diff)
downloadSCons-c7dcf9e7a31681c4a0d7043f2c4406be4e7648e9.zip
SCons-c7dcf9e7a31681c4a0d7043f2c4406be4e7648e9.tar.gz
SCons-c7dcf9e7a31681c4a0d7043f2c4406be4e7648e9.tar.bz2
Add a strfunction() to Command actions, and add an env argument to the FunctionAction.strfunction().
-rw-r--r--doc/man/scons.127
-rw-r--r--src/CHANGES.txt5
-rw-r--r--src/RELEASE.txt16
-rw-r--r--src/engine/SCons/Action.py21
-rw-r--r--src/engine/SCons/ActionTests.py36
-rw-r--r--src/engine/SCons/Environment.py2
-rw-r--r--src/engine/SCons/Node/FS.py2
7 files changed, 89 insertions, 20 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index b196fac..a1eac4c 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -2993,7 +2993,7 @@ The Python function takes three keyword arguments,
.B source
(a Node object representing the source file)
and
-.BR env
+.B env
(the construction environment
used for building the target file).
The
@@ -3029,17 +3029,30 @@ a = Action(build_it)
The second, optional argument
is a Python function that returns
-a string to be printed describing the action being executed.
-This function takes two arguments,
-an array of targets to be created by the function action,
-and an array of sources used to create the target(s):
+a string to be printed to describe the action being executed.
+Like the function to build a file,
+this function takes three arguments:
+.B target
+(a Node object representing the target file),
+.B source
+(a Node object representing the source file)
+and
+.BR env
+(a construction environment).
+The
+.B target
+and
+.B source
+arguments may be lists of Node objects if there is
+more than one target file or source file.
+Examples:
.ES
def build_it(target, source, env):
# build the target from the source
return 0
-def string_it(target, source):
+def string_it(target, source, env):
return "building '%s' from '%s'" % (target[0], source[0])
# Use a positional argument.
@@ -3056,7 +3069,7 @@ in the signature of the Action
when deciding whether a target should
be rebuilt because the action changed.
This is necessary whenever you want a target to
-be rebuilt by an action when a specific
+be rebuilt when a specific
construction variable changes,
because the underlying Python code for a function
will not change when the value of the construction variable does.
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 4e8fcee..b29889e 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -49,6 +49,11 @@ RELEASE 0.11 - XXX
- Clean up error messages from problems duplicating into read-only
BuildDir directories or into read-only files.
+ - Add a CommandAction.strfunction() method, and add an "env" argument
+ to the FunctionAction.strfunction() method, so that all Action
+ objects have strfunction() methods, and the functions for building
+ and returning a string both take the same arguments.
+
From Steve Leblanc:
- Fix the output of -c -n when directories are involved, so it
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index cc3adc8..d87808b 100644
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -56,6 +56,22 @@ RELEASE 0.10 - Thu, 16 Jan 2003 04:11:46 -0600
env['BUILDERS']['newbuilder'] = foo
+ - An "env" argument has been added to the calls to all functions that
+ return a string for a Python function Action. This makes the string
+ function and build function calls take the same arguments:
+
+ def build_it(target, source, env):
+ # build the target from the source
+ return 0
+
+ def string_it(target, source, env):
+ return "building '%s' from '%s'" % (target[0], source[0])
+
+ a = Action(build_it, string_it)
+
+ If you have defined a strfunction() for a Python function Action,
+ you will need to add a third "env" argument to your function call.
+
Please note the following important changes since release 0.09:
- The Scanner interface has been changed to make it easier to
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 646ee8d..3ab910b 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -227,6 +227,11 @@ class CommandAction(ActionBase):
def __init__(self, cmd):
self.cmd_list = cmd
+ def strfunction(self, target, source, env):
+ dict = self.subst_dict(target, source, env)
+ cmd_list = SCons.Util.scons_subst_list(self.cmd_list, dict, {}, _rm)
+ return map(_string_from_cmd_list, cmd_list)
+
def __call__(self, target, source, env):
"""Execute a command action.
@@ -352,9 +357,11 @@ class FunctionAction(ActionBase):
def __init__(self, execfunction, strfunction=_null, varlist=[]):
self.execfunction = execfunction
if strfunction is _null:
- def strfunction(target, source, execfunction=execfunction):
+ def strfunction(target, source, env, execfunction=execfunction):
def quote(s):
return '"' + str(s) + '"'
+ def array(a, q=quote):
+ return '[' + string.join(map(lambda x, q=q: q(x), a), ", ") + ']'
try:
name = execfunction.__name__
except AttributeError:
@@ -362,14 +369,8 @@ class FunctionAction(ActionBase):
name = execfunction.__class__.__name__
except AttributeError:
name = "unknown_python_function"
- if len(target) == 1:
- tstr = quote(target[0])
- else:
- tstr = str(map(lambda x, q=quote: q(x), target))
- if len(source) == 1:
- sstr = quote(source[0])
- else:
- sstr = str(map(lambda x, q=quote: q(x), source))
+ tstr = len(target) == 1 and quote(target[0]) or array(target)
+ sstr = len(source) == 1 and quote(source[0]) or array(source)
return "%s(%s, %s)" % (name, tstr, sstr)
self.strfunction = strfunction
self.varlist = varlist
@@ -381,7 +382,7 @@ class FunctionAction(ActionBase):
if not SCons.Util.is_List(source):
source = [source]
if print_actions and self.strfunction:
- s = self.strfunction(target, source)
+ s = self.strfunction(target, source, env)
if s:
self.show(s)
if execute_actions:
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index 0f96899..2d3540c 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -31,6 +31,7 @@ def Func():
pass
import os
+import StringIO
import sys
import types
import unittest
@@ -70,6 +71,10 @@ outfile2 = test.workpath('outfile2')
scons_env = SCons.Environment.Environment()
+# Capture all the stuff the Actions will print,
+# so it doesn't clutter the output.
+sys.stdout = StringIO.StringIO()
+
class Environment:
def __init__(self, **kw):
self.d = {}
@@ -319,6 +324,35 @@ class CommandActionTestCase(unittest.TestCase):
a = SCons.Action.CommandAction(["xyzzy"])
assert a.cmd_list == [ "xyzzy" ], a.cmd_list
+ def test_strfunction(self):
+ """Test fetching the string representation of command Actions
+ """
+ act = SCons.Action.CommandAction('xyzzy $TARGET $SOURCE')
+ s = act.strfunction([], [], Environment())
+ assert s == ['xyzzy'], s
+ s = act.strfunction(['target'], ['source'], Environment())
+ assert s == ['xyzzy target source'], s
+ s = act.strfunction(['t1', 't2'], ['s1', 's2'], Environment())
+ assert s == ['xyzzy t1 s1'], s
+
+ act = SCons.Action.CommandAction('xyzzy $TARGETS $SOURCES')
+ s = act.strfunction([], [], Environment())
+ assert s == ['xyzzy'], s
+ s = act.strfunction(['target'], ['source'], Environment())
+ assert s == ['xyzzy target source'], s
+ s = act.strfunction(['t1', 't2'], ['s1', 's2'], Environment())
+ assert s == ['xyzzy t1 t2 s1 s2'], s
+
+ act = SCons.Action.CommandAction(['xyzzy',
+ '$TARGET', '$SOURCE',
+ '$TARGETS', '$SOURCES'])
+ s = act.strfunction([], [], Environment())
+ assert s == ['xyzzy'], s
+ s = act.strfunction(['target'], ['source'], Environment())
+ assert s == ['xyzzy target source target source'], s
+ s = act.strfunction(['t1', 't2'], ['s1', 's2'], Environment())
+ assert s == ['xyzzy t1 s1 t1 t2 s1 s2'], s
+
def test_execute(self):
"""Test execution of command Actions
@@ -663,7 +697,7 @@ class FunctionActionTestCase(unittest.TestCase):
def build_it(target, source, env, self=self):
self.build_it = 1
return 0
- def string_it(target, source, self=self):
+ def string_it(target, source, env, self=self):
self.string_it = 1
return None
act = SCons.Action.FunctionAction(build_it, string_it)
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index f9448bd..f9c793d 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -47,7 +47,7 @@ import SCons.Tool
import SCons.Util
import SCons.Warnings
-def installString(target, source):
+def installString(target, source, env):
return 'Install file: "%s" as "%s"' % (source[0], target[0])
installAction = SCons.Action.Action(SCons.Node.FS.LinkFunc, installString)
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index 0978b57..923615f 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -89,7 +89,7 @@ def LinkFunc(target, source, env):
Link = SCons.Action.Action(LinkFunc, None)
-def LocalString(target, source):
+def LocalString(target, source, env):
return 'Local copy of %s from %s' % (target[0], source[0])
LocalCopy = SCons.Action.Action(LinkFunc, LocalString)