From 54d06fca7903a7207f1d94c6b269563f56235f51 Mon Sep 17 00:00:00 2001 From: Tamara Dahlgren <35777542+tldahlgren@users.noreply.github.com> Date: Thu, 22 Sep 2022 00:18:43 -0700 Subject: Add hash hint to multi-spec message (#32652) --- lib/spack/spack/cmd/__init__.py | 23 ++++++++++++++--------- lib/spack/spack/cmd/view.py | 12 +----------- lib/spack/spack/test/cmd/load.py | 12 +++++++----- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py index bf7f1a5959..e829166d39 100644 --- a/lib/spack/spack/cmd/__init__.py +++ b/lib/spack/spack/cmd/__init__.py @@ -291,19 +291,24 @@ def disambiguate_spec_from_hashes(spec, hashes, local=False, installed=True, fir elif first: return matching_specs[0] - elif len(matching_specs) > 1: - format_string = "{name}{@version}{%compiler}{arch=architecture}" - args = ["%s matches multiple packages." % spec, "Matching packages:"] - args += [ - colorize(" @K{%s} " % s.dag_hash(7)) + s.cformat(format_string) - for s in matching_specs - ] - args += ["Use a more specific spec."] - tty.die(*args) + ensure_single_spec_or_die(spec, matching_specs) return matching_specs[0] +def ensure_single_spec_or_die(spec, matching_specs): + if len(matching_specs) <= 1: + return + + format_string = "{name}{@version}{%compiler}{arch=architecture}" + args = ["%s matches multiple packages." % spec, "Matching packages:"] + args += [ + colorize(" @K{%s} " % s.dag_hash(7)) + s.cformat(format_string) for s in matching_specs + ] + args += ["Use a more specific spec (e.g., prepend '/' to the hash)."] + tty.die(*args) + + def gray_hash(spec, length): if not length: # default to maximum hash length diff --git a/lib/spack/spack/cmd/view.py b/lib/spack/spack/cmd/view.py index cb693c569d..a032b39ab2 100644 --- a/lib/spack/spack/cmd/view.py +++ b/lib/spack/spack/cmd/view.py @@ -35,7 +35,6 @@ YamlFilesystemView. """ import llnl.util.tty as tty from llnl.util.link_tree import MergeConflictError -from llnl.util.tty.color import colorize import spack.cmd import spack.environment as ev @@ -66,16 +65,7 @@ def disambiguate_in_view(specs, view): tty.die("Spec matches no installed packages.") matching_in_view = [ms for ms in matching_specs if ms in view_specs] - - if len(matching_in_view) > 1: - spec_format = "{name}{@version}{%compiler}{arch=architecture}" - args = ["Spec matches multiple packages.", "Matching packages:"] - args += [ - colorize(" @K{%s} " % s.dag_hash(7)) + s.cformat(spec_format) - for s in matching_in_view - ] - args += ["Use a more specific spec."] - tty.die(*args) + spack.cmd.ensure_single_spec_or_die("Spec", matching_in_view) return matching_in_view[0] if matching_in_view else matching_specs[0] diff --git a/lib/spack/spack/test/cmd/load.py b/lib/spack/spack/test/cmd/load.py index 93cb7348ce..9226a00bb3 100644 --- a/lib/spack/spack/test/cmd/load.py +++ b/lib/spack/spack/test/cmd/load.py @@ -10,7 +10,7 @@ import pytest import spack.spec import spack.user_environment as uenv -from spack.main import SpackCommand, SpackCommandError +from spack.main import SpackCommand load = SpackCommand("load") unload = SpackCommand("unload") @@ -115,10 +115,12 @@ def test_load_first(install_mockery, mock_fetch, mock_archive, mock_packages): """Test with and without the --first option""" install("libelf@0.8.12") install("libelf@0.8.13") - # Now there are two versions of libelf - with pytest.raises(SpackCommandError): - # This should cause an error due to multiple versions - load("--sh", "libelf") + + # Now there are two versions of libelf, which should cause an error + out = load("--sh", "libelf", fail_on_error=False) + assert "matches multiple packages" in out + assert "Use a more specific spec" in out + # Using --first should avoid the error condition load("--sh", "--first", "libelf") -- cgit v1.2.3-70-g09d2