Better error messages. (Gary Oberbrunner)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 3 Jul 2003 13:13:08 +0000 (13:13 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Thu, 3 Jul 2003 13:13:08 +0000 (13:13 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@733 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Builder.py
src/engine/SCons/BuilderTests.py
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py

index bd8c5da36a15d009d3d4e39e70eb7b5da64dc332..40fdbbb3cc4b68ddf4638219a69a119c957e0dfe 100644 (file)
@@ -22,6 +22,16 @@ RELEASE 0.XX - XXX
 
   - Documentation fixes:  typo in the man page.
 
+  From Gary Oberbrunner:
+
+  - Report the target being built in error messages when building
+    multiple sources from different extensions, or when the target file
+    extension can't be deduced, or when we don't have an action for a
+    file suffix.
+
+  - Provide helpful error messages when the arguments to env.Install()
+    are incorrect.
+
 
 
 RELEASE 0.90 - Wed, 25 Jun 2003 14:24:52 -0500
index f19983d37a2ecb03314532b8c08f611feb277a32..2d5828adf3398913e7fff9a2a77175ce29d0c375 100644 (file)
@@ -83,17 +83,17 @@ class DictCmdGenerator:
         for src in map(str, source):
             my_ext = SCons.Util.splitext(src)[1]
             if ext and my_ext != ext:
-                raise UserError("Cannot build multiple sources with different extensions: %s, %s" % (ext, my_ext))
+                raise UserError("While building `%s' from `%s': Cannot build multiple sources with different extensions: %s, %s" % (repr(map(str, target)), src, ext, my_ext))
             ext = my_ext
 
-        if ext is None:
-            raise UserError("Cannot deduce file extension from source files: %s" % repr(map(str, source)))
+        if not ext:
+            raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source))))
         try:
             # XXX Do we need to perform Environment substitution
             # on the keys of action_dict before looking it up?
             return self.action_dict[ext]
         except KeyError:
-            raise UserError("Don't know how to build a file with suffix %s." % ext)
+            raise UserError("While building `%s': Don't know how to build a file with suffix %s." % (repr(map(str, target)), repr(ext)))
     def __cmp__(self, other):
         return cmp(self.action_dict, other.action_dict)
 
index 062f8b9d918bbcb9ab72d44aebde066d30faa09f..d486e70c624c10444a442a846e3ea37065dc65d4 100644 (file)
@@ -459,9 +459,11 @@ class BuilderTestCase(unittest.TestCase):
         tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])
         try:
             tgt.build()
-        except SCons.Errors.UserError:
+        except SCons.Errors.UserError, e:
             flag = 1
         assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo"
+        assert match, e
 
         foo_bld = SCons.Builder.Builder(action = 'a-foo',
                                         src_suffix = '.ina',
@@ -497,28 +499,54 @@ class BuilderTestCase(unittest.TestCase):
         assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
 
         flag = 0
-        tgt = builder(env, target='t5', source='test5a.foo test5b.inb')
+        tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])
         try:
             tgt.build()
-        except SCons.Errors.UserError:
+        except SCons.Errors.UserError, e:
             flag = 1
         assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['t5']' from `test5b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
+        assert match, e
 
         flag = 0
-        tgt = builder(env, target='t6', source='test6a.bar test6b.ina')
+        tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])
         try:
             tgt.build()
-        except SCons.Errors.UserError:
+        except SCons.Errors.UserError, e:
             flag = 1
         assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['t6']' from `test6b.foo': Cannot build multiple sources with different extensions: .bar, .foo"
+        assert match, e
 
         flag = 0
-        tgt = builder(env, target='t4', source='test4a.ina test4b.inb')
+        tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])
         try:
             tgt.build()
-        except SCons.Errors.UserError:
+        except SCons.Errors.UserError, e:
             flag = 1
         assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['t4']' from `test4b.bar': Cannot build multiple sources with different extensions: .foo, .bar"
+        assert match, e
+
+        flag = 0
+        tgt = builder(env, target='t7', source=['test7'])
+        try:
+            tgt.build()
+        except SCons.Errors.UserError, e:
+            flag = 1
+        assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['t7']': Cannot deduce file extension from source files: ['test7']"
+        assert match, e
+
+        flag = 0
+        tgt = builder(env, target='t8', source=['test8.unknown'])
+        try:
+            tgt.build()
+        except SCons.Errors.UserError, e:
+            flag = 1
+        assert flag, "UserError should be thrown when we build targets with files of different suffixes."
+        match = str(e) == "While building `['t8']': Don't know how to build a file with suffix '.unknown'."
+        assert match, e
 
     def test_build_scanner(self):
         """Testing ability to set a target scanner through a builder."""
index 04452a9c01e56988e5e56a82351b62e528e1de47..cbf7a7c564b80d28d0b8581613ca57579a842103 100644 (file)
@@ -406,8 +406,17 @@ class Environment:
 
     def Install(self, dir, source):
         """Install specified files in the given directory."""
-        sources = SCons.Node.arg2nodes(source, self.fs.File)
-        dnodes = SCons.Node.arg2nodes(dir, self.fs.Dir)
+        try:
+            dnodes = SCons.Node.arg2nodes(dir, self.fs.Dir)
+        except TypeError:
+            raise SCons.Errors.UserError, "Target `%s' of Install() is a file, but should be a directory.  Perhaps you have the Install() arguments backwards?" % str(dir)
+        try:
+            sources = SCons.Node.arg2nodes(source, self.fs.File)
+        except TypeError:
+            if SCons.Util.is_List(source):
+                raise SCons.Errors.UserError, "Source `%s' of Install() contains one or more non-files.  Install() source must be one or more files." % repr(map(str, source))
+            else:
+                raise SCons.Errors.UserError, "Source `%s' of Install() is not a file.  Install() source must be one or more files." % str(source)
         tgt = []
         for dnode in dnodes:
             for src in sources:
index 3da8334c01482939b674b4acb70445c64fe10187..080c0d934d1f39af534a92642bc3597c2f395ad8 100644 (file)
@@ -344,6 +344,33 @@ class EnvironmentTestCase(unittest.TestCase):
         for tnode in tgt:
             assert tnode.builder == InstallBuilder
 
+        exc_caught = None
+        try:
+            tgt = env.Install('export', 'export')
+        except SCons.Errors.UserError, e:
+            exc_caught = 1
+        assert exc_caught, "UserError should be thrown when Install() target is not a file."
+        match = str(e) == "Source `export' of Install() is not a file.  Install() source must be one or more files."
+        assert match, e
+
+        exc_caught = None
+        try:
+            tgt = env.Install('export', ['export', 'build/foo1'])
+        except SCons.Errors.UserError, e:
+            exc_caught = 1
+        assert exc_caught, "UserError should be thrown when Install() target containins non-files."
+        match = str(e) == "Source `['export', 'build/foo1']' of Install() contains one or more non-files.  Install() source must be one or more files."
+        assert match, e
+
+        exc_caught = None
+        try:
+            tgt = env.Install('export/foo1', 'build/foo1')
+        except SCons.Errors.UserError, e:
+            exc_caught = 1
+        assert exc_caught, "UserError should be thrown reversing the order of Install() targets."
+        match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory.  Perhaps you have the Install() arguments backwards?"
+        assert match, e
+
         tgt = env.InstallAs(target=string.split('foo1 foo2'),
                             source=string.split('bar1 bar2'))
         assert len(tgt) == 2, len(tgt)