Ignore redirected stdout with --output, -o

This makes it easier to use HTTPie in cron jobs and scripts.

Closes #259
This commit is contained in:
Jakub Roztocil 2016-03-01 20:24:50 +08:00
parent 4f8d6c013b
commit 01ca7f0eb2
7 changed files with 37 additions and 9 deletions

View File

@ -5,6 +5,7 @@ Change Log
This document records all notable changes to `HTTPie <http://httpie.org>`_. This document records all notable changes to `HTTPie <http://httpie.org>`_.
This project adheres to `Semantic Versioning <http://semver.org/>`_. This project adheres to `Semantic Versioning <http://semver.org/>`_.
`1.0.0-dev`_ (Unreleased) `1.0.0-dev`_ (Unreleased)
------------------------- -------------------------
@ -15,6 +16,8 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
* Added ``-F`` as short name for ``--follow`` * Added ``-F`` as short name for ``--follow``
* Added JSON detection when ``--json, -j`` is used in order to correctly format * Added JSON detection when ``--json, -j`` is used in order to correctly format
JSON responses even when an incorrect ``Content-Type`` is returned. JSON responses even when an incorrect ``Content-Type`` is returned.
* Redirected ``stdout`` doesn't trigger an error anymore when ``--output FILE``
is set.
* Changed the default color style back to ``solarized`` as it supports * Changed the default color style back to ``solarized`` as it supports
both the light and dark terminal background mode both the light and dark terminal background mode
* Fixed ``--session`` when used with ``--download`` * Fixed ``--session`` when used with ``--download``
@ -22,7 +25,7 @@ This project adheres to `Semantic Versioning <http://semver.org/>`_.
`0.9.3`_ (2016-01-01) `0.9.3`_ (2016-01-01)
------------------------- ---------------------
* Changed the default color ``--style`` from ``solarized`` to ``monokai`` * Changed the default color ``--style`` from ``solarized`` to ``monokai``
* Added basic Bash autocomplete support (need to be installed manually) * Added basic Bash autocomplete support (need to be installed manually)

View File

@ -11,7 +11,7 @@ END=" \#\#\# \033[0m\n"
all: test all: test
init: init: uninstall-httpie
@echo $(TAG)Installing dev requirements$(END) @echo $(TAG)Installing dev requirements$(END)
pip install --upgrade -r $(REQUIREMENTS) pip install --upgrade -r $(REQUIREMENTS)

View File

@ -310,8 +310,9 @@ output_options.add_argument(
dest='output_file', dest='output_file',
metavar='FILE', metavar='FILE',
help=""" help="""
Save output to FILE. If --download is set, then only the response body is Save output to FILE instead of stdout. If --download is also set, then only
saved to the file. Other parts of the HTTP exchange are printed to stderr. the response body is saved to FILE. Other parts of the HTTP exchange are
printed to stderr.
""" """

View File

@ -204,4 +204,8 @@ def main(args=sys.argv[1:], env=Environment(), error=None):
if downloader and not downloader.finished: if downloader and not downloader.finished:
downloader.failed() downloader.failed()
if (not isinstance(args, list) and args.output_file and
args.output_file_specified):
args.output_file.close()
return exit_status return exit_status

View File

@ -171,12 +171,10 @@ class HTTPieArgumentParser(ArgumentParser):
Modify `env.stdout` and `env.stdout_isatty` based on args, if needed. Modify `env.stdout` and `env.stdout_isatty` based on args, if needed.
""" """
if not self.env.stdout_isatty and self.args.output_file: self.args.output_file_specified = bool(self.args.output_file)
self.error('Cannot use --output, -o with redirected output.')
if self.args.download: if self.args.download:
# FIXME: Come up with a cleaner solution. # FIXME: Come up with a cleaner solution.
if not self.env.stdout_isatty: if not self.args.output_file and not self.env.stdout_isatty:
# Use stdout as the download output file. # Use stdout as the download output file.
self.args.output_file = self.env.stdout self.args.output_file = self.env.stdout
# With `--download`, we write everything that would normally go to # With `--download`, we write everything that would normally go to

View File

@ -1,10 +1,30 @@
import os
from tempfile import gettempdir
import pytest import pytest
from utils import TestEnvironment, http, HTTP_OK, COLOR, CRLF from utils import TestEnvironment, http, HTTP_OK, COLOR, CRLF
from httpie import ExitStatus from httpie import ExitStatus
from httpie.compat import urlopen
from httpie.output.formatters.colors import get_lexer from httpie.output.formatters.colors import get_lexer
@pytest.mark.parametrize('stdout_isatty', [(True,), (False,)])
def test_output_option(httpbin, stdout_isatty):
output_filename = os.path.join(gettempdir(), test_output_option.__name__)
url = httpbin + '/robots.txt'
r = http('--output', output_filename, url,
env=TestEnvironment(stdout_isatty=stdout_isatty))
assert r == ''
expected_body = urlopen(url).read().decode()
with open(output_filename, 'r') as f:
actual_body = f.read()
assert actual_body == expected_body
class TestVerboseFlag: class TestVerboseFlag:
def test_verbose(self, httpbin): def test_verbose(self, httpbin):
r = http('--verbose', r = http('--verbose',

View File

@ -22,7 +22,9 @@ class TestFakeWindows:
def test_output_file_pretty_not_allowed_on_windows(self, httpbin): def test_output_file_pretty_not_allowed_on_windows(self, httpbin):
env = TestEnvironment(is_windows=True) env = TestEnvironment(is_windows=True)
output_file = os.path.join( output_file = os.path.join(
tempfile.gettempdir(), '__httpie_test_output__') tempfile.gettempdir(),
self.test_output_file_pretty_not_allowed_on_windows.__name__
)
r = http('--output', output_file, r = http('--output', output_file,
'--pretty=all', 'GET', httpbin.url + '/get', '--pretty=all', 'GET', httpbin.url + '/get',
env=env, error_exit_ok=True) env=env, error_exit_ok=True)