summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-03-03 19:39:25 (GMT)
committerSteven Knight <knight@baldmt.com>2003-03-03 19:39:25 (GMT)
commit57847f39e8598008ce3acddbcfb5a117e6981b3d (patch)
treeb6fc19421b03826488e03d795c4c258002f4ede7 /src/engine
parent1eac1ba89777cce14d1ed50322ee163e8b38fd1e (diff)
downloadSCons-57847f39e8598008ce3acddbcfb5a117e6981b3d.zip
SCons-57847f39e8598008ce3acddbcfb5a117e6981b3d.tar.gz
SCons-57847f39e8598008ce3acddbcfb5a117e6981b3d.tar.bz2
Add an Exit() function for explicit termination of SCons.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Errors.py6
-rw-r--r--src/engine/SCons/ErrorsTests.py7
-rw-r--r--src/engine/SCons/Script/SConscript.py4
-rw-r--r--src/engine/SCons/Script/__init__.py12
-rw-r--r--src/engine/SCons/Taskmaster.py8
-rw-r--r--src/engine/SCons/TaskmasterTests.py13
6 files changed, 44 insertions, 6 deletions
diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py
index 0028d95..9743674 100644
--- a/src/engine/SCons/Errors.py
+++ b/src/engine/SCons/Errors.py
@@ -49,3 +49,9 @@ class UserError(Exception):
class StopError(Exception):
def __init__(self, args=None):
self.args = args
+
+class ExplicitExit(Exception):
+ def __init__(self, node=None, status=None, *args):
+ self.node = node
+ self.status = status
+ self.args = args
diff --git a/src/engine/SCons/ErrorsTests.py b/src/engine/SCons/ErrorsTests.py
index 9d5010d..b128026 100644
--- a/src/engine/SCons/ErrorsTests.py
+++ b/src/engine/SCons/ErrorsTests.py
@@ -51,6 +51,13 @@ class ErrorsTestCase(unittest.TestCase):
except SCons.Errors.UserError, e:
assert e.args == "test user error"
+ def test_ExplicitExit(self):
+ """Test the ExplicitExit exception."""
+ try:
+ raise SCons.Errors.ExplicitExit, "node"
+ except SCons.Errors.ExplicitExit, e:
+ assert e.node == "node"
+
if __name__ == "__main__":
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index dfcfe5b..d9da651 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -418,6 +418,9 @@ def AddPostAction(files, action):
for n in nodes:
n.add_post_action(SCons.Action.Action(action))
+def Exit(value=0):
+ sys.exit(value)
+
def BuildDefaultGlobals():
"""
Create a dictionary containing all the default globals for
@@ -439,6 +442,7 @@ def BuildDefaultGlobals():
globals['EnsurePythonVersion'] = EnsurePythonVersion
globals['EnsureSConsVersion'] = EnsureSConsVersion
globals['Environment'] = SCons.Environment.Environment
+ globals['Exit'] = Exit
globals['Export'] = Export
globals['File'] = SCons.Node.FS.default_fs.File
globals['FindFile'] = FindFile
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index b14e50d..ca0d50e 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -86,16 +86,16 @@ class BuildTask(SCons.Taskmaster.Task):
command_time = command_time+finish_time-start_time
print "Command execution time: %f seconds"%(finish_time-start_time)
- def do_failed(self):
+ def do_failed(self, status=2):
global exit_status
if ignore_errors:
SCons.Taskmaster.Task.executed(self)
elif keep_going_on_error:
SCons.Taskmaster.Task.fail_continue(self)
- exit_status = 2
+ exit_status = status
else:
SCons.Taskmaster.Task.fail_stop(self)
- exit_status = 2
+ exit_status = status
def executed(self):
t = self.targets[0]
@@ -129,6 +129,7 @@ class BuildTask(SCons.Taskmaster.Task):
def failed(self):
e = sys.exc_value
+ status = 2
if sys.exc_type == SCons.Errors.BuildError:
sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
if e.errstr == 'Exception':
@@ -142,12 +143,15 @@ class BuildTask(SCons.Taskmaster.Task):
if not keep_going_on_error:
s = s + ' Stop.'
sys.stderr.write("scons: *** %s\n" % s)
+ elif sys.exc_type == SCons.Errors.ExplicitExit:
+ status = e.status
+ sys.stderr.write("scons: *** [%s] Explicit exit, status %s\n" % (e.node, e.status))
else:
if e is None:
e = sys.exc_type
sys.stderr.write("scons: *** %s\n" % e)
- self.do_failed()
+ self.do_failed(status)
class CleanTask(SCons.Taskmaster.Task):
"""An SCons clean task."""
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py
index 68e251c..2ab076b 100644
--- a/src/engine/SCons/Taskmaster.py
+++ b/src/engine/SCons/Taskmaster.py
@@ -83,6 +83,8 @@ class Task:
self.targets[0].build()
except KeyboardInterrupt:
raise
+ except SystemExit:
+ raise SCons.Errors.ExplicitExit(self.targets[0], sys.exc_value.code)
except SCons.Errors.UserError:
raise
except SCons.Errors.BuildError:
@@ -215,6 +217,12 @@ class Taskmaster:
try:
children = node.children()
+ except SystemExit:
+ e = SCons.Errors.ExplicitExit(node, sys.exc_value.code)
+ self.exception_set(SCons.Errors.ExplicitExit, e)
+ self.candidates.pop()
+ self.ready = node
+ break
except:
# We had a problem just trying to figure out the
# children (like a child couldn't be linked in to a
diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py
index 2f9383a..ea9b8b4 100644
--- a/src/engine/SCons/TaskmasterTests.py
+++ b/src/engine/SCons/TaskmasterTests.py
@@ -392,14 +392,23 @@ class TaskmasterTestCase(unittest.TestCase):
def test_children_errors(self):
"""Test errors when fetching the children of a node.
"""
- class MyNode(Node):
+ class StopNode(Node):
def children(self):
raise SCons.Errors.StopError, "stop!"
- n1 = MyNode("n1")
+ class ExitNode(Node):
+ def children(self):
+ sys.exit(77)
+ n1 = StopNode("n1")
tm = SCons.Taskmaster.Taskmaster([n1])
t = tm.next_task()
assert tm.exc_type == SCons.Errors.StopError, "Did not record StopError on node"
assert str(tm.exc_value) == "stop!", "Unexpected exc_value `%s'" % tm.exc_value
+ n2 = ExitNode("n2")
+ tm = SCons.Taskmaster.Taskmaster([n2])
+ t = tm.next_task()
+ assert tm.exc_type == SCons.Errors.ExplicitExit, "Did not record ExplicitExit on node"
+ assert tm.exc_value.node == n2, tm.exc_value.node
+ assert tm.exc_value.status == 77, tm.exc_value.status
def test_cycle_detection(self):
"""Test detecting dependency cycles