forked from extern/httpie-cli
Compare commits
8 Commits
isidentica
...
fix-initia
Author | SHA1 | Date | |
---|---|---|---|
9d2e2afede | |||
418b12bbd6 | |||
ecff53f2d5 | |||
41da87f7c8 | |||
4f172a61b4 | |||
542a2d35de | |||
d9e1dc08c9 | |||
3b734fb0bc |
@ -59,8 +59,10 @@ $ git checkout -b my_topical_branch
|
|||||||
|
|
||||||
#### Setup
|
#### Setup
|
||||||
|
|
||||||
The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started. Just run
|
The [Makefile](https://github.com/httpie/httpie/blob/master/Makefile) contains a bunch of tasks to get you started.
|
||||||
the following command, which:
|
You can run `$ make` to see all the available tasks.
|
||||||
|
|
||||||
|
To get started, run the command below, which:
|
||||||
|
|
||||||
- Creates an isolated Python virtual environment inside `./venv`
|
- Creates an isolated Python virtual environment inside `./venv`
|
||||||
(via the standard library [venv](https://docs.python.org/3/library/venv.html) tool);
|
(via the standard library [venv](https://docs.python.org/3/library/venv.html) tool);
|
||||||
@ -70,7 +72,7 @@ the following command, which:
|
|||||||
- and runs tests (It is the same as running `make install test`).
|
- and runs tests (It is the same as running `make install test`).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ make
|
$ make all
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Python virtual environment
|
#### Python virtual environment
|
||||||
|
22
Makefile
22
Makefile
@ -22,6 +22,26 @@ VENV_PYTHON=$(VENV_BIN)/python
|
|||||||
export PATH := $(VENV_BIN):$(PATH)
|
export PATH := $(VENV_BIN):$(PATH)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
default: list-tasks
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Default task to get a list of tasks when `make' is run without args.
|
||||||
|
# <https://stackoverflow.com/questions/4219255>
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
list-tasks:
|
||||||
|
@echo Available tasks:
|
||||||
|
@echo ----------------
|
||||||
|
@$(MAKE) -pRrq -f $(lastword $(MAKEFILE_LIST)) : 2>/dev/null | awk -v RS= -F: '/^# File/,/^# Finished Make data base/ {if ($$1 !~ "^[#.]") {print $$1}}' | sort | egrep -v -e '^[^[:alnum:]]' -e '^$@$$'
|
||||||
|
@echo
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Installation
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
all: uninstall-httpie install test
|
all: uninstall-httpie install test
|
||||||
|
|
||||||
|
|
||||||
@ -33,7 +53,7 @@ install-reqs:
|
|||||||
$(VENV_PIP) install --upgrade pip wheel build
|
$(VENV_PIP) install --upgrade pip wheel build
|
||||||
|
|
||||||
@echo $(H1)Installing dev requirements$(H1END)
|
@echo $(H1)Installing dev requirements$(H1END)
|
||||||
$(VENV_PIP) install --upgrade --editable '.[dev]'
|
$(VENV_PIP) install --upgrade '.[dev]' '.[test]'
|
||||||
|
|
||||||
@echo $(H1)Installing HTTPie$(H1END)
|
@echo $(H1)Installing HTTPie$(H1END)
|
||||||
$(VENV_PIP) install --upgrade --editable .
|
$(VENV_PIP) install --upgrade --editable .
|
||||||
|
@ -2425,7 +2425,7 @@ You can check whether a new update is available for your system by running `http
|
|||||||
|
|
||||||
In the past `pip` was used to install/uninstall plugins, but on some environments (e.g., brew installed
|
In the past `pip` was used to install/uninstall plugins, but on some environments (e.g., brew installed
|
||||||
packages) it wasn’t working properly. The new interface is a very simple overlay on top of `pip` to allow
|
packages) it wasn’t working properly. The new interface is a very simple overlay on top of `pip` to allow
|
||||||
plugin installations on every installation method.
|
plugin installations on every installation method.
|
||||||
|
|
||||||
By default, the plugins (and their missing dependencies) will be stored under the configuration directory,
|
By default, the plugins (and their missing dependencies) will be stored under the configuration directory,
|
||||||
but this can be modified through `plugins_dir` variable on the config.
|
but this can be modified through `plugins_dir` variable on the config.
|
||||||
|
@ -17,13 +17,13 @@ docs-structure:
|
|||||||
Windows:
|
Windows:
|
||||||
- chocolatey
|
- chocolatey
|
||||||
Linux:
|
Linux:
|
||||||
- snap-linux
|
|
||||||
- brew-linux
|
|
||||||
- apt
|
- apt
|
||||||
- dnf
|
- dnf
|
||||||
- yum
|
- yum
|
||||||
- pacman
|
|
||||||
- single-binary
|
- single-binary
|
||||||
|
- snap-linux
|
||||||
|
- brew-linux
|
||||||
|
- pacman
|
||||||
FreeBSD:
|
FreeBSD:
|
||||||
- pkg
|
- pkg
|
||||||
|
|
||||||
@ -191,6 +191,7 @@ tools:
|
|||||||
commands:
|
commands:
|
||||||
install:
|
install:
|
||||||
- https --download packages.httpie.io/binaries/linux/http-latest -o http
|
- https --download packages.httpie.io/binaries/linux/http-latest -o http
|
||||||
- chmod +x ./http
|
- ln -ls ./http ./https
|
||||||
|
- chmod +x ./http ./https
|
||||||
upgrade:
|
upgrade:
|
||||||
- https --download packages.httpie.io/binaries/linux/http-latest -o http
|
- https --download packages.httpie.io/binaries/linux/http-latest -o http
|
||||||
|
@ -6,6 +6,9 @@ from typing import Iterator, Tuple
|
|||||||
BUILD_DIR = Path(__file__).parent
|
BUILD_DIR = Path(__file__).parent
|
||||||
HTTPIE_DIR = BUILD_DIR.parent.parent.parent
|
HTTPIE_DIR = BUILD_DIR.parent.parent.parent
|
||||||
|
|
||||||
|
EXTRAS_DIR = HTTPIE_DIR / 'extras'
|
||||||
|
MAN_PAGES_DIR = EXTRAS_DIR / 'man'
|
||||||
|
|
||||||
SCRIPT_DIR = BUILD_DIR / Path('scripts')
|
SCRIPT_DIR = BUILD_DIR / Path('scripts')
|
||||||
HOOKS_DIR = SCRIPT_DIR / 'hooks'
|
HOOKS_DIR = SCRIPT_DIR / 'hooks'
|
||||||
|
|
||||||
@ -50,6 +53,11 @@ def build_packages(http_binary: Path, httpie_binary: Path) -> None:
|
|||||||
(http_binary, '/usr/bin/https'),
|
(http_binary, '/usr/bin/https'),
|
||||||
(httpie_binary, '/usr/bin/httpie'),
|
(httpie_binary, '/usr/bin/httpie'),
|
||||||
]
|
]
|
||||||
|
files.extend(
|
||||||
|
(man_page, f'/usr/share/man/man1/{man_page.name}')
|
||||||
|
for man_page in MAN_PAGES_DIR.glob('*.1')
|
||||||
|
)
|
||||||
|
|
||||||
# A list of additional dependencies
|
# A list of additional dependencies
|
||||||
deps = [
|
deps = [
|
||||||
'python3 >= 3.7',
|
'python3 >= 3.7',
|
||||||
|
@ -132,10 +132,3 @@ class RequestType(enum.Enum):
|
|||||||
FORM = enum.auto()
|
FORM = enum.auto()
|
||||||
MULTIPART = enum.auto()
|
MULTIPART = enum.auto()
|
||||||
JSON = enum.auto()
|
JSON = enum.auto()
|
||||||
|
|
||||||
|
|
||||||
EMPTY_STRING = ''
|
|
||||||
OPEN_BRACKET = '['
|
|
||||||
CLOSE_BRACKET = ']'
|
|
||||||
BACKSLASH = '\\'
|
|
||||||
HIGHLIGHTER = '^'
|
|
||||||
|
@ -9,8 +9,14 @@ from typing import (
|
|||||||
Type,
|
Type,
|
||||||
Union,
|
Union,
|
||||||
)
|
)
|
||||||
from httpie.cli.dicts import NestedJSONArray
|
from .dicts import NestedJSONArray
|
||||||
from httpie.cli.constants import EMPTY_STRING, OPEN_BRACKET, CLOSE_BRACKET, BACKSLASH, HIGHLIGHTER
|
|
||||||
|
|
||||||
|
EMPTY_STRING = ''
|
||||||
|
HIGHLIGHTER = '^'
|
||||||
|
OPEN_BRACKET = '['
|
||||||
|
CLOSE_BRACKET = ']'
|
||||||
|
BACKSLASH = '\\'
|
||||||
|
|
||||||
|
|
||||||
class HTTPieSyntaxError(ValueError):
|
class HTTPieSyntaxError(ValueError):
|
||||||
@ -31,7 +37,7 @@ class HTTPieSyntaxError(ValueError):
|
|||||||
if self.token is not None:
|
if self.token is not None:
|
||||||
lines.append(self.source)
|
lines.append(self.source)
|
||||||
lines.append(
|
lines.append(
|
||||||
' ' * (self.token.start)
|
' ' * self.token.start
|
||||||
+ HIGHLIGHTER * (self.token.end - self.token.start)
|
+ HIGHLIGHTER * (self.token.end - self.token.start)
|
||||||
)
|
)
|
||||||
return '\n'.join(lines)
|
return '\n'.join(lines)
|
||||||
@ -51,9 +57,15 @@ class TokenKind(Enum):
|
|||||||
return 'a ' + self.name.lower()
|
return 'a ' + self.name.lower()
|
||||||
|
|
||||||
|
|
||||||
OPERATORS = {OPEN_BRACKET: TokenKind.LEFT_BRACKET, CLOSE_BRACKET: TokenKind.RIGHT_BRACKET}
|
OPERATORS = {
|
||||||
|
OPEN_BRACKET: TokenKind.LEFT_BRACKET,
|
||||||
|
CLOSE_BRACKET: TokenKind.RIGHT_BRACKET,
|
||||||
|
}
|
||||||
SPECIAL_CHARS = OPERATORS.keys() | {BACKSLASH}
|
SPECIAL_CHARS = OPERATORS.keys() | {BACKSLASH}
|
||||||
LITERAL_TOKENS = [TokenKind.TEXT, TokenKind.NUMBER]
|
LITERAL_TOKENS = [
|
||||||
|
TokenKind.TEXT,
|
||||||
|
TokenKind.NUMBER,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class Token(NamedTuple):
|
class Token(NamedTuple):
|
||||||
|
@ -13,7 +13,8 @@ import urllib3
|
|||||||
from . import __version__
|
from . import __version__
|
||||||
from .adapters import HTTPieHTTPAdapter
|
from .adapters import HTTPieHTTPAdapter
|
||||||
from .context import Environment
|
from .context import Environment
|
||||||
from .cli.constants import EMPTY_STRING, HTTP_OPTIONS
|
from .cli.constants import HTTP_OPTIONS
|
||||||
|
from .cli.nested_json import EMPTY_STRING
|
||||||
from .cli.dicts import HTTPHeadersDict, NestedJSONArray
|
from .cli.dicts import HTTPHeadersDict, NestedJSONArray
|
||||||
from .encoding import UTF8
|
from .encoding import UTF8
|
||||||
from .models import RequestsMessage
|
from .models import RequestsMessage
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
This module provides an interface to spawn a detached task to be
|
This module provides an interface to spawn a detached task to be
|
||||||
runned with httpie.internal.daemon_runner on a separate process. It is
|
run with httpie.internal.daemon_runner on a separate process. It is
|
||||||
based on DVC's daemon system.
|
based on DVC's daemon system.
|
||||||
https://github.com/iterative/dvc/blob/main/dvc/daemon.py
|
https://github.com/iterative/dvc/blob/main/dvc/daemon.py
|
||||||
"""
|
"""
|
||||||
|
@ -277,7 +277,7 @@ def open_with_lockfile(file: Path, *args, **kwargs) -> Generator[IO[Any], None,
|
|||||||
target_file = Path(tempfile.gettempdir()) / file_id
|
target_file = Path(tempfile.gettempdir()) / file_id
|
||||||
|
|
||||||
# Have an atomic-like touch here, so we'll tighten the possibility of
|
# Have an atomic-like touch here, so we'll tighten the possibility of
|
||||||
# a race occuring between multiple processes accessing the same file.
|
# a race occurring between multiple processes accessing the same file.
|
||||||
try:
|
try:
|
||||||
target_file.touch(exist_ok=False)
|
target_file.touch(exist_ok=False)
|
||||||
except FileExistsError as exc:
|
except FileExistsError as exc:
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
"""Miscellaneous regression tests"""
|
"""Miscellaneous regression tests"""
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from httpie.cli.argtypes import KeyValueArgType
|
||||||
|
from httpie.cli.constants import SEPARATOR_HEADER, SEPARATOR_QUERY_PARAM, SEPARATOR_DATA_STRING
|
||||||
|
from httpie.cli.requestitems import RequestItems
|
||||||
from httpie.compat import is_windows
|
from httpie.compat import is_windows
|
||||||
from .utils.matching import assert_output_matches, Expect
|
|
||||||
from .utils import HTTP_OK, MockEnvironment, http
|
from .utils import HTTP_OK, MockEnvironment, http
|
||||||
|
from .utils.matching import assert_output_matches, Expect
|
||||||
|
|
||||||
|
|
||||||
def test_Host_header_overwrite(httpbin):
|
def test_Host_header_overwrite(httpbin):
|
||||||
@ -47,3 +50,21 @@ def test_verbose_redirected_stdout_separator(httpbin):
|
|||||||
Expect.RESPONSE_HEADERS,
|
Expect.RESPONSE_HEADERS,
|
||||||
Expect.BODY,
|
Expect.BODY,
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(['separator', 'target'], [
|
||||||
|
(SEPARATOR_HEADER, 'headers'),
|
||||||
|
(SEPARATOR_QUERY_PARAM, 'params'),
|
||||||
|
(SEPARATOR_DATA_STRING, 'data'),
|
||||||
|
])
|
||||||
|
def test_initial_backslash_number(separator, target):
|
||||||
|
"""
|
||||||
|
<https://github.com/httpie/httpie/issues/1408>
|
||||||
|
"""
|
||||||
|
back_digit = r'\0'
|
||||||
|
raw_arg = back_digit + separator + back_digit
|
||||||
|
expected_parsed_data = {back_digit: back_digit}
|
||||||
|
parsed_arg = KeyValueArgType(separator)(raw_arg)
|
||||||
|
items = RequestItems.from_args([parsed_arg])
|
||||||
|
parsed_data = getattr(items, target)
|
||||||
|
assert parsed_data == expected_parsed_data
|
||||||
|
Reference in New Issue
Block a user