Skip to content

Commit

Permalink
exporter: ensure local references use uri
Browse files Browse the repository at this point in the history
This change ensures that when exporting `requirements.txt`, local 
direct reference dependencies are exported as uri and not paths.

Resolves: #3189
  • Loading branch information
maxispeicher authored Mar 20, 2021
1 parent b55968a commit 175af5f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 9 deletions.
22 changes: 15 additions & 7 deletions poetry/utils/exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from clikit.api.io import IO

from poetry.core.packages.utils.utils import path_to_url
from poetry.poetry import Poetry
from poetry.utils._compat import Path
from poetry.utils._compat import decode
Expand Down Expand Up @@ -70,23 +71,30 @@ def _export_requirements_txt(
line += "-e "

requirement = dependency.to_pep_508(with_extras=False)
is_direct_reference = (
dependency.is_vcs()
or dependency.is_url()
or dependency.is_file()
or dependency.is_directory()
is_direct_local_reference = (
dependency.is_file() or dependency.is_directory()
)
is_direct_remote_reference = dependency.is_vcs() or dependency.is_url()

if is_direct_reference:
if is_direct_remote_reference:
line = requirement
elif is_direct_local_reference:
dependency_uri = path_to_url(dependency.source_url)
line = "{} @ {}".format(dependency.name, dependency_uri)
else:
line = "{}=={}".format(package.name, package.version)

if not is_direct_remote_reference:
if ";" in requirement:
markers = requirement.split(";", 1)[1].strip()
if markers:
line += "; {}".format(markers)

if not is_direct_reference and package.source_url:
if (
not is_direct_remote_reference
and not is_direct_local_reference
and package.source_url
):
indexes.add(package.source_url)

if package.files and with_hashes:
Expand Down
76 changes: 74 additions & 2 deletions tests/utils/test_exporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,79 @@ def test_exporter_can_export_requirements_txt_with_directory_packages(
expected = """\
foo @ {}/tests/fixtures/sample_project
""".format(
working_directory.as_posix()
working_directory.as_uri()
)

assert expected == content


def test_exporter_can_export_requirements_txt_with_nested_directory_packages(
tmp_dir, poetry, working_directory
):
poetry.locker.mock_lock_data(
{
"package": [
{
"name": "foo",
"version": "1.2.3",
"category": "main",
"optional": False,
"python-versions": "*",
"source": {
"type": "directory",
"url": "tests/fixtures/sample_project",
"reference": "",
},
},
{
"name": "bar",
"version": "4.5.6",
"category": "main",
"optional": False,
"python-versions": "*",
"source": {
"type": "directory",
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar",
"reference": "",
},
},
{
"name": "baz",
"version": "7.8.9",
"category": "main",
"optional": False,
"python-versions": "*",
"source": {
"type": "directory",
"url": "tests/fixtures/sample_project/../project_with_nested_local/bar/..",
"reference": "",
},
},
],
"metadata": {
"python-versions": "*",
"content-hash": "123456789",
"hashes": {"foo": [], "bar": [], "baz": []},
},
}
)
set_package_requires(poetry)

exporter = Exporter(poetry)

exporter.export("requirements.txt", Path(tmp_dir), "requirements.txt")

with (Path(tmp_dir) / "requirements.txt").open(encoding="utf-8") as f:
content = f.read()

expected = """\
bar @ {}/tests/fixtures/project_with_nested_local/bar
baz @ {}/tests/fixtures/project_with_nested_local
foo @ {}/tests/fixtures/sample_project
""".format(
working_directory.as_uri(),
working_directory.as_uri(),
working_directory.as_uri(),
)

assert expected == content
Expand Down Expand Up @@ -878,7 +950,7 @@ def test_exporter_can_export_requirements_txt_with_directory_packages_and_marker
expected = """\
foo @ {}/tests/fixtures/sample_project; python_version < "3.7"
""".format(
working_directory.as_posix()
working_directory.as_uri()
)

assert expected == content
Expand Down

0 comments on commit 175af5f

Please sign in to comment.