mirror of
https://github.com/mesonbuild/meson.git
synced 2026-11-06 05:16:42 +00:00
cmake: tolerate an unreadable $HOME when probing the user package registry
CMakeDependency._preliminary_find_check looks for ~/.cmake/packages/<Name> with Path.exists(), which only swallows ENOENT/ENOTDIR/EBADF/ELOOP. On a host where the build user's home directory exists but is not traversable (CI service accounts, a root-owned 0700 $HOME, HOME pointing at another user's directory) the probe raises PermissionError and meson setup dies with "Unhandled python OSError" on the first dependency() that reaches the CMake finder. CMake itself silently ignores an unreadable user package registry. Do the same: route the check through the existing _cached_isdir helper, which already turns OSError into "not found". The path is built with os.path.expanduser() rather than Path.home(). Path.home() raises RuntimeError when the home directory cannot be determined (HOME unset and no passwd entry for the uid, as in containers running under an arbitrary uid), so it would have needed its own handler for a case that should also just mean "not registered". os.path.expanduser() returns the string unchanged in that case, and a path starting with '~' is never an existing directory, so no extra handling is needed.
This commit is contained in:
1 parent
3e4cc8d237
commit
b3efc56536
2 files changed
+18
-5
No files matched your search
@@ -331,12 +331,12 @@ class CMakeDependency(ExternalDependency):
|
||||
return True
|
||||
|
||||
# Check the Linux CMake registry
|
||||
linux_reg = Path.home() / '.cmake' / 'packages'
|
||||
for p in [linux_reg / name, linux_reg / lname]:
|
||||
if p.exists():
|
||||
return True
|
||||
return self._in_cmake_user_registry(name, lname)
|
||||
|
||||
return False
|
||||
@staticmethod
|
||||
def _in_cmake_user_registry(name: str, lname: str) -> bool:
|
||||
# Like CMake, treat an unreadable or unresolvable home as "not registered".
|
||||
return any(CMakeDependency._cached_isdir(os.path.expanduser(f'~/.cmake/packages/{n}')) for n in (name, lname))
|
||||
|
||||
def _detect_dep(self, name: str, package_version: str, modules: T.List[T.Tuple[str, bool]], components: T.List[T.Tuple[str, bool]], args: T.List[str]) -> None:
|
||||
# Detect a dependency with CMake using the '--find-package' mode
|
||||
|
||||
@@ -65,6 +65,19 @@ from .helpers import IS_CI, chdir, skipIfNoPkgconfig
|
||||
|
||||
class InternalTests(unittest.TestCase):
|
||||
|
||||
@unittest.skipIf(is_windows() or is_cygwin() or os.geteuid() == 0, 'needs a directory the test user cannot traverse')
|
||||
def test_cmake_user_registry_unreadable_home(self):
|
||||
from mesonbuild.dependencies.cmake import CMakeDependency
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
home = Path(tmpdir) / 'home'
|
||||
(home / '.cmake' / 'packages' / 'Foo').mkdir(parents=True)
|
||||
with mock.patch.dict(os.environ, {'HOME': str(home)}):
|
||||
self.assertTrue(CMakeDependency._in_cmake_user_registry('Foo', 'foo'))
|
||||
self.assertFalse(CMakeDependency._in_cmake_user_registry('Bar', 'bar'))
|
||||
home.chmod(0)
|
||||
CMakeDependency._cached_isdir.cache_clear()
|
||||
self.assertFalse(CMakeDependency._in_cmake_user_registry('Foo', 'foo'))
|
||||
|
||||
def test_cmake_skip_compiler_test_invalid(self):
|
||||
properties = mesonbuild.envconfig.Properties({'cmake_skip_compiler_test': True})
|
||||
with self.assertRaisesRegex(
|
||||
|
||||
Reference in new issue
Block a user