Skip to content

Commit

Permalink
Improve phrasing for "unknown goal" and "unknown flag" errors. (#11664)
Browse files Browse the repository at this point in the history
Implements the same "did you mean...?" phrasing as specified in #11564, and creates a new function as a component of the MaybeColor class that can be used to print this same phrasing for future help cases if needed. Adds a unit test for this function as well.

[ci skip-rust]
[ci skip-build-wheels]
  • Loading branch information
wilsonliam committed Mar 10, 2021
1 parent 0e1f1f9 commit 023cd1f
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/python/pants/help/flag_error_help_printer.py
Expand Up @@ -48,8 +48,8 @@ def handle_unknown_flags(self, err: UnknownFlagsError):
f"come before any goals, or after any file/target arguments."
)
elif did_you_mean:
print(f"Did you mean {', '.join(self.maybe_cyan(g) for g in did_you_mean)}?")

formatted_matches = self._format_did_you_mean_matches(did_you_mean)
print(f"Did you mean {formatted_matches}?")
help_cmd = (
f"{self._bin_name} help"
f"{'' if err.arg_scope == GLOBAL_SCOPE else (' ' + err.arg_scope)}"
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/help/help_integration_test.py
Expand Up @@ -128,7 +128,7 @@ def test_unknown_goal() -> None:
pants_run = run_pants(["testx"])
pants_run.assert_failure()
assert "Unknown goal: testx" in pants_run.stdout
assert "Did you mean: test" in pants_run.stdout
assert "Did you mean test" in pants_run.stdout


def test_unknown_global_flags() -> None:
Expand Down
15 changes: 15 additions & 0 deletions src/python/pants/help/help_matches_test.py
@@ -0,0 +1,15 @@
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from pants.help.maybe_color import MaybeColor


def test_produce_fmt_matches() -> None:
dummy = MaybeColor(color=False)
diff_ex = ["match1", "match2", "match3"]
one_match = dummy._format_did_you_mean_matches(diff_ex[:1])
assert one_match == "match1"
two_match = dummy._format_did_you_mean_matches(diff_ex[:2])
assert two_match == "match1 or match2"
three_match = dummy._format_did_you_mean_matches(diff_ex[:3])
assert three_match == "match1, match2, or match3"
6 changes: 5 additions & 1 deletion src/python/pants/help/help_printer.py
Expand Up @@ -61,13 +61,17 @@ def print_hint() -> None:
# It gets confusing to try and show suggestions for multiple cases.
unknown_goal = self._help_request.unknown_goals[0]
print(f"Unknown goal: {self.maybe_red(unknown_goal)}")

did_you_mean = list(
difflib.get_close_matches(
unknown_goal, self._all_help_info.name_to_goal_info.keys()
)
)

if did_you_mean:
print(f"Did you mean: {', '.join(self.maybe_cyan(g) for g in did_you_mean)}?")
formatted_matches = self._format_did_you_mean_matches(did_you_mean)
print(f"Did you mean {formatted_matches}?")

print_hint()
return 1
elif isinstance(self._help_request, NoGoalHelp):
Expand Down
14 changes: 14 additions & 0 deletions src/python/pants/help/maybe_color.py
@@ -1,6 +1,8 @@
# Copyright 2020 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from typing import List

from colors import cyan, green, magenta, red, yellow


Expand All @@ -16,6 +18,18 @@ def __init__(self, color: bool) -> None:
self.maybe_magenta = magenta if color else noop
self.maybe_yellow = yellow if color else noop

def _format_did_you_mean_matches(self, did_you_mean: List[str]) -> str:
if len(did_you_mean) == 1:
formatted_candidates = self.maybe_cyan(did_you_mean[0])
elif len(did_you_mean) == 2:
formatted_candidates = " or ".join(self.maybe_cyan(g) for g in did_you_mean)
else:
formatted_candidates = (
f"{', '.join(self.maybe_cyan(g) for g in did_you_mean[:-1])}"
f", or {did_you_mean[-1]}"
)
return str(formatted_candidates)

@property
def color(self) -> bool:
return self._color

0 comments on commit 023cd1f

Please sign in to comment.