diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/llnl/util/filesystem.py | 9 | ||||
-rw-r--r-- | lib/spack/spack/bootstrap/core.py | 3 | ||||
-rw-r--r-- | lib/spack/spack/compiler.py | 14 | ||||
-rw-r--r-- | lib/spack/spack/compilers/__init__.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/compilers/msvc.py | 8 | ||||
-rw-r--r-- | lib/spack/spack/spec.py | 10 | ||||
-rw-r--r-- | lib/spack/spack/test/builder.py | 5 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/external.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/list.py | 19 | ||||
-rw-r--r-- | lib/spack/spack/test/cmd/uninstall.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 16 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize_preferences.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/conftest.py | 11 | ||||
-rw-r--r-- | lib/spack/spack/test/database.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/installer.py | 2 | ||||
-rw-r--r-- | lib/spack/spack/test/spec_syntax.py | 5 | ||||
-rw-r--r-- | lib/spack/spack/util/path.py | 2 |
17 files changed, 88 insertions, 32 deletions
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py index 388c6fd173..8e664cc0a9 100644 --- a/lib/spack/llnl/util/filesystem.py +++ b/lib/spack/llnl/util/filesystem.py @@ -99,7 +99,9 @@ def getuid(): def rename(src, dst): # On Windows, os.rename will fail if the destination file already exists if is_windows: - if os.path.exists(dst): + # Windows path existence checks will sometimes fail on junctions/links/symlinks + # so check for that case + if os.path.exists(dst) or os.path.islink(dst): os.remove(dst) os.rename(src, dst) @@ -288,7 +290,10 @@ def filter_file(regex, repl, *filenames, **kwargs): shutil.copy(filename, tmp_filename) try: - extra_kwargs = {"errors": "surrogateescape"} + # To avoid translating line endings (\n to \r\n and vis versa) + # we force os.open to ignore translations and use the line endings + # the file comes with + extra_kwargs = {"errors": "surrogateescape", "newline": ""} # Open as a text file and filter until the end of the file is # reached or we found a marker in the line if it was specified diff --git a/lib/spack/spack/bootstrap/core.py b/lib/spack/spack/bootstrap/core.py index 9cf25b29e9..e8cb429fa8 100644 --- a/lib/spack/spack/bootstrap/core.py +++ b/lib/spack/spack/bootstrap/core.py @@ -545,8 +545,9 @@ def ensure_core_dependencies(): """Ensure the presence of all the core dependencies.""" if sys.platform.lower() == "linux": ensure_patchelf_in_path_or_raise() + if not IS_WINDOWS: + ensure_gpg_in_path_or_raise() ensure_clingo_importable_or_raise() - ensure_gpg_in_path_or_raise() def all_core_root_specs(): diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 8b3afefa42..52c2db8c79 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -9,6 +9,7 @@ import os import platform import re import shutil +import sys import tempfile from typing import List, Optional, Sequence @@ -27,6 +28,8 @@ from spack.util.path import system_path_filter __all__ = ["Compiler"] +is_windows = sys.platform == "win32" + @llnl.util.lang.memoized def _get_compiler_version_output(compiler_path, version_arg, ignore_errors=()): @@ -592,7 +595,16 @@ class Compiler(object): # defined for the compiler compiler_names = getattr(cls, "{0}_names".format(language)) prefixes = [""] + cls.prefixes - suffixes = [""] + cls.suffixes + suffixes = [""] + # Windows compilers generally have an extension of some sort + # as do most files on Windows, handle that case here + if is_windows: + ext = r"\.(?:exe|bat)" + cls_suf = [suf + ext for suf in cls.suffixes] + ext_suf = [ext] + suffixes = suffixes + cls.suffixes + cls_suf + ext_suf + else: + suffixes = suffixes + cls.suffixes regexp_fmt = r"^({0}){1}({2})$" return [ re.compile(regexp_fmt.format(prefix, re.escape(name), suffix)) diff --git a/lib/spack/spack/compilers/__init__.py b/lib/spack/spack/compilers/__init__.py index d4aa54282b..3df8c4b218 100644 --- a/lib/spack/spack/compilers/__init__.py +++ b/lib/spack/spack/compilers/__init__.py @@ -722,6 +722,8 @@ def make_compiler_list(detected_versions): compiler_cls = spack.compilers.class_for_compiler_name(compiler_name) spec = spack.spec.CompilerSpec(compiler_cls.name, version) paths = [paths.get(x, None) for x in ("cc", "cxx", "f77", "fc")] + # TODO: johnwparent - revist the following line as per discussion at: + # https://github.com/spack/spack/pull/33385/files#r1040036318 target = archspec.cpu.host() compiler = compiler_cls(spec, operating_system, str(target.family), paths) return [compiler] diff --git a/lib/spack/spack/compilers/msvc.py b/lib/spack/spack/compilers/msvc.py index f26dcc78ec..d7576b78e6 100644 --- a/lib/spack/spack/compilers/msvc.py +++ b/lib/spack/spack/compilers/msvc.py @@ -42,16 +42,16 @@ def get_valid_fortran_pth(comp_ver): class Msvc(Compiler): # Subclasses use possible names of C compiler - cc_names: List[str] = ["cl.exe"] + cc_names: List[str] = ["cl"] # Subclasses use possible names of C++ compiler - cxx_names: List[str] = ["cl.exe"] + cxx_names: List[str] = ["cl"] # Subclasses use possible names of Fortran 77 compiler - f77_names: List[str] = ["ifx.exe"] + f77_names: List[str] = ["ifx"] # Subclasses use possible names of Fortran 90 compiler - fc_names: List[str] = ["ifx.exe"] + fc_names: List[str] = ["ifx"] # Named wrapper links within build_env_path # Due to the challenges of supporting compiler wrappers diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py index 6524bf3bef..012a75c89c 100644 --- a/lib/spack/spack/spec.py +++ b/lib/spack/spack/spec.py @@ -1289,7 +1289,7 @@ class Spec(object): # have package.py files for. self._normal = normal self._concrete = concrete - self.external_path = external_path + self._external_path = external_path self.external_modules = Spec._format_module_list(external_modules) # This attribute is used to store custom information for @@ -1327,6 +1327,14 @@ class Spec(object): return modules @property + def external_path(self): + return pth.path_to_os_path(self._external_path)[0] + + @external_path.setter + def external_path(self, ext_path): + self._external_path = ext_path + + @property def external(self): return bool(self.external_path) or bool(self.external_modules) diff --git a/lib/spack/spack/test/builder.py b/lib/spack/spack/test/builder.py index efba6aacf1..944514b610 100644 --- a/lib/spack/spack/test/builder.py +++ b/lib/spack/spack/test/builder.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os.path +import sys import pytest @@ -123,6 +124,10 @@ def test_old_style_compatibility_with_super(spec_str, method_name, expected): assert value == expected +@pytest.mark.skipif( + sys.platform == "win32", + reason="log_ouput cannot currently be used outside of subprocess on Windows", +) @pytest.mark.regression("33928") @pytest.mark.usefixtures("builder_test_repository", "config", "working_env") @pytest.mark.disable_clean_stage_check diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py index 1944a2e940..9b9376ecb1 100644 --- a/lib/spack/spack/test/cmd/external.py +++ b/lib/spack/spack/test/cmd/external.py @@ -347,7 +347,7 @@ def test_overriding_prefix(mock_executable, mutable_config, monkeypatch, _platfo assert "externals" in packages_yaml["gcc"] externals = packages_yaml["gcc"]["externals"] assert len(externals) == 1 - assert externals[0]["prefix"] == "/opt/gcc/bin" + assert externals[0]["prefix"] == os.path.sep + os.path.join("opt", "gcc", "bin") def test_new_entries_are_reported_correctly( diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py index ed5b2574f0..3ebcb4fa39 100644 --- a/lib/spack/spack/test/cmd/list.py +++ b/lib/spack/spack/test/cmd/list.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) +import sys from textwrap import dedent from spack.main import SpackCommand @@ -18,12 +19,24 @@ def test_list(): def test_list_cli_output_format(mock_tty_stdout): out = list("mpileaks") - assert out == dedent( - """\ + # Currently logging on Windows detaches stdout + # from the terminal so we miss some output during tests + # TODO: (johnwparent): Once logging is amended on Windows, + # restore this test + if not sys.platform == "win32": + out_str = dedent( + """\ mpileaks ==> 1 packages """ - ) + ) + else: + out_str = dedent( + """\ + mpileaks + """ + ) + assert out == out_str def test_list_filter(mock_packages): diff --git a/lib/spack/spack/test/cmd/uninstall.py b/lib/spack/spack/test/cmd/uninstall.py index be9fa3aa16..7798e03533 100644 --- a/lib/spack/spack/test/cmd/uninstall.py +++ b/lib/spack/spack/test/cmd/uninstall.py @@ -208,9 +208,7 @@ def test_in_memory_consistency_when_uninstalling(mutable_database, monkeypatch): # Note: I want to use https://docs.pytest.org/en/7.1.x/how-to/skipping.html#skip-all-test-functions-of-a-class-or-module # the style formatter insists on separating these two lines. -pytest.mark.skipif(sys.platform == "win32", reason="Envs unsupported on Windows") - - +@pytest.mark.skipif(sys.platform == "win32", reason="Envs unsupported on Windows") class TestUninstallFromEnv(object): """Tests an installation with two environments e1 and e2, which each have shared package installations: diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index 0ddc93b5f6..83597c7f3d 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import os -import posixpath import sys import jinja2 @@ -339,7 +338,7 @@ class TestConcretize(object): assert spec.satisfies("^openblas cflags='-g'") @pytest.mark.skipif( - os.environ.get("SPACK_TEST_SOLVER") == "original" or sys.platform == "win32", + os.environ.get("SPACK_TEST_SOLVER") == "original", reason="Optional compiler propagation isn't deprecated for original concretizer", ) def test_concretize_compiler_flag_does_not_propagate(self): @@ -349,7 +348,7 @@ class TestConcretize(object): assert not spec.satisfies("^openblas cflags='-g'") @pytest.mark.skipif( - os.environ.get("SPACK_TEST_SOLVER") == "original" or sys.platform == "win32", + os.environ.get("SPACK_TEST_SOLVER") == "original", reason="Optional compiler propagation isn't deprecated for original concretizer", ) def test_concretize_propagate_compiler_flag_not_passed_to_dependent(self): @@ -449,7 +448,7 @@ class TestConcretize(object): s.concretize() @pytest.mark.skipif( - os.environ.get("SPACK_TEST_SOLVER") == "original" or sys.platform == "win32", + os.environ.get("SPACK_TEST_SOLVER") == "original", reason="Optional compiler propagation isn't deprecated for original concretizer", ) def test_concretize_propagate_disabled_variant(self): @@ -466,7 +465,6 @@ class TestConcretize(object): assert spec.satisfies("^openblas+shared") - @pytest.mark.skipif(sys.platform == "win32", reason="No Compiler for Arch on Win") def test_no_matching_compiler_specs(self, mock_low_high_config): # only relevant when not building compilers as needed with spack.concretize.enable_compiler_existence_check(): @@ -527,7 +525,7 @@ class TestConcretize(object): def test_external_package(self): spec = Spec("externaltool%gcc") spec.concretize() - assert spec["externaltool"].external_path == posixpath.sep + posixpath.join( + assert spec["externaltool"].external_path == os.path.sep + os.path.join( "path", "to", "external_tool" ) assert "externalprereq" not in spec @@ -558,10 +556,10 @@ class TestConcretize(object): def test_external_and_virtual(self): spec = Spec("externaltest") spec.concretize() - assert spec["externaltool"].external_path == posixpath.sep + posixpath.join( + assert spec["externaltool"].external_path == os.path.sep + os.path.join( "path", "to", "external_tool" ) - assert spec["stuff"].external_path == posixpath.sep + posixpath.join( + assert spec["stuff"].external_path == os.path.sep + os.path.join( "path", "to", "external_virtual_gcc" ) assert spec["externaltool"].compiler.satisfies("gcc") @@ -1815,7 +1813,6 @@ class TestConcretize(object): c = s.concretized() assert hash in str(c) - @pytest.mark.skipif(sys.platform == "win32", reason="Not supported on Windows (yet)") @pytest.mark.parametrize("git_ref", ("a" * 40, "0.2.15", "main")) def test_git_ref_version_is_equivalent_to_specified_version(self, git_ref): if spack.config.get("config:concretizer") == "original": @@ -1827,7 +1824,6 @@ class TestConcretize(object): assert s.satisfies("@develop") assert s.satisfies("@0.1:") - @pytest.mark.skipif(sys.platform == "win32", reason="Not supported on Windows (yet)") @pytest.mark.parametrize("git_ref", ("a" * 40, "0.2.15", "fbranch")) def test_git_ref_version_errors_if_unknown_version(self, git_ref): if spack.config.get("config:concretizer") == "original": diff --git a/lib/spack/spack/test/concretize_preferences.py b/lib/spack/spack/test/concretize_preferences.py index b0ae008a72..1ebbfacfdd 100644 --- a/lib/spack/spack/test/concretize_preferences.py +++ b/lib/spack/spack/test/concretize_preferences.py @@ -270,7 +270,7 @@ mpich: # ensure that once config is in place, external is used spec = Spec("mpi") spec.concretize() - assert spec["mpich"].external_path == os.sep + os.path.join("dummy", "path") + assert spec["mpich"].external_path == os.path.sep + os.path.join("dummy", "path") def test_external_module(self, monkeypatch): """Test that packages can find externals specified by module @@ -305,7 +305,7 @@ mpi: # ensure that once config is in place, external is used spec = Spec("mpi") spec.concretize() - assert spec["mpich"].external_path == "/dummy/path" + assert spec["mpich"].external_path == os.path.sep + os.path.join("dummy", "path") def test_buildable_false(self): conf = syaml.load_config( diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py index 0449cd8cf8..2d9e72a89e 100644 --- a/lib/spack/spack/test/conftest.py +++ b/lib/spack/spack/test/conftest.py @@ -259,6 +259,17 @@ def _verify_executables_noop(*args): return None +def _host(): + """Mock archspec host so there is no inconsistency on the Windows platform + This function cannot be local as it needs to be pickleable""" + return archspec.cpu.Microarchitecture("x86_64", [], "generic", [], {}, 0) + + +@pytest.fixture(scope="function") +def archspec_host_is_spack_test_host(monkeypatch): + monkeypatch.setattr(archspec.cpu, "host", _host) + + # # Disable checks on compiler executable existence # diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py index 99e1b5c470..387daba1b5 100644 --- a/lib/spack/spack/test/database.py +++ b/lib/spack/spack/test/database.py @@ -719,13 +719,13 @@ def test_external_entries_in_db(mutable_database): assert not rec.spec.external_modules rec = mutable_database.get_record("externaltool") - assert rec.spec.external_path == os.sep + os.path.join("path", "to", "external_tool") + assert rec.spec.external_path == os.path.sep + os.path.join("path", "to", "external_tool") assert not rec.spec.external_modules assert rec.explicit is False rec.spec.package.do_install(fake=True, explicit=True) rec = mutable_database.get_record("externaltool") - assert rec.spec.external_path == os.sep + os.path.join("path", "to", "external_tool") + assert rec.spec.external_path == os.path.sep + os.path.join("path", "to", "external_tool") assert not rec.spec.external_modules assert rec.explicit is True diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py index 4c85f4ba26..8a446c650e 100644 --- a/lib/spack/spack/test/installer.py +++ b/lib/spack/spack/test/installer.py @@ -488,7 +488,7 @@ def test_update_tasks_for_compiler_packages_as_compiler(mock_packages, config, m def test_bootstrapping_compilers_with_different_names_from_spec( - install_mockery, mutable_config, mock_fetch + install_mockery, mutable_config, mock_fetch, archspec_host_is_spack_test_host ): with spack.config.override("config:install_missing_compilers", True): with spack.concretize.disable_compiler_existence_check(): diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py index 97c1a9a3ce..1a7d52e781 100644 --- a/lib/spack/spack/test/spec_syntax.py +++ b/lib/spack/spack/test/spec_syntax.py @@ -3,6 +3,7 @@ # # SPDX-License-Identifier: (Apache-2.0 OR MIT) import itertools +import sys import pytest @@ -11,6 +12,8 @@ import spack.spec import spack.variant from spack.parser import SpecParser, SpecTokenizationError, Token, TokenType +is_windows = sys.platform == "win32" + def simple_package_name(name): """A simple package name in canonical form""" @@ -834,6 +837,7 @@ def test_error_conditions(text, exc_cls): SpecParser(text).next_spec() +@pytest.mark.skipif(is_windows, reason="Spec parsing does not currently support Windows paths") def test_parse_specfile_simple(specfile_for, tmpdir): specfile = tmpdir.join("libdwarf.json") s = specfile_for("libdwarf", specfile) @@ -879,6 +883,7 @@ def test_parse_filename_missing_slash_as_spec(specfile_for, tmpdir, filename): ) +@pytest.mark.skipif(is_windows, reason="Spec parsing does not currently support Windows paths") def test_parse_specfile_dependency(default_mock_concretization, tmpdir): """Ensure we can use a specfile as a dependency""" s = default_mock_concretization("libdwarf") diff --git a/lib/spack/spack/util/path.py b/lib/spack/spack/util/path.py index 2dc646418e..9434fc5af4 100644 --- a/lib/spack/spack/util/path.py +++ b/lib/spack/spack/util/path.py @@ -122,7 +122,7 @@ def path_to_os_path(*pths): """ ret_pths = [] for pth in pths: - if type(pth) is str and not is_path_url(pth): + if isinstance(pth, str) and not is_path_url(pth): pth = convert_to_platform_path(pth) ret_pths.append(pth) return ret_pths |