mirror of
https://github.com/httpie/cli.git
synced 2024-11-21 23:33:12 +01:00
Make the naked invocation display a compacted help
This commit is contained in:
parent
9241a09360
commit
350abe3033
@ -10,6 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- Fixed displaying of status code without a status message on non-`auto` themes. ([#1300](https://github.com/httpie/httpie/issues/1300))
|
||||
- Fixed redundant issuance of stdin detection warnings on some rare cases due to underlying implementation. ([#1303](https://github.com/httpie/httpie/pull/1303))
|
||||
- Improved regulation of top-level arrays. ([#1292](https://github.com/httpie/httpie/commit/225dccb2186f14f871695b6c4e0bfbcdb2e3aa28))
|
||||
- Improved UI layout for standalone invocations. ([#1296](https://github.com/httpie/httpie/pull/1296))
|
||||
- Double `--quiet` flags will now suppress all python level warnings. ([#1271](https://github.com/httpie/httpie/issues/1271))
|
||||
|
||||
## [3.0.2](https://github.com/httpie/httpie/compare/3.0.1...3.0.2) (2022-01-24)
|
||||
|
@ -48,12 +48,39 @@ class HTTPieHelpFormatter(RawDescriptionHelpFormatter):
|
||||
text = dedent(text).strip() + '\n\n'
|
||||
return text.splitlines()
|
||||
|
||||
def add_usage(self, usage, actions, groups, prefix=None):
|
||||
# Only display the positional arguments
|
||||
displayed_actions = [
|
||||
action
|
||||
for action in actions
|
||||
if not action.option_strings
|
||||
]
|
||||
|
||||
_, exception, _ = sys.exc_info()
|
||||
if (
|
||||
isinstance(exception, argparse.ArgumentError)
|
||||
and len(exception.args) >= 1
|
||||
and isinstance(exception.args[0], argparse.Action)
|
||||
):
|
||||
# add_usage path is also taken when you pass an invalid option,
|
||||
# e.g --style=invalid. If something like that happens, we want
|
||||
# to include to action that caused to the invalid usage into
|
||||
# the list of actions we are displaying.
|
||||
displayed_actions.insert(0, exception.args[0])
|
||||
|
||||
super().add_usage(
|
||||
usage,
|
||||
displayed_actions,
|
||||
groups,
|
||||
prefix="usage:\n "
|
||||
)
|
||||
|
||||
|
||||
# TODO: refactor and design type-annotated data structures
|
||||
# for raw args + parsed args and keep things immutable.
|
||||
class BaseHTTPieArgumentParser(argparse.ArgumentParser):
|
||||
def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs):
|
||||
super().__init__(*args, formatter_class=formatter_class, **kwargs)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.env = None
|
||||
self.args = None
|
||||
self.has_stdin_data = False
|
||||
@ -116,9 +143,9 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, *args, formatter_class=HTTPieHelpFormatter, **kwargs):
|
||||
kwargs.setdefault('add_help', False)
|
||||
super().__init__(*args, **kwargs)
|
||||
super().__init__(*args, formatter_class=formatter_class, **kwargs)
|
||||
|
||||
# noinspection PyMethodOverriding
|
||||
def parse_args(
|
||||
@ -529,3 +556,21 @@ class HTTPieArgumentParser(BaseHTTPieArgumentParser):
|
||||
for options_group in format_options:
|
||||
parsed_options = parse_format_options(options_group, defaults=parsed_options)
|
||||
self.args.format_options = parsed_options
|
||||
|
||||
def error(self, message):
|
||||
"""Prints a usage message incorporating the message to stderr and
|
||||
exits."""
|
||||
self.print_usage(sys.stderr)
|
||||
self.exit(
|
||||
2,
|
||||
dedent(
|
||||
f'''
|
||||
error:
|
||||
{message}
|
||||
|
||||
For more information:
|
||||
- Try running {self.prog} --help
|
||||
- Or visiting https://httpie.io/docs/cli
|
||||
'''
|
||||
)
|
||||
)
|
||||
|
84
tests/test_cli_ui.py
Normal file
84
tests/test_cli_ui.py
Normal file
@ -0,0 +1,84 @@
|
||||
import pytest
|
||||
import shutil
|
||||
import os
|
||||
import sys
|
||||
from tests.utils import http
|
||||
|
||||
|
||||
if sys.version_info >= (3, 9):
|
||||
REQUEST_ITEM_MSG = "[REQUEST_ITEM ...]"
|
||||
else:
|
||||
REQUEST_ITEM_MSG = "[REQUEST_ITEM [REQUEST_ITEM ...]]"
|
||||
|
||||
|
||||
NAKED_HELP_MESSAGE = f"""\
|
||||
usage:
|
||||
http [METHOD] URL {REQUEST_ITEM_MSG}
|
||||
|
||||
error:
|
||||
the following arguments are required: URL
|
||||
|
||||
For more information:
|
||||
- Try running http --help
|
||||
- Or visiting https://httpie.io/docs/cli
|
||||
|
||||
"""
|
||||
|
||||
NAKED_HELP_MESSAGE_PRETTY_WITH_NO_ARG = f"""\
|
||||
usage:
|
||||
http [--pretty {{all,colors,format,none}}] [METHOD] URL {REQUEST_ITEM_MSG}
|
||||
|
||||
error:
|
||||
argument --pretty: expected one argument
|
||||
|
||||
For more information:
|
||||
- Try running http --help
|
||||
- Or visiting https://httpie.io/docs/cli
|
||||
|
||||
"""
|
||||
|
||||
NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG = f"""\
|
||||
usage:
|
||||
http [--pretty {{all,colors,format,none}}] [METHOD] URL {REQUEST_ITEM_MSG}
|
||||
|
||||
error:
|
||||
argument --pretty: invalid choice: '$invalid' (choose from 'all', 'colors', 'format', 'none')
|
||||
|
||||
For more information:
|
||||
- Try running http --help
|
||||
- Or visiting https://httpie.io/docs/cli
|
||||
|
||||
"""
|
||||
|
||||
|
||||
PREDEFINED_TERMINAL_SIZE = (160, 80)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def ignore_terminal_size(monkeypatch):
|
||||
"""Some tests wrap/crop the output depending on the
|
||||
size of the executed terminal, which might not be consistent
|
||||
through all runs.
|
||||
|
||||
This fixture ensures every run uses the same exact configuration.
|
||||
"""
|
||||
|
||||
def fake_terminal_size(*args, **kwargs):
|
||||
return os.terminal_size(PREDEFINED_TERMINAL_SIZE)
|
||||
|
||||
# Setting COLUMNS as an env var is required for 3.8<
|
||||
monkeypatch.setitem(os.environ, 'COLUMNS', str(PREDEFINED_TERMINAL_SIZE[0]))
|
||||
monkeypatch.setattr(shutil, 'get_terminal_size', fake_terminal_size)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'args, expected_msg', [
|
||||
([], NAKED_HELP_MESSAGE),
|
||||
(['--pretty'], NAKED_HELP_MESSAGE_PRETTY_WITH_NO_ARG),
|
||||
(['pie.dev', '--pretty'], NAKED_HELP_MESSAGE_PRETTY_WITH_NO_ARG),
|
||||
(['--pretty', '$invalid'], NAKED_HELP_MESSAGE_PRETTY_WITH_INVALID_ARG),
|
||||
]
|
||||
)
|
||||
def test_naked_invocation(ignore_terminal_size, args, expected_msg):
|
||||
result = http(*args, tolerate_error_exit_status=True)
|
||||
assert result.stderr == expected_msg
|
Loading…
Reference in New Issue
Block a user