Commit 18abfd7b by Arun Babu Neelicattu Committed by finswimmer

locker: unify duplicate dependencies on export

(cherry picked from commit 733736cd1c2ea6189a77e34ab640059dbff2be23)
parent a46b5c2f
import itertools
import json import json
import logging import logging
import os import os
...@@ -6,6 +5,7 @@ import re ...@@ -6,6 +5,7 @@ import re
from copy import deepcopy from copy import deepcopy
from hashlib import sha256 from hashlib import sha256
from typing import Iterable
from typing import Iterator from typing import Iterator
from typing import List from typing import List
from typing import Optional from typing import Optional
...@@ -188,7 +188,7 @@ class Locker(object): ...@@ -188,7 +188,7 @@ class Locker(object):
@classmethod @classmethod
def get_project_dependencies( def get_project_dependencies(
cls, project_requires, locked_packages, pinned_versions=False, with_nested=False cls, project_requires, locked_packages, pinned_versions=False, with_nested=False
): # type: (List[Dependency], List[Package], bool, bool) -> List[Dependency] ): # type: (List[Dependency], List[Package], bool, bool) -> Iterable[Dependency]
# group packages entries by name, this is required because requirement might use # group packages entries by name, this is required because requirement might use
# different constraints # different constraints
packages_by_name = {} packages_by_name = {}
...@@ -296,10 +296,17 @@ class Locker(object): ...@@ -296,10 +296,17 @@ class Locker(object):
__walk_level(dependencies, 0) __walk_level(dependencies, 0)
return sorted( # Merge same dependencies using marker union
itertools.chain(dependencies, nested_dependencies.values()), for requirement in dependencies:
key=lambda x: x.name.lower(), key = (requirement.name, requirement.pretty_constraint)
) if key not in nested_dependencies:
nested_dependencies[key] = requirement
else:
nested_dependencies[key].marker = nested_dependencies[key].marker.union(
requirement.marker
)
return sorted(nested_dependencies.values(), key=lambda x: x.name.lower())
def get_project_dependency_packages( def get_project_dependency_packages(
self, project_requires, dev=False, extras=None self, project_requires, dev=False, extras=None
......
...@@ -256,8 +256,12 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers( ...@@ -256,8 +256,12 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers(
assert expected == {} assert expected == {}
@pytest.mark.parametrize(
"dev,lines",
[(False, ['a==1.2.3; python_version < "3.8"']), (True, ["a==1.2.3", "b==4.5.6"])],
)
def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_any( def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_any(
tmp_dir, poetry tmp_dir, poetry, dev, lines
): ):
poetry.locker.mock_lock_data( poetry.locker.mock_lock_data(
{ {
...@@ -295,24 +299,16 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_a ...@@ -295,24 +299,16 @@ def test_exporter_can_export_requirements_txt_with_nested_packages_and_markers_a
Factory.create_dependency( Factory.create_dependency(
name="b", constraint=dict(version="^4.5.6"), category="dev" name="b", constraint=dict(version="^4.5.6"), category="dev"
), ),
Factory.create_dependency(name="a", constraint=dict(version="^1.2.3")),
] ]
exporter = Exporter(poetry) exporter = Exporter(poetry)
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=True) exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt", dev=dev)
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f: with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read() content = f.read()
assert ( assert content.strip() == "\n".join(lines)
content
== """\
a==1.2.3
a==1.2.3; python_version < "3.8"
b==4.5.6
"""
)
def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes( def test_exporter_can_export_requirements_txt_with_standard_packages_and_hashes(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment