示例#1
0
    def handle(self) -> int:
        from pathlib import Path

        from cleo.io.inputs.string_input import StringInput
        from cleo.io.io import IO

        from poetry.factory import Factory
        from poetry.utils.env import EnvManager

        plugins = self.argument("plugins")

        system_env = EnvManager.get_system_env(naive=True)
        env_dir = Path(os.getenv("POETRY_HOME") or system_env.path)

        # From this point forward, all the logic will be deferred to
        # the remove command, by using the global `pyproject.toml` file.
        application = cast(Application, self.application)
        remove_command: RemoveCommand = cast(RemoveCommand,
                                             application.find("remove"))
        # We won't go through the event dispatching done by the application
        # so we need to configure the command manually
        remove_command.set_poetry(Factory().create_poetry(env_dir))
        remove_command.set_env(system_env)
        application._configure_installer(remove_command, self._io)

        argv = ["remove"] + plugins
        if self.option("dry-run"):
            argv.append("--dry-run")

        return remove_command.run(
            IO(
                StringInput(" ".join(argv)),
                self._io.output,
                self._io.error_output,
            ))
示例#2
0
    def _update_with_new_method(self, version):
        from poetry.config.config import Config
        from poetry.core.packages.dependency import Dependency
        from poetry.core.packages.project_package import ProjectPackage
        from poetry.installation.installer import Installer
        from poetry.packages.locker import NullLocker
        from poetry.repositories.installed_repository import InstalledRepository
        from poetry.utils.env import EnvManager

        env = EnvManager.get_system_env(naive=True)
        installed = InstalledRepository.load(env)

        root = ProjectPackage("poetry-updater", "0.0.0")
        root.python_versions = ".".join(str(c) for c in env.version_info[:3])
        root.add_dependency(Dependency("poetry", version.text))

        installer = Installer(
            self.io,
            env,
            root,
            NullLocker(self.data_dir.joinpath("poetry.lock"), {}),
            self.pool,
            Config(),
            installed=installed,
        )
        installer.update(True)
        installer.run()
示例#3
0
    def handle(self):
        from poetry.__version__ import __version__
        from poetry.core.semver import Version
        from poetry.utils.env import EnvManager

        new_update_method = False
        try:
            self._check_recommended_installation()
        except RuntimeError as e:
            env = EnvManager.get_system_env(naive=True)
            try:
                env.path.relative_to(self.data_dir)
            except ValueError:
                raise e

            new_update_method = True

        version = self.argument("version")
        if not version:
            version = ">=" + __version__

        repo = self.pool.repositories[0]
        packages = repo.find_packages(
            Dependency("poetry",
                       version,
                       allows_prereleases=self.option("preview")))
        if not packages:
            self.line("No release found for the specified version")
            return

        packages.sort(key=cmp_to_key(lambda x, y: 0 if x.version == y.version
                                     else int(x.version < y.version or -1)))

        release = None
        for package in packages:
            if package.is_prerelease():
                if self.option("preview"):
                    release = package

                    break

                continue

            release = package

            break

        if release is None:
            self.line("No new release found")
            return

        if release.version == Version.parse(__version__):
            self.line("You are using the latest version")
            return

        if new_update_method:
            return self.update_with_new_method(release.version)

        self.update(release)
示例#4
0
    def update(self, release: Package) -> None:
        from poetry.utils.env import EnvManager

        version = release.version

        env = EnvManager.get_system_env(naive=True)

        # We can't use is_relative_to() since it's only available in Python 3.9+
        try:
            env.path.relative_to(self.data_dir)
        except ValueError:
            # Poetry was not installed using the recommended installer
            from poetry.console.exceptions import PoetrySimpleConsoleException

            raise PoetrySimpleConsoleException(
                "Poetry was not installed with the recommended installer, "
                "so it cannot be updated automatically.")

        self._update(version)
        self._make_bin()
示例#5
0
    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

        plugins: dict[str, dict[str,
                                Any]] = 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
示例#6
0
文件: show.py 项目: xobust/poetry
    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(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.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
示例#7
0
    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: dict[str, PluginPackage] = {}

        system_env = EnvManager.get_system_env(naive=True)
        entry_points = PluginManager(
            ApplicationPlugin.group).get_plugin_entry_points(
                env=system_env) + PluginManager(
                    Plugin.group).get_plugin_entry_points(env=system_env)
        installed_repository = InstalledRepository.load(system_env,
                                                        with_dependencies=True)

        packages_by_name: dict[str, Package] = {
            pkg.name: pkg
            for pkg in installed_repository.packages
        }

        for entry_point in entry_points:
            plugin = entry_point.load()

            assert entry_point.distro is not None
            package = packages_by_name[canonicalize_name(
                entry_point.distro.name)]

            name = package.pretty_name
            info = plugins.get(name) or PluginPackage(package=package)

            if issubclass(plugin, ApplicationPlugin):
                info.application_plugins.append(entry_point)
            else:
                info.plugins.append(entry_point)

            plugins[name] = info

        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
示例#8
0
    def handle(self) -> int:
        from pathlib import Path

        import tomlkit

        from cleo.io.inputs.string_input import StringInput
        from cleo.io.io import IO
        from poetry.core.pyproject.toml import PyProjectTOML
        from poetry.core.semver.helpers import parse_constraint

        from poetry.factory import Factory
        from poetry.packages.project_package import ProjectPackage
        from poetry.repositories.installed_repository import InstalledRepository
        from poetry.utils.env import EnvManager

        plugins = self.argument("plugins")

        # Plugins should be installed in the system env to be globally available
        system_env = EnvManager.get_system_env(naive=True)

        env_dir = Path(os.getenv("POETRY_HOME") or system_env.path)

        # We check for the plugins existence first.
        if env_dir.joinpath("pyproject.toml").exists():
            pyproject = tomlkit.loads(
                env_dir.joinpath("pyproject.toml").read_text(encoding="utf-8"))
            poetry_content = pyproject["tool"]["poetry"]
            existing_packages = self.get_existing_packages_from_input(
                plugins, poetry_content, "dependencies")

            if existing_packages:
                self.notify_about_existing_packages(existing_packages)

            plugins = [
                plugin for plugin in plugins if plugin not in existing_packages
            ]

        if not plugins:
            return 0

        plugins = self._determine_requirements(plugins)

        # We retrieve the packages installed in the system environment.
        # We assume that this environment will be a self contained virtual environment
        # built by the official installer or by pipx.
        # If not, it might lead to side effects since other installed packages
        # might not be required by Poetry but still taken into account when resolving dependencies.
        installed_repository = InstalledRepository.load(system_env,
                                                        with_dependencies=True)

        root_package = None
        for package in installed_repository.packages:
            if package.name == "poetry":
                root_package = ProjectPackage(package.name, package.version)
                for dependency in package.requires:
                    root_package.add_dependency(dependency)

                break

        root_package.python_versions = ".".join(
            str(v) for v in system_env.version_info[:3])
        # We create a `pyproject.toml` file based on all the information
        # we have about the current environment.
        if not env_dir.joinpath("pyproject.toml").exists():
            Factory.create_pyproject_from_package(root_package, env_dir)

        # We add the plugins to the dependencies section of the previously
        # created `pyproject.toml` file
        pyproject = PyProjectTOML(env_dir.joinpath("pyproject.toml"))
        poetry_content = pyproject.poetry_config
        poetry_dependency_section = poetry_content["dependencies"]
        plugin_names = []
        for plugin in plugins:
            if "version" in plugin:
                # Validate version constraint
                parse_constraint(plugin["version"])

            constraint = tomlkit.inline_table()
            for name, value in plugin.items():
                if name == "name":
                    continue

                constraint[name] = value

            if len(constraint) == 1 and "version" in constraint:
                constraint = constraint["version"]

            poetry_dependency_section[plugin["name"]] = constraint
            plugin_names.append(plugin["name"])

        pyproject.save()

        # From this point forward, all the logic will be deferred to
        # the update command, by using the previously created `pyproject.toml`
        # file.
        application = cast(Application, self.application)
        update_command: UpdateCommand = cast(UpdateCommand,
                                             application.find("update"))
        # We won't go through the event dispatching done by the application
        # so we need to configure the command manually
        update_command.set_poetry(Factory().create_poetry(env_dir))
        update_command.set_env(system_env)
        application._configure_installer(update_command, self._io)

        argv = ["update"] + plugin_names
        if self.option("dry-run"):
            argv.append("--dry-run")

        return update_command.run(
            IO(
                StringInput(" ".join(argv)),
                self._io.output,
                self._io.error_output,
            ))
示例#9
0
 def reset_env(self) -> None:
     self._env = EnvManager.get_system_env(naive=True)