def test_deprecation_warning(tester: CommandTester, repo: TestRepository) -> None: plugin = Package("poetry-plugin", "1.2.3") repo.add_package(Package("poetry", __version__)) repo.add_package(plugin) package = ProjectPackage("poetry-instance", __version__) package.add_dependency( Dependency(plugin.name, "^1.2.3", groups=[SelfCommand.ADDITIONAL_PACKAGE_GROUP])) content = Factory.create_pyproject_from_package(package) system_pyproject_file = SelfCommand.get_default_system_pyproject_file() system_pyproject_file.write_text(content.as_string(), encoding="utf-8") dependencies = get_self_command_dependencies(locked=False) assert "poetry-plugin" in dependencies tester.execute("poetry-plugin") assert (tester.io.fetch_error() == "This command is deprecated. Use self remove command instead.\n") dependencies = get_self_command_dependencies() assert "poetry-plugin" not in dependencies assert not dependencies
def install_plugin(installed: Repository) -> None: package = ProjectPackage("poetry-instance", __version__) plugin = Package("poetry-plugin", "1.2.3") package.add_dependency( Dependency(plugin.name, "^1.2.3", groups=[SelfCommand.ADDITIONAL_PACKAGE_GROUP]) ) content = Factory.create_pyproject_from_package(package) system_pyproject_file = SelfCommand.get_default_system_pyproject_file() system_pyproject_file.write_text(content.as_string(), encoding="utf-8") lock_content = { "package": [ { "name": "poetry-plugin", "version": "1.2.3", "category": "main", "optional": False, "platform": "*", "python-versions": "*", "checksum": [], }, ], "metadata": { "python-versions": "^3.6", "platform": "*", "content-hash": "123456789", "hashes": {"poetry-plugin": []}, }, } system_pyproject_file.parent.joinpath("poetry.lock").write_text( tomlkit.dumps(lock_content), encoding="utf-8" ) installed.add_package(plugin)
def test_create_pyproject_from_package(project: str): poetry = Factory().create_poetry(fixtures_dir / project) package = poetry.package pyproject = Factory.create_pyproject_from_package(package) result = pyproject["tool"]["poetry"] expected = poetry.pyproject.poetry_config # packages do not support this at present expected.pop("scripts", None) # remove any empty sections sections = list(expected.keys()) for section in sections: if not expected[section]: expected.pop(section) assert not DeepDiff(expected, result)
def generate_system_pyproject(self) -> None: preserved = {} if self.system_pyproject.exists(): content = PyProjectTOML(self.system_pyproject).poetry_config for key in {"group", "source"}: if key in content: preserved[key] = content[key] package = ProjectPackage(name="poetry-instance", version=__version__) package.add_dependency( Dependency(name="poetry", constraint=f"{__version__}")) package.python_versions = ".".join( str(v) for v in self.env.version_info[:3]) content = Factory.create_pyproject_from_package(package=package) for key in preserved: content[key] = preserved[key] self.system_pyproject.write_text(content.as_string(), encoding="utf-8")
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, ))