forked from extern/httpie-cli
Compare commits
17 Commits
mickael/os
...
2.6.0
Author | SHA1 | Date | |
---|---|---|---|
42af2f786f | |||
a65771e271 | |||
7b683d4b57 | |||
a15fd6f966 | |||
19691bba68 | |||
344491ba8e | |||
9f6fa090df | |||
59f4ef03cc | |||
ef92e2a74a | |||
1171984ec2 | |||
ce9746b1f8 | |||
6b99e1c932 | |||
7d418aecd0 | |||
459cdfcf53 | |||
ab8512f96c | |||
6befaf9067 | |||
1b7f74c2b2 |
7
.github/workflows/docs-update-install.yml
vendored
7
.github/workflows/docs-update-install.yml
vendored
@ -3,6 +3,7 @@ on:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- .github/workflows/docs-update-install.yml
|
||||
- docs/installation/*
|
||||
|
||||
# Allow to call the workflow manually
|
||||
@ -21,6 +22,10 @@ jobs:
|
||||
- uses: Automattic/action-commit-to-branch@master
|
||||
with:
|
||||
branch: master
|
||||
commit_message: Auto-update installation instructions in the docs
|
||||
commit_message: |
|
||||
Auto-update install docs
|
||||
|
||||
Via .github/workflows/docs-update-install.yml
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
22
.github/workflows/release-snap.yml
vendored
Normal file
22
.github/workflows/release-snap.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
branch:
|
||||
description: "The branch, tag or SHA to release from"
|
||||
required: true
|
||||
default: "master"
|
||||
|
||||
jobs:
|
||||
snap:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.branch }}
|
||||
- uses: snapcore/action-build@v1
|
||||
id: build
|
||||
- uses: snapcore/action-publish@v1
|
||||
with:
|
||||
store_login: ${{ secrets.SNAP_STORE_LOGIN }}
|
||||
snap: ${{ steps.build.outputs.snap }}
|
||||
release: edge
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -17,6 +17,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: ${{ github.event.inputs.branch }}
|
||||
- uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: 3.9
|
||||
|
@ -3,14 +3,15 @@
|
||||
This document records all notable changes to [HTTPie](https://httpie.io).
|
||||
This project adheres to [Semantic Versioning](https://semver.org/).
|
||||
|
||||
## [2.6.0.dev0](https://github.com/httpie/httpie/compare/2.5.0...master) (unreleased)
|
||||
## [2.6.0](https://github.com/httpie/httpie/compare/2.5.0...2.6.0) (2021-10-14)
|
||||
|
||||
- Added support for formatting & coloring of JSON bodies preceded by non-JSON data (e.g., an XXSI prefix). ([#1130](https://github.com/httpie/httpie/issues/1130))
|
||||
- Added charset auto-detection when `Content-Type` doesn’t include it. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
|
||||
- Added `--response-charset` to allow overriding the response encoding for terminal display purposes. ([#1168](https://github.com/httpie/httpie/issues/1168))
|
||||
- Added `--response-mime` to allow overriding the response mime type for coloring and formatting for the terminal. ([#1168](https://github.com/httpie/httpie/issues/1168))
|
||||
- Improved handling of responses with incorrect `Content-Type`. ([#1110](https://github.com/httpie/httpie/issues/1110), [#1168](https://github.com/httpie/httpie/issues/1168))
|
||||
- Installed plugins are now listed in `--debug` output. ([#1165](https://github.com/httpie/httpie/issues/1165))
|
||||
- Fixed duplicate keys preservation of JSON data. ([#1163](https://github.com/httpie/httpie/issues/1163))
|
||||
- Added the ability to silence warnings through using `-q` or `--quiet` twice (e.g. `-qq`) ([#1175](https://github.com/httpie/httpie/issues/1175))
|
||||
- Added installed plugin list to `--debug` output. ([#1165](https://github.com/httpie/httpie/issues/1165))
|
||||
- Fixed duplicate keys preservation in JSON data. ([#1163](https://github.com/httpie/httpie/issues/1163))
|
||||
|
||||
## [2.5.0](https://github.com/httpie/httpie/compare/2.4.0...2.5.0) (2021-09-06)
|
||||
|
||||
|
170
docs/README.md
170
docs/README.md
@ -63,13 +63,13 @@ Do not edit here, but in docs/installation/.
|
||||
Please make sure you have Python 3.6 or newer (`python --version`).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ python -m pip install --upgrade pip wheel
|
||||
$ python -m pip install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ python -m pip install --upgrade pip wheel
|
||||
$ python -m pip install --upgrade httpie
|
||||
```
|
||||
@ -78,61 +78,47 @@ $ python -m pip install --upgrade httpie
|
||||
|
||||
#### Homebrew
|
||||
|
||||
To install [Homebrew](https://brew.sh/) follow [installation instructions](https://docs.brew.sh/Installation).
|
||||
To install [Homebrew](https://brew.sh/), see [its installation](https://docs.brew.sh/Installation).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ brew update
|
||||
$ brew install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ brew update
|
||||
$ brew upgrade httpie
|
||||
```
|
||||
|
||||
#### MacPorts
|
||||
|
||||
To install [MacPorts](https://www.macports.org/) follow [installation instructions](https://www.macports.org/install.php).
|
||||
To install [MacPorts](https://www.macports.org/), see [its installation](https://www.macports.org/install.php).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ port selfupdate
|
||||
$ port install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ port selfupdate
|
||||
$ port upgrade httpie
|
||||
```
|
||||
|
||||
#### Snapcraft (macOS)
|
||||
|
||||
To install [Snapcraft](https://snapcraft.io/) follow [installation instructions](https://snapcraft.io/docs/installing-snapd).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
$ snap install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
$ snap refresh httpie
|
||||
```
|
||||
|
||||
#### Spack (macOS)
|
||||
|
||||
To install [Spack](https://spack.readthedocs.io/en/latest/index.html) follow [installation instructions](https://spack.readthedocs.io/en/latest/getting_started.html#installation).
|
||||
To install [Spack](https://spack.readthedocs.io/en/latest/index.html), see [its installation](https://spack.readthedocs.io/en/latest/getting_started.html#installation).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ spack install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ spack install httpie
|
||||
```
|
||||
|
||||
@ -140,15 +126,15 @@ $ spack install httpie
|
||||
|
||||
#### Chocolatey
|
||||
|
||||
To install [Chocolatey](https://chocolatey.org/) follow [installation instructions](https://chocolatey.org/install).
|
||||
To install [Chocolatey](https://chocolatey.org/), see [its installation](https://chocolatey.org/install).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ choco install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ choco upgrade httpie
|
||||
```
|
||||
|
||||
@ -156,30 +142,30 @@ $ choco upgrade httpie
|
||||
|
||||
#### Snapcraft (Linux)
|
||||
|
||||
To install [Snapcraft](https://snapcraft.io/) follow [installation instructions](https://snapcraft.io/docs/installing-snapd).
|
||||
To install [Snapcraft](https://snapcraft.io/), see [its installation](https://snapcraft.io/docs/installing-snapd).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ snap install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ snap refresh httpie
|
||||
```
|
||||
|
||||
#### Linuxbrew
|
||||
|
||||
To install [Linuxbrew](https://docs.brew.sh/Homebrew-on-Linux) follow [installation instructions](https://docs.brew.sh/Homebrew-on-Linux#install).
|
||||
To install [Linuxbrew](https://docs.brew.sh/Homebrew-on-Linux), see [its installation](https://docs.brew.sh/Homebrew-on-Linux#install).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ brew update
|
||||
$ brew install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ brew update
|
||||
$ brew upgrade httpie
|
||||
```
|
||||
@ -189,13 +175,13 @@ $ brew upgrade httpie
|
||||
Also works for other Debian-derived distributions like MX Linux, Linux Mint, deepin, Pop!_OS, KDE neon, Zorin OS, elementary OS, Kubuntu, Devuan, Linux Lite, Peppermint OS, Lubuntu, antiX, Xubuntu, etc.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ apt update
|
||||
$ apt install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ apt update
|
||||
$ apt upgrade httpie
|
||||
```
|
||||
@ -203,13 +189,13 @@ $ apt upgrade httpie
|
||||
#### Fedora
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ dnf update
|
||||
$ dnf install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ dnf update
|
||||
$ dnf upgrade httpie
|
||||
```
|
||||
@ -219,14 +205,14 @@ $ dnf upgrade httpie
|
||||
Also works for other RHEL-derived distributions like ClearOS, Oracle Linux, etc.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ yum update
|
||||
$ yum install epel-release
|
||||
$ yum install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ yum update
|
||||
$ yum upgrade httpie
|
||||
```
|
||||
@ -234,13 +220,13 @@ $ yum upgrade httpie
|
||||
#### Alpine Linux
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ apk update
|
||||
$ apk add httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ apk update
|
||||
$ apk add --upgrade httpie
|
||||
```
|
||||
@ -248,13 +234,13 @@ $ apk add --upgrade httpie
|
||||
#### Gentoo
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ emerge --sync
|
||||
$ emerge httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ emerge --sync
|
||||
$ emerge --update httpie
|
||||
```
|
||||
@ -264,40 +250,40 @@ $ emerge --update httpie
|
||||
Also works for other Arch-derived distributions like ArcoLinux, EndeavourOS, Artix Linux, etc.
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ pacman -Sy httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ pacman -Syu httpie
|
||||
```
|
||||
|
||||
#### Void Linux
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ xbps-install -Su
|
||||
$ xbps-install -S httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ xbps-install -Su
|
||||
$ xbps-install -Su httpie
|
||||
```
|
||||
|
||||
#### Spack (Linux)
|
||||
|
||||
To install [Spack](https://spack.readthedocs.io/en/latest/index.html) follow [installation instructions](https://spack.readthedocs.io/en/latest/getting_started.html#installation).
|
||||
To install [Spack](https://spack.readthedocs.io/en/latest/index.html), see [its installation](https://spack.readthedocs.io/en/latest/getting_started.html#installation).
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ spack install httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ spack install httpie
|
||||
```
|
||||
|
||||
@ -306,12 +292,12 @@ $ spack install httpie
|
||||
#### FreshPorts
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ pkg install www/py-httpie
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ pkg upgrade www/py-httpie
|
||||
```
|
||||
|
||||
@ -348,7 +334,7 @@ Verify that now you have the [current development version identifier](https://gi
|
||||
|
||||
```bash
|
||||
$ http --version
|
||||
# 2.6.0.dev0
|
||||
# 2.6.0
|
||||
```
|
||||
|
||||
## Usage
|
||||
@ -1247,6 +1233,13 @@ This doesn’t affect output to a file via `--output` or `--download`.
|
||||
It takes the same arguments as `--print, -p` but applies to the intermediary requests only.
|
||||
|
||||
```bash
|
||||
# Print the intermediary requests/responses differently than the final one:
|
||||
$ http -A digest -a foo:bar --all -p Hh -P H pie.dev/digest-auth/auth/foo/bar
|
||||
```
|
||||
|
||||
### Conditional body download
|
||||
|
||||
As an optimization, the response body is downloaded from the server only if it’s part of the output.
|
||||
This is similar to performing a `HEAD` request, except that it applies to any HTTP method you use.
|
||||
|
||||
Let’s say that there is an API that returns the whole resource when it is updated, but you are only interested in the response headers to see the status code after an update:
|
||||
@ -1297,7 +1290,8 @@ The universal method for passing request data is through redirected `stdin`
|
||||
$ echo -n '{"name": "John"}' | http PATCH pie.dev/patch X-API-Token:123
|
||||
```
|
||||
|
||||
|
||||
You can also use a Bash *here string*:
|
||||
|
||||
```bash
|
||||
$ http pie.dev/post <<<'{"name": "John"}'
|
||||
```
|
||||
@ -1407,16 +1401,32 @@ $ http --chunked pie.dev/post @files/data.xml
|
||||
HTTPie does several things by default in order to make its terminal output easy to read.
|
||||
|
||||
### Colors and formatting
|
||||
|
||||
Syntax highlighting is applied to HTTP headers and bodies (where it makes sense).
|
||||
You can choose your preferred color scheme via the --style option if you don’t like the default one.
|
||||
There are dozens of styles available, here are just a few notable ones:
|
||||
|
||||
| Style | Description |
|
||||
| --------: | ----------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `auto` | Follows your terminal ANSI color styles. This is the default style used by HTTPie |
|
||||
| `default` | Default styles of the underlying Pygments library. Not actually used by default by HTTPie. You can enable it with `--style=default` |
|
||||
| `monokai` | A popular color scheme. Enable with `--style=monokai` |
|
||||
| `fruity` | A bold, colorful scheme. Enable with `--style=fruity` |
|
||||
| … | See `$ http --help` for all the possible `--style` values |
|
||||
|
||||
Use one of these options to control output processing:
|
||||
|
||||
| Option | Description |
|
||||
| ----------------: | ------------------------------------------------------------- |
|
||||
| `--pretty=all` | Apply both colors and formatting. Default for terminal output |
|
||||
| `--pretty=colors` | Apply colors |
|
||||
| `--pretty=format` | Apply formatting |
|
||||
| `--pretty=none` | Disables output processing. Default for redirected output |
|
||||
|
||||
HTTPie looks at `Content-Type` to select the right syntax highlighter and formatter for each message body. If that fails (e.g., the server provides the wrong type), or you prefer a different treatment, you can manually overwrite the mime type for a response with `--response-mime`:
|
||||
|
||||
Formatting has the following effects:
|
||||
|
||||
```bash
|
||||
- JSON data is indented, sorted by keys, and unicode escapes are converted
|
||||
$ http --response-mime=text/yaml pie.dev/get
|
||||
```
|
||||
|
||||
Formatting has the following effects:
|
||||
@ -1436,6 +1446,12 @@ Use one of these options to control output processing:
|
||||
| Option | Default value | Shortcuts |
|
||||
| ---------------: | :-----------: | ------------------------ |
|
||||
| `headers.sort` | `true` | `--sorted`, `--unsorted` |
|
||||
| `json.format` | `true` | N/A |
|
||||
| `json.indent` | `4` | N/A |
|
||||
| `json.sort_keys` | `true` | `--sorted`, `--unsorted` |
|
||||
| `xml.format` | `true` | N/A |
|
||||
| `xml.indent` | `2` | N/A |
|
||||
|
||||
For example, this is how you would disable the default header and JSON key
|
||||
sorting, and specify a custom JSON indent size:
|
||||
|
||||
@ -1472,29 +1488,6 @@ sorting-related format options (currently it means JSON keys and headers):
|
||||
```bash
|
||||
$ http octodex.github.com/images/original.jpg | convert - -resize 25% - | http example.org/Octocats
|
||||
```
|
||||
### Redirected output
|
||||
|
||||
HTTPie uses a different set of defaults for redirected output than for [terminal output](#terminal-output).
|
||||
The differences being:
|
||||
|
||||
- Formatting and colors aren’t applied (unless `--pretty` is specified).
|
||||
- Only the response body is printed (unless one of the [output options](#output-options) is set).
|
||||
- Also, binary data isn’t suppressed.
|
||||
|
||||
The reason is to make piping HTTPie’s output to another programs and downloading files work with no extra flags.
|
||||
Most of the time, only the raw response body is of an interest when the output is redirected.
|
||||
|
||||
Download a file:
|
||||
|
||||
```bash
|
||||
$ http pie.dev/image/png > image.png
|
||||
```
|
||||
|
||||
Download an image of an [Octocat](https://octodex.github.com/images/original.jpg), resize it using [ImageMagick](https://imagemagick.org/), and upload it elsewhere:
|
||||
|
||||
```bash
|
||||
$ http octodex.github.com/images/original.jpg | convert - -resize 25% - | http example.org/Octocats
|
||||
```
|
||||
|
||||
Force colorizing and formatting, and show both the request and the response in `less` pager:
|
||||
|
||||
@ -1557,20 +1550,13 @@ Content-Type: application/octet-stream
|
||||
|
||||
Downloading 251.30 kB to "httpie-master.tar.gz"
|
||||
Done. 251.30 kB in 2.73862s (91.76 kB/s)
|
||||
HTTP/1.1 200 OK
|
||||
```
|
||||
|
||||
Content-Type: application/x-gzip
|
||||
|
||||
### Downloaded filename
|
||||
|
||||
Done. 251.30 kB in 2.73862s (91.76 kB/s)
|
||||
```
|
||||
|
||||
### Downloaded filename
|
||||
|
||||
There are three mutually exclusive ways through which HTTPie determines
|
||||
the output filename (with decreasing priority):
|
||||
|
||||
There are three mutually exclusive ways through which HTTPie determines
|
||||
the output filename (with decreasing priority):
|
||||
|
||||
1. You can explicitly provide it via `--output, -o`. The file gets overwritten if it already exists (or appended to with `--continue, -c`).
|
||||
2. The server may specify the filename in the optional `Content-Disposition` response header. Any leading dots are stripped from a server-provided filename.
|
||||
3. The last resort HTTPie uses is to generate the filename from a combination of the request URL and the response `Content-Type`. The initial URL is always used as the basis for the generated filename — even if there has been one or more redirects.
|
||||
|
3
docs/contributors/README.md
Normal file
3
docs/contributors/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
Here we maintain a database of contributors, from which we generate credits on release blog posts and social medias.
|
||||
|
||||
For the HTTPie blog see: <https://httpie.io/blog>.
|
280
docs/contributors/fetch.py
Normal file
280
docs/contributors/fetch.py
Normal file
@ -0,0 +1,280 @@
|
||||
"""
|
||||
Generate the contributors database.
|
||||
|
||||
FIXME: replace `requests` calls with the HTTPie API, when available.
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from copy import deepcopy
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from subprocess import check_output
|
||||
from time import sleep
|
||||
from typing import Any, Dict, Optional, Set
|
||||
|
||||
import requests
|
||||
|
||||
FullNames = Set[str]
|
||||
GitHubLogins = Set[str]
|
||||
Person = Dict[str, str]
|
||||
People = Dict[str, Person]
|
||||
UserInfo = Dict[str, Any]
|
||||
|
||||
CO_AUTHORS = re.compile(r'Co-authored-by: ([^<]+) <').finditer
|
||||
API_URL = 'https://api.github.com'
|
||||
REPO = OWNER = 'httpie'
|
||||
REPO_URL = f'{API_URL}/repos/{REPO}/{OWNER}'
|
||||
|
||||
HERE = Path(__file__).parent
|
||||
DB_FILE = HERE / 'people.json'
|
||||
|
||||
DEFAULT_PERSON: Person = {'committed': [], 'reported': [], 'github': '', 'twitter': ''}
|
||||
SKIPPED_LABELS = {'invalid'}
|
||||
|
||||
GITHUB_TOKEN = os.getenv('GITHUB_TOKEN')
|
||||
assert GITHUB_TOKEN, 'GITHUB_TOKEN envar is missing'
|
||||
|
||||
|
||||
class FinishedForNow(Exception):
|
||||
"""Raised when remaining GitHub rate limit is zero."""
|
||||
|
||||
|
||||
def main(previous_release: str, current_release: str) -> int:
|
||||
since = release_date(previous_release)
|
||||
until = release_date(current_release)
|
||||
|
||||
contributors = load_awesome_people()
|
||||
try:
|
||||
committers = find_committers(since, until)
|
||||
reporters = find_reporters(since, until)
|
||||
except Exception as exc:
|
||||
# We want to save what we fetched so far. So pass.
|
||||
print(' !! ', exc)
|
||||
|
||||
try:
|
||||
merge_all_the_people(current_release, contributors, committers, reporters)
|
||||
fetch_missing_users_details(contributors)
|
||||
except FinishedForNow:
|
||||
# We want to save what we fetched so far. So pass.
|
||||
print(' !! Committers:', committers)
|
||||
print(' !! Reporters:', reporters)
|
||||
exit_status = 1
|
||||
else:
|
||||
exit_status = 0
|
||||
|
||||
save_awesome_people(contributors)
|
||||
return exit_status
|
||||
|
||||
|
||||
def find_committers(since: str, until: str) -> FullNames:
|
||||
url = f'{REPO_URL}/commits'
|
||||
page = 1
|
||||
per_page = 100
|
||||
params = {
|
||||
'since': since,
|
||||
'until': until,
|
||||
'per_page': per_page,
|
||||
}
|
||||
committers: FullNames = set()
|
||||
|
||||
while 'there are commits':
|
||||
params['page'] = page
|
||||
data = fetch(url, params=params)
|
||||
|
||||
for item in data:
|
||||
commit = item['commit']
|
||||
committers.add(commit['author']['name'])
|
||||
debug(' >>> Commit', item['html_url'])
|
||||
for co_author in CO_AUTHORS(commit['message']):
|
||||
name = co_author.group(1)
|
||||
committers.add(name)
|
||||
|
||||
if len(data) < per_page:
|
||||
break
|
||||
page += 1
|
||||
|
||||
return committers
|
||||
|
||||
|
||||
def find_reporters(since: str, until: str) -> GitHubLogins:
|
||||
url = f'{API_URL}/search/issues'
|
||||
page = 1
|
||||
per_page = 100
|
||||
params = {
|
||||
'q': f'repo:{REPO}/{OWNER} is:issue closed:{since}..{until}',
|
||||
'per_page': per_page,
|
||||
}
|
||||
reporters: GitHubLogins = set()
|
||||
|
||||
while 'there are issues':
|
||||
params['page'] = page
|
||||
data = fetch(url, params=params)
|
||||
|
||||
for item in data['items']:
|
||||
# Filter out unwanted labels.
|
||||
if any(label['name'] in SKIPPED_LABELS for label in item['labels']):
|
||||
continue
|
||||
debug(' >>> Issue', item['html_url'])
|
||||
reporters.add(item['user']['login'])
|
||||
|
||||
if len(data['items']) < per_page:
|
||||
break
|
||||
page += 1
|
||||
|
||||
return reporters
|
||||
|
||||
|
||||
def merge_all_the_people(release: str, contributors: People, committers: FullNames, reporters: GitHubLogins) -> None:
|
||||
"""
|
||||
>>> contributors = {'Alice': new_person(github='alice', twitter='alice')}
|
||||
>>> merge_all_the_people('2.6.0', contributors, {}, {})
|
||||
>>> contributors
|
||||
{'Alice': {'committed': [], 'reported': [], 'github': 'alice', 'twitter': 'alice'}}
|
||||
|
||||
>>> contributors = {'Bob': new_person(github='bob', twitter='bob')}
|
||||
>>> merge_all_the_people('2.6.0', contributors, {'Bob'}, {'bob'})
|
||||
>>> contributors
|
||||
{'Bob': {'committed': ['2.6.0'], 'reported': ['2.6.0'], 'github': 'bob', 'twitter': 'bob'}}
|
||||
|
||||
>>> contributors = {'Charlotte': new_person(github='charlotte', twitter='charlotte', committed=['2.5.0'], reported=['2.5.0'])}
|
||||
>>> merge_all_the_people('2.6.0', contributors, {'Charlotte'}, {'charlotte'})
|
||||
>>> contributors
|
||||
{'Charlotte': {'committed': ['2.5.0', '2.6.0'], 'reported': ['2.5.0', '2.6.0'], 'github': 'charlotte', 'twitter': 'charlotte'}}
|
||||
|
||||
"""
|
||||
# Update known contributors.
|
||||
for name, details in contributors.items():
|
||||
if name in committers:
|
||||
if release not in details['committed']:
|
||||
details['committed'].append(release)
|
||||
committers.remove(name)
|
||||
if details['github'] in reporters:
|
||||
if release not in details['reported']:
|
||||
details['reported'].append(release)
|
||||
reporters.remove(details['github'])
|
||||
|
||||
# Add new committers.
|
||||
for name in committers:
|
||||
user_info = user(fullname=name)
|
||||
contributors[name] = new_person(
|
||||
github=user_info['login'],
|
||||
twitter=user_info['twitter_username'],
|
||||
committed=[release],
|
||||
)
|
||||
if user_info['login'] in reporters:
|
||||
contributors[name]['reported'].append(release)
|
||||
reporters.remove(user_info['login'])
|
||||
|
||||
# Add new reporters.
|
||||
for github_username in reporters:
|
||||
user_info = user(github_username=github_username)
|
||||
contributors[user_info['name'] or user_info['login']] = new_person(
|
||||
github=github_username,
|
||||
twitter=user_info['twitter_username'],
|
||||
reported=[release],
|
||||
)
|
||||
|
||||
|
||||
def release_date(release: str) -> str:
|
||||
date = check_output(['git', 'log', '-1', '--format=%ai', release], text=True).strip()
|
||||
return datetime.strptime(date, '%Y-%m-%d %H:%M:%S %z').isoformat()
|
||||
|
||||
|
||||
def load_awesome_people() -> People:
|
||||
try:
|
||||
with DB_FILE.open(encoding='utf-8') as fh:
|
||||
return json.load(fh)
|
||||
except (FileNotFoundError, ValueError):
|
||||
return {}
|
||||
|
||||
|
||||
def fetch(url: str, params: Optional[Dict[str, str]] = None) -> UserInfo:
|
||||
headers = {
|
||||
'Accept': 'application/vnd.github.v3+json',
|
||||
'Authentication': f'token {GITHUB_TOKEN}'
|
||||
}
|
||||
for retry in range(1, 6):
|
||||
debug(f'[{retry}/5]', f'{url = }', f'{params = }')
|
||||
with requests.get(url, params=params, headers=headers) as req:
|
||||
try:
|
||||
req.raise_for_status()
|
||||
except requests.exceptions.HTTPError as exc:
|
||||
if exc.response.status_code == 403:
|
||||
# 403 Client Error: rate limit exceeded for url: ...
|
||||
now = int(datetime.utcnow().timestamp())
|
||||
xrate_limit_reset = int(exc.response.headers['X-RateLimit-Reset'])
|
||||
wait = xrate_limit_reset - now
|
||||
if wait > 20:
|
||||
raise FinishedForNow()
|
||||
debug(' !', 'Waiting', wait, 'seconds before another try ...')
|
||||
sleep(wait)
|
||||
continue
|
||||
return req.json()
|
||||
assert ValueError('Rate limit exceeded')
|
||||
|
||||
|
||||
def new_person(**kwargs: str) -> Person:
|
||||
data = deepcopy(DEFAULT_PERSON)
|
||||
data.update(**kwargs)
|
||||
return data
|
||||
|
||||
|
||||
def user(fullname: Optional[str] = '', github_username: Optional[str] = '') -> UserInfo:
|
||||
if github_username:
|
||||
url = f'{API_URL}/users/{github_username}'
|
||||
return fetch(url)
|
||||
|
||||
url = f'{API_URL}/search/users'
|
||||
for query in (f'fullname:{fullname}', f'user:{fullname}'):
|
||||
params = {
|
||||
'q': f'repo:{REPO}/{OWNER} {query}',
|
||||
'per_page': 1,
|
||||
}
|
||||
user_info = fetch(url, params=params)
|
||||
if user_info['items']:
|
||||
user_url = user_info['items'][0]['url']
|
||||
return fetch(user_url)
|
||||
|
||||
|
||||
def fetch_missing_users_details(people: People) -> None:
|
||||
for name, details in people.items():
|
||||
if details['github'] and details['twitter']:
|
||||
continue
|
||||
user_info = user(github_username=details['github'], fullname=name)
|
||||
if not details['github']:
|
||||
details['github'] = user_info['login']
|
||||
if not details['twitter']:
|
||||
details['twitter'] = user_info['twitter_username']
|
||||
|
||||
|
||||
def save_awesome_people(people: People) -> None:
|
||||
with DB_FILE.open(mode='w', encoding='utf-8') as fh:
|
||||
json.dump(people, fh, indent=4, sort_keys=True)
|
||||
|
||||
|
||||
def debug(*args: Any) -> None:
|
||||
if os.getenv('DEBUG') == '1':
|
||||
print(*args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = 1
|
||||
try:
|
||||
ret = main(*sys.argv[1:])
|
||||
except TypeError:
|
||||
ret = 2
|
||||
print(f'''
|
||||
Fetch contributors to a release.
|
||||
|
||||
Usage:
|
||||
python {sys.argv[0]} {sys.argv[0]} <RELEASE N-1> <RELEASE N>
|
||||
Example:
|
||||
python {sys.argv[0]} 2.4.0 2.5.0
|
||||
|
||||
Define the DEBUG=1 environment variable to enable verbose output.
|
||||
''')
|
||||
except KeyboardInterrupt:
|
||||
ret = 255
|
||||
sys.exit(ret)
|
41
docs/contributors/generate.py
Normal file
41
docs/contributors/generate.py
Normal file
@ -0,0 +1,41 @@
|
||||
"""
|
||||
Generate snippets to copy-paste.
|
||||
"""
|
||||
import sys
|
||||
|
||||
from jinja2 import Template
|
||||
|
||||
from fetch import HERE, load_awesome_people
|
||||
|
||||
TPL_FILE = HERE / 'snippet.jinja2'
|
||||
HTTPIE_TEAM = {'jakubroztocil', 'BoboTiG', 'claudiatd'}
|
||||
|
||||
|
||||
def generate_snippets(release: str) -> str:
|
||||
people = load_awesome_people()
|
||||
contributors = {
|
||||
name: details
|
||||
for name, details in people.items()
|
||||
if details['github'] not in HTTPIE_TEAM
|
||||
and (release in details['committed'] or release in details['reported'])
|
||||
}
|
||||
|
||||
template = Template(source=TPL_FILE.read_text(encoding='utf-8'))
|
||||
output = template.render(contributors=contributors, release=release)
|
||||
print(output)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ret = 1
|
||||
try:
|
||||
ret = generate_snippets(sys.argv[1])
|
||||
except (IndexError, TypeError):
|
||||
ret = 2
|
||||
print(f'''
|
||||
Generate snippets for contributors to a release.
|
||||
|
||||
Usage:
|
||||
python {sys.argv[0]} {sys.argv[0]} <RELEASE>
|
||||
''')
|
||||
sys.exit(ret)
|
240
docs/contributors/people.json
Normal file
240
docs/contributors/people.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"Almad": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "Almad",
|
||||
"reported": [],
|
||||
"twitter": "almadcz"
|
||||
},
|
||||
"Anton Emelyanov": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "king-menin",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"D8ger": {
|
||||
"committed": [],
|
||||
"github": "caofanCPU",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Dawid Ferenczy Rogo\u017ean": {
|
||||
"committed": [],
|
||||
"github": "ferenczy",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": "DawidFerenczy"
|
||||
},
|
||||
"Elena Lape": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "elenalape",
|
||||
"reported": [],
|
||||
"twitter": "elena_lape"
|
||||
},
|
||||
"F\u00fash\u0113ng": {
|
||||
"committed": [],
|
||||
"github": "lienide",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Giampaolo Rodola": {
|
||||
"committed": [],
|
||||
"github": "giampaolo",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Hugh Williams": {
|
||||
"committed": [],
|
||||
"github": "hughpv",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Ilya Sukhanov": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "IlyaSukhanov",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Jakub Roztocil": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "jakubroztocil",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": "jakubroztocil"
|
||||
},
|
||||
"Jan Verbeek": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "blyxxyz",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"Jannik Vieten": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "exploide",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"Marcel St\u00f6r": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "marcelstoer",
|
||||
"reported": [],
|
||||
"twitter": "frightanic"
|
||||
},
|
||||
"Mariano Ruiz": {
|
||||
"committed": [],
|
||||
"github": "mrsarm",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": "mrsarm82"
|
||||
},
|
||||
"Micka\u00ebl Schoentgen": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "BoboTiG",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": "__tiger222__"
|
||||
},
|
||||
"Miro Hron\u010dok": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "hroncok",
|
||||
"reported": [],
|
||||
"twitter": "hroncok"
|
||||
},
|
||||
"Mohamed Daahir": {
|
||||
"committed": [],
|
||||
"github": "ducaale",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Pavel Alexeev aka Pahan-Hubbitus": {
|
||||
"committed": [],
|
||||
"github": "Hubbitus",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Samuel Marks": {
|
||||
"committed": [],
|
||||
"github": "SamuelMarks",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Sullivan SENECHAL": {
|
||||
"committed": [],
|
||||
"github": "soullivaneuh",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Thomas Klinger": {
|
||||
"committed": [],
|
||||
"github": "mosesontheweb",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"Yannic Schneider": {
|
||||
"committed": [],
|
||||
"github": "cynay",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"a1346054": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "a1346054",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"bl-ue": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "FiReBlUe45",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"henryhu712": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "henryhu712",
|
||||
"reported": [],
|
||||
"twitter": null
|
||||
},
|
||||
"jungle-boogie": {
|
||||
"committed": [],
|
||||
"github": "jungle-boogie",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"nixbytes": {
|
||||
"committed": [
|
||||
"2.5.0"
|
||||
],
|
||||
"github": "nixbytes",
|
||||
"reported": [],
|
||||
"twitter": "linuxbyte3"
|
||||
},
|
||||
"qiulang": {
|
||||
"committed": [],
|
||||
"github": "qiulang",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
},
|
||||
"zwx00": {
|
||||
"committed": [],
|
||||
"github": "zwx00",
|
||||
"reported": [
|
||||
"2.5.0"
|
||||
],
|
||||
"twitter": null
|
||||
}
|
||||
}
|
13
docs/contributors/snippet.jinja2
Normal file
13
docs/contributors/snippet.jinja2
Normal file
@ -0,0 +1,13 @@
|
||||
<!-- Blog post -->
|
||||
|
||||
## Community contributions
|
||||
|
||||
We’d like to thank these amazing people for their contributions to this release: {% for name, details in contributors.items() -%}
|
||||
[{{ name }}](https://github.com/{{ details.github }}){{ '' if loop.last else ', ' }}
|
||||
{%- endfor %}.
|
||||
|
||||
<!-- Twitter -->
|
||||
|
||||
We’d like to thank these amazing people for their contributions to HTTPie {{ release }}: {% for name, details in contributors.items() if details.twitter -%}
|
||||
@{{ details.twitter }}{{ '' if loop.last else ', ' }}
|
||||
{%- endfor %} 🥧
|
@ -19,16 +19,16 @@ Do not edit here, but in docs/installation/.
|
||||
{% endif %}
|
||||
|
||||
{% if tool.links.setup %}
|
||||
To install [{{ tool.name }}]({{ tool.links.homepage }}) follow [installation instructions]({{ tool.links.setup }}).
|
||||
To install [{{ tool.name }}]({{ tool.links.homepage }}), see [its installation]({{ tool.links.setup }}).
|
||||
{% endif %}
|
||||
|
||||
```bash
|
||||
# Install
|
||||
# Install httpie
|
||||
$ {{ tool.commands.install|join('\n$ ') }}
|
||||
```
|
||||
|
||||
```bash
|
||||
# Upgrade
|
||||
# Upgrade httpie
|
||||
$ {{ tool.commands.upgrade|join('\n$ ') }}
|
||||
```
|
||||
{% endfor %}
|
||||
|
@ -14,7 +14,6 @@ docs-structure:
|
||||
macOS:
|
||||
- brew-mac
|
||||
- port
|
||||
- snap-mac
|
||||
- spack-mac
|
||||
Windows:
|
||||
- chocolatey
|
||||
@ -202,19 +201,6 @@ tools:
|
||||
upgrade:
|
||||
- snap refresh httpie
|
||||
|
||||
snap-mac:
|
||||
title: Snapcraft (macOS)
|
||||
name: Snapcraft
|
||||
links:
|
||||
homepage: https://snapcraft.io/
|
||||
setup: https://snapcraft.io/docs/installing-snapd
|
||||
package: https://snapcraft.io/httpie
|
||||
commands:
|
||||
install:
|
||||
- snap install httpie
|
||||
upgrade:
|
||||
- snap refresh httpie
|
||||
|
||||
spack-linux:
|
||||
title: Spack (Linux)
|
||||
name: Spack
|
||||
|
@ -23,7 +23,8 @@ That is done quite easily by manually triggering the [release workflow](https://
|
||||
|
||||
## Then, company-specific tasks
|
||||
|
||||
- Update the HTTPie version bundled into termible ([example](https://github.com/httpie/termible/pull/1)).
|
||||
- Blank the `master_and_released_docs_differ_after` value in [config.json](https://github.com/httpie/httpie/blob/master/docs/config.json).
|
||||
- Update the HTTPie version bundled into [Termible](https://termible.io/) ([example](https://github.com/httpie/termible/pull/1)).
|
||||
|
||||
## Finally, spread dowstream
|
||||
|
||||
|
@ -1,6 +1,2 @@
|
||||
$ErrorActionPreference = 'Stop';
|
||||
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
|
||||
$nuspecPath = "$(Join-Path (Split-Path -parent $toolsDir) ($env:ChocolateyPackageName + ".nuspec"))"
|
||||
[XML]$nuspec = Get-Content $nuspecPath
|
||||
$pipVersion = $nuspec.package.metadata.version
|
||||
py -m pip install "$($env:ChocolateyPackageName)==$($pipVersion)" --disable-pip-version-check
|
||||
py -m pip install $env:ChocolateyPackageName==$env:ChocolateyPackageVersion --disable-pip-version-check
|
||||
|
@ -3,6 +3,6 @@ HTTPie: command-line HTTP client for the API era.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '2.6.0.dev0'
|
||||
__version__ = '2.6.0'
|
||||
__author__ = 'Jakub Roztocil'
|
||||
__licence__ = 'BSD'
|
||||
|
@ -497,12 +497,14 @@ output_options.add_argument(
|
||||
|
||||
output_options.add_argument(
|
||||
'--quiet', '-q',
|
||||
action='store_true',
|
||||
default=False,
|
||||
action='count',
|
||||
default=0,
|
||||
help='''
|
||||
Do not print to stdout or stderr.
|
||||
Do not print to stdout or stderr, except for errors and warnings when provided once.
|
||||
Provide twice to suppress warnings as well.
|
||||
stdout is still redirected if --output is specified.
|
||||
Flag doesn't affect behaviour of download beyond not printing to terminal.
|
||||
|
||||
'''
|
||||
)
|
||||
|
||||
|
@ -185,7 +185,7 @@ def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
|
||||
final_response = message
|
||||
if args.check_status or downloader:
|
||||
exit_status = http_status_to_exit_status(http_status=message.status_code, follow=args.follow)
|
||||
if exit_status != ExitStatus.SUCCESS and (not env.stdout_isatty or args.quiet):
|
||||
if exit_status != ExitStatus.SUCCESS and (not env.stdout_isatty or args.quiet == 1):
|
||||
env.log_error(f'HTTP {message.raw.status} {message.raw.reason}', level='warning')
|
||||
write_message(requests_message=message, env=env, args=args, with_headers=with_headers,
|
||||
with_body=do_write_body)
|
||||
|
@ -20,7 +20,7 @@ class EnhancedJsonLexer(RegexLexer):
|
||||
tokens = {
|
||||
'root': [
|
||||
# Eventual non-JSON data prefix followed by actual JSON body.
|
||||
# FIX: data prefix + number (integer or float) are not correctly handled.
|
||||
# FIX: data prefix + number (integer or float) is not correctly handled.
|
||||
(
|
||||
fr'({PREFIX_REGEX})' + r'((?:[{\["]|true|false|null).+)',
|
||||
bygroups(PREFIX_TOKEN, using(JsonLexer))
|
||||
|
@ -39,15 +39,16 @@ def test_output_option(tmp_path, httpbin, stdout_isatty):
|
||||
|
||||
|
||||
class TestQuietFlag:
|
||||
QUIET_SCENARIOS = [('--quiet',), ('-q',), ('--quiet', '--quiet'), ('-qq',)]
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ['--quiet', '-q'])
|
||||
def test_quiet(self, httpbin, argument_name):
|
||||
@pytest.mark.parametrize('quiet_flags', QUIET_SCENARIOS)
|
||||
def test_quiet(self, httpbin, quiet_flags):
|
||||
env = MockEnvironment(
|
||||
stdin_isatty=True,
|
||||
stdout_isatty=True,
|
||||
devnull=io.BytesIO()
|
||||
)
|
||||
r = http(argument_name, 'GET', httpbin.url + '/get', env=env)
|
||||
r = http(*quiet_flags, 'GET', httpbin.url + '/get', env=env)
|
||||
assert env.stdout is env.devnull
|
||||
assert env.stderr is env.devnull
|
||||
assert HTTP_OK in r.devnull
|
||||
@ -69,9 +70,25 @@ class TestQuietFlag:
|
||||
)
|
||||
assert 'http: warning: HTTP 500' in r.stderr
|
||||
|
||||
def test_quiet_quiet_with_check_status_non_zero(self, httpbin):
|
||||
r = http(
|
||||
'--quiet', '--quiet', '--check-status', httpbin + '/status/500',
|
||||
tolerate_error_exit_status=True,
|
||||
)
|
||||
assert not r.stderr
|
||||
|
||||
def test_quiet_quiet_with_check_status_non_zero_pipe(self, httpbin):
|
||||
r = http(
|
||||
'--quiet', '--quiet', '--check-status', httpbin + '/status/500',
|
||||
tolerate_error_exit_status=True,
|
||||
env=MockEnvironment(stdout_isatty=False)
|
||||
)
|
||||
assert 'http: warning: HTTP 500' in r.stderr
|
||||
|
||||
@pytest.mark.parametrize('quiet_flags', QUIET_SCENARIOS)
|
||||
@mock.patch('httpie.cli.argtypes.AuthCredentials._getpass',
|
||||
new=lambda self, prompt: 'password')
|
||||
def test_quiet_with_password_prompt(self, httpbin):
|
||||
def test_quiet_with_password_prompt(self, httpbin, quiet_flags):
|
||||
"""
|
||||
Tests whether httpie still prompts for a password when request
|
||||
requires authentication and only username is provided
|
||||
@ -83,7 +100,7 @@ class TestQuietFlag:
|
||||
devnull=io.BytesIO()
|
||||
)
|
||||
r = http(
|
||||
'--quiet', '--auth', 'user', 'GET',
|
||||
*quiet_flags, '--auth', 'user', 'GET',
|
||||
httpbin.url + '/basic-auth/user/password',
|
||||
env=env
|
||||
)
|
||||
@ -93,17 +110,19 @@ class TestQuietFlag:
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
|
||||
@pytest.mark.parametrize('argument_name', ['-h', '-b', '-v', '-p=hH'])
|
||||
def test_quiet_with_explicit_output_options(self, httpbin, argument_name):
|
||||
@pytest.mark.parametrize('quiet_flags', QUIET_SCENARIOS)
|
||||
@pytest.mark.parametrize('output_options', ['-h', '-b', '-v', '-p=hH'])
|
||||
def test_quiet_with_explicit_output_options(self, httpbin, quiet_flags, output_options):
|
||||
env = MockEnvironment(stdin_isatty=True, stdout_isatty=True)
|
||||
r = http('--quiet', argument_name, httpbin.url + '/get', env=env)
|
||||
r = http(*quiet_flags, output_options, httpbin.url + '/get', env=env)
|
||||
assert env.stdout is env.devnull
|
||||
assert env.stderr is env.devnull
|
||||
assert r == ''
|
||||
assert r.stderr == ''
|
||||
|
||||
@pytest.mark.parametrize('quiet_flags', QUIET_SCENARIOS)
|
||||
@pytest.mark.parametrize('with_download', [True, False])
|
||||
def test_quiet_with_output_redirection(self, tmp_path, httpbin, with_download):
|
||||
def test_quiet_with_output_redirection(self, tmp_path, httpbin, quiet_flags, with_download):
|
||||
url = httpbin + '/robots.txt'
|
||||
output_path = Path('output.txt')
|
||||
env = MockEnvironment()
|
||||
@ -114,7 +133,7 @@ class TestQuietFlag:
|
||||
try:
|
||||
assert os.listdir('.') == []
|
||||
r = http(
|
||||
'--quiet',
|
||||
*quiet_flags,
|
||||
'--output', str(output_path),
|
||||
*extra_args,
|
||||
url,
|
||||
@ -142,7 +161,7 @@ class TestVerboseFlag:
|
||||
|
||||
def test_verbose_raw(self, httpbin):
|
||||
r = http('--verbose', '--raw', 'foo bar',
|
||||
'POST', httpbin.url + '/post',)
|
||||
'POST', httpbin.url + '/post')
|
||||
assert HTTP_OK in r
|
||||
assert 'foo bar' in r
|
||||
|
||||
|
Reference in New Issue
Block a user