From 1849ff611b22a55b8933dc9f05db66114e34cd14 Mon Sep 17 00:00:00 2001 From: grbd Date: Thu, 3 Aug 2017 15:53:20 +0100 Subject: Added support for a PyPackageDir function --- src/engine/SCons/Environment.py | 9 ++++ src/engine/SCons/Node/FS.py | 29 +++++++++++ src/engine/SCons/Script/__init__.py | 1 + test/Dir/PyPackageDir/PyPackageDir.py | 56 ++++++++++++++++++++++ test/Dir/PyPackageDir/image/SConstruct | 29 +++++++++++ test/Dir/PyPackageDir/image/sconstest.skip | 0 test/Dir/PyPackageDir/image/syspath/sconstest.skip | 0 .../PyPackageDir/image/syspath/submod1/__init__.py | 0 .../image/syspath/submod1/sconstest.skip | 0 .../image/syspath/submod1/submod2/__init__.py | 0 .../image/syspath/submod1/submod2/sconstest.skip | 0 .../image/syspath/submod1/submod2/testmod4.py | 0 .../PyPackageDir/image/syspath/submod1/testmod3.py | 0 .../image/syspath/testmod1/__init__.py | 0 .../image/syspath/testmod1/sconstest.skip | 0 test/Dir/PyPackageDir/image/syspath/testmod2.py | 0 test/toolpath/nested/image/SConstruct | 7 +++ test/toolpath/nested/nested.py | 3 ++ 18 files changed, 134 insertions(+) create mode 100644 test/Dir/PyPackageDir/PyPackageDir.py create mode 100644 test/Dir/PyPackageDir/image/SConstruct create mode 100644 test/Dir/PyPackageDir/image/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py create mode 100644 test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip create mode 100644 test/Dir/PyPackageDir/image/syspath/testmod2.py diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 60a45e4..480a1d6 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -1983,6 +1983,15 @@ class Base(SubstitutionEnvironment): return result return self.fs.Dir(s, *args, **kw) + def PyPackageDir(self, modulename): + s = self.subst(modulename) + if SCons.Util.is_Sequence(s): + result=[] + for e in s: + result.append(self.fs.PyPackageDir(e)) + return result + return self.fs.PyPackageDir(s) + def NoClean(self, *targets): """Tags a target so that it will not be cleaned by -c""" tlist = [] diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index d98f7d0..8c1161d 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1390,6 +1390,35 @@ class FS(LocalFS): if not isinstance(d, SCons.Node.Node): d = self.Dir(d) self.Top.addRepository(d) + + def PyPackageDir(self, modulename): + """Locate the directory of a given python module name + + For example scons might resolve to + Windows: C:\Python27\Lib\site-packages\scons-2.5.1 + Linux: /usr/lib/scons + + This can be useful when we want to determine a toolpath based on a python module name""" + + dirpath = '' + if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] in (0,1,2,3,4)): + # Python2 Code + import imp + splitname = modulename.split('.') + srchpths = sys.path + for item in splitname: + file, path, desc = imp.find_module(item, srchpths) + if file is not None: + path = os.path.dirname(path) + srchpths = [path] + dirpath = path + else: + # Python3 Code + import importlib.util + modspec = importlib.util.find_spec(modulename) + dirpath = os.path.dirname(modspec.origin) + return self._lookup(dirpath, None, Dir, True) + def variant_dir_target_climb(self, orig, dir, tail): """Create targets in corresponding variant directories diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 3fa3a48..5bdd63e 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -337,6 +337,7 @@ GlobalDefaultEnvironmentFunctions = [ 'Local', 'ParseDepends', 'Precious', + 'PyPackageDir', 'Repository', 'Requires', 'SConsignFile', diff --git a/test/Dir/PyPackageDir/PyPackageDir.py b/test/Dir/PyPackageDir/PyPackageDir.py new file mode 100644 index 0000000..b215c7b --- /dev/null +++ b/test/Dir/PyPackageDir/PyPackageDir.py @@ -0,0 +1,56 @@ +#!/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 os.path +import TestSCons + +test = TestSCons.TestSCons() + +test.dir_fixture('image') + +test.run(arguments = '.', stdout = """\ +scons: Reading SConscript files ... +Test identification of directory for a given python package +testmod1 +. +submod1 +submod1/submod2 +Test parameter substitution +submod1/submod2 +submod1/submod2 +scons: done reading SConscript files. +scons: Building targets ... +scons: `.' is up to date. +scons: done building targets. +""") + +test.pass_test() + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/test/Dir/PyPackageDir/image/SConstruct b/test/Dir/PyPackageDir/image/SConstruct new file mode 100644 index 0000000..90d2a80 --- /dev/null +++ b/test/Dir/PyPackageDir/image/SConstruct @@ -0,0 +1,29 @@ +import sys, os + +oldsyspath = sys.path +dir_path = Dir('.').srcnode().abspath +dir_path = os.path.join(dir_path, 'syspath') +sys.path.append(dir_path) + +def TestPyPackageDir(env, modname): + packagepath = env.PyPackageDir(modname).abspath + # Convert from an absolute path back to a relative one for testing + commonprefix = os.path.commonprefix([dir_path, packagepath]) + relpath = os.path.relpath(packagepath, commonprefix) + relpath = relpath.replace(os.sep, '/') + print(relpath) + +print("Test identification of directory for a given python package") +env = Environment() +TestPyPackageDir(env, 'testmod1') +TestPyPackageDir(env, 'testmod2') +TestPyPackageDir(env, 'submod1.testmod3') +TestPyPackageDir(env, 'submod1.submod2.testmod4') + +print("Test parameter substitution") +env = Environment(FOO = 'submod1.submod2.testmod4') +TestPyPackageDir(env, '${FOO}') +env = Environment(FOO = 'submod1.submod2', BAR = 'testmod4') +TestPyPackageDir(env, '${FOO}.${BAR}') + +sys.path = oldsyspath diff --git a/test/Dir/PyPackageDir/image/sconstest.skip b/test/Dir/PyPackageDir/image/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/__init__.py b/test/Dir/PyPackageDir/image/syspath/submod1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/submod1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py b/test/Dir/PyPackageDir/image/syspath/submod1/submod2/testmod4.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py b/test/Dir/PyPackageDir/image/syspath/submod1/testmod3.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py b/test/Dir/PyPackageDir/image/syspath/testmod1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip b/test/Dir/PyPackageDir/image/syspath/testmod1/sconstest.skip new file mode 100644 index 0000000..e69de29 diff --git a/test/Dir/PyPackageDir/image/syspath/testmod2.py b/test/Dir/PyPackageDir/image/syspath/testmod2.py new file mode 100644 index 0000000..e69de29 diff --git a/test/toolpath/nested/image/SConstruct b/test/toolpath/nested/image/SConstruct index 211a0d7..78ae21d 100644 --- a/test/toolpath/nested/image/SConstruct +++ b/test/toolpath/nested/image/SConstruct @@ -55,4 +55,11 @@ print("env3['Toolpath_TestTool1_2'] =", env3.get('Toolpath_TestTool1_2')) print("env3['Toolpath_TestTool2_1'] =", env3.get('Toolpath_TestTool2_1')) print("env3['Toolpath_TestTool2_2'] =", env3.get('Toolpath_TestTool2_2')) + +print('Test using PyPackageDir') +toollist = ['Toolpath_TestTool2_1', 'Toolpath_TestTool2_2'] +env4 = Environment(tools = toollist, toolpath = [PyPackageDir('tools_example.subdir1.subdir2')]) +print("env4['Toolpath_TestTool2_1'] =", env4.get('Toolpath_TestTool2_1')) +print("env4['Toolpath_TestTool2_2'] =", env4.get('Toolpath_TestTool2_2')) + sys.path = oldsyspath diff --git a/test/toolpath/nested/nested.py b/test/toolpath/nested/nested.py index a736d58..df2ba07 100644 --- a/test/toolpath/nested/nested.py +++ b/test/toolpath/nested/nested.py @@ -57,6 +57,9 @@ env3['Toolpath_TestTool1_1'] = 1 env3['Toolpath_TestTool1_2'] = 1 env3['Toolpath_TestTool2_1'] = 1 env3['Toolpath_TestTool2_2'] = 1 +Test using PyPackageDir +env4['Toolpath_TestTool2_1'] = 1 +env4['Toolpath_TestTool2_2'] = 1 scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. -- cgit v0.12