Add command and package suggestions (#40895)
* Add command suggestions This adds suggestions of similar commands in case users mistype a command. Before: ``` $ spack spack ==> Error: spack is not a recognized Spack command or extension command; check with `spack commands`. ``` After: ``` $ spack spack ==> Error: spack is not a recognized Spack command or extension command; check with `spack commands`. Did you mean one of the following commands? spec patch ``` * Add package name suggestions * Remove suggestion to run spack clean -m
This commit is contained in:
parent
f6b23b4653
commit
141c7de5d8
5 changed files with 35 additions and 12 deletions
|
@ -99,10 +99,7 @@ def dev_build(self, args):
|
|||
|
||||
spec = specs[0]
|
||||
if not spack.repo.PATH.exists(spec.name):
|
||||
tty.die(
|
||||
"No package for '{0}' was found.".format(spec.name),
|
||||
" Use `spack create` to create a new package",
|
||||
)
|
||||
raise spack.repo.UnknownPackageError(spec.name)
|
||||
|
||||
if not spec.versions.concrete_range_as_version:
|
||||
tty.die(
|
||||
|
|
|
@ -43,10 +43,7 @@ def edit_package(name, repo_path, namespace):
|
|||
if not os.access(path, os.R_OK):
|
||||
tty.die("Insufficient permissions on '%s'!" % path)
|
||||
else:
|
||||
tty.die(
|
||||
"No package for '{0}' was found.".format(spec.name),
|
||||
" Use `spack create` to create a new package",
|
||||
)
|
||||
raise spack.repo.UnknownPackageError(spec.name)
|
||||
|
||||
editor(path)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"""Service functions and classes to implement the hooks
|
||||
for Spack's command extensions.
|
||||
"""
|
||||
import difflib
|
||||
import importlib
|
||||
import os
|
||||
import re
|
||||
|
@ -176,10 +177,19 @@ class CommandNotFoundError(spack.error.SpackError):
|
|||
"""
|
||||
|
||||
def __init__(self, cmd_name):
|
||||
super().__init__(
|
||||
msg = (
|
||||
"{0} is not a recognized Spack command or extension command;"
|
||||
" check with `spack commands`.".format(cmd_name)
|
||||
)
|
||||
long_msg = None
|
||||
|
||||
similar = difflib.get_close_matches(cmd_name, spack.cmd.all_commands())
|
||||
|
||||
if 1 <= len(similar) <= 5:
|
||||
long_msg = "\nDid you mean one of the following commands?\n "
|
||||
long_msg += "\n ".join(similar)
|
||||
|
||||
super().__init__(msg, long_msg)
|
||||
|
||||
|
||||
class ExtensionNamingError(spack.error.SpackError):
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import abc
|
||||
import collections.abc
|
||||
import contextlib
|
||||
import difflib
|
||||
import errno
|
||||
import functools
|
||||
import importlib
|
||||
|
@ -1516,7 +1517,18 @@ def __init__(self, name, repo=None):
|
|||
long_msg = "Did you mean to specify a filename with './{0}'?"
|
||||
long_msg = long_msg.format(name)
|
||||
else:
|
||||
long_msg = "You may need to run 'spack clean -m'."
|
||||
long_msg = "Use 'spack create' to create a new package."
|
||||
|
||||
if not repo:
|
||||
repo = spack.repo.PATH
|
||||
|
||||
# We need to compare the base package name
|
||||
pkg_name = name.rsplit(".", 1)[-1]
|
||||
similar = difflib.get_close_matches(pkg_name, repo.all_package_names())
|
||||
|
||||
if 1 <= len(similar) <= 5:
|
||||
long_msg += "\n\nDid you mean one of the following packages?\n "
|
||||
long_msg += "\n ".join(similar)
|
||||
|
||||
super().__init__(msg, long_msg)
|
||||
self.name = name
|
||||
|
|
|
@ -163,8 +163,15 @@ def test_dev_build_fails_multiple_specs(mock_packages):
|
|||
|
||||
|
||||
def test_dev_build_fails_nonexistent_package_name(mock_packages):
|
||||
output = dev_build("no_such_package", fail_on_error=False)
|
||||
assert "No package for 'no_such_package' was found" in output
|
||||
output = ""
|
||||
|
||||
try:
|
||||
dev_build("no_such_package")
|
||||
assert False, "no exception was raised!"
|
||||
except spack.repo.UnknownPackageError as e:
|
||||
output = e.message
|
||||
|
||||
assert "Package 'no_such_package' not found" in output
|
||||
|
||||
|
||||
def test_dev_build_fails_no_version(mock_packages):
|
||||
|
|
Loading…
Reference in a new issue