Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 1.0.0 issues #50

Merged
merged 14 commits into from
Apr 11, 2022
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 8 additions & 21 deletions src/poetry_plugin_export/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,12 +78,9 @@ def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None:
content = ""
dependency_lines = set()

if self._groups is not None:
root = self._poetry.package.with_dependency_groups(
list(self._groups), only=True
)
else:
root = self._poetry.package.without_optional_dependency_groups()
root = self._poetry.package.with_dependency_groups(
list(self._groups or ["default"]), only=True
)

locked_repository = self._poetry.locker.locked_repository(True)
abn marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -98,17 +95,9 @@ def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None:
ops = solver.solve().calculate_operations()
packages = sorted((op.package for op in ops), key=lambda pkg: pkg.name)

# Get project dependencies.
if self._groups is not None:
abn marked this conversation as resolved.
Show resolved Hide resolved
root_package = self._poetry.package.with_dependency_groups(
list(self._groups), only=True
)
else:
root_package = self._poetry.package.without_optional_dependency_groups()

for dependency_package in self._poetry.locker.get_project_dependency_packages(
project_requires=root_package.all_requires,
project_python_marker=root_package.python_marker,
project_requires=root.all_requires,
project_python_marker=root.python_marker,
extras=self._extras,
):
line = ""
Expand Down Expand Up @@ -161,11 +150,9 @@ def _export_requirements_txt(self, cwd: Path, output: IO | str) -> None:

hashes.append(f"{algorithm}:{h}")

if hashes:
line += " \\\n"
for i, h in enumerate(hashes):
suffix = " \\\n" if i < len(hashes) - 1 else ""
line += f" --hash={h}{suffix}"
for h in hashes:
line += f" \\\n --hash={h}"
abn marked this conversation as resolved.
Show resolved Hide resolved

dependency_lines.add(line)

content += "\n".join(sorted(dependency_lines))
Expand Down
8 changes: 4 additions & 4 deletions tests/command/test_command_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def _export_requirements(tester: CommandTester, poetry: Poetry) -> None:
foo==1.0.0 ; {MARKER_PY}
"""

assert expected == content
assert content == expected


def test_export_exports_requirements_txt_file_locks_if_no_lock_file(
Expand Down Expand Up @@ -116,7 +116,7 @@ def test_export_prints_to_stdout_by_default(tester: CommandTester, do_lock: None
expected = f"""\
foo==1.0.0 ; {MARKER_PY}
"""
assert expected == tester.io.fetch_output()
assert tester.io.fetch_output() == expected


def test_export_uses_requirements_txt_format_by_default(
Expand All @@ -126,7 +126,7 @@ def test_export_uses_requirements_txt_format_by_default(
expected = f"""\
foo==1.0.0 ; {MARKER_PY}
"""
assert expected == tester.io.fetch_output()
assert tester.io.fetch_output() == expected


def test_export_includes_extras_by_flag(tester: CommandTester, do_lock: None):
Expand All @@ -135,7 +135,7 @@ def test_export_includes_extras_by_flag(tester: CommandTester, do_lock: None):
bar==1.1.0 ; {MARKER_PY}
foo==1.0.0 ; {MARKER_PY}
"""
assert expected == tester.io.fetch_output()
assert tester.io.fetch_output() == expected


def test_export_with_urls(
Expand Down
91 changes: 48 additions & 43 deletions tests/test_exporter.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
from __future__ import annotations

import sys

from pathlib import Path
from typing import TYPE_CHECKING
from typing import Any
from typing import Iterator

import pytest

from cleo.io.buffered_io import BufferedIO
from poetry.core.packages.dependency import Dependency
from poetry.core.toml.file import TOMLFile
from poetry.core.version.markers import parse_marker
from poetry.factory import Factory
from poetry.packages import Locker as BaseLocker
from poetry.repositories.legacy_repository import LegacyRepository
from poetry.utils.exporter import Exporter

from poetry_plugin_export.exporter import Exporter
from tests.markers import MARKER_PY
from tests.markers import MARKER_PY27
from tests.markers import MARKER_PY36
Expand All @@ -33,7 +32,6 @@


if TYPE_CHECKING:
from _pytest.capture import CaptureFixture
from poetry.poetry import Poetry
from pytest_mock import MockerFixture

Expand Down Expand Up @@ -92,11 +90,14 @@ def poetry(fixture_dir: FixtureDirGetter, locker: Locker) -> Poetry:

def set_package_requires(poetry: Poetry, skip: set[str] | None = None) -> None:
skip = skip or set()
packages = poetry.locker.locked_repository(with_dev_reqs=True).packages
packages = poetry.locker.locked_repository().packages
package = poetry.package.with_dependency_groups([], only=True)
for pkg in packages:
if pkg.name not in skip:
package.add_dependency(pkg.to_dependency())
dep = pkg.to_dependency()
if pkg.category == "dev":
dep._groups = frozenset(["dev"])
package.add_dependency(dep)

poetry._package = package

Expand Down Expand Up @@ -538,7 +539,9 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_a
poetry._package = root

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=dev)
if dev:
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -623,9 +626,8 @@ def test_exporter_requirements_txt_with_standard_packages_and_hashes_disabled(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export(
"requirements.txt", Path(tmp_dir), "requirements.txt", with_hashes=False
)
exporter.with_hashes(False)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -713,7 +715,8 @@ def test_exporter_exports_requirements_txt_with_dev_packages_if_opted_in(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True)
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -759,7 +762,8 @@ def test_exporter_exports_requirements_txt_without_optional_packages(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True)
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -844,13 +848,13 @@ def test_exporter_exports_requirements_txt_with_optional_packages(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.only_groups(["default", "dev"])
exporter.with_hashes(False)
exporter.with_extras(extras)
exporter.export(
"requirements.txt",
Path(tmp_dir),
"requirements.txt",
dev=True,
with_hashes=False,
extras=extras,
)

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
Expand Down Expand Up @@ -1063,9 +1067,8 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_multiple_
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export(
"requirements.txt", Path(tmp_dir), "requirements.txt", with_hashes=False
)
exporter.with_hashes(False)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1409,7 +1412,8 @@ def test_exporter_exports_requirements_txt_with_legacy_packages(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True)
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1466,9 +1470,9 @@ def test_exporter_exports_requirements_txt_with_url_false(tmp_dir: str, poetry:
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export(
"requirements.txt", Path(tmp_dir), "requirements.txt", dev=True, with_urls=False
)
exporter.only_groups(["default", "dev"])
exporter.with_urls(False)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1517,7 +1521,8 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_trusted_host(
)
set_package_requires(poetry)
exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True)
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1599,7 +1604,9 @@ def test_exporter_exports_requirements_txt_with_dev_extras(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=dev)
if dev:
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1672,7 +1679,8 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_and_duplicate_so
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True)
exporter.only_groups(["default", "dev"])
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()
Expand Down Expand Up @@ -1737,12 +1745,12 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_and_credentials(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.only_groups(["default", "dev"])
exporter.with_credentials()
exporter.export(
"requirements.txt",
Path(tmp_dir),
"requirements.txt",
dev=True,
with_credentials=True,
)

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
Expand All @@ -1761,7 +1769,7 @@ def test_exporter_exports_requirements_txt_with_legacy_packages_and_credentials(


def test_exporter_exports_requirements_txt_to_standard_output(
tmp_dir: str, poetry: Poetry, capsys: CaptureFixture
tmp_dir: str, poetry: Poetry
):
poetry.locker.mock_lock_data(
{
Expand Down Expand Up @@ -1791,20 +1799,18 @@ def test_exporter_exports_requirements_txt_to_standard_output(
set_package_requires(poetry)

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)
io = BufferedIO()
exporter.export("requirements.txt", Path(tmp_dir), io)

out, err = capsys.readouterr()
expected = f"""\
bar==4.5.6 ; {MARKER_PY}
foo==1.2.3 ; {MARKER_PY}
"""

assert out == expected
assert io.fetch_output() == expected


def test_exporter_doesnt_confuse_repeated_packages(
tmp_dir: str, poetry: Poetry, capsys: CaptureFixture
):
def test_exporter_doesnt_confuse_repeated_packages(tmp_dir: str, poetry: Poetry):
# Testcase derived from <https://github.com/python-poetry/poetry/issues/5141>.
poetry.locker.mock_lock_data(
{
Expand Down Expand Up @@ -1905,9 +1911,10 @@ def test_exporter_doesnt_confuse_repeated_packages(
poetry._package = root

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)
exporter.only_groups(["default", "dev"])
io = BufferedIO()
exporter.export("requirements.txt", Path(tmp_dir), io)

out, err = capsys.readouterr()
expected = f"""\
celery==5.1.2 ; {MARKER_PY36_ONLY}
celery==5.2.3 ; {MARKER_PY37}
Expand All @@ -1918,12 +1925,10 @@ def test_exporter_doesnt_confuse_repeated_packages(
click==8.0.3 ; {MARKER_PY37.union(MARKER_PY37_PY400)}
"""

assert out == expected
assert io.fetch_output() == expected


def test_exporter_handles_extras_next_to_non_extras(
tmp_dir: str, poetry: Poetry, capsys: CaptureFixture
):
def test_exporter_handles_extras_next_to_non_extras(tmp_dir: str, poetry: Poetry):
# Testcase similar to the solver testcase added at #5305.
poetry.locker.mock_lock_data(
{
Expand Down Expand Up @@ -2019,14 +2024,14 @@ def test_exporter_handles_extras_next_to_non_extras(
poetry._package = root

exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), sys.stdout)
io = BufferedIO()
exporter.export("requirements.txt", Path(tmp_dir), io)

out, err = capsys.readouterr()
expected = f"""\
localstack-ext==1.0.0 ; {MARKER_PY36}
localstack==1.0.0 ; {MARKER_PY36}
something-else==1.0.0 ; {MARKER_PY36}
something==1.0.0 ; {MARKER_PY36}
"""

assert out == expected
assert io.fetch_output() == expected