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 <y...@example.com>
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
-
-
-@pytest.mark.requires_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)
-
-
-@pytest.mark.parametrize(
-    '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)
-
-
-@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()
-    env.config['version_info_file'] = tmp_path / 'version.json'
-    env.config['disable_update_warnings'] = False
-    return env
-
-
-@pytest.fixture
-def without_warnings(tmp_path):
-    env = PersistentMockEnvironment()
-    env.config['version_info_file'] = tmp_path / 'version.json'
-    env.config['disable_update_warnings'] = True
-    return env
-
-
-@pytest.fixture
-def fetch_update_mock(mocker):
-    mock_fetch = mocker.patch('httpie.internal.update_warnings.fetch_updates')
-    return mock_fetch
-
-
-@pytest.fixture
-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
-
-
-@pytest.fixture
-def unknown_build_channel(mocker):
-    mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL', 
UNKNOWN_BUILD_CHANNEL)
-
-
-@pytest.fixture
-def higher_build_channel(mocker):
-    mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL', 
BUILD_CHANNEL)
-
-
-@pytest.fixture
-def lower_build_channel(mocker):
-    mocker.patch('httpie.internal.update_warnings.BUILD_CHANNEL', 
BUILD_CHANNEL_2)
-- 
2.39.2

Reply via email to