mirror of
https://github.com/httpie/cli.git
synced 2025-06-25 20:11:32 +02:00
Added --unsorted
It acts as a shortcut for --format-options=json.sort_keys:false,headers.sort:false #128
This commit is contained in:
parent
b86598886e
commit
826489950d
@ -11,6 +11,7 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
|
|||||||
|
|
||||||
* Fixed built-in plugins-related circular imports (`#925`_).
|
* Fixed built-in plugins-related circular imports (`#925`_).
|
||||||
* Added ``--format-options`` to allow disabling sorting, etc. (`#128`_)
|
* Added ``--format-options`` to allow disabling sorting, etc. (`#128`_)
|
||||||
|
* Added ``--unsorted`` shortcut to set all sorting-related ``--format-options`` to ``false``. (`#128`_)
|
||||||
* Added ``--ciphers`` to allow configuring OpenSSL ciphers (`#870`_).
|
* Added ``--ciphers`` to allow configuring OpenSSL ciphers (`#870`_).
|
||||||
* Added support for ``$XDG_CONFIG_HOME`` (`#920`_).
|
* Added support for ``$XDG_CONFIG_HOME`` (`#920`_).
|
||||||
* Added support for custom content types for uploaded files (`#668`_).
|
* Added support for custom content types for uploaded files (`#668`_).
|
||||||
|
@ -9,9 +9,14 @@ from urllib.parse import urlsplit
|
|||||||
|
|
||||||
from requests.utils import get_netrc_auth
|
from requests.utils import get_netrc_auth
|
||||||
|
|
||||||
from httpie.cli.argtypes import AuthCredentials, KeyValueArgType, parse_auth
|
from httpie.cli.argtypes import (
|
||||||
|
AuthCredentials, KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS,
|
||||||
|
parse_auth,
|
||||||
|
parse_format_options,
|
||||||
|
)
|
||||||
from httpie.cli.constants import (
|
from httpie.cli.constants import (
|
||||||
HTTP_GET, HTTP_POST, OUTPUT_OPTIONS, OUTPUT_OPTIONS_DEFAULT,
|
DEFAULT_FORMAT_OPTIONS, HTTP_GET, HTTP_POST, OUTPUT_OPTIONS,
|
||||||
|
OUTPUT_OPTIONS_DEFAULT,
|
||||||
OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED, OUT_RESP_BODY, PRETTY_MAP,
|
OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED, OUT_RESP_BODY, PRETTY_MAP,
|
||||||
PRETTY_STDOUT_TTY_ONLY, SEPARATOR_CREDENTIALS, SEPARATOR_GROUP_ALL_ITEMS,
|
PRETTY_STDOUT_TTY_ONLY, SEPARATOR_CREDENTIALS, SEPARATOR_GROUP_ALL_ITEMS,
|
||||||
SEPARATOR_GROUP_DATA_ITEMS, URL_SCHEME_RE,
|
SEPARATOR_GROUP_DATA_ITEMS, URL_SCHEME_RE,
|
||||||
@ -44,6 +49,8 @@ class HTTPieHelpFormatter(RawDescriptionHelpFormatter):
|
|||||||
return text.splitlines()
|
return text.splitlines()
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: refactor and design type-annotated data structures
|
||||||
|
# for raw args + parsed args and keep things immutable.
|
||||||
class HTTPieArgumentParser(argparse.ArgumentParser):
|
class HTTPieArgumentParser(argparse.ArgumentParser):
|
||||||
"""Adds additional logic to `argparse.ArgumentParser`.
|
"""Adds additional logic to `argparse.ArgumentParser`.
|
||||||
|
|
||||||
@ -84,6 +91,7 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
|
|||||||
self._setup_standard_streams()
|
self._setup_standard_streams()
|
||||||
self._process_output_options()
|
self._process_output_options()
|
||||||
self._process_pretty_options()
|
self._process_pretty_options()
|
||||||
|
self._process_format_options()
|
||||||
self._guess_method()
|
self._guess_method()
|
||||||
self._parse_items()
|
self._parse_items()
|
||||||
|
|
||||||
@ -405,3 +413,9 @@ class HTTPieArgumentParser(argparse.ArgumentParser):
|
|||||||
if self.args.download_resume and not (
|
if self.args.download_resume and not (
|
||||||
self.args.download and self.args.output_file):
|
self.args.download and self.args.output_file):
|
||||||
self.error('--continue requires --output to be specified')
|
self.error('--continue requires --output to be specified')
|
||||||
|
|
||||||
|
def _process_format_options(self):
|
||||||
|
parsed_options = PARSED_DEFAULT_FORMAT_OPTIONS
|
||||||
|
for options_group in self.args.format_options:
|
||||||
|
parsed_options = parse_format_options(options_group, defaults=parsed_options)
|
||||||
|
self.args.format_options = parsed_options
|
||||||
|
@ -242,3 +242,9 @@ PARSED_DEFAULT_FORMAT_OPTIONS = parse_format_options(
|
|||||||
s=','.join(DEFAULT_FORMAT_OPTIONS),
|
s=','.join(DEFAULT_FORMAT_OPTIONS),
|
||||||
defaults=None,
|
defaults=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UnsortedAction(argparse.Action):
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return 1
|
||||||
|
@ -91,7 +91,10 @@ DEFAULT_FORMAT_OPTIONS = [
|
|||||||
'json.indent:4',
|
'json.indent:4',
|
||||||
'json.sort_keys:true',
|
'json.sort_keys:true',
|
||||||
]
|
]
|
||||||
|
UNSORTED_FORMAT_OPTIONS = [
|
||||||
|
'headers.sort:false',
|
||||||
|
'json.sort_keys:false',
|
||||||
|
]
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
OUTPUT_OPTIONS_DEFAULT = OUT_RESP_HEAD + OUT_RESP_BODY
|
OUTPUT_OPTIONS_DEFAULT = OUT_RESP_HEAD + OUT_RESP_BODY
|
||||||
|
@ -9,14 +9,13 @@ from httpie import __doc__, __version__
|
|||||||
from httpie.cli.argparser import HTTPieArgumentParser
|
from httpie.cli.argparser import HTTPieArgumentParser
|
||||||
from httpie.cli.argtypes import (
|
from httpie.cli.argtypes import (
|
||||||
KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS, SessionNameValidator,
|
KeyValueArgType, PARSED_DEFAULT_FORMAT_OPTIONS, SessionNameValidator,
|
||||||
parse_format_options,
|
|
||||||
readable_file_arg,
|
readable_file_arg,
|
||||||
)
|
)
|
||||||
from httpie.cli.constants import (
|
from httpie.cli.constants import (
|
||||||
DEFAULT_FORMAT_OPTIONS, OUTPUT_OPTIONS,
|
DEFAULT_FORMAT_OPTIONS, OUTPUT_OPTIONS,
|
||||||
OUTPUT_OPTIONS_DEFAULT, OUT_REQ_BODY, OUT_REQ_HEAD,
|
OUTPUT_OPTIONS_DEFAULT, OUT_REQ_BODY, OUT_REQ_HEAD,
|
||||||
OUT_RESP_BODY, OUT_RESP_HEAD, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY,
|
OUT_RESP_BODY, OUT_RESP_HEAD, PRETTY_MAP, PRETTY_STDOUT_TTY_ONLY,
|
||||||
SEPARATOR_GROUP_ALL_ITEMS, SEPARATOR_PROXY,
|
SEPARATOR_GROUP_ALL_ITEMS, SEPARATOR_PROXY, UNSORTED_FORMAT_OPTIONS,
|
||||||
)
|
)
|
||||||
from httpie.output.formatters.colors import (
|
from httpie.output.formatters.colors import (
|
||||||
AUTO_STYLE, AVAILABLE_STYLES, DEFAULT_STYLE,
|
AUTO_STYLE, AVAILABLE_STYLES, DEFAULT_STYLE,
|
||||||
@ -229,14 +228,22 @@ output_processing.add_argument(
|
|||||||
auto_style=AUTO_STYLE,
|
auto_style=AUTO_STYLE,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
output_processing.add_argument(
|
||||||
|
'--unsorted',
|
||||||
|
action='append_const',
|
||||||
|
const=','.join(UNSORTED_FORMAT_OPTIONS),
|
||||||
|
dest='format_options',
|
||||||
|
help="""
|
||||||
|
Disables all sorting while formatting output. It is a shortcut for:
|
||||||
|
|
||||||
|
--format-options=json.sort_keys:false,headers.sort:false
|
||||||
|
|
||||||
|
"""
|
||||||
|
)
|
||||||
output_processing.add_argument(
|
output_processing.add_argument(
|
||||||
'--format-options',
|
'--format-options',
|
||||||
type=lambda s: parse_format_options(
|
default=[],
|
||||||
s=s,
|
action='append',
|
||||||
defaults=PARSED_DEFAULT_FORMAT_OPTIONS
|
|
||||||
),
|
|
||||||
default=PARSED_DEFAULT_FORMAT_OPTIONS,
|
|
||||||
help="""
|
help="""
|
||||||
Controls output formatting. Only relevant when formatting is enabled
|
Controls output formatting. Only relevant when formatting is enabled
|
||||||
through (explicit or implied) --pretty=all or --pretty=format.
|
through (explicit or implied) --pretty=all or --pretty=format.
|
||||||
@ -244,10 +251,11 @@ output_processing.add_argument(
|
|||||||
|
|
||||||
{option_list}
|
{option_list}
|
||||||
|
|
||||||
You can specify multiple comma-separated options. For example, this modifies
|
You may use this option multiple times, as well as specify multiple
|
||||||
the settings to disable the sorting of JSON keys and headers:
|
comma-separated options at the same time. For example, this modifies the
|
||||||
|
settings to disable the sorting of JSON keys, and sets the indent size to 2:
|
||||||
|
|
||||||
--format-options json.sort_keys:false,headers.sort:false
|
--format-options json.sort_keys:false,json.indent:2
|
||||||
|
|
||||||
This is something you will typically put into your config file.
|
This is something you will typically put into your config file.
|
||||||
|
|
||||||
|
@ -6,7 +6,12 @@ from urllib.request import urlopen
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from httpie.cli.argtypes import parse_format_options
|
from httpie.cli.constants import DEFAULT_FORMAT_OPTIONS
|
||||||
|
from httpie.cli.definition import parser
|
||||||
|
from httpie.cli.argtypes import (
|
||||||
|
PARSED_DEFAULT_FORMAT_OPTIONS,
|
||||||
|
parse_format_options,
|
||||||
|
)
|
||||||
from httpie.output.formatters.colors import get_lexer
|
from httpie.output.formatters.colors import get_lexer
|
||||||
from httpie.status import ExitStatus
|
from httpie.status import ExitStatus
|
||||||
from utils import COLOR, CRLF, HTTP_OK, MockEnvironment, http
|
from utils import COLOR, CRLF, HTTP_OK, MockEnvironment, http
|
||||||
@ -249,3 +254,55 @@ class TestFormatOptions:
|
|||||||
}
|
}
|
||||||
with pytest.raises(argparse.ArgumentTypeError, match=expected_error):
|
with pytest.raises(argparse.ArgumentTypeError, match=expected_error):
|
||||||
parse_format_options(s=options_string, defaults=defaults)
|
parse_format_options(s=options_string, defaults=defaults)
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
argnames=['args', 'expected_format_options'],
|
||||||
|
argvalues=[
|
||||||
|
(
|
||||||
|
[
|
||||||
|
'--format-options',
|
||||||
|
'headers.sort:false,json.sort_keys:false',
|
||||||
|
'--format-options=json.indent:10'
|
||||||
|
],
|
||||||
|
{
|
||||||
|
'headers': {'sort': False},
|
||||||
|
'json': {'sort_keys': False, 'indent': 10, 'format': True},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[
|
||||||
|
'--unsorted'
|
||||||
|
],
|
||||||
|
{
|
||||||
|
'headers': {'sort': False},
|
||||||
|
'json': {'sort_keys': False, 'indent': 4, 'format': True},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[
|
||||||
|
'--format-options=headers.sort:true',
|
||||||
|
'--unsorted',
|
||||||
|
'--format-options=headers.sort:true',
|
||||||
|
],
|
||||||
|
{
|
||||||
|
'headers': {'sort': True},
|
||||||
|
'json': {'sort_keys': False, 'indent': 4, 'format': True},
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
[
|
||||||
|
'--no-format-options', # --no-<option> anywhere resets
|
||||||
|
'--format-options=headers.sort:true',
|
||||||
|
'--unsorted',
|
||||||
|
'--format-options=headers.sort:true',
|
||||||
|
],
|
||||||
|
PARSED_DEFAULT_FORMAT_OPTIONS,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_format_options_accumulation(self, args, expected_format_options):
|
||||||
|
parsed_args = parser.parse_args(
|
||||||
|
args=[*args, 'example.org'],
|
||||||
|
env=MockEnvironment(),
|
||||||
|
)
|
||||||
|
assert parsed_args.format_options == expected_format_options
|
||||||
|
Loading…
x
Reference in New Issue
Block a user