Package: httpie
Followup-For: Bug #1041792
Control: tags -1 patch
quick patch attached
>From 3ce3cacb8d3f7beff8d684a088ac4ecc016cc9c1 Mon Sep 17 00:00:00 2001
From: Your Name <[email protected]>
Date: Wed, 2 Aug 2023 11:23:38 +0000
Subject: [PATCH] disable updates
---
httpie/core.py | 2 -
httpie/internal/daemon_runner.py | 2 -
httpie/internal/update_warnings.py | 171 -------------------
httpie/manager/tasks/__init__.py | 2 -
httpie/manager/tasks/check_updates.py | 10 --
tests/test_update_warnings.py | 237 --------------------------
6 files changed, 424 deletions(-)
delete mode 100644 httpie/internal/update_warnings.py
delete mode 100644 httpie/manager/tasks/check_updates.py
delete mode 100644 tests/test_update_warnings.py
diff --git a/httpie/core.py b/httpie/core.py
index d0c26dc..0755e6d 100644
--- a/httpie/core.py
+++ b/httpie/core.py
@@ -24,7 +24,6 @@ from .output.writer import write_message, write_stream,
write_raw_data, MESSAGE_
from .plugins.registry import plugin_manager
from .status import ExitStatus, http_status_to_exit_status
from .utils import unwrap_context
-from .internal.update_warnings import check_updates
from .internal.daemon_runner import is_daemon_mode, run_daemon_task
@@ -95,7 +94,6 @@ def raw_main(
raise
exit_status = ExitStatus.ERROR
else:
- check_updates(env)
try:
exit_status = main_program(
args=parsed_args,
diff --git a/httpie/internal/daemon_runner.py b/httpie/internal/daemon_runner.py
index ec20b50..b2d3fb1 100644
--- a/httpie/internal/daemon_runner.py
+++ b/httpie/internal/daemon_runner.py
@@ -3,7 +3,6 @@ from contextlib import redirect_stderr, redirect_stdout
from typing import List
from httpie.context import Environment
-from httpie.internal.update_warnings import _fetch_updates,
_get_suppress_context
from httpie.status import ExitStatus
STATUS_FILE = '.httpie-test-daemon-status'
@@ -23,7 +22,6 @@ def _check_status(env):
DAEMONIZED_TASKS = {
'check_status': _check_status,
- 'fetch_updates': _fetch_updates,
}
diff --git a/httpie/internal/update_warnings.py
b/httpie/internal/update_warnings.py
deleted file mode 100644
index a4b80d4..0000000
--- a/httpie/internal/update_warnings.py
+++ /dev/null
@@ -1,171 +0,0 @@
-import json
-from contextlib import nullcontext, suppress
-from datetime import datetime, timedelta
-from pathlib import Path
-from typing import Any, Optional, Callable
-
-import requests
-
-import httpie
-from httpie.context import Environment, LogLevel
-from httpie.internal.__build_channel__ import BUILD_CHANNEL
-from httpie.internal.daemons import spawn_daemon
-from httpie.utils import is_version_greater, open_with_lockfile
-
-# Automatically updated package version index.
-PACKAGE_INDEX_LINK = 'https://packages.httpie.io/latest.json'
-
-FETCH_INTERVAL = timedelta(weeks=2)
-WARN_INTERVAL = timedelta(weeks=1)
-
-UPDATE_MESSAGE_FORMAT = """\
-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.
- try:
- with open(file) as stream:
- return json.load(stream)
- except (ValueError, OSError):
- return {}
-
-
-def _fetch_updates(env: Environment) -> str:
- file = env.config.version_info_file
- data = _read_data_error_free(file)
-
- response = requests.get(PACKAGE_INDEX_LINK, verify=False)
- response.raise_for_status()
-
- data.setdefault('last_warned_date', None)
- data['last_fetched_date'] = datetime.now().isoformat()
- data['last_released_versions'] = response.json()
-
- with open_with_lockfile(file, 'w') as stream:
- json.dump(data, stream)
-
-
-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:
- if env.config.get('disable_update_warnings'):
- return None
-
- data = _read_data_error_free(env.config.version_info_file)
-
- if data:
- current_date = datetime.now()
- last_fetched_date = datetime.fromisoformat(data['last_fetched_date'])
- earliest_fetch_date = last_fetched_date + FETCH_INTERVAL
- if current_date < earliest_fetch_date:
- return None
-
- fetch_updates(env)
-
-
-def _get_suppress_context(env: Environment) -> Any:
- """Return a context manager that suppress
- all possible errors.
-
- Note: if you have set the developer_mode=True in
- your config, then it will show all errors for easier
- debugging."""
- if env.config.developer_mode:
- return nullcontext()
- else:
- return suppress(BaseException)
-
-
-def _update_checker(
- func: Callable[[Environment], None]
-) -> Callable[[Environment], None]:
- """Control the execution of the update checker (suppress errors, trigger
- auto updates etc.)"""
-
- def wrapper(env: Environment) -> None:
- with _get_suppress_context(env):
- func(env)
-
- with _get_suppress_context(env):
- maybe_fetch_updates(env)
-
- 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
- update_status = _get_update_status(env)
-
- if not update_status:
- return None
-
- # 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)
-
- # 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()
- last_warned_date = version_info['last_warned_date']
- if last_warned_date is not None:
- earliest_warn_date = (
- datetime.fromisoformat(last_warned_date) + WARN_INTERVAL
- )
- if current_date < earliest_warn_date:
- return None
-
- env.log_error(update_status, level=LogLevel.INFO)
- version_info['last_warned_date'] = current_date.isoformat()
-
- with open_with_lockfile(file, 'w') as stream:
- json.dump(version_info, stream)
diff --git a/httpie/manager/tasks/__init__.py b/httpie/manager/tasks/__init__.py
index b9b30fb..9c591a2 100644
--- a/httpie/manager/tasks/__init__.py
+++ b/httpie/manager/tasks/__init__.py
@@ -1,11 +1,9 @@
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
}
diff --git a/httpie/manager/tasks/check_updates.py
b/httpie/manager/tasks/check_updates.py
deleted file mode 100644
index 07fd124..0000000
--- a/httpie/manager/tasks/check_updates.py
+++ /dev/null
@@ -1,10 +0,0 @@
-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
diff --git a/tests/test_update_warnings.py b/tests/test_update_warnings.py
deleted file mode 100644
index b2c24c3..0000000
--- a/tests/test_update_warnings.py
+++ /dev/null
@@ -1,237 +0,0 @@
-import json
-import tempfile
-import time
-from contextlib import suppress
-from datetime import datetime
-from pathlib import Path
-
-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, httpie
-
-BUILD_CHANNEL = 'test'
-BUILD_CHANNEL_2 = 'test2'
-UNKNOWN_BUILD_CHANNEL = 'test3'
-
-HIGHEST_VERSION = '999.999.999'
-LOWEST_VERSION = '1.1.1'
-
-FIXED_DATE = datetime(1970, 1, 1).isoformat()
-
-MAX_ATTEMPT = 40
-MAX_TIMEOUT = 2.0
-
-
-def check_update_warnings(text):
- return 'A new HTTPie release' in text
-
-
[email protected]_external_processes
-def test_daemon_runner():
- # We have a pseudo daemon task called 'check_status'
- # which creates a temp file called STATUS_FILE under
- # user's temp directory. This test simply ensures that
- # we create a daemon that successfully performs the
- # external task.
-
- status_file = Path(tempfile.gettempdir()) / STATUS_FILE
- with suppress(FileNotFoundError):
- status_file.unlink()
-
- spawn_daemon('check_status')
-
- for attempt in range(MAX_ATTEMPT):
- time.sleep(MAX_TIMEOUT / MAX_ATTEMPT)
- if status_file.exists():
- break
- else:
- pytest.fail(
- 'Maximum number of attempts failed for daemon status check.'
- )
-
- assert status_file.exists()
-
-
-def test_fetch(static_fetch_data, without_warnings):
- http('fetch_updates', '--daemon', env=without_warnings)
-
- with open(without_warnings.config.version_info_file) as stream:
- version_data = json.load(stream)
-
- assert version_data['last_warned_date'] is None
- assert version_data['last_fetched_date'] is not None
- assert (
- version_data['last_released_versions'][BUILD_CHANNEL]
- == HIGHEST_VERSION
- )
- assert (
- version_data['last_released_versions'][BUILD_CHANNEL_2]
- == LOWEST_VERSION
- )
-
-
-def test_fetch_dont_override_existing_layout(
- static_fetch_data, without_warnings
-):
- with open(without_warnings.config.version_info_file, 'w') as stream:
- existing_layout = {
- 'last_warned_date': FIXED_DATE,
- 'last_fetched_date': FIXED_DATE,
- 'last_released_versions': {BUILD_CHANNEL: LOWEST_VERSION},
- }
- json.dump(existing_layout, stream)
-
- http('fetch_updates', '--daemon', env=without_warnings)
-
- with open(without_warnings.config.version_info_file) as stream:
- version_data = json.load(stream)
-
- # The "last updated at" field should not be modified, but the
- # rest need to be updated.
- assert version_data['last_warned_date'] == FIXED_DATE
- assert version_data['last_fetched_date'] != FIXED_DATE
- assert (
- version_data['last_released_versions'][BUILD_CHANNEL]
- == HIGHEST_VERSION
- )
-
-
-def test_fetch_broken_json(static_fetch_data, without_warnings):
- with open(without_warnings.config.version_info_file, 'w') as stream:
- stream.write('$$broken$$')
-
- http('fetch_updates', '--daemon', env=without_warnings)
-
- with open(without_warnings.config.version_info_file) as stream:
- version_data = json.load(stream)
-
- assert (
- version_data['last_released_versions'][BUILD_CHANNEL]
- == HIGHEST_VERSION
- )
-
-
-def test_check_updates_disable_warnings(
- without_warnings, httpbin, fetch_update_mock
-):
- r = http(httpbin + '/get', env=without_warnings)
- assert not fetch_update_mock.called
- assert not check_update_warnings(r.stderr)
-
-
-def test_check_updates_first_invocation(
- with_warnings, httpbin, fetch_update_mock
-):
- r = http(httpbin + '/get', env=with_warnings)
- assert fetch_update_mock.called
- assert not check_update_warnings(r.stderr)
-
-
[email protected](
- 'should_issue_warning, build_channel',
- [
- (False, pytest.lazy_fixture('lower_build_channel')),
- (True, pytest.lazy_fixture('higher_build_channel')),
- ],
-)
-def test_check_updates_first_time_after_data_fetch(
- with_warnings,
- httpbin,
- fetch_update_mock,
- static_fetch_data,
- should_issue_warning,
- build_channel,
-):
- http('fetch_updates', '--daemon', env=with_warnings)
- r = http(httpbin + '/get', env=with_warnings)
-
- assert not fetch_update_mock.called
- assert (not should_issue_warning) or check_update_warnings(r.stderr)
-
-
-def test_check_updates_first_time_after_data_fetch_unknown_build_channel(
- with_warnings,
- httpbin,
- fetch_update_mock,
- static_fetch_data,
- unknown_build_channel,
-):
- http('fetch_updates', '--daemon', env=with_warnings)
- r = http(httpbin + '/get', env=with_warnings)
-
- assert not fetch_update_mock.called
- 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)
-
-
[email protected](
- "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)
-
-
[email protected]
-def with_warnings(tmp_path):
- env = PersistentMockEnvironment()
- env.config['version_info_file'] = tmp_path / 'version.json'
- env.config['disable_update_warnings'] = False
- return env
-
-
[email protected]
-def without_warnings(tmp_path):
- env = PersistentMockEnvironment()
- env.config['version_info_file'] = tmp_path / 'version.json'
- env.config['disable_update_warnings'] = True
- return env
-
-
[email protected]
-def fetch_update_mock(mocker):
- mock_fetch = mocker.patch('httpie.internal.update_warnings.fetch_updates')
- return mock_fetch
-
-
[email protected]
-def static_fetch_data(mocker):
- mock_get = mocker.patch('requests.get')
- mock_get.return_value.status_code = 200
- mock_get.return_value.json.return_value = {
- BUILD_CHANNEL: HIGHEST_VERSION,
- BUILD_CHANNEL_2: LOWEST_VERSION,
- }
- return mock_get
-
-
[email protected]
-def unknown_build_channel(mocker):
- mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL',
UNKNOWN_BUILD_CHANNEL)
-
-
[email protected]
-def higher_build_channel(mocker):
- mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL',
BUILD_CHANNEL)
-
-
[email protected]
-def lower_build_channel(mocker):
- mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL',
BUILD_CHANNEL_2)
--
2.39.2