[Scons-users] Printing after command
Eric Lunderberg
eric.lunderberg at gmail.com
Tue Jan 3 17:30:26 EST 2017
I am attempting to improve the readability of the messages being printed to
screen. I've used the *COMSTR variables before to customize what gets
printed before a command is run. I would like to add a message that gets
printed after the command as well, summarizing the results of the command
(i.e. ok, warning, or error).
With make, I can do this by printing a before-run status message, running
the command with the output piped to a file, printing an after-run status
message, then printing the contents of the piped file. The overall effect
is shown in this gif <https://i.stack.imgur.com/ndiin.gif>. This way, I
can visually distinguish which file produced warning and error messages,
especially with the different colors for each. I haven't found a way to
replicate these status messages with scons.
I can get fairly close to a solution by replacing env['SPAWN'] in the
environment. From there, I can run the command, printing before and after
running the command. There are two main difficulties that I ran into.
First, the spawn function is passed only the command to be run, and not the
description of the command, as formed from the comstr. As far as I can
tell, that information is only present in the SCons.Action._ActionAction.
I can get a little bit closer by also replacing the command action (CXXCOM,
SHCXXCOM, etc) with a custom function. That custom function can generate
the string to be printed, based on the appropriate COMSTR. It can run the
command, using the custom SPAWN function to grab the output of the command,
then print it afterward.
However, while replacing env['CXXCOM'] allows me to call my custom
function, the COMSTR is still being printed twice. As far as I can tell,
this is done in the action defined in Defaults.py, before control ever gets
passed to my function. I would like some way to silence this printing, but
cannot find a way to do so. As it stands, my best attempt to reproduce the
behavior from the makefile is shown in this gif
<http://i.imgur.com/ITE8ber.gif>. Note that the COMSTR has been printed
twice.
The relevant parts of the SConstruct in order to produce this behavior are
shown below. Any advice on fixing the double-printing would be most
appreciated.
import sys
class BufferSpawn(object):
def __init__(self):
self.stdout = ''
def __call__(self, sh, escape, cmd, args, spawnenv):
asciienv = {key:str(value) for key,value in spawnenv.items()}
# Call a subprocess, grabbing all output
p = subprocess.Popen(
' '.join(args),
shell=True,
env=asciienv,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
stdout,stderr = p.communicate()
self.stdout = stdout
return p.returncode
class CommandWrapper(object):
_null = SCons.Action._null
def __init__(self, env, com, comstr):
self.overrides = {com:env[com],
comstr:env[comstr],
}
self.action = SCons.Action.Action('$'+com, '$'+comstr)
self.pad_to = 50
def __call__(self, target, source, env,
exitstatfunc=_null,
presub=_null,
show=_null,
execute=_null,
chdir=_null,
executor=None):
# Generate the environment for the subordinate action
overrides = self.overrides.copy()
spawn = BufferSpawn()
overrides['SPAWN'] = spawn
env = env.Override(overrides)
# Generate the status message to be printed
try:
to_print = self.action.strfunction(target, source, env,
executor)
except TypeError:
to_print = self.action.strfunction(target, source, env)
to_print = to_print.ljust(self.pad_to)
# Print the before-command status
print to_print + '\r',
sys.stdout.flush()
# Run the command, without printing anything.
show = False
retval = self.action(target, source, env, exitstatfunc,
presub, show, execute, chdir, executor)
# Figure out the change to the status message
if retval:
print_result = '[ERROR]'
elif spawn.stdout:
print_result = '[WARNING]'
else:
print_result = '[OK]'
# Print the after-command status, and the stdout, if any
print to_print + print_result
if spawn.stdout:
print spawn.stdout
sys.stdout.flush()
env['CXXCOMSTR'] = 'Compiling C++ object $TARGETS'
env['CXXCOM'] = CommandWrapper(env, 'CXXCOM','CXXCOMSTR')
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20170103/bec6e01b/attachment.html>
More information about the Scons-users
mailing list