diff options
-rw-r--r-- | lib/spack/spack/solver/asp.py | 17 | ||||
-rw-r--r-- | lib/spack/spack/solver/concretize.lp | 1 | ||||
-rw-r--r-- | lib/spack/spack/test/concretize.py | 42 | ||||
-rw-r--r-- | var/spack/repos/builtin.mock/packages/git-ref-package/package.py | 41 |
4 files changed, 97 insertions, 4 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index dc1aa5fea0..2701ea25fd 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -116,6 +116,8 @@ class Provenance(enum.IntEnum): PACKAGE_PY = enum.auto() # An installed spec INSTALLED = enum.auto() + # lower provenance for installed git refs so concretizer prefers StandardVersion installs + INSTALLED_GIT_VERSION = enum.auto() # A runtime injected from another package (e.g. a compiler) RUNTIME = enum.auto() @@ -2072,7 +2074,7 @@ class SpackSolverSetup: # best possible, so they're guaranteed to be used preferentially. version = s.versions.concrete - if version is None or any(v == version for v in self.possible_versions[s.name]): + if version is None or (any((v == version) for v in self.possible_versions[s.name])): continue if require_checksum and not _is_checksummed_git_version(version): @@ -2386,9 +2388,16 @@ class SpackSolverSetup: # - Add OS to possible OS's for dep in spec.traverse(): self.possible_versions[dep.name].add(dep.version) - self.declared_versions[dep.name].append( - DeclaredVersion(version=dep.version, idx=0, origin=Provenance.INSTALLED) - ) + if isinstance(dep.version, vn.GitVersion): + self.declared_versions[dep.name].append( + DeclaredVersion( + version=dep.version, idx=0, origin=Provenance.INSTALLED_GIT_VERSION + ) + ) + else: + self.declared_versions[dep.name].append( + DeclaredVersion(version=dep.version, idx=0, origin=Provenance.INSTALLED) + ) self.possible_oses.add(dep.os) def define_concrete_input_specs(self, specs, possible): diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 20bcd46ad6..8c270e1702 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -256,6 +256,7 @@ possible_version_weight(node(ID, Package), Weight) :- attr("version", node(ID, Package), Version), version_weight(node(ID, Package), Weight), not pkg_fact(Package, version_declared(Version, Weight, "installed")), + not pkg_fact(Package, version_declared(Version, Weight, "installed_git_version")), not build(node(ID, Package)), internal_error("Build version weight used for reused package"). diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py index b1cd35bff9..547e3209eb 100644 --- a/lib/spack/spack/test/concretize.py +++ b/lib/spack/spack/test/concretize.py @@ -3043,3 +3043,45 @@ def test_spec_filters(specs, include, exclude, expected): factory=lambda: specs, is_usable=lambda x: True, include=include, exclude=exclude ) assert f.selected_specs() == expected + + +@pytest.mark.only_clingo("clingo only reuse feature being tested") +@pytest.mark.regression("38484") +def test_git_ref_version_can_be_reused( + install_mockery_mutable_config, do_not_check_runtimes_on_reuse +): + first_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5~opt").concretized() + first_spec.package.do_install(fake=True, explicit=True) + + with spack.config.override("concretizer:reuse", True): + # reproducer of the issue is that spack will solve when there is a change to the base spec + second_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5+opt").concretized() + assert second_spec.dag_hash() != first_spec.dag_hash() + # we also want to confirm that reuse actually works so leave variant off to + # let solver reuse + third_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5") + assert first_spec.satisfies(third_spec) + third_spec.concretize() + assert third_spec.dag_hash() == first_spec.dag_hash() + + +@pytest.mark.only_clingo("clingo only reuse feature being tested") +@pytest.mark.parametrize("standard_version", ["2.0.0", "2.1.5", "2.1.6"]) +def test_reuse_prefers_standard_over_git_versions( + standard_version, install_mockery_mutable_config, do_not_check_runtimes_on_reuse +): + """ + order matters in this test. typically reuse would pick the highest versioned installed match + but we want to prefer the standard version over git ref based versions + so install git ref last and ensure it is not picked up by reuse + """ + standard_spec = spack.spec.Spec(f"git-ref-package@{standard_version}").concretized() + standard_spec.package.do_install(fake=True, explicit=True) + + git_spec = spack.spec.Spec("git-ref-package@git.2.1.5=2.1.5").concretized() + git_spec.package.do_install(fake=True, explicit=True) + + with spack.config.override("concretizer:reuse", True): + test_spec = spack.spec.Spec("git-ref-package@2").concretized() + assert git_spec.dag_hash() != test_spec.dag_hash() + assert standard_spec.dag_hash() == test_spec.dag_hash() diff --git a/var/spack/repos/builtin.mock/packages/git-ref-package/package.py b/var/spack/repos/builtin.mock/packages/git-ref-package/package.py new file mode 100644 index 0000000000..21fe10e818 --- /dev/null +++ b/var/spack/repos/builtin.mock/packages/git-ref-package/package.py @@ -0,0 +1,41 @@ +# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +from spack.package import * + + +class GitRefPackage(AutotoolsPackage): + """ + dummy package copied from zlib-ng + """ + + homepage = "https://github.com/dummy/dummy" + url = "https://github.com/dummy/dummy/archive/2.0.0.tar.gz" + git = "https://github.com/dummy/dummy.git" + + version("2.1.6", sha256="a5d504c0d52e2e2721e7e7d86988dec2e290d723ced2307145dedd06aeb6fef2") + version("2.1.5", sha256="3f6576971397b379d4205ae5451ff5a68edf6c103b2f03c4188ed7075fbb5f04") + version("2.1.4", sha256="a0293475e6a44a3f6c045229fe50f69dc0eebc62a42405a51f19d46a5541e77a") + version( + "2.1.3", + sha256="d20e55f89d71991c59f1c5ad1ef944815e5850526c0d9cd8e504eaed5b24491a", + deprecated=True, + ) + version( + "2.1.2", + sha256="383560d6b00697c04e8878e26c0187b480971a8bce90ffd26a5a7b0f7ecf1a33", + deprecated=True, + ) + version("2.0.7", sha256="6c0853bb27738b811f2b4d4af095323c3d5ce36ceed6b50e5f773204fb8f7200") + version("2.0.0", sha256="86993903527d9b12fc543335c19c1d33a93797b3d4d37648b5addae83679ecd8") + + variant("compat", default=True, description="Enable compatibility API") + variant("opt", default=True, description="Enable optimizations") + variant("shared", default=True, description="Build shared library") + variant("pic", default=True, description="Enable position-independent code (PIC)") + + conflicts("+shared~pic") + + variant("new_strategies", default=True, description="Enable new deflate strategies") |