1
0
mirror of https://github.com/httpie/cli.git synced 2025-08-10 22:42:05 +02:00

httpie cli check-updates

This commit is contained in:
Batuhan Taskaya
2022-04-29 14:35:12 +03:00
parent c56692c9af
commit 366b0c3fcd
6 changed files with 95 additions and 20 deletions

View File

@@ -2402,6 +2402,14 @@ This command is currently in beta.
"Program: http, Version: 0.0.1a0"
```
#### `httpie cli plugins`
`plugins` interface is a very simple plugin manager for installing, listing and uninstalling HTTPie plugins.
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
plugin installations on every installation method.
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.

View File

@@ -2,7 +2,7 @@ import json
from contextlib import nullcontext, suppress
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Callable
from typing import Any, Optional, Callable
import requests
@@ -23,6 +23,10 @@ A new HTTPie release ({last_released_version}) is available.
To see how you can update, please visit https://httpie.io/docs/cli/{installation_method}
"""
ALREADY_UP_TO_DATE_MESSAGE = """\
You are already up-to-date.
"""
def _read_data_error_free(file: Path) -> Any:
# If the file is broken / non-existent, ignore it.
@@ -48,8 +52,11 @@ def _fetch_updates(env: Environment) -> str:
json.dump(data, stream)
def fetch_updates():
spawn_daemon('fetch_updates')
def fetch_updates(env: Environment, lazy: bool = True):
if lazy:
spawn_daemon('fetch_updates')
else:
_fetch_updates(env)
def maybe_fetch_updates(env: Environment) -> None:
@@ -65,7 +72,7 @@ def maybe_fetch_updates(env: Environment) -> None:
if current_date < earliest_fetch_date:
return None
fetch_updates()
fetch_updates(env)
def _get_suppress_context(env: Environment) -> Any:
@@ -97,13 +104,48 @@ def _update_checker(
return wrapper
def _get_update_status(env: Environment) -> Optional[str]:
"""If there is a new update available, return the warning text.
Otherwise just return None."""
file = env.config.version_info_file
if not file.exists():
return None
with _get_suppress_context(env):
# If the user quickly spawns multiple httpie processes
# we don't want to end in a race.
with open_with_lockfile(file) as stream:
version_info = json.load(stream)
available_channels = version_info['last_released_versions']
if BUILD_CHANNEL not in available_channels:
return None
current_version = httpie.__version__
last_released_version = available_channels[BUILD_CHANNEL]
if not is_version_greater(last_released_version, current_version):
return None
text = UPDATE_MESSAGE_FORMAT.format(
last_released_version=last_released_version,
installation_method=BUILD_CHANNEL,
)
return text
def get_update_status(env: Environment) -> str:
return _get_update_status(env) or ALREADY_UP_TO_DATE_MESSAGE
@_update_checker
def check_updates(env: Environment) -> None:
if env.config.get('disable_update_warnings'):
return None
file = env.config.version_info_file
if not file.exists():
update_status = _get_update_status(env)
if not update_status:
return None
# If the user quickly spawns multiple httpie processes
@@ -111,10 +153,6 @@ def check_updates(env: Environment) -> None:
with open_with_lockfile(file) as stream:
version_info = json.load(stream)
available_channels = version_info['last_released_versions']
if BUILD_CHANNEL not in available_channels:
return None
# We don't want to spam the user with too many warnings,
# so we'll only warn every once a while (WARN_INTERNAL).
current_date = datetime.now()
@@ -126,16 +164,7 @@ def check_updates(env: Environment) -> None:
if current_date < earliest_warn_date:
return None
current_version = httpie.__version__
last_released_version = available_channels[BUILD_CHANNEL]
if not is_version_greater(last_released_version, current_version):
return None
text = UPDATE_MESSAGE_FORMAT.format(
last_released_version=last_released_version,
installation_method=BUILD_CHANNEL,
)
env.log_error(text, level=Levels.WARNING)
env.log_error(update_status, level=Levels.WARNING)
version_info['last_warned_date'] = current_date.isoformat()
with open_with_lockfile(file, 'w') as stream:

View File

@@ -23,6 +23,9 @@ COMMANDS = {
'default': 'json'
}
],
'check-updates': [
'Check for updates'
],
'sessions': {
'help': 'Manage HTTPie sessions',
'upgrade': [

View File

@@ -1,9 +1,11 @@
from httpie.manager.tasks.sessions import cli_sessions
from httpie.manager.tasks.export_args import cli_export_args
from httpie.manager.tasks.plugins import cli_plugins
from httpie.manager.tasks.check_updates import cli_check_updates
CLI_TASKS = {
'sessions': cli_sessions,
'export-args': cli_export_args,
'plugins': cli_plugins,
'check-updates': cli_check_updates
}

View File

@@ -0,0 +1,10 @@
import argparse
from httpie.context import Environment
from httpie.status import ExitStatus
from httpie.internal.update_warnings import fetch_updates, get_update_status
def cli_check_updates(env: Environment, args: argparse.Namespace) -> ExitStatus:
fetch_updates(env, lazy=False)
env.stdout.write(get_update_status(env))
return ExitStatus.SUCCESS

View File

@@ -9,8 +9,9 @@ import pytest
from httpie.internal.daemon_runner import STATUS_FILE
from httpie.internal.daemons import spawn_daemon
from httpie.status import ExitStatus
from .utils import PersistentMockEnvironment, http
from .utils import PersistentMockEnvironment, http, httpie
BUILD_CHANNEL = 'test'
BUILD_CHANNEL_2 = 'test2'
@@ -166,6 +167,28 @@ def test_check_updates_first_time_after_data_fetch_unknown_build_channel(
assert not check_update_warnings(r.stderr)
def test_cli_check_updates(
static_fetch_data, higher_build_channel
):
r = httpie('cli', 'check-updates')
assert r.exit_status == ExitStatus.SUCCESS
assert check_update_warnings(r)
@pytest.mark.parametrize(
"build_channel", [
pytest.lazy_fixture("lower_build_channel"),
pytest.lazy_fixture("unknown_build_channel")
]
)
def test_cli_check_updates_not_shown(
static_fetch_data, build_channel
):
r = httpie('cli', 'check-updates')
assert r.exit_status == ExitStatus.SUCCESS
assert not check_update_warnings(r)
@pytest.fixture
def with_warnings(tmp_path):
env = PersistentMockEnvironment()