Handle exceptions in FunctionActions. (Steve Christensen)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Sep 2004 01:19:55 +0000 (01:19 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 15 Sep 2004 01:19:55 +0000 (01:19 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@1068 fdb21ef1-2011-0410-befe-b5e4ea1792b1

etc/TestCmd.py
etc/TestCommon.py
src/engine/SCons/Action.py
src/engine/SCons/Node/FS.py
src/engine/SCons/Node/FSTests.py
src/engine/SCons/Script/__init__.py
test/build-errors.py
www/index.html
www/project_highlights.html

index 95333981d8fa2e2430760a674ed84e8de8aeeb1a..cc73dd1ed2a6f700f6dde20854f18cae4dd58ed3 100644 (file)
@@ -175,8 +175,8 @@ version.
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCmd.py 0.8.D001 2004/07/15 06:24:14 knight"
-__version__ = "0.8"
+__revision__ = "TestCmd.py 0.11.D001 2004/09/13 13:22:19 knight"
+__version__ = "0.11"
 
 import os
 import os.path
@@ -860,10 +860,14 @@ class TestCmd:
             f = _mode_writable
         else:
             f = _mode_non_writable
-        try:
-            os.path.walk(top, _walk_chmod, f)
-        except:
-            pass # ignore any problems changing modes
+        if os.path.isfile(top):
+            st = os.stat(top)
+            os.chmod(top, f(st[stat.ST_MODE]))
+        else:
+            try:
+                os.path.walk(top, _walk_chmod, f)
+            except:
+                pass # ignore any problems changing modes
 
     def write(self, file, content, mode = 'wb'):
         """Writes the specified content text (second argument) to the
index 43cfdddf8641182c3f252a573eb485dc23a23843..924f8f8b8b60faae2d2201bfeb77c42b42e0c4d1 100644 (file)
@@ -76,8 +76,8 @@ The TestCommon module also provides the following variables
 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
 __author__ = "Steven Knight <knight at baldmt dot com>"
-__revision__ = "TestCommon.py 0.10.D001 2004/08/17 17:39:41 knight"
-__version__ = "0.10"
+__revision__ = "TestCommon.py 0.11.D001 2004/09/13 13:22:19 knight"
+__version__ = "0.11"
 
 import os
 import os.path
index 63d8c9870d419ba66e440f9cebf316e8dcfa135a..e110d6095c7566e839652c0d52672e8d50181f0c 100644 (file)
@@ -497,7 +497,12 @@ class FunctionAction(ActionBase):
 
     def execute(self, target, source, env):
         rsources = map(rfile, source)
-        return self.execfunction(target=target, source=rsources, env=env)
+        try:
+            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)
+        return result
 
     def get_contents(self, target, source, env, dict=None):
         """Return the signature contents of this callable action.
index 7f0ca6292ca77285683ba9fb8911967843f9fe0d..6d2dd8b43a4ab036b5f99d7370004bb279fa96b2 100644 (file)
@@ -1639,11 +1639,7 @@ class File(Base):
         if self.get_state() != SCons.Node.up_to_date:
             if self.exists():
                 if self.is_derived() and not self.precious:
-                    try:
-                        Unlink(self, [], None)
-                    except OSError, e:
-                        raise SCons.Errors.BuildError(node = self,
-                                                      errstr = e.strerror)
+                    Unlink(self, [], None)
                     try:
                         delattr(self, '_exists')
                     except AttributeError:
@@ -1670,12 +1666,12 @@ class File(Base):
                 self._createDir()
                 try:
                     Unlink(self, None, None)
-                except OSError:
+                except SCons.Errors.BuildError:
                     pass
                 try:
                     Link(self, src, None)
-                except IOError, e:
-                    desc = "Cannot duplicate `%s' in `%s': %s." % (src, self.dir, e.strerror)
+                except SCons.Errors.BuildError, e:
+                    desc = "Cannot duplicate `%s' in `%s': %s." % (src, self.dir, e.errstr)
                     raise SCons.Errors.StopError, desc
                 self.linked = 1
                 # The Link() action may or may not have actually
index c213d265b93a6ada7126044fedad63bc1fc81318..3e803096babf024c8256783f4b7b809f6e76cdc0 100644 (file)
@@ -344,7 +344,7 @@ class BuildDirTestCase(unittest.TestCase):
         save_Link = SCons.Node.FS.Link
         def Link_IOError(target, source, env):
             raise IOError, "Link_IOError"
-        SCons.Node.FS.Link = Link_IOError
+        SCons.Node.FS.Link = SCons.Action.Action(Link_IOError, None)
 
         test.write(['work', 'src', 'IOError'], "work/src/IOError\n")
 
index 0ad910216e7e0651ccaf9b2f6b5957b709ec3c04..6ae76bf68d45f68d3de52ec333cb6e4ca6c7cd4a 100644 (file)
@@ -161,7 +161,10 @@ class BuildTask(SCons.Taskmaster.Task):
             t, e = sys.exc_info()[:2]
 
         if t == SCons.Errors.BuildError:
-            sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
+            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])
         elif t == SCons.Errors.ExplicitExit:
index 1ea2d7a9fbf80a6d1e4ffacea03e1acb78a109f3..f64786fce5e0e7506538ae9982eb8e584759825f 100644 (file)
@@ -187,4 +187,37 @@ else:
             break
     test.fail_test(error_message_not_found)
 
+test.write('SConstruct4', r"""
+env = Environment()
+env.Command('test.out', 'test.in', 'cp $SOURCE $TARGET')
+env.InstallAs('test2.out', 'test.out')
+# Mark test2.out as precious so we'll handle the exception in
+# FunctionAction() rather than when the target is cleaned before building.
+env.Precious('test2.out')
+env.Default('test2.out')
+""")
+
+test.write('test.in', "test.in 1\n")
+
+test.run(arguments = '-f SConstruct4 .')
+
+test.write('test.in', "test.in 2\n")
+
+test.writable('test2.out', 0)
+f = open(test.workpath('test2.out'))
+
+test.run(arguments = '-f SConstruct4 .',
+         stderr = None,
+         status = 2)
+
+f.close()
+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",
+]
+test.fail_test(test.stderr() not in errs)
+
 test.pass_test()
index 52ee1f53e63f6409b06ccd29b1f94efd2d0dc907..eb349787f69296653343aff4725de0583f037eed 100644 (file)
@@ -4,7 +4,7 @@
 <body>
 
 <p>SCons is a next-generation, 
-cross-platform build tool.
+cross-platform, build tool.
 Think of SCons as an improved
 substitute for the classic
 <tt>Make</tt> utility
@@ -19,9 +19,10 @@ or wedge a scripting language onto some other
 configuration file syntax,
 SCons configuration files
 are actually Python scripts.
-This gives you a tremendous amount of flexibility
+The ability to script your build
+gives you a tremendous amount of flexibility
 to solve complicated build problems
-in surprisingly small amounts of code.
+in surprisingly small amounts of maintainable code.
 </p>
 
 <p>
@@ -56,7 +57,13 @@ project.</li>
 
 <h3>Mission</h3>
 
-<p>What is the goal of this project?
+<p>The goal of The SCons Project
+is to become the premiere build tool for
+cross-platform, multi-language software projects
+by offering unparalleled
+reliability,
+flexibility
+and ease of use.
 </p>
 
 <p>What is the scope of this project?
index 93078bc7532baf8cf7bef1547b0a5e55617e462e..0a153875ed0f833d2c1ba166b16ea75ac3251aec 100644 (file)
@@ -4,13 +4,13 @@
 <body>
 
 <p>
-<b>23 August 2004:</b>
+<strong>23 August 2004:</strong>
 Bugfix release 0.96.1 fixes
 a handful of critical problems in 0.96.
 <p>
 
 <p>
-<b>18 August 2004:</b>
+<strong>18 August 2004:</strong>
 Beta release 0.96 adds Fortran 90/95 support,
 better Qt support,
 platform-independent file manipulation actions,