aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hirsch, Ph.D <10931741+scivision@users.noreply.github.com>2020-01-30 16:07:44 -0500
committerGitHub <noreply@github.com>2020-01-30 23:07:44 +0200
commit00f5dadd5b7d71c30bd7393d165a87f554eb92e5 (patch)
tree6a8f65c47b75ce0152b450dce40214190781135f
parent1682058decb5f16ce1b78121ee587c024e9cfa17 (diff)
downloadmeson-00f5dadd5b7d71c30bd7393d165a87f554eb92e5.zip
meson-00f5dadd5b7d71c30bd7393d165a87f554eb92e5.tar.gz
meson-00f5dadd5b7d71c30bd7393d165a87f554eb92e5.tar.bz2
Bugfix: sanitize_dir: use pathlib to handle case-insensitive filesystems (#6398)
-rw-r--r--mesonbuild/coredata.py31
-rwxr-xr-xrun_project_tests.py6
-rwxr-xr-xrun_unittests.py21
-rw-r--r--test cases/common/105 testframework options/meson.build3
-rw-r--r--test cases/failing/38 libdir must be inside prefix/meson.build4
5 files changed, 46 insertions, 19 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 9d5e7ce..7a9fefe 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -463,7 +463,7 @@ class CoreData:
prefix = prefix[:-1]
return prefix
- def sanitize_dir_option_value(self, prefix, option, value):
+ def sanitize_dir_option_value(self, prefix: str, option: str, value: Any) -> Any:
'''
If the option is an installation directory option and the value is an
absolute path, check that it resides within prefix and return the value
@@ -471,22 +471,31 @@ class CoreData:
This way everyone can do f.ex, get_option('libdir') and be sure to get
the library directory relative to prefix.
+
+ .as_posix() keeps the posix-like file seperators Meson uses.
'''
- if option.endswith('dir') and os.path.isabs(value) and \
+ try:
+ value = PurePath(value)
+ except TypeError:
+ return value
+ if option.endswith('dir') and value.is_absolute() and \
option not in builtin_dir_noprefix_options:
# Value must be a subdir of the prefix
# commonpath will always return a path in the native format, so we
# must use pathlib.PurePath to do the same conversion before
# comparing.
- if os.path.commonpath([value, prefix]) != str(PurePath(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.'
- raise MesonException(m.format(option, value, prefix))
- # Convert path to be relative to prefix
- skip = len(prefix) + 1
- value = value[skip:]
- return value
+ msg = ('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.')
+ # os.path.commonpath doesn't understand case-insensitive filesystems,
+ # but PurePath().relative_to() does.
+ try:
+ value = value.relative_to(prefix)
+ except ValueError:
+ raise MesonException(msg.format(option, value, prefix))
+ if '..' in str(value):
+ raise MesonException(msg.format(option, value, prefix))
+ return value.as_posix()
def init_builtins(self):
# Create builtin options with default values
diff --git a/run_project_tests.py b/run_project_tests.py
index acad225..e4dd8f7 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -381,7 +381,7 @@ def _run_test(testdir, test_build_dir, install_dir, extra_args, compiler, backen
setup_env = None
# Configure in-process
if pass_prefix_to_test(testdir):
- gen_args = ['--prefix', '/usr']
+ gen_args = ['--prefix', 'x:/usr'] if mesonlib.is_windows() else ['--prefix', '/usr']
else:
gen_args = []
if pass_libdir_to_test(testdir):
@@ -547,6 +547,10 @@ def skippable(suite, test):
if not suite.endswith('frameworks'):
return True
+ # this test assumptions aren't valid for Windows paths
+ if test.endswith('38 libdir must be inside prefix'):
+ return True
+
# gtk-doc test may be skipped, pending upstream fixes for spaces in
# filenames landing in the distro used for CI
if test.endswith('10 gtk-doc'):
diff --git a/run_unittests.py b/run_unittests.py
index 4c1d4b5..5388679 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -1783,7 +1783,8 @@ class AllPlatformTests(BasePlatformTests):
https://github.com/mesonbuild/meson/issues/1345
'''
testdir = os.path.join(self.common_test_dir, '90 default options')
- prefix = '/someabs'
+ # on Windows, /someabs is *not* an absolute path
+ prefix = 'x:/someabs' if is_windows() else '/someabs'
libdir = 'libdir'
extra_args = ['--prefix=' + prefix,
# This can just be a relative path, but we want to test
@@ -1804,16 +1805,25 @@ class AllPlatformTests(BasePlatformTests):
'''
testdir = os.path.join(self.common_test_dir, '1 trivial')
# libdir being inside prefix is ok
- args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
+ if is_windows():
+ args = ['--prefix', 'x:/opt', '--libdir', 'x:/opt/lib32']
+ else:
+ args = ['--prefix', '/opt', '--libdir', '/opt/lib32']
self.init(testdir, extra_args=args)
self.wipe()
# libdir not being inside prefix is not ok
- args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
+ if is_windows():
+ args = ['--prefix', 'x:/usr', '--libdir', 'x:/opt/lib32']
+ else:
+ args = ['--prefix', '/usr', '--libdir', '/opt/lib32']
self.assertRaises(subprocess.CalledProcessError, self.init, testdir, extra_args=args)
self.wipe()
# libdir must be inside prefix even when set via mesonconf
self.init(testdir)
- self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=/opt', False)
+ if is_windows():
+ self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=x:/opt', False)
+ else:
+ self.assertRaises(subprocess.CalledProcessError, self.setconf, '-Dlibdir=/opt', False)
def test_prefix_dependent_defaults(self):
'''
@@ -7310,14 +7320,11 @@ def main():
import pytest # noqa: F401
# Need pytest-xdist for `-n` arg
import xdist # noqa: F401
- if sys.version_info.major <= 3 and sys.version_info.minor <= 5:
- raise ImportError('pytest with python <= 3.5 is causing issues on the CI')
pytest_args = ['-n', 'auto', './run_unittests.py']
pytest_args += convert_args(sys.argv[1:])
return subprocess.run(python_command + ['-m', 'pytest'] + pytest_args).returncode
except ImportError:
print('pytest-xdist not found, using unittest instead')
- pass
# All attempts at locating pytest failed, fall back to plain unittest.
cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
diff --git a/test cases/common/105 testframework options/meson.build b/test cases/common/105 testframework options/meson.build
index 2773730..827bae7 100644
--- a/test cases/common/105 testframework options/meson.build
+++ b/test cases/common/105 testframework options/meson.build
@@ -1,3 +1,6 @@
+# normally run only from run_tests.py or run_project_tests.py
+# else do like
+# meson build '-Dtestoption=A string with spaces' -Dother_one=true -Dcombo_opt=one -Dprefix=/usr -Dlibdir=lib -Dbackend=ninja -Dwerror=True
project('options', 'c')
assert(get_option('testoption') == 'A string with spaces', 'Incorrect value for testoption option.')
diff --git a/test cases/failing/38 libdir must be inside prefix/meson.build b/test cases/failing/38 libdir must be inside prefix/meson.build
index 66272ea..4cce7f8 100644
--- a/test cases/failing/38 libdir must be inside prefix/meson.build
+++ b/test cases/failing/38 libdir must be inside prefix/meson.build
@@ -1,2 +1,6 @@
project('libdir prefix', 'c',
default_options : ['libdir=/opt/lib'])
+
+if host_machine.system() == 'windows'
+ error('MESON_SKIP_TEST: this test does not work on Windows since /foo is not absolute')
+endif \ No newline at end of file