summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/engine/SCons/Action.py10
-rw-r--r--src/engine/SCons/Errors.py9
-rw-r--r--src/engine/SCons/ErrorsTests.py8
-rw-r--r--src/engine/SCons/Script/Main.py27
-rw-r--r--src/engine/SCons/Taskmaster.py8
-rw-r--r--src/engine/SCons/TaskmasterTests.py8
-rw-r--r--test/Install/Install.py7
-rw-r--r--test/build-errors.py4
9 files changed, 62 insertions, 23 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 2255a4f..0df1696 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -135,6 +135,10 @@ RELEASE 0.97 - XXX
- Fix (?) a runtest.py hang on Windows when the --xml option is used.
+ - Change the message when an error occurs trying to interact with the
+ file system to report the target(s) in square brackets (as before) and
+ the actual file or directory that encountered the error afterwards.
+
From Chen Lee:
- Add x64 support for Microsoft Visual Studio 8.
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 25c7133..4014dea 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -645,7 +645,15 @@ class FunctionAction(_ActionAction):
result = self.execfunction(target=target, source=rsources, env=env)
except EnvironmentError, e:
# If an IOError/OSError happens, raise a BuildError.
- raise SCons.Errors.BuildError(node=target, errstr=e.strerror)
+ # Report the name of the file or directory that caused the
+ # error, which might be different from the target being built
+ # (for example, failure to create the directory in which the
+ # target file will appear).
+ try: filename = e.filename
+ except AttributeError: filename = None
+ raise SCons.Errors.BuildError(node=target,
+ errstr=e.strerror,
+ filename=filename)
return result
def get_contents(self, target, source, env):
diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py
index 4dacde6..3a3306e 100644
--- a/src/engine/SCons/Errors.py
+++ b/src/engine/SCons/Errors.py
@@ -33,9 +33,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
class BuildError(Exception):
- def __init__(self, node=None, errstr="Unknown error", *args):
+ def __init__(self, node=None, errstr="Unknown error", filename=None, *args):
self.node = node
self.errstr = errstr
+ self.filename = filename
apply(Exception.__init__, (self,) + args)
class InternalError(Exception):
@@ -53,3 +54,9 @@ class ExplicitExit(Exception):
self.status = status
apply(Exception.__init__, (self,) + args)
+class TaskmasterException(Exception):
+ def __init__(self, node=None, exc_info=(None, None, None), *args):
+ self.node = node
+ self.errstr = "Exception"
+ self.exc_info = exc_info
+ apply(Exception.__init__, (self,) + args)
diff --git a/src/engine/SCons/ErrorsTests.py b/src/engine/SCons/ErrorsTests.py
index c63d988..93d516c 100644
--- a/src/engine/SCons/ErrorsTests.py
+++ b/src/engine/SCons/ErrorsTests.py
@@ -58,6 +58,14 @@ class ErrorsTestCase(unittest.TestCase):
except SCons.Errors.ExplicitExit, e:
assert e.node == "node"
+ def test_TaskmasterException(self):
+ """Test the TaskmasterException exception."""
+ try:
+ raise SCons.Errors.TaskmasterException("tm exception", (1, 2, 3))
+ except SCons.Errors.TaskmasterException, e:
+ assert e.node == "tm exception"
+ assert e.exc_info == (1, 2, 3)
+
if __name__ == "__main__":
suite = unittest.makeSuite(ErrorsTestCase, 'test_')
if not unittest.TextTestRunner().run(suite).wasSuccessful():
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index 6074708..73f96e2 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -138,16 +138,29 @@ class BuildTask(SCons.Taskmaster.Task):
# see if the sys module has one.
t, e = sys.exc_info()[:2]
+ def nodestring(n):
+ if not SCons.Util.is_List(n):
+ n = [ n ]
+ return string.join(map(str, n), ', ')
+
+ errfmt = "scons: *** [%s] %s\n"
+
if t == SCons.Errors.BuildError:
- fname = e.node
- if SCons.Util.is_List(e.node):
- fname = string.join(map(str, e.node), ', ')
- sys.stderr.write("scons: *** [%s] %s\n" % (fname, e.errstr))
- if e.errstr == 'Exception':
- traceback.print_exception(e.args[0], e.args[1], e.args[2])
+ tname = nodestring(e.node)
+ errstr = e.errstr
+ if e.filename:
+ errstr = e.filename + ': ' + errstr
+ sys.stderr.write(errfmt % (tname, errstr))
+ elif t == SCons.Errors.TaskmasterException:
+ tname = nodestring(e.node)
+ sys.stderr.write(errfmt % (tname, e.errstr))
+ type, value, trace = e.exc_info
+ traceback.print_exception(type, value, trace)
elif t == SCons.Errors.ExplicitExit:
status = e.status
- sys.stderr.write("scons: *** [%s] Explicit exit, status %s\n" % (e.node, e.status))
+ tname = nodestring(e.node)
+ errstr = 'Explicit exit, status %s' % status
+ sys.stderr.write(errfmt % (tname, errstr))
else:
if e is None:
e = t
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index 6d5f87c..ecd6b07 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -143,12 +143,8 @@ class Task:
except SCons.Errors.BuildError:
raise
except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- raise SCons.Errors.BuildError(self.targets[0],
- "Exception",
- exc_type,
- exc_value,
- exc_traceback)
+ raise SCons.Errors.TaskmasterException(self.targets[0],
+ sys.exc_info())
def get_target(self):
"""Fetch the target being built or updated by this task.
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index f3cb5f0..7e24d2b 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -880,14 +880,12 @@ class TaskmasterTestCase(unittest.TestCase):
t = tm.next_task()
try:
t.execute()
- except SCons.Errors.BuildError, e:
+ except SCons.Errors.TaskmasterException, e:
assert e.node == n4, e.node
assert e.errstr == "Exception", e.errstr
- assert len(e.args) == 3, `e.args`
- assert e.args[0] == OtherError, e.args[0]
- assert isinstance(e.args[1], OtherError), type(e.args[1])
+ assert len(e.exc_info) == 3, e.exc_info
exc_traceback = sys.exc_info()[2]
- assert type(e.args[2]) == type(exc_traceback), e.args[2]
+ assert type(e.exc_info[2]) == type(exc_traceback), e.exc_info[2]
else:
raise TestFailed, "did not catch expected BuildError"
diff --git a/test/Install/Install.py b/test/Install/Install.py
index 50f3820..7018466 100644
--- a/test/Install/Install.py
+++ b/test/Install/Install.py
@@ -128,9 +128,14 @@ test.write(['work', 'f1.in'], "f1.in again again\n")
os.chmod(test.workpath('work', 'export'), 0555)
f = open(f1_out, 'rb')
+expect = """\
+scons: *** [%s] %s: Permission denied
+""" % (os.path.join('export', 'f1.out'),
+ test.workpath('work', 'export', 'f1.out'))
+
test.run(chdir = 'work',
arguments = f1_out,
- stderr="scons: *** [%s] Permission denied\n" % os.path.join('export', 'f1.out'),
+ stderr=expect,
status=2)
f.close()
diff --git a/test/build-errors.py b/test/build-errors.py
index 9b6443d..e25fbd5 100644
--- a/test/build-errors.py
+++ b/test/build-errors.py
@@ -215,8 +215,8 @@ test.writable('test2.out', 1)
test.description_set("Incorrect STDERR:\n%s" % test.stderr())
errs = [
- "scons: *** [test2.out] Permission denied\n",
- "scons: *** [test2.out] permission denied\n",
+ "scons: *** [test2.out] test2.out: Permission denied\n",
+ "scons: *** [test2.out] test2.out: permission denied\n",
]
test.fail_test(test.stderr() not in errs)