Skip to content

Commit ce0d78f

Browse files
committed
Add command suggestions feature
1 parent 2a8f95f commit ce0d78f

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

invoke/program.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import difflib
12
import getpass
23
import inspect
34
import json
@@ -86,6 +87,12 @@ def core_args(self) -> List["Argument"]:
8687
default=False,
8788
help="Echo executed commands before running.",
8889
),
90+
Argument(
91+
names=("suggestions", "S"),
92+
kind=bool,
93+
default=True,
94+
help="Show possible commands suggestions.",
95+
),
8996
Argument(
9097
names=("help", "h"),
9198
optional=True,
@@ -403,6 +410,11 @@ def run(self, argv: Optional[List[str]] = None, exit: bool = True) -> None:
403410
# problems.
404411
if isinstance(e, ParseError):
405412
print(e, file=sys.stderr)
413+
if self.args.suggestions.value:
414+
unrecognised_cmd = str(e).replace("No idea what '", "")
415+
unrecognised_cmd = unrecognised_cmd.replace("' is!", "")
416+
msg = self._possible_commands_msg(unrecognised_cmd)
417+
print(msg, file=sys.stderr)
406418
if isinstance(e, Exit) and e.message:
407419
print(e.message, file=sys.stderr)
408420
if isinstance(e, UnexpectedExit) and e.result.hide:
@@ -985,3 +997,24 @@ def print_columns(
985997
else:
986998
print(spec.rstrip())
987999
print("")
1000+
1001+
def _possible_commands_msg(self, unknown_cmd: str):
1002+
output_message = ""
1003+
try:
1004+
all_tasks = self.scoped_collection.task_names
1005+
except AttributeError:
1006+
all_tasks = {}
1007+
1008+
possible_cmds = list(all_tasks.keys())
1009+
suggestions = difflib.get_close_matches(
1010+
unknown_cmd, possible_cmds, n=3, cutoff=0.7
1011+
)
1012+
output_message = f"'{unknown_cmd}' is not an invoke command."
1013+
output_message += "See 'invoke --list'.\n"
1014+
if suggestions:
1015+
output_message += "\nThe most similar command(s):\n"
1016+
for cmd in suggestions:
1017+
output_message += f" {cmd}\n"
1018+
else:
1019+
output_message += "\nNo suggestions was found.\n"
1020+
return output_message

0 commit comments

Comments
 (0)