Skip to content

Commit 175af5f

Browse files
authored
exporter: ensure local references use uri
This change ensures that when exporting `requirements.txt`, local direct reference dependencies are exported as uri and not paths. Resolves: #3189
1 parent b55968a commit 175af5f

File tree

2 files changed

+89
-9
lines changed

2 files changed

+89
-9
lines changed

poetry/utils/exporter.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from clikit.api.io import IO
66

7+
from poetry.core.packages.utils.utils import path_to_url
78
from poetry.poetry import Poetry
89
from poetry.utils._compat import Path
910
from poetry.utils._compat import decode
@@ -70,23 +71,30 @@ def _export_requirements_txt(
7071
line += "-e "
7172

7273
requirement = dependency.to_pep_508(with_extras=False)
73-
is_direct_reference = (
74-
dependency.is_vcs()
75-
or dependency.is_url()
76-
or dependency.is_file()
77-
or dependency.is_directory()
74+
is_direct_local_reference = (
75+
dependency.is_file() or dependency.is_directory()
7876
)
77+
is_direct_remote_reference = dependency.is_vcs() or dependency.is_url()
7978

80-
if is_direct_reference:
79+
if is_direct_remote_reference:
8180
line = requirement
81+
elif is_direct_local_reference:
82+
dependency_uri = path_to_url(dependency.source_url)
83+
line = "{} @ {}".format(dependency.name, dependency_uri)
8284
else:
8385
line = "{}=={}".format(package.name, package.version)
86+
87+
if not is_direct_remote_reference:
8488
if ";" in requirement:
8589
markers = requirement.split(";", 1)[1].strip()
8690
if markers:
8791
line += "; {}".format(markers)
8892

89-
if not is_direct_reference and package.source_url:
93+
if (
94+
not is_direct_remote_reference
95+
and not is_direct_local_reference
96+
and package.source_url
97+
):
9098
indexes.add(package.source_url)
9199

92100
if package.files and with_hashes:

tests/utils/test_exporter.py

+74-2
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,79 @@ def test_exporter_can_export_requirements_txt_with_directory_packages(
833833
expected = """\
834834
foo @ {}/tests/fixtures/sample_project
835835
""".format(
836-
working_directory.as_posix()
836+
working_directory.as_uri()
837+
)
838+
839+
assert expected == content
840+
841+
842+
def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
843+
tmp_dir, poetry, working_directory
844+
):
845+
poetry.locker.mock_lock_data(
846+
{
847+
"package": [
848+
{
849+
"name": "foo",
850+
"version": "1.2.3",
851+
"category": "main",
852+
"optional": False,
853+
"python-versions": "*",
854+
"source": {
855+
"type": "directory",
856+
"url": "tests/fixtures/sample_project",
857+
"reference": "",
858+
},
859+
},
860+
{
861+
"name": "bar",
862+
"version": "4.5.6",
863+
"category": "main",
864+
"optional": False,
865+
"python-versions": "*",
866+
"source": {
867+
"type": "directory",
868+
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar",
869+
"reference": "",
870+
},
871+
},
872+
{
873+
"name": "baz",
874+
"version": "7.8.9",
875+
"category": "main",
876+
"optional": False,
877+
"python-versions": "*",
878+
"source": {
879+
"type": "directory",
880+
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar/..",
881+
"reference": "",
882+
},
883+
},
884+
],
885+
"metadata": {
886+
"python-versions": "*",
887+
"content-hash": "123456789",
888+
"hashes": {"foo": [], "bar": [], "baz": []},
889+
},
890+
}
891+
)
892+
set_package_requires(poetry)
893+
894+
exporter = Exporter(poetry)
895+
896+
exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")
897+
898+
with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
899+
content = f.read()
900+
901+
expected = """\
902+
bar @ {}/tests/fixtures/project_with_nested_local/bar
903+
baz @ {}/tests/fixtures/project_with_nested_local
904+
foo @ {}/tests/fixtures/sample_project
905+
""".format(
906+
working_directory.as_uri(),
907+
working_directory.as_uri(),
908+
working_directory.as_uri(),
837909
)
838910

839911
assert expected == content
@@ -878,7 +950,7 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker
878950
expected = """\
879951
foo @ {}/tests/fixtures/sample_project; python_version < "3.7"
880952
""".format(
881-
working_directory.as_posix()
953+
working_directory.as_uri()
882954
)
883955

884956
assert expected == content

0 commit comments

Comments
 (0)