Skip to content

Commit 12b8f25

Browse files
Fix issue displaying missing action errors when --help is specified (#662)
Co-authored-by: ykim-1 <[email protected]>
1 parent 360aec2 commit 12b8f25

File tree

6 files changed

+37
-11
lines changed

6 files changed

+37
-11
lines changed

linodecli/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,5 @@ def main(): # pylint: disable=too-many-branches,too-many-statements
230230
if parsed.help:
231231
print_help_action(cli, parsed.command, parsed.action)
232232
sys.exit(ExitCodes.SUCCESS)
233+
233234
cli.handle_command(parsed.command, parsed.action, args)

linodecli/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def find_operation(self, command, action):
208208
return op
209209

210210
# Fail if no matching alias was found
211-
raise ValueError(f"No action {action} for command {command}")
211+
raise ValueError(f"Action not found for command {command}: {action}")
212212

213213
@property
214214
def user_agent(self) -> str:

linodecli/exit_codes.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ class ExitCodes(IntEnum):
2020
KUBECONFIG_ERROR = 6
2121
ARGUMENT_ERROR = 7
2222
FILE_ERROR = 8
23+
UNRECOGNIZED_ACTION = 9

linodecli/help_pages.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@
1515
from rich.table import Column, Table
1616
from rich.text import Text
1717

18-
from linodecli import plugins
1918
from linodecli.baked import OpenAPIOperation
2019
from linodecli.baked.request import OpenAPIRequestArg
20+
from linodecli.exit_codes import ExitCodes
21+
from linodecli.plugins import plugins
2122

2223
HELP_ENV_VARS = {
2324
"LINODE_CLI_TOKEN": "A Linode Personal Access Token for the CLI to make requests with. "
@@ -181,8 +182,9 @@ def print_help_action(
181182
"""
182183
try:
183184
op = cli.find_operation(command, action)
184-
except ValueError:
185-
return
185+
except ValueError as exc:
186+
print(exc, file=sys.stderr)
187+
sys.exit(ExitCodes.UNRECOGNIZED_ACTION)
186188

187189
console = Console(highlight=False)
188190

tests/unit/test_cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def test_find_operation(
7373
with pytest.raises(ValueError, match=r"Command not found: *"):
7474
mock_cli.find_operation("bad", "list")
7575

76-
with pytest.raises(ValueError, match=r"No action *"):
76+
with pytest.raises(ValueError, match=r"Action not found for command *"):
7777
mock_cli.find_operation("foo", "cool")
7878
mock_cli.find_operation("cool", "cool")
7979

tests/unit/test_help_pages.py

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import contextlib
12
from io import StringIO
23
from types import SimpleNamespace
34

4-
from linodecli import help_pages
5+
import pytest
6+
7+
from linodecli import CLI, help_pages
8+
from linodecli.baked import OpenAPIOperation
59
from tests.unit.conftest import assert_contains_ordered_substrings
610

711

@@ -100,7 +104,7 @@ def test_help_with_ops(self, capsys, mocked_config):
100104

101105
def test_help_with_ops_with_plugins(self, capsys, mocker, mocked_config):
102106
mocker.patch(
103-
"linodecli.arg_helpers.plugins.available",
107+
"linodecli.help_pages.plugins.available",
104108
return_value=["testing.plugin"],
105109
)
106110
help_pages.print_help_plugins(mocked_config)
@@ -120,10 +124,28 @@ def test_help_topics(self, capsys):
120124
assert topic in captured.out
121125

122126
# arg_helpers.print_help_action(cli, command, action)
123-
def test_action_help_value_error(self, capsys, mock_cli):
124-
help_pages.print_help_action(mock_cli, None, None)
125-
captured = capsys.readouterr()
126-
assert not captured.out
127+
def test_action_help_value_error(
128+
self, capsys, mock_cli: CLI, create_operation: OpenAPIOperation
129+
):
130+
mock_cli.ops = {
131+
"foo": {
132+
"bar": create_operation,
133+
}
134+
}
135+
136+
stderr_buf = StringIO()
137+
138+
with pytest.raises(SystemExit), contextlib.redirect_stderr(stderr_buf):
139+
help_pages.print_help_action(mock_cli, "fake", "fake")
140+
141+
assert "Command not found: fake" in stderr_buf.getvalue()
142+
143+
stderr_buf = StringIO()
144+
145+
with pytest.raises(SystemExit), contextlib.redirect_stderr(stderr_buf):
146+
help_pages.print_help_action(mock_cli, "foo", "fake")
147+
148+
assert "Action not found for command foo: fake" in stderr_buf.getvalue()
127149

128150
def test_action_help_post_method(self, capsys, mocker, mock_cli):
129151
mocked_ops = mocker.MagicMock()

0 commit comments

Comments
 (0)