fix for bug #2393. Instead of just 'import'ing
authorgaryo <garyo@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 29 Apr 2009 01:18:14 +0000 (01:18 +0000)
committergaryo <garyo@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Wed, 29 Apr 2009 01:18:14 +0000 (01:18 +0000)
site_scons/site_init.py, I now load that file directly into the
SCons.Script namespace using exec ... in.  This allows site_init.py to
define tools in the way users expect.

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4162 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/engine/SCons/Script/Main.py
test/site_scons/site_init.py [new file with mode: 0644]

index f7ea9c02b9df3927836728874430ef4c6e5a79db..926cf5ce0d320d7a2f0dab9518f9709dbd13b565 100644 (file)
@@ -701,17 +701,30 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
         try:
             fp, pathname, description = imp.find_module(site_init_modname,
                                                         [site_dir])
+            # Load the file into SCons.Script namespace.  This is
+            # opaque and clever; m is the module object for the
+            # SCons.Script module, and the exec ... in call executes a
+            # file (or string containing code) in the context of the
+            # module's dictionary, so anything that code defines ends
+            # up adding to that module.  This is really short, but all
+            # the error checking makes it longer.
             try:
-                imp.load_module(site_init_modname, fp, pathname, description)
-            finally:
-                if fp:
-                    fp.close()
+                m=sys.modules['SCons.Script']
+            except Exception, e:
+                raise SCons.Errors.InternalError, \
+                    "can't import site_init.py: missing SCons.Script module, %s"%str(e)
+            try:
+                # This is the magic.
+                exec fp in m.__dict__
+            except Exception, e:
+                sys.stderr.write("*** Error loading site_init file %s:\n"%site_init_file)
+                raise
         except ImportError, e:
-            sys.stderr.write("Can't import site init file '%s': %s\n"%(site_init_file, e))
-            raise
-        except Exception, e:
-            sys.stderr.write("Site init file '%s' raised exception: %s\n"%(site_init_file, e))
+            sys.stderr.write("Can't import site init file '%s':\n"%site_init_file)
             raise
+        finally:
+            if fp:
+                fp.close()
     if os.path.exists(site_tools_dir):
         SCons.Tool.DefaultToolpath.append(os.path.abspath(site_tools_dir))
 
diff --git a/test/site_scons/site_init.py b/test/site_scons/site_init.py
new file mode 100644 (file)
index 0000000..231f36c
--- /dev/null
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import TestSCons
+
+"""
+Verify site_scons/site_init.py file can define a tool, and it shows up
+automatically in the SCons.Script namespace.
+"""
+
+test = TestSCons.TestSCons()
+
+test.subdir('site_scons')
+
+test.write(['site_scons', 'site_init.py'], """
+def TOOL_FOO(env):
+      env['FOO'] = 'cat'
+      bld = Builder(action = '$FOO ${SOURCE} > ${TARGET}',
+                                     suffix = '.tgt')
+      env.Append(BUILDERS = {'Foo' : bld})
+
+""")
+
+test.write('SConstruct', """
+e=Environment(tools=['default', TOOL_FOO])
+e.Foo(target='foo.out', source='SConstruct')
+""")
+
+test.run(arguments = '-Q .',
+         stdout = """cat SConstruct > foo.out\n""")
+
+
+"""
+Test errors in site_scons/site_init.py.
+"""
+
+test = TestSCons.TestSCons()
+
+test.subdir('site_scons')
+
+test.write(['site_scons', 'site_init.py'], """
+raise Exception("Huh?")
+""")
+
+test.write('SConstruct', """
+e=Environment(tools=['default', TOOL_FOO])
+e.Foo(target='foo.out', source='SConstruct')
+""")
+
+test.run(arguments = '-Q .',
+         stdout = "",
+         stderr = """.*Error loading site_init file.*Huh\?.*""",
+         status=2,
+         match=TestSCons.match_re_dotall)
+
+
+
+test.pass_test()
+
+# end of file
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: