Skip to content

Commit 003f209

Browse files
isidenticaljkbrzt
andauthored
Automatic release update warnings. (#1336)
* Hide pretty help * Automatic release update warnings. * `httpie cli check-updates` * adapt to the new loglevel construct * Don't make the pie-colors the bold * Apply review feedback. Co-authored-by: Jakub Roztocil <[email protected]>
1 parent f9b5c2f commit 003f209

File tree

21 files changed

+708
-36
lines changed

21 files changed

+708
-36
lines changed

.github/workflows/release-pypi.yml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,8 @@ jobs:
2121
with:
2222
python-version: 3.9
2323

24-
- name: Install pypa/build
25-
run: python -m pip install build
26-
2724
- name: Build a binary wheel and a source tarball
28-
run: python -m build --sdist --wheel --outdir dist/
25+
run: make build
2926

3027
- name: Release on PyPI
3128
uses: pypa/gh-action-pypi-publish@master

Makefile

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ install: venv install-reqs
3030

3131
install-reqs:
3232
@echo $(H1)Updating package tools$(H1END)
33-
$(VENV_PIP) install --upgrade pip wheel
33+
$(VENV_PIP) install --upgrade pip wheel build
3434

3535
@echo $(H1)Installing dev requirements$(H1END)
3636
$(VENV_PIP) install --upgrade --editable '.[dev]'
@@ -153,8 +153,11 @@ doc-check:
153153

154154

155155
build:
156-
rm -rf build/
157-
$(VENV_PYTHON) setup.py sdist bdist_wheel
156+
rm -rf build/ dist/
157+
mv httpie/internal/__build_channel__.py httpie/internal/__build_channel__.py.original
158+
echo 'BUILD_CHANNEL = "pip"' > httpie/internal/__build_channel__.py
159+
$(VENV_PYTHON) -m build --sdist --wheel --outdir dist/
160+
mv httpie/internal/__build_channel__.py.original httpie/internal/__build_channel__.py
158161

159162

160163
publish: test-all publish-no-test
@@ -198,7 +201,7 @@ brew-test:
198201
- brew uninstall httpie
199202

200203
@echo $(H1)Building from source…$(H1END)
201-
- brew install --build-from-source ./docs/packaging/brew/httpie.rb
204+
- brew install --HEAD --build-from-source ./docs/packaging/brew/httpie.rb
202205

203206
@echo $(H1)Verifying…$(H1END)
204207
http --version

docs/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,10 @@ If you’d like to silence warnings as well, use `-q` or `--quiet` twice:
16551655
$ http -qq --check-status pie.dev/post enjoy='the silence without warnings'
16561656
```
16571657
1658+
### Update warnings
1659+
1660+
When there is a new release available for your platform (for example; if you installed HTTPie through `pip`, it will check the latest version on `PyPI`), HTTPie will regularly warn you about the new update (once a week). If you want to disable this behavior, you can set `disable_update_warnings` to `true` in your [config](#config) file.
1661+
16581662
### Viewing intermediary requests/responses
16591663
16601664
To see all the HTTP communication, i.e. the final request/response as well as any possible intermediary requests/responses, use the `--all` option.
@@ -2400,6 +2404,14 @@ This command is currently in beta.
24002404
24012405
### `httpie cli`
24022406
2407+
#### `httpie cli check-updates`
2408+
2409+
You can check whether a new update is available for your system by running `httpie cli check-updates`:
2410+
2411+
```bash-termible
2412+
$ httpie cli check-updates
2413+
````
2414+
24032415
#### `httpie cli export-args`
24042416
24052417
`httpie cli export-args` command can expose the parser specification of `http`/`https` commands

extras/packaging/linux/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ RUN python -m pip install /app
2727
RUN python -m pip install pyinstaller wheel
2828
RUN python -m pip install --force-reinstall --upgrade pip
2929

30+
RUN echo 'BUILD_CHANNEL="pypi"' > /app/httpie/internal/__build_channel__.py
3031
RUN python build.py
3132

3233
ENTRYPOINT ["mv", "/app/extras/packaging/linux/dist/", "/artifacts"]

extras/packaging/linux/build.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ def main():
9292
build_packages(binaries['http_cli'], binaries['httpie_cli'])
9393

9494
# Rename http_cli/httpie_cli to http/httpie
95-
binaries['http_cli'].rename('http')
96-
binaries['httpie_cli'].rename('httpie')
95+
binaries['http_cli'].rename(DIST_DIR / 'http')
96+
binaries['httpie_cli'].rename(DIST_DIR / 'httpie')
97+
9798

9899

99100
if __name__ == '__main__':

httpie/config.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,24 @@ def __init__(self, directory: Union[str, Path] = DEFAULT_CONFIG_DIR):
149149
def default_options(self) -> list:
150150
return self['default_options']
151151

152+
def _configured_path(self, config_option: str, default: str) -> None:
153+
return Path(
154+
self.get(config_option, self.directory / default)
155+
).expanduser().resolve()
156+
152157
@property
153158
def plugins_dir(self) -> Path:
154-
return Path(self.get('plugins_dir', self.directory / 'plugins')).resolve()
159+
return self._configured_path('plugins_dir', 'plugins')
160+
161+
@property
162+
def version_info_file(self) -> Path:
163+
return self._configured_path('version_info_file', 'version_info.json')
164+
165+
@property
166+
def developer_mode(self) -> bool:
167+
"""This is a special setting for the development environment. It is
168+
different from the --debug mode in the terms that it might change
169+
the behavior for certain parameters (e.g updater system) that
170+
we usually ignore."""
171+
172+
return self.get('developer_mode')

httpie/core.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
from .plugins.registry import plugin_manager
2525
from .status import ExitStatus, http_status_to_exit_status
2626
from .utils import unwrap_context
27+
from .internal.update_warnings import check_updates
28+
from .internal.daemon_runner import is_daemon_mode, run_daemon_task
2729

2830

2931
# noinspection PyDefaultArgument
@@ -37,6 +39,10 @@ def raw_main(
3739
program_name, *args = args
3840
env.program_name = os.path.basename(program_name)
3941
args = decode_raw_args(args, env.stdin_encoding)
42+
43+
if is_daemon_mode(args):
44+
return run_daemon_task(env, args)
45+
4046
plugin_manager.load_installed_plugins(env.config.plugins_dir)
4147

4248
if use_default_options and env.config.default_options:
@@ -89,6 +95,7 @@ def handle_generic_error(e, annotation=None):
8995
raise
9096
exit_status = ExitStatus.ERROR
9197
else:
98+
check_updates(env)
9299
try:
93100
exit_status = main_program(
94101
args=parsed_args,
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Represents the packaging method. This file should
2+
# be overridden by every build system we support on
3+
# the packaging step.
4+
5+
BUILD_CHANNEL = 'unknown'

httpie/internal/__init__.py

Whitespace-only changes.

httpie/internal/daemon_runner.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import argparse
2+
from contextlib import redirect_stderr, redirect_stdout
3+
from typing import List
4+
5+
from httpie.context import Environment
6+
from httpie.internal.update_warnings import _fetch_updates
7+
from httpie.status import ExitStatus
8+
9+
STATUS_FILE = '.httpie-test-daemon-status'
10+
11+
12+
def _check_status(env):
13+
# This function is used only for the testing (test_update_warnings).
14+
# Since we don't want to trigger the fetch_updates (which would interact
15+
# with real world resources), we'll only trigger this pseudo task
16+
# and check whether the STATUS_FILE is created or not.
17+
import tempfile
18+
from pathlib import Path
19+
20+
status_file = Path(tempfile.gettempdir()) / STATUS_FILE
21+
status_file.touch()
22+
23+
24+
DAEMONIZED_TASKS = {
25+
'check_status': _check_status,
26+
'fetch_updates': _fetch_updates,
27+
}
28+
29+
30+
def _parse_options(args: List[str]) -> argparse.Namespace:
31+
parser = argparse.ArgumentParser()
32+
parser.add_argument('task_id')
33+
parser.add_argument('--daemon', action='store_true')
34+
return parser.parse_known_args(args)[0]
35+
36+
37+
def is_daemon_mode(args: List[str]) -> bool:
38+
return '--daemon' in args
39+
40+
41+
def run_daemon_task(env: Environment, args: List[str]) -> ExitStatus:
42+
options = _parse_options(args)
43+
44+
assert options.daemon
45+
assert options.task_id in DAEMONIZED_TASKS
46+
with redirect_stdout(env.devnull), redirect_stderr(env.devnull):
47+
DAEMONIZED_TASKS[options.task_id](env)
48+
49+
return ExitStatus.SUCCESS

0 commit comments

Comments
 (0)