Compare commits

...

8 Commits

Author SHA1 Message Date
9d2e2afede Add failing reproduction test case 2022-06-07 14:50:56 +02:00
418b12bbd6 Cleanup 2022-06-07 14:31:15 +02:00
ecff53f2d5 Have naked $ make list all tasks 2022-06-07 14:29:19 +02:00
41da87f7c8 Install .[test] reqs in make install-reqs 2022-06-07 14:26:48 +02:00
4f172a61b4 Fix installation 2022-06-07 14:23:52 +02:00
542a2d35de Fix typos in comment lines (#1405)
* httpie/internal/daemons.py
* httpie/utils.py
2022-05-19 16:22:50 +03:00
d9e1dc08c9 Package man pages into the deb packages as well. (#1403) 2022-05-16 18:19:49 +03:00
3b734fb0bc Fix a misput backtick 2022-05-16 10:10:51 +03:00
11 changed files with 83 additions and 25 deletions

View File

@ -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

View File

@ -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 .

View File

@ -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 wasnt working properly. The new interface is a very simple overlay on top of `pip` to allow packages) it wasnt 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.

View File

@ -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

View File

@ -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',

View File

@ -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 = '^'

View File

@ -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):

View File

@ -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

View File

@ -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
""" """

View File

@ -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:

View File

@ -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