Example #1
0
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)
Example #2
0
def test_with_compatible_locked_dependencies_with_extras(
    root: ProjectPackage, provider: Provider, repo: Repository
):
    root.add_dependency(Factory.create_dependency("foo", "^1.0"))

    package_foo_0 = get_package("foo", "1.0.0")
    package_foo_1 = get_package("foo", "1.0.1")
    bar_extra_dep = Factory.create_dependency(
        "bar", {"version": "^1.0", "extras": "extra"}
    )
    for package_foo in (package_foo_0, package_foo_1):
        package_foo.add_dependency(bar_extra_dep)
        repo.add_package(package_foo)

    bar_deps = {"baz": {"version": "^1.0", "extras": ["extra"]}}
    add_to_repo(repo, "bar", "1.0.0", bar_deps)
    add_to_repo(repo, "bar", "1.0.1", bar_deps)
    add_to_repo(repo, "baz", "1.0.0")
    add_to_repo(repo, "baz", "1.0.1")

    check_solver_result(
        root,
        provider,
        result={"foo": "1.0.0", "bar": "1.0.0", "baz": "1.0.0"},
        locked={
            "foo": get_package("foo", "1.0.0"),
            "bar": get_package("bar", "1.0.0"),
            "baz": get_package("baz", "1.0.0"),
        },
    )
Example #3
0
def test_remove_without_specific_group_removes_from_specific_groups(
    tester: CommandTester,
    app: PoetryTestApplication,
    repo: TestRepository,
    command_tester_factory: CommandTesterFactory,
    installed: Repository,
):
    """
    Removing with a specific group given removes packages only from this group.
    """
    installed.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("baz", "1.0.0"))

    content = app.poetry.file.read()

    groups_content = tomlkit.parse("""\
[tool.poetry.group.bar.dependencies]
foo = "^2.0.0"
baz = "^1.0.0"

""")
    content["tool"]["poetry"]["dependencies"]["foo"] = "^2.0.0"
    content["tool"]["poetry"]["group"] = groups_content["tool"]["poetry"][
        "group"]
    app.poetry.file.write(content)

    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0"))
    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0", groups=["bar"]))
    app.poetry.package.add_dependency(
        Factory.create_dependency("baz", "^1.0.0", groups=["bar"]))

    tester.execute("foo --group bar")

    content = app.poetry.file.read()["tool"]["poetry"]
    assert "foo" in content["dependencies"]
    assert "foo" not in content["group"]["bar"]["dependencies"]
    assert "baz" in content["group"]["bar"]["dependencies"]

    expected = """\

[tool.poetry.group.bar.dependencies]
baz = "^1.0.0"

"""
    string_content = content.as_string()
    if "\r\n" in string_content:
        # consistent line endings
        expected = expected.replace("\n", "\r\n")

    assert expected in string_content
Example #4
0
def test_remove_canonicalized_named_removes_dependency_correctly(
    tester: CommandTester,
    app: PoetryTestApplication,
    repo: TestRepository,
    command_tester_factory: CommandTesterFactory,
    installed: Repository,
):
    """
    Removing a dependency using a canonicalized named removes the dependency.
    """
    installed.add_package(Package("foo-bar", "2.0.0"))
    repo.add_package(Package("foo-bar", "2.0.0"))
    repo.add_package(Package("baz", "1.0.0"))

    content = app.poetry.file.read()

    groups_content = tomlkit.parse("""\
[tool.poetry.group.bar.dependencies]
foo-bar = "^2.0.0"
baz = "^1.0.0"

""")
    content["tool"]["poetry"]["dependencies"]["foo-bar"] = "^2.0.0"
    content["tool"]["poetry"].value._insert_after(
        "dependencies", "group", groups_content["tool"]["poetry"]["group"])
    app.poetry.file.write(content)

    app.poetry.package.add_dependency(
        Factory.create_dependency("foo-bar", "^2.0.0"))
    app.poetry.package.add_dependency(
        Factory.create_dependency("foo-bar", "^2.0.0", groups=["bar"]))
    app.poetry.package.add_dependency(
        Factory.create_dependency("baz", "^1.0.0", groups=["bar"]))

    tester.execute("Foo_Bar")

    content = app.poetry.file.read()["tool"]["poetry"]
    assert "foo-bar" not in content["dependencies"]
    assert "foo-bar" not in content["group"]["bar"]["dependencies"]
    assert "baz" in content["group"]["bar"]["dependencies"]

    expected = """\

[tool.poetry.group.bar.dependencies]
baz = "^1.0.0"

"""
    string_content = content.as_string()
    if "\r\n" in string_content:
        # consistent line endings
        expected = expected.replace("\n", "\r\n")

    assert expected in string_content
Example #5
0
    def _populate_local_repo(self, local_repo: Repository,
                             ops: Sequence["Operation"]) -> None:
        for op in ops:
            if isinstance(op, Uninstall):
                continue
            elif isinstance(op, Update):
                package = op.target_package
            else:
                package = op.package

            if not local_repo.has_package(package):
                local_repo.add_package(package)
Example #6
0
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
Example #7
0
def mock_metadata_entry_points(
    plugin_package: Package,
    plugin_distro: metadata.Distribution,
    installed: Repository,
    mocker: MockerFixture,
    tmp_venv: Env,
    entry_points: Callable[[...], metadata.EntryPoint],
) -> None:
    installed.add_package(plugin_package)

    mocker.patch.object(tmp_venv.site_packages,
                        "find_distribution",
                        return_value=plugin_distro)
    mocker.patch.object(metadata, "entry_points", entry_points)
Example #8
0
def test_remove_without_specific_group_removes_from_all_groups(
    tester: CommandTester,
    app: PoetryTestApplication,
    repo: TestRepository,
    command_tester_factory: CommandTesterFactory,
    installed: Repository,
):
    """
    Removing without specifying a group removes packages from all groups.
    """
    installed.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("baz", "1.0.0"))

    content = app.poetry.file.read()

    groups_content = tomlkit.parse("""\
[tool.poetry.group.bar.dependencies]
foo = "^2.0.0"
baz = "^1.0.0"

""")
    content["tool"]["poetry"]["dependencies"]["foo"] = "^2.0.0"
    content["tool"]["poetry"].value._insert_after(
        "dependencies", "group", groups_content["tool"]["poetry"]["group"])
    app.poetry.file.write(content)

    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0"))
    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0", groups=["bar"]))
    app.poetry.package.add_dependency(
        Factory.create_dependency("baz", "^1.0.0", groups=["bar"]))

    tester.execute("foo")

    content = app.poetry.file.read()["tool"]["poetry"]
    assert "foo" not in content["dependencies"]
    assert "foo" not in content["group"]["bar"]["dependencies"]
    assert "baz" in content["group"]["bar"]["dependencies"]

    expected = """\

[tool.poetry.group.bar.dependencies]
baz = "^1.0.0"

"""

    assert expected in content.as_string()
Example #9
0
def test_add_existing_plugin_warns_about_no_operation(
    app: PoetryTestApplication,
    repo: TestRepository,
    tester: CommandTester,
    env: MockEnv,
    installed: Repository,
):
    env.path.joinpath("pyproject.toml").write_text(
        """\
[tool.poetry]
name = "poetry"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = [
    "Sébastien Eustace <*****@*****.**>"
]

[tool.poetry.dependencies]
python = "^3.6"
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))

    tester.execute("poetry-plugin")

    expected = """\
The following plugins are already present in the pyproject.toml file and will be\
 skipped:

  • poetry-plugin

If you want to update it to the latest compatible version,\
 you can use `poetry plugin update package`.
If you prefer to upgrade it to the latest available version,\
 you can use `poetry plugin add package@latest`.

"""

    assert tester.io.fetch_output() == expected

    update_command: UpdateCommand = app.find("update")
    # The update command should not have been called
    assert update_command.poetry.file.parent != env.path
Example #10
0
def add_to_repo(
    repository: Repository,
    name: str,
    version: str,
    deps: dict[str, str] | None = None,
    python: str | None = None,
) -> None:
    package = Package(name, version)
    if python:
        package.python_versions = python

    if deps:
        for dep_name, dep_constraint in deps.items():
            package.add_dependency(Factory.create_dependency(dep_name, dep_constraint))

    repository.add_package(package)
Example #11
0
    def _do_refresh(self) -> int:
        from poetry.puzzle import Solver

        # Checking extras
        for extra in self._extras:
            if extra not in self._package.extras:
                raise ValueError(f"Extra [{extra}] is not specified.")

        locked_repository = self._locker.locked_repository()
        solver = Solver(
            self._package,
            self._pool,
            locked_repository,
            locked_repository,
            self._io,
        )

        with solver.provider.use_source_root(
            source_root=self._env.path.joinpath("src")
        ):
            ops = solver.solve(use_latest=[]).calculate_operations()

        local_repo = Repository()
        self._populate_local_repo(local_repo, ops)

        self._write_lock_file(local_repo, force=True)

        return 0
Example #12
0
    def _do_refresh(self):
        from poetry.puzzle import Solver

        # Checking extras
        for extra in self._extras:
            if extra not in self._package.extras:
                raise ValueError("Extra [{}] is not specified.".format(extra))

        locked_repository = self._locker.locked_repository(True)
        solver = Solver(
            self._package,
            self._pool,
            locked_repository,
            locked_repository,
            self._io,  # noqa
        )

        ops = solver.solve(use_latest=[])

        local_repo = Repository()
        self._populate_local_repo(local_repo, ops)

        self._write_lock_file(local_repo, force=True)

        return 0
Example #13
0
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
Example #14
0
    def locked_repository(self, with_dev_reqs: bool = False) -> Repository:
        """
        Searches and returns a repository of locked packages.
        """
        if not self.is_locked():
            return Repository()

        lock_data = self.lock_data
        packages = Repository()

        if with_dev_reqs:
            locked_packages = lock_data['package']
        else:
            locked_packages = [
                p for p in lock_data['package'] if p['category'] == 'main'
            ]

        if not locked_packages:
            return packages

        for info in locked_packages:
            package = poetry.packages.Package(
                info['name'],
                info['version'],
                info['version']
            )
            package.description = info.get('description', '')
            package.category = info['category']
            package.optional = info['optional']
            package.hashes = lock_data['metadata']['hashes'][info['name']]
            package.python_versions = info['python-versions']

            for dep_name, constraint in info.get('dependencies', {}).items():
                package.add_dependency(dep_name, constraint)

            if 'requirements' in info:
                package.requirements = info['requirements']

            if 'source' in info:
                package.source_type = info['source']['type']
                package.source_url = info['source']['url']
                package.source_reference = info['source']['reference']

            packages.add_package(package)

        return packages
Example #15
0
def test_add_existing_plugin_updates_if_requested(
    app: PoetryTestApplication,
    repo: TestRepository,
    tester: CommandTester,
    env: MockEnv,
    installed: Repository,
    mocker: MockerFixture,
):
    env.path.joinpath("pyproject.toml").write_text(
        """\
[tool.poetry]
name = "poetry"
version = "1.2.0"
description = "Python dependency management and packaging made easy."
authors = [
    "Sébastien Eustace <*****@*****.**>"
]

[tool.poetry.dependencies]
python = "^3.6"
poetry-plugin = "^1.2.3"
""",
        encoding="utf-8",
    )

    installed.add_package(Package("poetry-plugin", "1.2.3"))

    repo.add_package(Package("poetry-plugin", "1.2.3"))
    repo.add_package(Package("poetry-plugin", "2.3.4"))

    tester.execute("poetry-plugin@latest")

    expected = """\
Using version ^2.3.4 for poetry-plugin
Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 0 installs, 1 update, 0 removals

  • Updating poetry-plugin (1.2.3 -> 2.3.4)
"""

    assert_plugin_add_result(tester, app, env, expected, "^2.3.4")
Example #16
0
def test_remove_does_not_live_empty_groups(
    tester: CommandTester,
    app: PoetryTestApplication,
    repo: TestRepository,
    command_tester_factory: CommandTesterFactory,
    installed: Repository,
):
    """
    Empty groups are automatically discarded after package removal.
    """
    installed.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("foo", "2.0.0"))
    repo.add_package(Package("baz", "1.0.0"))

    content = app.poetry.file.read()

    groups_content = tomlkit.parse("""\
[tool.poetry.group.bar.dependencies]
foo = "^2.0.0"
baz = "^1.0.0"

""")
    content["tool"]["poetry"]["dependencies"]["foo"] = "^2.0.0"
    content["tool"]["poetry"].value._insert_after(
        "dependencies", "group", groups_content["tool"]["poetry"]["group"])
    app.poetry.file.write(content)

    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0"))
    app.poetry.package.add_dependency(
        Factory.create_dependency("foo", "^2.0.0", groups=["bar"]))
    app.poetry.package.add_dependency(
        Factory.create_dependency("baz", "^1.0.0", groups=["bar"]))

    tester.execute("foo baz --group bar")

    content = app.poetry.file.read()["tool"]["poetry"]
    assert "foo" in content["dependencies"]
    assert "foo" not in content["group"]["bar"]["dependencies"]
    assert "baz" not in content["group"]["bar"]["dependencies"]
    assert "[tool.poetry.group.bar]" not in content.as_string()
    assert "[tool.poetry.group]" not in content.as_string()
Example #17
0
    def run(self):
        # Force update if there is no lock file present
        if not self._update and not self._locker.is_locked():
            self._update = True

        if self.is_dry_run():
            self.verbose(True)
            self._write_lock = False
            self._execute_operations = False

        local_repo = Repository()

        return self._do_install(local_repo)
Example #18
0
    def _do_refresh(self):
        # Checking extras
        for extra in self._extras:
            if extra not in self._package.extras:
                raise ValueError("Extra [{}] is not specified.".format(extra))

        ops = self._get_operations_from_lock(self._locker.locked_repository(True))
        local_repo = Repository()
        self._populate_local_repo(local_repo, ops)

        self._write_lock_file(local_repo, force=True)

        return 0
Example #19
0
def test_adding_a_plugin_can_update_poetry_dependencies_if_needed(
    app: PoetryTestApplication,
    repo: TestRepository,
    tester: CommandTester,
    env: MockEnv,
    installed: Repository,
):
    poetry_package = Package("poetry", "1.2.0")
    poetry_package.add_dependency(
        Factory.create_dependency("tomlkit", "^0.7.0"))

    plugin_package = Package("poetry-plugin", "1.2.3")
    plugin_package.add_dependency(
        Factory.create_dependency("tomlkit", "^0.7.2"))

    installed.add_package(poetry_package)
    installed.add_package(Package("tomlkit", "0.7.1"))

    repo.add_package(plugin_package)
    repo.add_package(Package("tomlkit", "0.7.1"))
    repo.add_package(Package("tomlkit", "0.7.2"))

    tester.execute("poetry-plugin")

    expected = """\
Using version ^1.2.3 for poetry-plugin
Updating dependencies
Resolving dependencies...

Writing lock file

Package operations: 1 install, 1 update, 0 removals

  • Updating tomlkit (0.7.1 -> 0.7.2)
  • Installing poetry-plugin (1.2.3)
"""

    assert_plugin_add_result(tester, app, env, expected, "^1.2.3")
Example #20
0
def install_plugin(env: MockEnv, installed: Repository,
                   pyproject: None) -> None:
    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": []
            },
        },
    }

    env.path.joinpath("poetry.lock").write_text(tomlkit.dumps(lock_content),
                                                encoding="utf-8")

    pyproject_toml = tomlkit.loads(
        env.path.joinpath("pyproject.toml").read_text(encoding="utf-8"))
    content = pyproject_toml["tool"]["poetry"]

    dependency_section = content["dependencies"]
    dependency_section["poetry-plugin"] = "^1.2.3"

    env.path.joinpath("pyproject.toml").write_text(
        tomlkit.dumps(pyproject_toml), encoding="utf-8")

    installed.add_package(Package("poetry-plugin", "1.2.3"))
Example #21
0
def test_show_displays_installed_plugins(
    app: PoetryTestApplication,
    tester: CommandTester,
    installed: Repository,
    mocker: MockerFixture,
):
    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
Example #22
0
def setup(mocker, installer):
    # Set Installer's installer
    p = mocker.patch('poetry.installation.installer.Installer._get_installer')
    p.return_value = installer

    p = mocker.patch('poetry.installation.installer.Installer._get_installed')
    p.return_value = Repository()

    # Patch git module to not actually clone projects
    mocker.patch('poetry.vcs.git.Git.clone', new=mock_clone)
    mocker.patch('poetry.vcs.git.Git.checkout', new=lambda *_: None)
    p = mocker.patch('poetry.vcs.git.Git.rev_parse')
    p.return_value = '9cf87a285a2d3fbb0b9fa621997b3acc3631ed24'

    # Patch provider progress rate to have a consistent
    # dependency resolution output
    p = mocker.patch('poetry.puzzle.provider.Provider.progress_rate',
                     new_callable=mocker.PropertyMock)
    p.return_value = 3600
Example #23
0
    def _do_install(self, local_repo):
        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked():
                locked_repository = self._locker.locked_repository(True)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError(
                        'Extra [{}] is not specified.'.format(extra))

            self._io.writeln('<info>Updating dependencies</>')
            fixed = []

            # If the whitelist is enabled, packages not in it are fixed
            # to the version specified in the lock
            if self._whitelist:
                # collect packages to fixate from root requirements
                candidates = []
                for package in locked_repository.packages:
                    candidates.append(package)

                # fix them to the version in lock if they are not updateable
                for candidate in candidates:
                    to_fix = True
                    for require in self._whitelist.keys():
                        if require == candidate.name:
                            to_fix = False

                    if to_fix:
                        dependency = Dependency(
                            candidate.name,
                            candidate.version,
                            optional=candidate.optional,
                            category=candidate.category,
                            allows_prereleases=candidate.is_prerelease())
                        fixed.append(dependency)

            solver = Solver(self._package, self._pool,
                            self._installed_repository, locked_repository,
                            self._io)

            request = self._package.requires
            request += self._package.dev_requires

            ops = solver.solve(request, fixed=fixed)
        else:
            self._io.writeln('<info>Installing dependencies from lock file</>')

            locked_repository = self._locker.locked_repository(True)

            if not self._locker.is_fresh():
                self._io.writeln(
                    '<warning>'
                    'Warning: The lock file is not up to date with '
                    'the latest changes in pyproject.toml. '
                    'You may be getting outdated dependencies. '
                    'Run update to update them.'
                    '</warning>')

            for extra in self._extras:
                if extra not in self._locker.lock_data.get('extras', {}):
                    raise ValueError(
                        'Extra [{}] is not specified.'.format(extra))

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops, locked_repository)

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        self._io.new_line()

        # Execute operations
        actual_ops = [op for op in ops if not op.skipped]
        if not actual_ops and (self._execute_operations or self._dry_run):
            self._io.writeln('Nothing to install or update')

        if actual_ops and (self._execute_operations or self._dry_run):
            installs = []
            updates = []
            uninstalls = []
            skipped = []
            for op in ops:
                if op.skipped:
                    skipped.append(op)
                    continue

                if op.job_type == 'install':
                    installs.append('{}:{}'.format(
                        op.package.pretty_name,
                        op.package.full_pretty_version))
                elif op.job_type == 'update':
                    updates.append('{}:{}'.format(
                        op.target_package.pretty_name,
                        op.target_package.full_pretty_version))
                elif op.job_type == 'uninstall':
                    uninstalls.append(op.package.pretty_name)

            self._io.new_line()
            self._io.writeln(
                'Package operations: '
                '<info>{}</> install{}, '
                '<info>{}</> update{}, '
                '<info>{}</> removal{}'
                '{}'.format(
                    len(installs), '' if len(installs) == 1 else 's',
                    len(updates), '' if len(updates) == 1 else 's',
                    len(uninstalls), '' if len(uninstalls) == 1 else 's',
                    ', <info>{}</> skipped'.format(len(skipped))
                    if skipped and self.is_verbose() else ''))

        # Writing lock before installing
        if self._update and self._write_lock:
            updated_lock = self._locker.set_lock_data(self._package,
                                                      local_repo.packages)

            if updated_lock:
                self._io.writeln('')
                self._io.writeln('<info>Writing lock file</>')

        self._io.writeln('')
        for op in ops:
            self._execute(op)
Example #24
0
def installed() -> Repository:
    return Repository()
Example #25
0
    def _do_install(self, local_repo):
        from poetry.puzzle import Solver

        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked() and not self._lock:
                locked_repository = self._locker.locked_repository(True)

                # If no packages have been whitelisted (The ones we want to update),
                # we whitelist every package in the lock file.
                if not self._whitelist:
                    for pkg in locked_repository.packages:
                        self._whitelist.append(pkg.name)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError(
                        "Extra [{}] is not specified.".format(extra))

            self._io.write_line("<info>Updating dependencies</>")
            solver = Solver(
                self._package,
                self._pool,
                self._installed_repository,
                locked_repository,
                self._io,
                remove_untracked=self._remove_untracked,
            )

            ops = solver.solve(use_latest=self._whitelist)
        else:
            self._io.write_line(
                "<info>Installing dependencies from lock file</>")

            locked_repository = self._locker.locked_repository(True)

            if not self._locker.is_fresh():
                self._io.write_line(
                    "<warning>"
                    "Warning: The lock file is not up to date with "
                    "the latest changes in pyproject.toml. "
                    "You may be getting outdated dependencies. "
                    "Run update to update them."
                    "</warning>")

            for extra in self._extras:
                if extra not in self._locker.lock_data.get("extras", {}):
                    raise ValueError(
                        "Extra [{}] is not specified.".format(extra))

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops)

        if self._update:
            self._write_lock_file(local_repo)

            if self._lock:
                # If we are only in lock mode, no need to go any further
                return 0

        root = self._package
        if not self.is_dev_mode():
            root = root.clone()
            del root.dev_requires[:]
        elif self.is_dev_only():
            root = root.clone()
            del root.requires[:]

        if self._io.is_verbose():
            self._io.write_line("")
            self._io.write_line(
                "<info>Finding the necessary packages for the current system</>"
            )

        # We resolve again by only using the lock file
        pool = Pool(ignore_repository_names=True)

        # Making a new repo containing the packages
        # newly resolved and the ones from the current lock file
        repo = Repository()
        for package in local_repo.packages + locked_repository.packages:
            if not repo.has_package(package):
                repo.add_package(package)

        pool.add_repository(repo)

        # We whitelist all packages to be sure
        # that the latest ones are picked up
        whitelist = []
        for pkg in locked_repository.packages:
            whitelist.append(pkg.name)

        solver = Solver(
            root,
            pool,
            self._installed_repository,
            locked_repository,
            NullIO(),
            remove_untracked=self._remove_untracked,
        )

        with solver.use_environment(self._env):
            ops = solver.solve(use_latest=whitelist)

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        # Execute operations
        return self._execute(ops)
Example #26
0
def test_pool_raises_package_not_found_when_no_package_is_found():
    pool = Pool()
    pool.add_repository(Repository())

    with pytest.raises(PackageNotFound):
        pool.package("foo", "1.0.0")
Example #27
0
def test_pool_with_initial_repositories():
    repo = Repository()
    pool = Pool([repo])

    assert len(pool.repositories) == 1
    assert not pool.has_default()
Example #28
0
    def _do_install(self, local_repo: Repository) -> int:
        from poetry.puzzle import Solver

        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked() and not self._lock:
                locked_repository = self._locker.locked_repository()

                # If no packages have been whitelisted (The ones we want to update),
                # we whitelist every package in the lock file.
                if not self._whitelist:
                    for pkg in locked_repository.packages:
                        self._whitelist.append(pkg.name)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError(f"Extra [{extra}] is not specified.")

            self._io.write_line("<info>Updating dependencies</>")
            solver = Solver(
                self._package,
                self._pool,
                self._installed_repository,
                locked_repository,
                self._io,
            )

            with solver.provider.use_source_root(
                source_root=self._env.path.joinpath("src")
            ):
                ops = solver.solve(use_latest=self._whitelist).calculate_operations()
        else:
            self._io.write_line("<info>Installing dependencies from lock file</>")

            locked_repository = self._locker.locked_repository()

            if not self._locker.is_fresh():
                self._io.write_error_line(
                    "<warning>"
                    "Warning: poetry.lock is not consistent with pyproject.toml. "
                    "You may be getting improper dependencies. "
                    "Run `poetry lock [--no-update]` to fix it."
                    "</warning>"
                )

            for extra in self._extras:
                if extra not in self._locker.lock_data.get("extras", {}):
                    raise ValueError(f"Extra [{extra}] is not specified.")

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops)

        if self._update:
            self._write_lock_file(local_repo)

            if self._lock:
                # If we are only in lock mode, no need to go any further
                return 0

        if self._groups is not None:
            root = self._package.with_dependency_groups(list(self._groups), only=True)
        else:
            root = self._package.without_optional_dependency_groups()

        if self._io.is_verbose():
            self._io.write_line("")
            self._io.write_line(
                "<info>Finding the necessary packages for the current system</>"
            )

        # We resolve again by only using the lock file
        pool = Pool(ignore_repository_names=True)

        # Making a new repo containing the packages
        # newly resolved and the ones from the current lock file
        repo = Repository()
        for package in local_repo.packages + locked_repository.packages:
            if not repo.has_package(package):
                repo.add_package(package)

        pool.add_repository(repo)

        solver = Solver(
            root, pool, self._installed_repository, locked_repository, NullIO()
        )
        # Everything is resolved at this point, so we no longer need
        # to load deferred dependencies (i.e. VCS, URL and path dependencies)
        solver.provider.load_deferred(False)

        with solver.use_environment(self._env):
            ops = solver.solve(use_latest=self._whitelist).calculate_operations(
                with_uninstalls=self._requires_synchronization,
                synchronize=self._requires_synchronization,
            )

        if not self._requires_synchronization:
            # If no packages synchronisation has been requested we need
            # to calculate the uninstall operations
            from poetry.puzzle.transaction import Transaction

            transaction = Transaction(
                locked_repository.packages,
                [(package, 0) for package in local_repo.packages],
                installed_packages=self._installed_repository.packages,
                root_package=root,
            )

            ops = [
                op
                for op in transaction.calculate_operations(with_uninstalls=True)
                if op.job_type == "uninstall"
            ] + ops

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        # Execute operations
        return self._execute(ops)
Example #29
0
def repo():
    return Repository()
Example #30
0
    def _do_install(self, local_repo):
        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked() and not self._lock:
                locked_repository = self._locker.locked_repository(True)

                # If no packages have been whitelisted (The ones we want to update),
                # we whitelist every package in the lock file.
                if not self._whitelist:
                    for pkg in locked_repository.packages:
                        self._whitelist.append(pkg.name)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError(
                        "Extra [{}] is not specified.".format(extra))

            self._io.writeln("<info>Updating dependencies</>")
            solver = Solver(
                self._package,
                self._pool,
                self._installed_repository,
                locked_repository,
                self._io,
            )

            ops = solver.solve(use_latest=self._whitelist)
        else:
            self._io.writeln("<info>Installing dependencies from lock file</>")

            locked_repository = self._locker.locked_repository(True)

            if not self._locker.is_fresh():
                self._io.writeln(
                    "<warning>"
                    "Warning: The lock file is not up to date with "
                    "the latest changes in pyproject.toml. "
                    "You may be getting outdated dependencies. "
                    "Run update to update them."
                    "</warning>")

            for extra in self._extras:
                if extra not in self._locker.lock_data.get("extras", {}):
                    raise ValueError(
                        "Extra [{}] is not specified.".format(extra))

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops)

        if self._update:
            self._write_lock_file(local_repo)

            if self._lock:
                # If we are only in lock mode, no need to go any further
                return 0

        root = self._package
        if not self.is_dev_mode():
            root = root.clone()
            del root.dev_requires[:]

        with root.with_python_versions(".".join(
            [str(i) for i in self._env.version_info[:3]])):
            # We resolve again by only using the lock file
            pool = Pool()

            # Making a new repo containing the packages
            # newly resolved and the ones from the current lock file
            locked_repository = self._locker.locked_repository(True)
            repo = Repository()
            for package in local_repo.packages + locked_repository.packages:
                if not repo.has_package(package):
                    repo.add_package(package)

            pool.add_repository(repo)

            # We whitelist all packages to be sure
            # that the latest ones are picked up
            whitelist = []
            for pkg in locked_repository.packages:
                whitelist.append(pkg.name)

            solver = Solver(root, pool, self._installed_repository,
                            locked_repository, NullIO())

            ops = solver.solve(use_latest=whitelist)

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        self._io.new_line()

        # Execute operations
        actual_ops = [op for op in ops if not op.skipped]
        if not actual_ops and (self._execute_operations or self._dry_run):
            self._io.writeln("Nothing to install or update")

        if actual_ops and (self._execute_operations or self._dry_run):
            installs = []
            updates = []
            uninstalls = []
            skipped = []
            for op in ops:
                if op.skipped:
                    skipped.append(op)
                    continue

                if op.job_type == "install":
                    installs.append("{}:{}".format(
                        op.package.pretty_name,
                        op.package.full_pretty_version))
                elif op.job_type == "update":
                    updates.append("{}:{}".format(
                        op.target_package.pretty_name,
                        op.target_package.full_pretty_version,
                    ))
                elif op.job_type == "uninstall":
                    uninstalls.append(op.package.pretty_name)

            self._io.new_line()
            self._io.writeln("Package operations: "
                             "<info>{}</> install{}, "
                             "<info>{}</> update{}, "
                             "<info>{}</> removal{}"
                             "{}".format(
                                 len(installs),
                                 "" if len(installs) == 1 else "s",
                                 len(updates),
                                 "" if len(updates) == 1 else "s",
                                 len(uninstalls),
                                 "" if len(uninstalls) == 1 else "s",
                                 ", <info>{}</> skipped".format(len(skipped))
                                 if skipped and self.is_verbose() else "",
                             ))

        self._io.writeln("")
        for op in ops:
            self._execute(op)
Example #31
0
    def _do_install(self, local_repo):
        locked_repository = Repository()
        if self._update:
            if self._locker.is_locked():
                locked_repository = self._locker.locked_repository(True)

                # If no packages have been whitelisted (The ones we want to update),
                # we whitelist every package in the lock file.
                if not self._whitelist:
                    for pkg in locked_repository.packages:
                        self._whitelist.append(pkg.name)

            # Checking extras
            for extra in self._extras:
                if extra not in self._package.extras:
                    raise ValueError("Extra [{}] is not specified.".format(extra))

            self._io.writeln("<info>Updating dependencies</>")
            solver = Solver(
                self._package,
                self._pool,
                self._installed_repository,
                locked_repository,
                self._io,
            )

            ops = solver.solve(use_latest=self._whitelist)
        else:
            self._io.writeln("<info>Installing dependencies from lock file</>")

            locked_repository = self._locker.locked_repository(True)

            if not self._locker.is_fresh():
                self._io.writeln(
                    "<warning>"
                    "Warning: The lock file is not up to date with "
                    "the latest changes in pyproject.toml. "
                    "You may be getting outdated dependencies. "
                    "Run update to update them."
                    "</warning>"
                )

            for extra in self._extras:
                if extra not in self._locker.lock_data.get("extras", {}):
                    raise ValueError("Extra [{}] is not specified.".format(extra))

            # If we are installing from lock
            # Filter the operations by comparing it with what is
            # currently installed
            ops = self._get_operations_from_lock(locked_repository)

        self._populate_local_repo(local_repo, ops, locked_repository)

        with self._package.with_python_versions(
            ".".join([str(i) for i in self._venv.version_info[:3]])
        ):
            # We resolve again by only using the lock file
            pool = Pool()

            # Making a new repo containing the packages
            # newly resolved and the ones from the current lock file
            locked_repository = self._locker.locked_repository(True)
            repo = Repository()
            for package in local_repo.packages + locked_repository.packages:
                if not repo.has_package(package):
                    repo.add_package(package)

            pool.add_repository(repo)

            # We whitelist all packages to be sure
            # that the latest ones are picked up
            whitelist = []
            for pkg in locked_repository.packages:
                whitelist.append(pkg.name)

            solver = Solver(
                self._package,
                pool,
                self._installed_repository,
                locked_repository,
                NullIO(),
            )

            ops = solver.solve(use_latest=whitelist)

        # We need to filter operations so that packages
        # not compatible with the current system,
        # or optional and not requested, are dropped
        self._filter_operations(ops, local_repo)

        self._io.new_line()

        # Execute operations
        actual_ops = [op for op in ops if not op.skipped]
        if not actual_ops and (self._execute_operations or self._dry_run):
            self._io.writeln("Nothing to install or update")

        if actual_ops and (self._execute_operations or self._dry_run):
            installs = []
            updates = []
            uninstalls = []
            skipped = []
            for op in ops:
                if op.skipped:
                    skipped.append(op)
                    continue

                if op.job_type == "install":
                    installs.append(
                        "{}:{}".format(
                            op.package.pretty_name, op.package.full_pretty_version
                        )
                    )
                elif op.job_type == "update":
                    updates.append(
                        "{}:{}".format(
                            op.target_package.pretty_name,
                            op.target_package.full_pretty_version,
                        )
                    )
                elif op.job_type == "uninstall":
                    uninstalls.append(op.package.pretty_name)

            self._io.new_line()
            self._io.writeln(
                "Package operations: "
                "<info>{}</> install{}, "
                "<info>{}</> update{}, "
                "<info>{}</> removal{}"
                "{}".format(
                    len(installs),
                    "" if len(installs) == 1 else "s",
                    len(updates),
                    "" if len(updates) == 1 else "s",
                    len(uninstalls),
                    "" if len(uninstalls) == 1 else "s",
                    ", <info>{}</> skipped".format(len(skipped))
                    if skipped and self.is_verbose()
                    else "",
                )
            )

        # Writing lock before installing
        if self._update and self._write_lock:
            updated_lock = self._locker.set_lock_data(
                self._package, local_repo.packages
            )

            if updated_lock:
                self._io.writeln("")
                self._io.writeln("<info>Writing lock file</>")

        self._io.writeln("")
        for op in ops:
            self._execute(op)