summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tanner <ttanner2@bloomberg.net>2013-09-26 18:01:53 +0100
committerTom Tanner <ttanner2@bloomberg.net>2013-09-26 18:01:53 +0100
commit6cb9bf6e408041789f3a1ebadf54c2d19edff161 (patch)
tree563be1c134096291c3d7cee90ce6b1892e1be06f
parentf094b77fc68787c61efdc9ca095098c88bf52373 (diff)
downloadscons-6cb9bf6e408041789f3a1ebadf54c2d19edff161.tar.gz
Addition of warning if build doesn't build expected targets.
Added option to runtest.py to stop on first error
-rw-r--r--doc/man/scons.xml8
-rwxr-xr-x[-rw-r--r--]runtest.py38
-rw-r--r--src/engine/SCons/Node/__init__.py8
-rw-r--r--src/engine/SCons/Script/Main.py1
-rw-r--r--src/engine/SCons/Warnings.py3
5 files changed, 45 insertions, 13 deletions
diff --git a/doc/man/scons.xml b/doc/man/scons.xml
index 602bdbee..7036caff 100644
--- a/doc/man/scons.xml
+++ b/doc/man/scons.xml
@@ -1940,6 +1940,14 @@ These warnings are enabled by default.</para>
</listitem>
</varlistentry>
<varlistentry>
+ <term>--warn=target_not_build, --warn=no-target_not_built</term>
+ <listitem>
+<para>Enables or disables warnings about a build rule not building the
+ expected targets. These warnings are not currently enabled by default.</para>
+
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>-Y<emphasis> repository</emphasis>, --repository=<emphasis>repository</emphasis>, --srcdir=<emphasis>repository</emphasis></term>
<listitem>
<para>Search the specified repository for any input and target
diff --git a/runtest.py b/runtest.py
index 6beb4ba7..2b7f7cee 100644..100755
--- a/runtest.py
+++ b/runtest.py
@@ -58,6 +58,8 @@
# command line it will execute before
# executing it. This suppresses that print.
#
+# --quit-on-failure Quit on any test failure
+#
# -s Short progress. Prints only the command line
# and a percentage value, based on the total and
# current number of tests.
@@ -123,6 +125,7 @@ print_progress = 1
suppress_stdout = False
suppress_stderr = False
allow_pipe_files = True
+quit_on_failure = False
helpstr = """\
Usage: runtest.py [OPTIONS] [TEST ...]
@@ -158,6 +161,7 @@ Options:
--passed Summarize which tests passed.
--qmtest Run using the QMTest harness (deprecated).
-q, --quiet Don't print the test being executed.
+ --quit-on-failure Quit on any test failure
-s, --short-progress Short progress, prints only the command line
and a percentage value, based on the total and
current number of tests.
@@ -214,7 +218,9 @@ opts, args = getopt.getopt(args, "3b:def:hj:klnP:p:qsv:Xx:t",
'jobs=',
'list', 'no-exec', 'nopipefiles',
'package=', 'passed', 'python=', 'qmtest',
- 'quiet', 'short-progress', 'time',
+ 'quiet',
+ 'quit-on-failure',
+ 'short-progress', 'time',
'version=', 'exec=',
'verbose='])
@@ -267,7 +273,9 @@ for o, a in opts:
elif o in ['-q', '--quiet']:
printcommand = 0
suppress_stdout = True
- suppress_stderr = True
+ suppress_stderr = True
+ elif o in ['--quit-on-failure']:
+ quit_on_failure = True
elif o in ['-s', '--short-progress']:
print_progress = 1
suppress_stdout = True
@@ -373,16 +381,16 @@ else:
# Else, we catch the output of both pipes...
if allow_pipe_files:
# The subprocess.Popen() suffers from a well-known
- # problem. Data for stdout/stderr is read into a
+ # problem. Data for stdout/stderr is read into a
# memory buffer of fixed size, 65K which is not very much.
# When it fills up, it simply stops letting the child process
# write to it. The child will then sit and patiently wait to
- # be able to write the rest of its output. Hang!
+ # be able to write the rest of its output. Hang!
# In order to work around this, we follow a suggestion
# by Anders Pearson in
# http://http://thraxil.org/users/anders/posts/2008/03/13/Subprocess-Hanging-PIPE-is-your-enemy/
# and pass temp file objects to Popen() instead of the ubiquitous
- # subprocess.PIPE.
+ # subprocess.PIPE.
def spawn_it(command_args):
# Create temporary files
import tempfile
@@ -395,7 +403,7 @@ else:
shell=True)
# ... and wait for it to finish.
ret = p.wait()
-
+
try:
# Rewind to start of files
tmp_stdout.seek(0)
@@ -407,10 +415,10 @@ else:
# Remove temp files by closing them
tmp_stdout.close()
tmp_stderr.close()
-
+
# Return values
return (spawned_stderr, spawned_stdout, ret)
-
+
else:
# We get here only if the user gave the '--nopipefiles'
# option, meaning the "temp file" approach for
@@ -419,9 +427,9 @@ else:
# potential deadlock situation in the following code:
# If the subprocess writes a lot of data to its stderr,
# the pipe will fill up (nobody's reading it yet) and the
- # subprocess will wait for someone to read it.
+ # subprocess will wait for someone to read it.
# But the parent process is trying to read from stdin
- # (but the subprocess isn't writing anything there).
+ # (but the subprocess isn't writing anything there).
# Hence a deadlock.
# Be dragons here! Better don't use this!
def spawn_it(command_args):
@@ -469,7 +477,7 @@ class PopenExecutor(Base):
shell=True)
# ... and wait for it to finish.
self.status = p.wait()
-
+
try:
# Rewind to start of files
tmp_stdout.seek(0)
@@ -481,7 +489,7 @@ class PopenExecutor(Base):
# Remove temp files by closing them
tmp_stdout.close()
tmp_stderr.close()
- else:
+ else:
def execute(self):
p = subprocess.Popen(self.command_str,
stdout=subprocess.PIPE,
@@ -832,7 +840,7 @@ def run_test(t, io_lock, async=True):
if head:
os.environ['PYTHON_SCRIPT_DIR'] = head
else:
- os.environ['PYTHON_SCRIPT_DIR'] = ''
+ os.environ['PYTHON_SCRIPT_DIR'] = ''
test_start_time = time_func()
if execute_tests:
t.execute()
@@ -849,6 +857,10 @@ def run_test(t, io_lock, async=True):
print_time_func("Test execution time: %.1f seconds\n", t.test_time)
if io_lock:
io_lock.release()
+ if quit_on_failure and t.status == 1:
+ print "Exiting due to error"
+ print t.status
+ sys.exit(1)
class RunTest(threading.Thread):
def __init__(self, queue, io_lock):
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 992284dc..56e46945 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -57,6 +57,10 @@ from SCons.Debug import Trace
def classname(obj):
return str(obj.__class__).split('.')[-1]
+# Set to false if we're doing a dry run. There's more than one of these
+# little treats
+do_store_info = True
+
# Node states
#
# These are in "priority" order, so that the maximum value for any
@@ -385,6 +389,10 @@ class Node(object):
self.clear()
+ if not self.exists() and do_store_info:
+ SCons.Warnings.warn(SCons.Warnings.TargetNotBuiltWarning,
+ "Cannot find target " + str(self) + " after building")
+
self.ninfo.update(self)
def visited(self):
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 837c1039..191c7b55 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -1083,6 +1083,7 @@ def _build_targets(fs, options, targets, target_top):
SCons.Action.print_actions = not options.silent
SCons.Action.execute_actions = not options.no_exec
SCons.Node.FS.do_store_info = not options.no_exec
+ SCons.Node.do_store_info = not options.no_exec
SCons.SConf.dryrun = options.no_exec
if options.diskcheck:
diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py
index a260c4ac..ca6acee9 100644
--- a/src/engine/SCons/Warnings.py
+++ b/src/engine/SCons/Warnings.py
@@ -42,6 +42,9 @@ class WarningOnByDefault(Warning):
# NOTE: If you add a new warning class, add it to the man page, too!
+class TargetNotBuiltWarning(Warning): # Should go to OnByDefault
+ pass
+
class CacheWriteErrorWarning(Warning):
pass