-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
275 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
from collections import defaultdict | ||
from typing import TYPE_CHECKING | ||
from typing import DefaultDict | ||
from typing import Dict | ||
from typing import List | ||
from typing import Union | ||
|
||
from poetry.console.commands.command import Command | ||
|
||
|
||
if TYPE_CHECKING: | ||
from poetry.core.packages.package import Package | ||
|
||
|
||
class PluginShowCommand(Command): | ||
|
||
name = "plugin show" | ||
|
||
description = "Shows information about the currently installed plugins." | ||
|
||
def handle(self) -> int: | ||
from poetry.plugins.application_plugin import ApplicationPlugin | ||
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 | ||
|
||
plugins: DefaultDict[str, Dict[str, Union["Package", List[str]]]] = defaultdict( | ||
lambda: { | ||
"package": None, | ||
"plugins": [], | ||
"application_plugins": [], | ||
} | ||
) | ||
|
||
entry_points = ( | ||
PluginManager("application.plugin").get_plugin_entry_points() | ||
+ PluginManager("plugin").get_plugin_entry_points() | ||
) | ||
|
||
system_env = EnvManager.get_system_env() | ||
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.name)] | ||
plugins[package.pretty_name]["package"] = package | ||
plugins[package.pretty_name][category].append(entry_point) | ||
|
||
for name, info in plugins.items(): | ||
package = info["package"] | ||
self.line("") | ||
self.line( | ||
" • <c1>{}</c1> (<c2>{}</c2>){}".format( | ||
name, | ||
package.version, | ||
" " + package.description if package.description else "", | ||
) | ||
) | ||
provide_line = " " | ||
if info["plugins"]: | ||
provide_line += " <info>{}</info> plugin{}".format( | ||
len(info["plugins"]), "s" if len(info["plugins"]) > 1 else "" | ||
) | ||
|
||
if info["application_plugins"]: | ||
if info["plugins"]: | ||
provide_line += " and" | ||
|
||
provide_line += " <info>{}</info> application plugin{}".format( | ||
len(info["application_plugins"]), | ||
"s" if len(info["application_plugins"]) > 1 else "", | ||
) | ||
|
||
self.line(provide_line) | ||
|
||
if package.requires: | ||
self.line("") | ||
self.line(" <info>Dependencies</info>") | ||
for dependency in package.requires: | ||
self.line( | ||
" - {} (<c2>{}</c2>)".format( | ||
dependency.pretty_name, dependency.pretty_constraint | ||
) | ||
) | ||
|
||
return 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import pytest | ||
|
||
from entrypoints import EntryPoint as _EntryPoint | ||
|
||
from poetry.__version__ import __version__ | ||
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 | ||
from poetry.repositories.installed_repository import InstalledRepository | ||
from poetry.repositories.pool import Pool | ||
from poetry.utils.env import EnvManager | ||
|
||
|
||
class EntryPoint(_EntryPoint): | ||
def load(self): | ||
if "ApplicationPlugin" in self.object_name: | ||
return ApplicationPlugin | ||
|
||
return Plugin | ||
|
||
|
||
@pytest.fixture() | ||
def tester(command_tester_factory): | ||
return command_tester_factory("plugin show") | ||
|
||
|
||
@pytest.fixture() | ||
def installed(): | ||
repository = InstalledRepository() | ||
|
||
repository.add_package(Package("poetry", __version__)) | ||
|
||
return repository | ||
|
||
|
||
def configure_sources_factory(repo): | ||
def _configure_sources(poetry, sources, config, io): | ||
pool = Pool() | ||
pool.add_repository(repo) | ||
poetry.set_pool(pool) | ||
|
||
return _configure_sources | ||
|
||
|
||
@pytest.fixture(autouse=True) | ||
def setup_mocks(mocker, env, repo, installed): | ||
mocker.patch.object(EnvManager, "get_system_env", return_value=env) | ||
mocker.patch.object(InstalledRepository, "load", return_value=installed) | ||
mocker.patch.object( | ||
Factory, "configure_sources", side_effect=configure_sources_factory(repo) | ||
) | ||
|
||
|
||
def test_show_displays_installed_plugins(app, tester, installed, mocker): | ||
mocker.patch( | ||
"entrypoints.get_group_all", | ||
side_effect=[ | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:ApplicationPlugin", | ||
"FirstApplicationPlugin", | ||
) | ||
], | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:Plugin", | ||
"FirstPlugin", | ||
) | ||
], | ||
], | ||
) | ||
|
||
installed.add_package(Package("poetry-plugin", "1.2.3")) | ||
|
||
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, tester, installed, mocker | ||
): | ||
mocker.patch( | ||
"entrypoints.get_group_all", | ||
side_effect=[ | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:ApplicationPlugin", | ||
"FirstApplicationPlugin", | ||
), | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:ApplicationPlugin", | ||
"SecondApplicationPlugin", | ||
), | ||
], | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:Plugin", | ||
"FirstPlugin", | ||
), | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:Plugin", | ||
"SecondPlugin", | ||
), | ||
], | ||
], | ||
) | ||
|
||
installed.add_package(Package("poetry-plugin", "1.2.3")) | ||
|
||
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, tester, installed, mocker | ||
): | ||
mocker.patch( | ||
"entrypoints.get_group_all", | ||
side_effect=[ | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:ApplicationPlugin", | ||
"FirstApplicationPlugin", | ||
) | ||
], | ||
[ | ||
EntryPoint( | ||
"poetry-plugin", | ||
"poetry_plugin.plugins:Plugin", | ||
"FirstPlugin", | ||
) | ||
], | ||
], | ||
) | ||
|
||
plugin = Package("poetry-plugin", "1.2.3") | ||
plugin.add_dependency(Factory.create_dependency("foo", ">=1.2.3")) | ||
plugin.add_dependency(Factory.create_dependency("bar", "<4.5.6")) | ||
installed.add_package(plugin) | ||
|
||
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 |