From ca9b52bbc562b1be7753f64105fd21af0dfce469 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Fri, 7 Jul 2023 12:05:32 +0200 Subject: Prevent "spack external find" to error out on wrong permissions (#38755) fixes #38733 --- lib/spack/spack/detection/common.py | 13 +++++++++---- lib/spack/spack/test/cmd/external.py | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/spack/spack/detection/common.py b/lib/spack/spack/detection/common.py index 525b19fd26..41455e43ae 100644 --- a/lib/spack/spack/detection/common.py +++ b/lib/spack/spack/detection/common.py @@ -112,10 +112,15 @@ def path_to_dict(search_paths): # Reverse order of search directories so that a lib in the first # entry overrides later entries for search_path in reversed(search_paths): - for lib in os.listdir(search_path): - lib_path = os.path.join(search_path, lib) - if llnl.util.filesystem.is_readable_file(lib_path): - path_to_lib[lib_path] = lib + try: + for lib in os.listdir(search_path): + lib_path = os.path.join(search_path, lib) + if llnl.util.filesystem.is_readable_file(lib_path): + path_to_lib[lib_path] = lib + except OSError as e: + msg = f"cannot scan '{search_path}' for external software: {str(e)}" + llnl.util.tty.debug(msg) + return path_to_lib diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py index 848e14315d..135ed026cb 100644 --- a/lib/spack/spack/test/cmd/external.py +++ b/lib/spack/spack/test/cmd/external.py @@ -396,3 +396,30 @@ def test_use_tags_for_detection(command_args, mock_executable, mutable_config, m assert "The following specs have been" in output assert "cmake" in output assert "openssl" not in output + + +@pytest.mark.regression("38733") +@pytest.mark.skipif(sys.platform == "win32", reason="the test uses bash scripts") +def test_failures_in_scanning_do_not_result_in_an_error( + mock_executable, monkeypatch, mutable_config +): + """Tests that scanning paths with wrong permissions, won't cause `external find` to error.""" + cmake_exe1 = mock_executable( + "cmake", output="echo cmake version 3.19.1", subdir=("first", "bin") + ) + cmake_exe2 = mock_executable( + "cmake", output="echo cmake version 3.23.3", subdir=("second", "bin") + ) + + # Remove access from the first directory executable + cmake_exe1.parent.chmod(0o600) + + value = os.pathsep.join([str(cmake_exe1.parent), str(cmake_exe2.parent)]) + monkeypatch.setenv("PATH", value) + + output = external("find", "cmake") + assert external.returncode == 0 + assert "The following specs have been" in output + assert "cmake" in output + assert "3.23.3" in output + assert "3.19.1" not in output -- cgit v1.2.3-70-g09d2