[Scons-users] Printing after command

Eric Lunderberg eric.lunderberg at gmail.com
Tue Jan 3 22:47:49 EST 2017


William,

I've tried to suppress the output by changing the value of CXXCOMSTR.
Unfortunately for me, if it is an empty string, or anything that evaluates
to an empty string (e.g. a non-existent variable, or a lambda function that
returns empty string), then the entire command will be printed instead.

I have a bit of a workaround at the moment, where I am using '\033[A', the
ANSI escape code for "CURSOR_UP", so that I can place the cursor overtop
the already-printed message.  It feels rather hacky, though, and I'd like
to find a cleaner solution if possible.

Eric

On Tue, Jan 3, 2017 at 10:25 PM, William Blevins <wblevins001 at gmail.com>
wrote:

> Eric,
>
> My understanding is that you are trying to keep the compiler command
> information at the same location as the compiler command output
> (success/fail). Can you just make CXXCOMSTR empty and make your own
> variable for the 3rd parameter in your CommandWrapper? That way even if
> SCons prints something initially it will just be an empty string (or
> newline maybe...).
>
> V/R,
> William
>
> On Tue, Jan 3, 2017 at 10:02 PM, Eric Lunderberg <
> eric.lunderberg at gmail.com> wrote:
>
>> Thank you for the suggestion.  I had tried the post action, but ran into
>> two main issues in using it for this purpose.  First, the post action only
>> runs if the command finishes successfully, and so it cannot print anything
>> if there is an error.  Second, it does not capture the stdout/stderr of the
>> command.  This means that the output of the command would appear above the
>> status message, instead of below, and that it cannot tell whether a warning
>> had been issued by the compiler.
>>
>> On Tue, Jan 3, 2017 at 7:22 PM, William Blevins <wblevins001 at gmail.com>
>> wrote:
>>
>>> Eric,
>>>
>>> Probably not what you are looking for but you "could" use a post action.
>>> AddPostAction(target, action) , env.AddPostAction(target, action)
>>>
>>> Arranges for the specified action to be performed after the specified
>>> target has been built. The specified action(s) may be an Action object,
>>> or anything that can be converted into an Action object (see below).
>>>
>>> When multiple targets are supplied, the action may be called multiple
>>> times, once after each action that generates one or more targets in the
>>> list.
>>> V/R,
>>> William
>>>
>>> On Tue, Jan 3, 2017 at 5:30 PM, Eric Lunderberg <
>>> eric.lunderberg at gmail.com> wrote:
>>>
>>>> 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')
>>>>
>>>> _______________________________________________
>>>> Scons-users mailing list
>>>> Scons-users at scons.org
>>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>>
>>>>
>>>
>>> _______________________________________________
>>> Scons-users mailing list
>>> Scons-users at scons.org
>>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>>
>>>
>>
>> _______________________________________________
>> Scons-users mailing list
>> Scons-users at scons.org
>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>
>>
>
> _______________________________________________
> Scons-users mailing list
> Scons-users at scons.org
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20170103/6cd90c5a/attachment-0001.html>


More information about the Scons-users mailing list