Commit dea06d7a by Arun Babu Neelicattu

cli: plugins show -> self show plugins

parent 7aca7b20
......@@ -88,6 +88,7 @@ COMMANDS = [
"self remove",
"self update",
"self show",
"self show plugins",
# Source commands
"source add",
"source remove",
......
from __future__ import annotations
from collections import defaultdict
from typing import Any
from typing import cast
from cleo.io.inputs.string_input import StringInput
from cleo.io.io import IO
from poetry.console.application import Application
from poetry.console.commands.command import Command
from poetry.console.commands.self.show.plugins import SelfShowPluginsCommand
class PluginShowCommand(Command):
......@@ -11,75 +15,22 @@ class PluginShowCommand(Command):
name = "plugin show"
description = "Shows information about the currently installed plugins."
help = (
"<warning>This command is deprecated. Use <c2>self show plugins</> "
"command instead.</warning>"
)
def handle(self) -> int:
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin import Plugin
from poetry.plugins.plugin_manager import PluginManager
from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils.env import EnvManager
from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import pluralize
self.line_error(self.help)
plugins: dict[str, dict[str, Any]] = defaultdict(
lambda: {
"package": None,
"plugins": [],
"application_plugins": [],
}
application = cast(Application, self.application)
command: SelfShowPluginsCommand = cast(
SelfShowPluginsCommand, application.find("self show plugins")
)
entry_points = (
PluginManager(ApplicationPlugin.group).get_plugin_entry_points()
+ PluginManager(Plugin.group).get_plugin_entry_points()
return command.run(
IO(
StringInput(""),
self._io.output,
self._io.error_output,
)
system_env = EnvManager.get_system_env(naive=True)
installed_repository = InstalledRepository.load(
system_env, with_dependencies=True
)
packages_by_name = {pkg.name: pkg for pkg in installed_repository.packages}
for entry_point in entry_points:
plugin = entry_point.load()
category = "plugins"
if issubclass(plugin, ApplicationPlugin):
category = "application_plugins"
assert entry_point.distro is not None
package = packages_by_name[canonicalize_name(entry_point.distro.name)]
plugins[package.pretty_name]["package"] = package
plugins[package.pretty_name][category].append(entry_point)
for name, info in plugins.items():
package = info["package"]
description = " " + package.description if package.description else ""
self.line("")
self.line(f" • <c1>{name}</c1> (<c2>{package.version}</c2>){description}")
provide_line = " "
if info["plugins"]:
count = len(info["plugins"])
provide_line += f" <info>{count}</info> plugin{pluralize(count)}"
if info["application_plugins"]:
if info["plugins"]:
provide_line += " and"
count = len(info["application_plugins"])
provide_line += (
f" <info>{count}</info> application plugin{pluralize(count)}"
)
self.line(provide_line)
if package.requires:
self.line("")
self.line(" <info>Dependencies</info>")
for dependency in package.requires:
self.line(
f" - {dependency.pretty_name}"
f" (<c2>{dependency.pretty_constraint}</c2>)"
)
return 0
from __future__ import annotations
from collections import defaultdict
from typing import TYPE_CHECKING
from typing import DefaultDict
from poetry.console.commands.self.self_command import SelfCommand
if TYPE_CHECKING:
from poetry.core.packages.package import Package
class SelfShowPluginsCommand(SelfCommand):
name = "self show plugins"
description = "Shows information about the currently installed plugins."
help = """\
The <c1>self show plugins</c1> command lists all installed Poetry plugins.
Plugins can be added and removed using the <c1>self add</c1> and <c1>self remove</c1> \
commands respectively.
<warning>This command does not list packages that do not provide a Poetry plugin.</>
"""
def _system_project_handle(self) -> int:
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin import Plugin
from poetry.plugins.plugin_manager import PluginManager
from poetry.repositories.installed_repository import InstalledRepository
from poetry.utils.env import EnvManager
from poetry.utils.helpers import canonicalize_name
from poetry.utils.helpers import pluralize
plugins: DefaultDict[str, dict[str, Package | list[str]]] = defaultdict(
lambda: {
"package": None,
"plugins": [],
"application_plugins": [],
}
)
entry_points = (
PluginManager(ApplicationPlugin.group).get_plugin_entry_points()
+ PluginManager(Plugin.group).get_plugin_entry_points()
)
system_env = EnvManager.get_system_env(naive=True)
installed_repository = InstalledRepository.load(
system_env, with_dependencies=True
)
packages_by_name = {pkg.name: pkg for pkg in installed_repository.packages}
for entry_point in entry_points:
plugin = entry_point.load()
category = "plugins"
if issubclass(plugin, ApplicationPlugin):
category = "application_plugins"
package = packages_by_name[canonicalize_name(entry_point.distro.name)]
plugins[package.pretty_name]["package"] = package
plugins[package.pretty_name][category].append(entry_point)
for name, info in plugins.items():
package = info["package"]
description = " " + package.description if package.description else ""
self.line("")
self.line(f" • <c1>{name}</c1> (<c2>{package.version}</c2>){description}")
provide_line = " "
if info["plugins"]:
count = len(info["plugins"])
provide_line += f" <info>{count}</info> plugin{pluralize(count)}"
if info["application_plugins"]:
if info["plugins"]:
provide_line += " and"
count = len(info["application_plugins"])
provide_line += (
f" <info>{count}</info> application plugin{pluralize(count)}"
)
self.line(provide_line)
if package.requires:
self.line("")
self.line(" <info>Dependencies</info>")
for dependency in package.requires:
self.line(
f" - {dependency.pretty_name}"
f" (<c2>{dependency.pretty_constraint}</c2>)"
)
return 0
......@@ -4,189 +4,21 @@ from typing import TYPE_CHECKING
import pytest
from entrypoints import Distribution
from entrypoints import EntryPoint as _EntryPoint
from poetry.core.packages.package import Package
from poetry.factory import Factory
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin import Plugin
if TYPE_CHECKING:
from cleo.testers.command_tester import CommandTester
from pytest_mock import MockerFixture
from poetry.plugins.base_plugin import BasePlugin
from poetry.repositories import Repository
from tests.helpers import PoetryTestApplication
from tests.types import CommandTesterFactory
class EntryPoint(_EntryPoint):
def load(self) -> type[BasePlugin]:
if "ApplicationPlugin" in self.object_name:
return ApplicationPlugin
return Plugin
@pytest.fixture()
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
return command_tester_factory("plugin show")
@pytest.fixture()
def plugin_package() -> Package:
return Package("poetry-plugin", "1.2.3")
@pytest.fixture()
def plugin_distro(plugin_package: Package) -> Distribution:
return Distribution(plugin_package.name, plugin_package.version.to_string())
@pytest.mark.parametrize("entrypoint_name", ["poetry-plugin", "not-package-name"])
def test_show_displays_installed_plugins(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
entrypoint_name: str,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
entrypoint_name,
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
)
],
[
EntryPoint(
entrypoint_name,
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
)
],
],
)
installed.add_package(plugin_package)
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
1 plugin and 1 application plugin
"""
assert tester.io.fetch_output() == expected
def test_show_displays_installed_plugins_with_multiple_plugins(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
),
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"SecondApplicationPlugin",
distro=plugin_distro,
),
],
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
),
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"SecondPlugin",
distro=plugin_distro,
),
],
],
)
installed.add_package(plugin_package)
def test_deprecation_warning(tester: CommandTester) -> None:
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
2 plugins and 2 application plugins
"""
assert tester.io.fetch_output() == expected
def test_show_displays_installed_plugins_with_dependencies(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
)
],
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
)
],
],
assert (
tester.io.fetch_error()
== "This command is deprecated. Use self show plugins command instead.\n"
)
plugin_package.add_dependency(Factory.create_dependency("foo", ">=1.2.3"))
plugin_package.add_dependency(Factory.create_dependency("bar", "<4.5.6"))
installed.add_package(plugin_package)
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
1 plugin and 1 application plugin
Dependencies
- foo (>=1.2.3)
- bar (<4.5.6)
"""
assert tester.io.fetch_output() == expected
from __future__ import annotations
from typing import TYPE_CHECKING
import pytest
from entrypoints import Distribution
from entrypoints import EntryPoint as _EntryPoint
from poetry.core.packages.package import Package
from poetry.factory import Factory
from poetry.plugins.application_plugin import ApplicationPlugin
from poetry.plugins.plugin import Plugin
if TYPE_CHECKING:
from cleo.testers.command_tester import CommandTester
from pytest_mock import MockerFixture
from poetry.plugins.base_plugin import BasePlugin
from poetry.repositories import Repository
from tests.helpers import PoetryTestApplication
from tests.types import CommandTesterFactory
class EntryPoint(_EntryPoint):
def load(self) -> type[BasePlugin]:
if "ApplicationPlugin" in self.object_name:
return ApplicationPlugin
return Plugin
@pytest.fixture()
def tester(command_tester_factory: CommandTesterFactory) -> CommandTester:
return command_tester_factory("self show plugins")
@pytest.fixture()
def plugin_package() -> Package:
return Package("poetry-plugin", "1.2.3")
@pytest.fixture()
def plugin_distro(plugin_package: Package) -> Distribution:
return Distribution(plugin_package.name, plugin_package.version.to_string(True))
@pytest.mark.parametrize("entrypoint_name", ["poetry-plugin", "not-package-name"])
def test_show_displays_installed_plugins(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
entrypoint_name: str,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
entrypoint_name,
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
)
],
[
EntryPoint(
entrypoint_name,
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
)
],
],
)
installed.add_package(plugin_package)
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
1 plugin and 1 application plugin
"""
assert tester.io.fetch_output() == expected
def test_show_displays_installed_plugins_with_multiple_plugins(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
),
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"SecondApplicationPlugin",
distro=plugin_distro,
),
],
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
),
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"SecondPlugin",
distro=plugin_distro,
),
],
],
)
installed.add_package(plugin_package)
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
2 plugins and 2 application plugins
"""
assert tester.io.fetch_output() == expected
def test_show_displays_installed_plugins_with_dependencies(
app: PoetryTestApplication,
tester: CommandTester,
installed: Repository,
mocker: MockerFixture,
plugin_package: Package,
plugin_distro: Distribution,
):
mocker.patch(
"entrypoints.get_group_all",
side_effect=[
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:ApplicationPlugin",
"FirstApplicationPlugin",
distro=plugin_distro,
)
],
[
EntryPoint(
"poetry-plugin",
"poetry_plugin.plugins:Plugin",
"FirstPlugin",
distro=plugin_distro,
)
],
],
)
plugin_package.add_dependency(Factory.create_dependency("foo", ">=1.2.3"))
plugin_package.add_dependency(Factory.create_dependency("bar", "<4.5.6"))
installed.add_package(plugin_package)
tester.execute("")
expected = """
• poetry-plugin (1.2.3)
1 plugin and 1 application plugin
Dependencies
- foo (>=1.2.3)
- bar (<4.5.6)
"""
assert tester.io.fetch_output() == expected
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment