Display commands as string with "WAF_CMD_FORMAT=string waf build -v"

This commit is contained in:
Thomas Nagy 2017-03-04 08:20:27 +01:00
parent 5fb2e21ccf
commit 5d4074eb7f
No known key found for this signature in database
GPG Key ID: 49B4C67C05277AAA
5 changed files with 69 additions and 87 deletions

View File

@ -5,6 +5,7 @@ NEW IN WAF 2.0.0
* Force new files into the build directory by default (use Node objects to bypass)
* Process support for building over UNC paths
* Simplify the Task class hierarchy; TaskBase is removed
* Display commands as string with "WAF_CMD_FORMAT=string waf build -v"
* New ant_glob(..., generator=True) now returns a Python generator
* Accept nested lists and generators in bld(source=...)
* Sort TaskGen methods in alphabetical order by reversing TaskGen.prec order

39
tests/utils/wscript Normal file
View File

@ -0,0 +1,39 @@
#! /usr/bin/env python
# encoding: utf-8
# Thomas Nagy, 2012 (ita)
VERSION='0.0.1'
APPNAME='preproc_test'
top = '.'
out = 'build'
from waflib import Utils
from waflib.Logs import pprint
def configure(conf):
pass
def build(bld):
bld.failure = 0
def disp(color, result):
pprint(color, result)
if color == 'RED':
bld.failure=1
def stop_status(bld):
if bld.failure:
bld.fatal('One or several test failed, check the outputs above')
bld.add_post_fun(stop_status)
def test_shell(inp, expected):
ret = Utils.shell_escape(inp)
if ret == expected:
color = "GREEN"
else:
color = "RED"
disp(color, "%r -> %r\t\texpected: %r" % (inp, ret, expected))
test_shell("ls -l", "ls -l")
test_shell(['ls', '-l', 'a space'], "ls -l 'a space'")

View File

@ -296,6 +296,15 @@ class Context(ctx):
raise Errors.WafError('Cannot read the folder %r' % d)
raise Errors.WafError('No wscript file in directory %s' % d)
def log_command(self, cmd, kw):
if Logs.verbose:
fmt = os.environ.get('WAF_CMD_FORMAT')
if fmt == 'string':
if not isinstance(cmd, str):
cmd = Utils.shell_escape(cmd)
Logs.debug('runner: %r', cmd)
Logs.debug('runner_env: kw=%s', kw)
def exec_command(self, cmd, **kw):
"""
Runs an external process and returns the exit status::
@ -317,8 +326,7 @@ class Context(ctx):
"""
subprocess = Utils.subprocess
kw['shell'] = isinstance(cmd, str)
Logs.debug('runner: %r', cmd)
Logs.debug('runner_env: kw=%s', kw)
self.log_command(cmd, kw)
if self.logger:
self.logger.info(cmd)
@ -396,7 +404,7 @@ class Context(ctx):
"""
subprocess = Utils.subprocess
kw['shell'] = isinstance(cmd, str)
Logs.debug('runner: %r', cmd)
self.log_command(cmd, kw)
if 'quiet' in kw:
quiet = kw['quiet']

View File

@ -568,10 +568,26 @@ def quote_define_name(s):
fu = fu.upper()
return fu
re_sh = re.compile('\\s|\'|"')
"""
Regexp used for shell_escape below
"""
def shell_escape(cmd):
"""
Escapes a command:
['ls', '-l', 'arg space'] -> ls -l 'arg space'
"""
if isinstance(cmd, str):
return cmd
return ' '.join(repr(x) if re_sh.search(x) else x for x in cmd)
def h_list(lst):
"""
Hash lists. We would prefer to use hash(tup) for tuples because it is much more efficient,
but Python now enforces hash randomization by assuming everybody is running a web application.
Hashes lists of ordered data.
Using hash(tup) for tuples would be much more efficient,
but Python now enforces hash randomization
:param lst: list to hash
:type lst: list of strings

View File

@ -1,82 +0,0 @@
#! /usr/bin/env python
"""
Illustrate how to override a class method to do something
In this case, print the commands being executed as strings
(the commands are usually lists, so this can be misleading)
"""
import sys
from waflib import Context, Utils, Errors, Logs
def exec_command(self, cmd, **kw):
subprocess = Utils.subprocess
kw['shell'] = isinstance(cmd, str)
if isinstance(cmd, str):
kw['shell'] = True
txt = cmd
else:
txt = ' '.join(repr(x) if ' ' in x else x for x in cmd)
Logs.debug('runner: %s', txt)
Logs.debug('runner_env: kw=%s', kw)
if self.logger:
self.logger.info(cmd)
if 'stdout' not in kw:
kw['stdout'] = subprocess.PIPE
if 'stderr' not in kw:
kw['stderr'] = subprocess.PIPE
if Logs.verbose and not kw['shell'] and not Utils.check_exe(cmd[0]):
raise Errors.WafError("Program %s not found!" % cmd[0])
wargs = {}
if 'timeout' in kw:
if kw['timeout'] is not None:
wargs['timeout'] = kw['timeout']
del kw['timeout']
if 'input' in kw:
if kw['input']:
wargs['input'] = kw['input']
kw['stdin'] = Utils.subprocess.PIPE
del kw['input']
if 'cwd' in kw:
if not isinstance(kw['cwd'], str):
kw['cwd'] = kw['cwd'].abspath()
try:
if kw['stdout'] or kw['stderr']:
p = subprocess.Popen(cmd, **kw)
(out, err) = p.communicate(**wargs)
ret = p.returncode
else:
out, err = (None, None)
ret = subprocess.Popen(cmd, **kw).wait(**wargs)
except Exception as e:
raise Errors.WafError('Execution failure: %s' % str(e), ex=e)
if out:
if not isinstance(out, str):
out = out.decode(sys.stdout.encoding or 'latin-1')
if self.logger:
self.logger.debug('out: %s' % out)
else:
Logs.info(out, extra={'stream':sys.stdout, 'c1': ''})
if err:
if not isinstance(err, str):
err = err.decode(sys.stdout.encoding or 'latin-1')
if self.logger:
self.logger.error('err: %s' % err)
else:
Logs.info(err, extra={'stream':sys.stderr, 'c1': ''})
return ret
Context.Context.exec_command = exec_command