mirror of
https://github.com/httpie/cli.git
synced 2024-11-30 08:46:48 +02:00
Finish --quiet
This commit is contained in:
parent
2c7f24e3e5
commit
1aa1366f99
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
|||||||
liberapay: # Replace with a single Liberapay username
|
liberapay: # Replace with a single Liberapay username
|
||||||
issuehunt: # Replace with a single IssueHunt username
|
issuehunt: # Replace with a single IssueHunt username
|
||||||
otechie: # Replace with a single Otechie username
|
otechie: # Replace with a single Otechie username
|
||||||
custom: https://paypal.me/roztocil
|
custom:
|
||||||
|
@ -10,8 +10,8 @@ This project adheres to `Semantic Versioning <https://semver.org/>`_.
|
|||||||
-------------------------
|
-------------------------
|
||||||
* Added support for combining cookies specified on the CLI and in a session file (`#932`_).
|
* Added support for combining cookies specified on the CLI and in a session file (`#932`_).
|
||||||
* Added out of the box SOCKS support with no extra installation (`#904`_).
|
* Added out of the box SOCKS support with no extra installation (`#904`_).
|
||||||
|
* Added ``--quiet, -q`` flag to enforce silent behaviour.
|
||||||
* Removed Tox testing entirely (`#943`_).
|
* Removed Tox testing entirely (`#943`_).
|
||||||
* Added a ``--quiet`` flag to enforce silent behaviour.
|
|
||||||
|
|
||||||
|
|
||||||
`2.2.0`_ (2020-06-18)
|
`2.2.0`_ (2020-06-18)
|
||||||
|
58
README.rst
58
README.rst
@ -1156,12 +1156,34 @@ be printed via several options:
|
|||||||
``--verbose, -v`` Print the whole HTTP exchange (request and response).
|
``--verbose, -v`` Print the whole HTTP exchange (request and response).
|
||||||
This option also enables ``--all`` (see below).
|
This option also enables ``--all`` (see below).
|
||||||
``--print, -p`` Selects parts of the HTTP exchange.
|
``--print, -p`` Selects parts of the HTTP exchange.
|
||||||
``--quiet, -q`` Doesn't print anything. Overrides other output flags.
|
``--quiet, -q`` Don't print anything to ``stdout`` and ``stderr``.
|
||||||
================= =====================================================
|
================= =====================================================
|
||||||
If ``--quiet`` is used in conjuction with ``--output`` the flag is ignored
|
|
||||||
and ``stdout`` is still redirected. If ``--quiet`` is used with ``--download``
|
|
||||||
file is still downloaded as usual but ``stdout`` and ``stdin`` are redirected
|
What parts of the HTTP exchange should be printed
|
||||||
to ``devnull``.
|
-------------------------------------------------
|
||||||
|
|
||||||
|
All the other `output options`_ are under the hood just shortcuts for
|
||||||
|
the more powerful ``--print, -p``. It accepts a string of characters each
|
||||||
|
of which represents a specific part of the HTTP exchange:
|
||||||
|
|
||||||
|
========== ==================
|
||||||
|
Character Stands for
|
||||||
|
========== ==================
|
||||||
|
``H`` request headers
|
||||||
|
``B`` request body
|
||||||
|
``h`` response headers
|
||||||
|
``b`` response body
|
||||||
|
========== ==================
|
||||||
|
|
||||||
|
Print request and response headers:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
$ http --print=Hh PUT httpbin.org/put hello=world
|
||||||
|
|
||||||
|
Verbose output
|
||||||
|
--------------
|
||||||
|
|
||||||
``--verbose`` can often be useful for debugging the request and generating
|
``--verbose`` can often be useful for debugging the request and generating
|
||||||
documentation examples:
|
documentation examples:
|
||||||
@ -1192,28 +1214,12 @@ documentation examples:
|
|||||||
[…]
|
[…]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Quiet output
|
||||||
|
------------
|
||||||
|
|
||||||
What parts of the HTTP exchange should be printed
|
``--quiet`` redirects all output that would otherwise go to ``stdout``
|
||||||
-------------------------------------------------
|
and ``stderr`` (except for error messages) to ``/dev/null``.
|
||||||
|
This doesn’t affect output to a file via ``--output`` or ``--download``.
|
||||||
All the other `output options`_ are under the hood just shortcuts for
|
|
||||||
the more powerful ``--print, -p``. It accepts a string of characters each
|
|
||||||
of which represents a specific part of the HTTP exchange:
|
|
||||||
|
|
||||||
========== ==================
|
|
||||||
Character Stands for
|
|
||||||
========== ==================
|
|
||||||
``H`` request headers
|
|
||||||
``B`` request body
|
|
||||||
``h`` response headers
|
|
||||||
``b`` response body
|
|
||||||
========== ==================
|
|
||||||
|
|
||||||
Print request and response headers:
|
|
||||||
|
|
||||||
.. code-block:: bash
|
|
||||||
|
|
||||||
$ http --print=Hh PUT httpbin.org/put hello=world
|
|
||||||
|
|
||||||
|
|
||||||
Viewing intermediary requests/responses
|
Viewing intermediary requests/responses
|
||||||
|
@ -35,7 +35,6 @@ class Environment:
|
|||||||
stdout_encoding: str = None
|
stdout_encoding: str = None
|
||||||
stderr: IO = sys.stderr
|
stderr: IO = sys.stderr
|
||||||
stderr_isatty: bool = stderr.isatty()
|
stderr_isatty: bool = stderr.isatty()
|
||||||
_devnull = None
|
|
||||||
colors = 256
|
colors = 256
|
||||||
program_name: str = 'http'
|
program_name: str = 'http'
|
||||||
if not is_windows:
|
if not is_windows:
|
||||||
@ -58,7 +57,7 @@ class Environment:
|
|||||||
)
|
)
|
||||||
del colorama
|
del colorama
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, devnull=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Use keyword arguments to overwrite
|
Use keyword arguments to overwrite
|
||||||
any of the class attributes for this instance.
|
any of the class attributes for this instance.
|
||||||
@ -67,6 +66,10 @@ class Environment:
|
|||||||
assert all(hasattr(type(self), attr) for attr in kwargs.keys())
|
assert all(hasattr(type(self), attr) for attr in kwargs.keys())
|
||||||
self.__dict__.update(**kwargs)
|
self.__dict__.update(**kwargs)
|
||||||
|
|
||||||
|
# The original STDERR unaffected by --quiet’ing.
|
||||||
|
self._orig_stderr = self.stderr
|
||||||
|
self._devnull = devnull
|
||||||
|
|
||||||
# Keyword arguments > stream.encoding > default utf8
|
# Keyword arguments > stream.encoding > default utf8
|
||||||
if self.stdin and self.stdin_encoding is None:
|
if self.stdin and self.stdin_encoding is None:
|
||||||
self.stdin_encoding = getattr(
|
self.stdin_encoding = getattr(
|
||||||
@ -122,4 +125,4 @@ class Environment:
|
|||||||
|
|
||||||
def log_error(self, msg, level='error'):
|
def log_error(self, msg, level='error'):
|
||||||
assert level in ['error', 'warning']
|
assert level in ['error', 'warning']
|
||||||
self.stderr.write(f'\n{self.program_name}: {level}: {msg}\n\n')
|
self._orig_stderr.write(f'\n{self.program_name}: {level}: {msg}\n\n')
|
||||||
|
@ -183,52 +183,11 @@ class TestDownloads:
|
|||||||
# Redirect from `/redirect/1` to `/get`.
|
# Redirect from `/redirect/1` to `/get`.
|
||||||
expected_filename = '1.json'
|
expected_filename = '1.json'
|
||||||
orig_cwd = os.getcwd()
|
orig_cwd = os.getcwd()
|
||||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_test_'))
|
with tempfile.TemporaryDirectory() as tmp_dirname:
|
||||||
try:
|
os.chdir(tmp_dirname)
|
||||||
assert os.listdir('.') == []
|
try:
|
||||||
http('--download', httpbin.url + '/redirect/1')
|
assert os.listdir('.') == []
|
||||||
assert os.listdir('.') == [expected_filename]
|
http('--download', httpbin.url + '/redirect/1')
|
||||||
finally:
|
assert os.listdir('.') == [expected_filename]
|
||||||
os.chdir(orig_cwd)
|
finally:
|
||||||
|
os.chdir(orig_cwd)
|
||||||
def test_download_with_quiet_flag(self, httpbin):
|
|
||||||
robots_txt = '/robots.txt'
|
|
||||||
expected_body = requests.get(httpbin + robots_txt).text
|
|
||||||
expected_filename = 'robots.txt'
|
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
|
||||||
orig_cwd = os.getcwd()
|
|
||||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
|
||||||
try:
|
|
||||||
assert os.listdir('.') == []
|
|
||||||
r = http('--quiet', '--download', httpbin + robots_txt, env=env)
|
|
||||||
assert os.listdir('.') == [expected_filename]
|
|
||||||
assert r.stderr == ''
|
|
||||||
assert env.devnull == env.stderr
|
|
||||||
assert env.devnull == env.stdout
|
|
||||||
with open(expected_filename, 'r') as f:
|
|
||||||
assert f.read() == expected_body
|
|
||||||
finally:
|
|
||||||
os.chdir(orig_cwd)
|
|
||||||
|
|
||||||
def test_download_with_quiet_and_output_flag(self, httpbin):
|
|
||||||
robots_txt = '/robots.txt'
|
|
||||||
expected_body = requests.get(httpbin + robots_txt).text
|
|
||||||
expected_filename = 'test.txt'
|
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
|
||||||
orig_cwd = os.getcwd()
|
|
||||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
|
||||||
try:
|
|
||||||
assert os.listdir('.') == []
|
|
||||||
r = http('--quiet',
|
|
||||||
'--download',
|
|
||||||
'--output=' + expected_filename,
|
|
||||||
httpbin + robots_txt,
|
|
||||||
env=env)
|
|
||||||
assert os.listdir('.') == [expected_filename]
|
|
||||||
assert r.stderr == ''
|
|
||||||
assert env.devnull == env.stderr
|
|
||||||
assert env.devnull == env.stdout
|
|
||||||
with open(expected_filename, 'r') as f:
|
|
||||||
assert f.read() == expected_body
|
|
||||||
finally:
|
|
||||||
os.chdir(orig_cwd)
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import argparse
|
import argparse
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@ -40,69 +42,81 @@ class TestQuietFlag:
|
|||||||
|
|
||||||
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
||||||
def test_quiet(self, httpbin, argument_name):
|
def test_quiet(self, httpbin, argument_name):
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
env = MockEnvironment(
|
||||||
|
stdin_isatty=True,
|
||||||
|
stdout_isatty=True,
|
||||||
|
devnull=io.BytesIO()
|
||||||
|
)
|
||||||
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
||||||
assert env.stdout == env.devnull
|
assert env.stdout is env.devnull
|
||||||
assert env.stderr == env.devnull
|
assert env.stderr is env.devnull
|
||||||
assert r.stderr == ''
|
|
||||||
assert str(r) == ''
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
|
||||||
def test_quiet_correct_message(self, httpbin, argument_name):
|
|
||||||
sim_devnull = io.BytesIO()
|
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
|
||||||
env.devnull = sim_devnull
|
|
||||||
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
|
||||||
assert env.stdout == env.devnull
|
|
||||||
assert env.stderr == env.devnull
|
|
||||||
assert r.stderr == ''
|
|
||||||
assert HTTP_OK in r.devnull
|
assert HTTP_OK in r.devnull
|
||||||
assert str(r) == ''
|
assert r == ''
|
||||||
|
assert r.stderr == ''
|
||||||
|
|
||||||
@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
|
@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
|
||||||
new=lambda self, prompt: 'password')
|
new=lambda self, prompt: 'password')
|
||||||
def test_quiet_password_prompt(self, httpbin):
|
def test_quiet_with_password_prompt(self, httpbin):
|
||||||
""" Tests whether httpie still prompts for password when request
|
"""
|
||||||
requires authetication and only username is provided"""
|
Tests whether httpie still prompts for a password when request
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
requires authentication and only username is provided
|
||||||
env.devnull = io.BytesIO()
|
|
||||||
r = http('--quiet', '--auth', 'user', 'GET', httpbin.url + '/basic-auth/user/password', env=env)
|
"""
|
||||||
|
env = MockEnvironment(
|
||||||
|
stdin_isatty=True,
|
||||||
|
stdout_isatty=True,
|
||||||
|
devnull=io.BytesIO()
|
||||||
|
)
|
||||||
|
r = http(
|
||||||
|
'--quiet', '--auth', 'user', 'GET',
|
||||||
|
httpbin.url + '/basic-auth/user/password',
|
||||||
|
env=env
|
||||||
|
)
|
||||||
|
assert env.stdout is env.devnull
|
||||||
|
assert env.stderr is env.devnull
|
||||||
assert HTTP_OK in r.devnull
|
assert HTTP_OK in r.devnull
|
||||||
assert env.stdout == env.devnull
|
assert r == ''
|
||||||
assert env.stderr == env.devnull
|
|
||||||
assert str(r) == ''
|
|
||||||
assert r.stderr == ''
|
assert r.stderr == ''
|
||||||
|
|
||||||
@pytest.mark.parametrize('argument_name', ['-h', '-b', '-v', '-p=hH'])
|
@pytest.mark.parametrize('argument_name', ['-h', '-b', '-v', '-p=hH'])
|
||||||
def test_quiet_flag_overrides_other_output_options(self, httpbin, argument_name):
|
def test_quiet_with_explicit_output_options(self, httpbin, argument_name):
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||||
r = http('--quiet', argument_name, httpbin.url + '/GET', env=env)
|
r = http('--quiet', argument_name, httpbin.url + '/get', env=env)
|
||||||
assert env.stdout == env.devnull
|
assert env.stdout is env.devnull
|
||||||
assert env.stderr == env.devnull
|
assert env.stderr is env.devnull
|
||||||
assert str(r) == ''
|
assert r == ''
|
||||||
assert r.stderr == ''
|
assert r.stderr == ''
|
||||||
|
|
||||||
def test_quiet_flag_with_output_redirection(self, httpbin):
|
@pytest.mark.parametrize('with_download', [True, False])
|
||||||
robots_txt = '/robots.txt'
|
def test_quiet_with_output_redirection(self, httpbin, with_download):
|
||||||
expected_body = requests.get(httpbin + robots_txt).text
|
url = httpbin + '/robots.txt'
|
||||||
expected_filename = 'test.txt'
|
output_path = Path('output.txt')
|
||||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
env = MockEnvironment()
|
||||||
orig_cwd = os.getcwd()
|
orig_cwd = os.getcwd()
|
||||||
os.chdir(tempfile.mkdtemp(prefix='httpie_download_quiet_test_'))
|
output = requests.get(url).text
|
||||||
try:
|
extra_args = ['--download'] if with_download else []
|
||||||
assert os.listdir('.') == []
|
with tempfile.TemporaryDirectory() as tmp_dirname:
|
||||||
r = http('--quiet',
|
os.chdir(tmp_dirname)
|
||||||
'--output=' + expected_filename,
|
try:
|
||||||
httpbin + robots_txt,
|
assert os.listdir('.') == []
|
||||||
env=env)
|
r = http(
|
||||||
assert os.listdir('.') == [expected_filename]
|
'--quiet',
|
||||||
assert r.stderr == ''
|
'--output', str(output_path),
|
||||||
assert env.devnull == env.stderr
|
*extra_args,
|
||||||
assert env.devnull != env.stdout
|
url,
|
||||||
with open(expected_filename, 'r') as f:
|
env=env
|
||||||
assert f.read() == expected_body
|
)
|
||||||
finally:
|
assert os.listdir('.') == [str(output_path)]
|
||||||
os.chdir(orig_cwd)
|
assert r == ''
|
||||||
|
assert r.stderr == ''
|
||||||
|
assert env.stderr is env.devnull
|
||||||
|
if with_download:
|
||||||
|
assert env.stdout is env.devnull
|
||||||
|
else:
|
||||||
|
assert env.stdout is not env.devnull # --output swaps stdout.
|
||||||
|
assert output_path.read_text() == output
|
||||||
|
finally:
|
||||||
|
os.chdir(orig_cwd)
|
||||||
|
|
||||||
|
|
||||||
class TestVerboseFlag:
|
class TestVerboseFlag:
|
||||||
|
Loading…
Reference in New Issue
Block a user