summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBatuhan Taskaya <isidentical@gmail.com>2022-04-03 16:06:42 +0300
committerGitHub <noreply@github.com>2022-04-03 06:06:42 -0700
commitc15794853188d56af7a1d53473e1ad821f3ec861 (patch)
tree49dae4737f0b4f2b02721a8790a249d15892333a
parent33ea977b6443a023315084f2fb78e712a073ad65 (diff)
Add `httpie cli plugins` in favor of the new cli namespace. (#1320)
* Add `httpie cli plugins` in favor of the new cli namespace. * Separate each task to individual modules. * Move httpie.manager.plugins to httpie.manager.tasks.plugins Co-authored-by: Jakub Roztocil <jakub@roztocil.co>
-rw-r--r--CHANGELOG.md2
-rw-r--r--docs/README.md24
-rw-r--r--httpie/manager/cli.py64
-rw-r--r--httpie/manager/core.py4
-rw-r--r--httpie/manager/tasks/__init__.py9
-rw-r--r--httpie/manager/tasks/export_args.py27
-rw-r--r--httpie/manager/tasks/plugins.py (renamed from httpie/manager/plugins.py)21
-rw-r--r--httpie/manager/tasks/sessions.py (renamed from httpie/manager/tasks.py)39
-rw-r--r--tests/test_plugins_cli.py17
-rw-r--r--tests/utils/plugins_cli.py13
10 files changed, 120 insertions, 100 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 509e7ee2..c8cd462e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,8 +5,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
## [3.1.1.dev0](https://github.com/httpie/httpie/compare/3.1.0...HEAD) (Unreleased)
+- Changed `httpie plugins` to the new `httpie cli` namespace as `httpie cli plugins` (`httpie plugins` continues to work as a hidden alias). ([#1320](https://github.com/httpie/httpie/issues/1320))
- Fixed redundant creation of `Content-Length` header on `OPTIONS` requests. ([#1310](https://github.com/httpie/httpie/issues/1310))
+
## [3.1.0](https://github.com/httpie/httpie/compare/3.0.2...3.1.0) (2022-03-08)
- **SECURITY** Fixed the [vulnerability](https://github.com/httpie/httpie/security/advisories/GHSA-9w4w-cpc8-h2fq) that caused exposure of cookies on redirects to third party hosts. ([#1312](https://github.com/httpie/httpie/pull/1312))
diff --git a/docs/README.md b/docs/README.md
index 605640f1..dbab8714 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2347,7 +2347,7 @@ However, it is not recommended modifying the default behavior in a way that woul
#### `plugins_dir`
The directory where the plugins will be installed. HTTPie needs to have read/write access on that directory, since
-`httpie plugins install` will download new plugins to there. See [plugin manager](#plugin-manager) for more information.
+`httpie cli plugins install` will download new plugins to there. See [plugin manager](#plugin-manager) for more information.
### Un-setting previously specified options
@@ -2425,7 +2425,7 @@ $ httpie cli export-args | jq '"Program: " + .spec.name + ", Version: " + .vers
"Program: http, Version: 0.0.1a0"
```
-### `httpie plugins`
+#### `httpie cli plugins`
`plugins` interface is a very simple plugin manager for installing, listing and uninstalling HTTPie plugins.
@@ -2436,13 +2436,13 @@ 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.
-#### `httpie plugins install`
+##### `httpie cli plugins install`
-For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie plugins install`
+For installing plugins from [PyPI](https://pypi.org/) or from local paths, `httpie cli plugins install`
can be used.
```bash
-$ httpie plugins install httpie-plugin
+$ httpie cli plugins install httpie-plugin
Installing httpie-plugin...
Successfully installed httpie-plugin-1.0.2
```
@@ -2450,12 +2450,12 @@ Successfully installed httpie-plugin-1.0.2
> Tip: Generally HTTPie plugins start with `httpie-` prefix. Try searching for it on [PyPI](https://pypi.org/search/?q=httpie-)
> to find out all plugins from the community.
-#### `httpie plugins list`
+##### `httpie cli plugins list`
List all installed plugins.
```bash
-$ httpie plugins list
+$ httpie cli plugins list
httpie_plugin (1.0.2)
httpie_plugin (httpie.plugins.auth.v1)
httpie_plugin_2 (1.0.6)
@@ -2465,21 +2465,21 @@ httpie_converter (1.0.0)
httpie_konsole_konverter (httpie.plugins.converter.v1)
```
-#### `httpie plugins upgrade`
+##### `httpie cli plugins upgrade`
For upgrading already installed plugins, use `httpie plugins upgrade`.
```bash
-$ httpie plugins upgrade httpie-plugin
+$ httpie cli plugins upgrade httpie-plugin
```
-#### `httpie plugins uninstall`
+##### `httpie cli plugins uninstall`
Uninstall plugins from the isolated plugins directory. If the plugin is not installed
-through `httpie plugins install`, it won’t uninstall it.
+through `httpie cli plugins install`, it won’t uninstall it.
```bash
-$ httpie plugins uninstall httpie-plugin
+$ httpie cli plugins uninstall httpie-plugin
```
## Meta
diff --git a/httpie/manager/cli.py b/httpie/manager/cli.py
index 313f1450..2ae34fdb 100644
--- a/httpie/manager/cli.py
+++ b/httpie/manager/cli.py
@@ -12,37 +12,6 @@ CLI_SESSION_UPGRADE_FLAGS = [
]
COMMANDS = {
- 'plugins': {
- 'help': 'Manage HTTPie plugins.',
- 'install': [
- 'Install the given targets from PyPI '
- 'or from a local paths.',
- {
- 'dest': 'targets',
- 'nargs': '+',
- 'help': 'targets to install'
- }
- ],
- 'upgrade': [
- 'Upgrade the given plugins',
- {
- 'dest': 'targets',
- 'nargs': '+',
- 'help': 'targets to upgrade'
- }
- ],
- 'uninstall': [
- 'Uninstall the given HTTPie plugins.',
- {
- 'dest': 'targets',
- 'nargs': '+',
- 'help': 'targets to install'
- }
- ],
- 'list': [
- 'List all installed HTTPie plugins.'
- ],
- },
'cli': {
'help': 'Manage HTTPie for Terminal',
'export-args': [
@@ -82,6 +51,39 @@ COMMANDS = {
}
+COMMANDS['plugins'] = COMMANDS['cli']['plugins'] = {
+ 'help': 'Manage HTTPie plugins.',
+ 'install': [
+ 'Install the given targets from PyPI '
+ 'or from a local paths.',
+ {
+ 'dest': 'targets',
+ 'nargs': '+',
+ 'help': 'targets to install'
+ }
+ ],
+ 'upgrade': [
+ 'Upgrade the given plugins',
+ {
+ 'dest': 'targets',
+ 'nargs': '+',
+ 'help': 'targets to upgrade'
+ }
+ ],
+ 'uninstall': [
+ 'Uninstall the given HTTPie plugins.',
+ {
+ 'dest': 'targets',
+ 'nargs': '+',
+ 'help': 'targets to install'
+ }
+ ],
+ 'list': [
+ 'List all installed HTTPie plugins.'
+ ],
+}
+
+
def missing_subcommand(*args) -> str:
base = COMMANDS
for arg in args:
diff --git a/httpie/manager/core.py b/httpie/manager/core.py
index 1289fef1..0d669ecc 100644
--- a/httpie/manager/core.py
+++ b/httpie/manager/core.py
@@ -2,7 +2,6 @@ import argparse
from typing import Optional
from httpie.context import Environment
-from httpie.manager.plugins import PluginInstaller
from httpie.status import ExitStatus
from httpie.manager.cli import missing_subcommand, parser
from httpie.manager.tasks import CLI_TASKS
@@ -36,8 +35,7 @@ def program(args: argparse.Namespace, env: Environment) -> ExitStatus:
parser.error(MSG_NAKED_INVOCATION)
if args.action == 'plugins':
- plugins = PluginInstaller(env, debug=args.debug)
- return plugins.run(args.plugins_action, args)
+ return dispatch_cli_task(env, args.action, args)
elif args.action == 'cli':
return dispatch_cli_task(env, args.cli_action, args)
diff --git a/httpie/manager/tasks/__init__.py b/httpie/manager/tasks/__init__.py
new file mode 100644
index 00000000..9c591a24
--- /dev/null
+++ b/httpie/manager/tasks/__init__.py
@@ -0,0 +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
+
+CLI_TASKS = {
+ 'sessions': cli_sessions,
+ 'export-args': cli_export_args,
+ 'plugins': cli_plugins,
+}
diff --git a/httpie/manager/tasks/export_args.py b/httpie/manager/tasks/export_args.py
new file mode 100644
index 00000000..9a684a49
--- /dev/null
+++ b/httpie/manager/tasks/export_args.py
@@ -0,0 +1,27 @@
+import argparse
+import json
+
+from httpie.cli.definition import options
+from httpie.cli.options import to_data
+from httpie.output.writer import write_raw_data
+from httpie.status import ExitStatus
+from httpie.context import Environment
+
+
+FORMAT_TO_CONTENT_TYPE = {
+ 'json': 'application/json'
+}
+
+
+def cli_export_args(env: Environment, args: argparse.Namespace) -> ExitStatus:
+ if args.format == 'json':
+ data = json.dumps(to_data(options))
+ else:
+ raise NotImplementedError(f'Unexpected format value: {args.format}')
+
+ write_raw_data(
+ env,
+ data,
+ stream_kwargs={'mime_overwrite': FORMAT_TO_CONTENT_TYPE[args.format]},
+ )
+ return ExitStatus.SUCCESS
diff --git a/httpie/manager/plugins.py b/httpie/manager/tasks/plugins.py
index 899e9925..e6b1ee23 100644
--- a/httpie/manager/plugins.py
+++ b/httpie/manager/tasks/plugins.py
@@ -1,18 +1,18 @@
import argparse
import os
+import re
+import shutil
import subprocess
import sys
import textwrap
-import re
-import shutil
from collections import defaultdict
from contextlib import suppress
from pathlib import Path
-from typing import Tuple, Optional, List
+from typing import List, Optional, Tuple
-from httpie.manager.cli import parser, missing_subcommand
-from httpie.compat import importlib_metadata, get_dist_name
+from httpie.compat import get_dist_name, importlib_metadata
from httpie.context import Environment
+from httpie.manager.cli import missing_subcommand, parser
from httpie.status import ExitStatus
from httpie.utils import as_site
@@ -248,3 +248,14 @@ class PluginInstaller:
status = self.list()
return status or ExitStatus.SUCCESS
+
+
+def cli_plugins(env: Environment, args: argparse.Namespace) -> ExitStatus:
+ plugins = PluginInstaller(env, debug=args.debug)
+
+ try:
+ action = args.cli_plugins_action
+ except AttributeError:
+ action = args.plugins_action
+
+ return plugins.run(action, args)
diff --git a/httpie/manager/tasks.py b/httpie/manager/tasks/sessions.py
index 5b726a9b..10866cae 100644
--- a/httpie/manager/tasks.py
+++ b/httpie/manager/tasks/sessions.py
@@ -1,5 +1,5 @@
import argparse
-from typing import TypeVar, Callable, Tuple
+from typing import Tuple
from httpie.sessions import SESSIONS_DIR_NAME, get_httpie_session
from httpie.status import ExitStatus
@@ -7,19 +7,7 @@ from httpie.context import Environment
from httpie.legacy import cookie_format as legacy_cookies
from httpie.manager.cli import missing_subcommand, parser
-T = TypeVar('T')
-CLI_TASKS = {}
-
-
-def task(name: str) -> Callable[[T], T]:
- def wrapper(func: T) -> T:
- CLI_TASKS[name] = func
- return func
- return wrapper
-
-
-@task('sessions')
def cli_sessions(env: Environment, args: argparse.Namespace) -> ExitStatus:
action = args.cli_sessions_action
if action is None:
@@ -114,28 +102,3 @@ def cli_upgrade_all_sessions(env: Environment, args: argparse.Namespace) -> Exit
session_name=session_name
)
return status
-
-
-FORMAT_TO_CONTENT_TYPE = {
- 'json': 'application/json'
-}
-
-
-@task('export-args')
-def cli_export(env: Environment, args: argparse.Namespace) -> ExitStatus:
- import json
- from httpie.cli.definition import options
- from httpie.cli.options import to_data
- from httpie.output.writer import write_raw_data
-
- if args.format == 'json':
- data = json.dumps(to_data(options))
- else:
- raise NotImplementedError(f'Unexpected format value: {args.format}')
-
- write_raw_data(
- env,
- data,
- stream_kwargs={'mime_overwrite': FORMAT_TO_CONTENT_TYPE[args.format]},
- )
- return ExitStatus.SUCCESS
diff --git a/tests/test_plugins_cli.py b/tests/test_plugins_cli.py
index 70cecb1f..7be110de 100644
--- a/tests/test_plugins_cli.py
+++ b/tests/test_plugins_cli.py
@@ -5,8 +5,9 @@ from tests.utils.plugins_cli import parse_listing
@pytest.mark.requires_installation
-def test_plugins_installation(httpie_plugins_success, interface, dummy_plugin):
- lines = httpie_plugins_success('install', dummy_plugin.path)
+@pytest.mark.parametrize('cli_mode', [True, False])
+def test_plugins_installation(httpie_plugins_success, interface, dummy_plugin, cli_mode):
+ lines = httpie_plugins_success('install', dummy_plugin.path, cli_mode=cli_mode)
assert lines[0].startswith(
f'Installing {dummy_plugin.path}'
)
@@ -28,8 +29,9 @@ def test_plugin_installation_with_custom_config(httpie_plugins_success, interfac
@pytest.mark.requires_installation
-def test_plugins_listing(httpie_plugins_success, interface, dummy_plugin):
- httpie_plugins_success('install', dummy_plugin.path)
+@pytest.mark.parametrize('cli_mode', [True, False])
+def test_plugins_listing(httpie_plugins_success, interface, dummy_plugin, cli_mode):
+ httpie_plugins_success('install', dummy_plugin.path, cli_mode=cli_mode)
data = parse_listing(httpie_plugins_success('list'))
assert data == {
@@ -50,9 +52,10 @@ def test_plugins_listing_multiple(interface, httpie_plugins_success, dummy_plugi
@pytest.mark.requires_installation
-def test_plugins_uninstall(interface, httpie_plugins_success, dummy_plugin):
- httpie_plugins_success('install', dummy_plugin.path)
- httpie_plugins_success('uninstall', dummy_plugin.name)
+@pytest.mark.parametrize('cli_mode', [True, False])
+def test_plugins_uninstall(interface, httpie_plugins_success, dummy_plugin, cli_mode):
+ httpie_plugins_success('install', dummy_plugin.path, cli_mode=cli_mode)
+ httpie_plugins_success('uninstall', dummy_plugin.name, cli_mode=cli_mode)
assert not interface.is_installed(dummy_plugin.name)
diff --git a/tests/utils/plugins_cli.py b/tests/utils/plugins_cli.py
index a750e664..39b515d4 100644
--- a/tests/utils/plugins_cli.py
+++ b/tests/utils/plugins_cli.py
@@ -208,12 +208,17 @@ def httpie_plugins(interface):
from tests.utils import httpie
from httpie.plugins.registry import plugin_manager
- def runner(*args):
+ def runner(*args, cli_mode: bool = True):
+ args = list(args)
+ if cli_mode:
+ args.insert(0, 'cli')
+ args.insert(cli_mode, 'plugins')
+
# Prevent installed plugins from showing up.
original_plugins = plugin_manager.copy()
clean_sys_path = set(sys.path).difference(site.getsitepackages())
with patch('sys.path', list(clean_sys_path)):
- response = httpie('plugins', *args, env=interface.environment)
+ response = httpie(*args, env=interface.environment)
plugin_manager.clear()
plugin_manager.extend(original_plugins)
return response
@@ -223,8 +228,8 @@ def httpie_plugins(interface):
@pytest.fixture
def httpie_plugins_success(httpie_plugins):
- def runner(*args):
- response = httpie_plugins(*args)
+ def runner(*args, cli_mode: bool = True):
+ response = httpie_plugins(*args, cli_mode=True)
assert response.exit_status == ExitStatus.SUCCESS
return response.splitlines()
return runner