You've already forked httpie-cli
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:
@@ -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.
|
||||
|
||||
|
@@ -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:
|
||||
|
@@ -23,6 +23,9 @@ COMMANDS = {
|
||||
'default': 'json'
|
||||
}
|
||||
],
|
||||
'check-updates': [
|
||||
'Check for updates'
|
||||
],
|
||||
'sessions': {
|
||||
'help': 'Manage HTTPie sessions',
|
||||
'upgrade': [
|
||||
|
@@ -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
|
||||
}
|
||||
|
10
httpie/manager/tasks/check_updates.py
Normal file
10
httpie/manager/tasks/check_updates.py
Normal 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
|
@@ -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()
|
||||
|
Reference in New Issue
Block a user