diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index cae40095e..7b4059e51 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -13,7 +13,8 @@ # limitations under the License. import pickle, os, uuid -from .mesonlib import MesonException, default_libdir, default_libexecdir, default_prefix +from .mesonlib import MesonException, commonpath +from .mesonlib import default_libdir, default_libexecdir, default_prefix version = '0.38.1' backendlist = ['ninja', 'vs2010', 'vs2015', 'xcode'] @@ -158,7 +159,7 @@ class CoreData: if option.endswith('dir') and os.path.isabs(value) and \ option not in builtin_dir_noprefix_options: # Value must be a subdir of the prefix - if os.path.commonpath([value, prefix]) != prefix: + if commonpath([value, prefix]) != prefix: m = 'The value of the {!r} option is {!r} which must be a ' \ 'subdir of the prefix {!r}.\nNote that if you pass a ' \ 'relative path, it is assumed to be a subdir of prefix.' @@ -194,9 +195,9 @@ class CoreData: elif optname in self.builtins: prefix = self.builtins['prefix'].value value = self.sanitize_dir_option_value(prefix, optname, value) - self.builtins[optname].set_value(value) else: raise RuntimeError('Tried to set unknown builtin option %s.' % optname) + self.builtins[optname].set_value(value) def load(filename): load_fail_msg = 'Coredata file {!r} is corrupted. Try with a fresh build tree.'.format(filename) diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 2ad43c823..f0b20e1bd 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -496,3 +496,28 @@ def Popen_safe(args, write=None, stderr=subprocess.PIPE, **kwargs): stderr=stderr, **kwargs) o, e = p.communicate(write) return p, o, e + +def commonpath(paths): + ''' + For use on Python 3.4 where os.path.commonpath is not available. + We currently use it everywhere so this receives enough testing. + ''' + # XXX: Replace me with os.path.commonpath when we start requiring Python 3.5 + import pathlib + if not paths: + raise ValueError('arg is an empty sequence') + common = pathlib.PurePath(paths[0]) + for path in paths[1:]: + new = [] + path = pathlib.PurePath(path) + for c, p in zip(common.parts, path.parts): + if c != p: + break + new.append(c) + # Don't convert '' into '.' + if not new: + common = '' + break + new = os.path.join(*new) + common = pathlib.PurePath(new) + return str(common) diff --git a/run_tests.py b/run_tests.py index 2dfbaffad..005717e07 100755 --- a/run_tests.py +++ b/run_tests.py @@ -20,9 +20,11 @@ from mesonbuild import mesonlib if __name__ == '__main__': returncode = 0 + print('Running unittests.\n') if mesonlib.is_linux(): - print('Running unittests.\n') returncode += subprocess.call([sys.executable, 'run_unittests.py', '-v']) + else: + returncode += subprocess.call([sys.executable, 'run_unittests.py', '-v', 'InternalTests']) # Ubuntu packages do not have a binary without -6 suffix. if shutil.which('arm-linux-gnueabihf-gcc-6') and not platform.machine().startswith('arm'): print('Running cross compilation tests.\n') diff --git a/run_unittests.py b/run_unittests.py index a1d99f392..e8659f40a 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -153,6 +153,23 @@ class InternalTests(unittest.TestCase): a = ['-Ldir', '-Lbah'] + a self.assertEqual(a, ['-Ibar', '-Ifoo', '-Ibaz', '-I..', '-I.', '-Ldir', '-Lbah', '-Werror', '-O3', '-O2', '-Wall']) + def test_commonpath(self): + from os.path import sep + commonpath = mesonbuild.mesonlib.commonpath + self.assertRaises(ValueError, commonpath, []) + self.assertEqual(commonpath(['/usr', '/usr']), sep + 'usr') + self.assertEqual(commonpath(['/usr', '/usr/']), sep + 'usr') + self.assertEqual(commonpath(['/usr', '/usr/bin']), sep + 'usr') + self.assertEqual(commonpath(['/usr/', '/usr/bin']), sep + 'usr') + self.assertEqual(commonpath(['/usr/./', '/usr/bin']), sep + 'usr') + self.assertEqual(commonpath(['/usr/bin', '/usr/bin']), sep + 'usr' + sep + 'bin') + self.assertEqual(commonpath(['/usr//bin', '/usr/bin']), sep + 'usr' + sep + 'bin') + self.assertEqual(commonpath(['/usr/./bin', '/usr/bin']), sep + 'usr' + sep + 'bin') + self.assertEqual(commonpath(['/usr/local', '/usr/lib']), sep + 'usr') + self.assertEqual(commonpath(['/usr', '/bin']), sep) + self.assertEqual(commonpath(['/usr', 'bin']), '') + self.assertEqual(commonpath(['blam', 'bin']), '') + class LinuxlikeTests(unittest.TestCase): def setUp(self):