diff --git a/docs/docs/cli.md b/docs/docs/cli.md index db91f5822a5..f0da6446b62 100644 --- a/docs/docs/cli.md +++ b/docs/docs/cli.md @@ -433,7 +433,7 @@ poetry export -f requirements.txt > requirements.txt !!!note - Only the `requirements.txt` format is currently supported. + Only the `requirements.txt` and `setup.py` format is currently supported. ### Options diff --git a/poetry/console/commands/export.py b/poetry/console/commands/export.py index 37cfc1394e8..3c327e4ac6e 100644 --- a/poetry/console/commands/export.py +++ b/poetry/console/commands/export.py @@ -13,16 +13,22 @@ class ExportCommand(Command): options = [ option("format", "f", "Format to export to.", flag=False), option("output", "o", "The name of the output file.", flag=False), - option("without-hashes", None, "Exclude hashes from the exported file."), - option("dev", None, "Include development dependencies."), + option( + "without-hashes", None, "Exclude hashes from the exported file if used." + ), + option("dev", None, "Include development dependencies if configurable."), option( "extras", "E", - "Extra sets of dependencies to include.", + "Extra sets of dependencies to include if configurable.", flag=False, multiple=True, ), - option("with-credentials", None, "Include credentials for extra indices."), + option( + "with-credentials", + None, + "Include credentials for extra indices if format supports indices.", + ), ] def handle(self): diff --git a/poetry/utils/exporter.py b/poetry/utils/exporter.py index 3c05a4da864..227c657bcc1 100644 --- a/poetry/utils/exporter.py +++ b/poetry/utils/exporter.py @@ -1,7 +1,10 @@ +from typing import Any from typing import Union from clikit.api.io import IO +from poetry.io.null_io import NullIO +from poetry.masonry.builders import SdistBuilder from poetry.packages.directory_dependency import DirectoryDependency from poetry.packages.file_dependency import FileDependency from poetry.packages.url_dependency import URLDependency @@ -9,6 +12,7 @@ from poetry.poetry import Poetry from poetry.utils._compat import Path from poetry.utils._compat import decode +from poetry.utils.env import NullEnv class Exporter(object): @@ -16,7 +20,7 @@ class Exporter(object): Exporter class to export a lock file to alternative formats. """ - ACCEPTED_FORMATS = ("requirements.txt",) + ACCEPTED_FORMATS = ("requirements.txt", "setup.py") ALLOWED_HASH_ALGORITHMS = ("sha256", "sha384", "sha512") def __init__(self, poetry): # type: (Poetry) -> None @@ -163,6 +167,13 @@ def _export_requirements_txt( self._output(content, cwd, output) + def _export_setup_py( + self, cwd, output, *_, **__ + ): # type: (Path, Union[IO, str], Any, Any) -> None + builder = SdistBuilder(self._poetry, NullEnv(), NullIO()) + content = decode(builder.build_setup()) + self._output(content, cwd, output) + def _output( self, content, cwd, output ): # type: (str, Path, Union[IO, str]) -> None diff --git a/tests/utils/test_exporter.py b/tests/utils/test_exporter.py index 4c67820c346..81e035d9208 100644 --- a/tests/utils/test_exporter.py +++ b/tests/utils/test_exporter.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- import sys import pytest @@ -6,7 +7,7 @@ from poetry.poetry import Poetry from poetry.repositories.auth import Auth from poetry.repositories.legacy_repository import LegacyRepository -from poetry.utils._compat import Path +from poetry.utils._compat import Path, encode, decode from poetry.utils.exporter import Exporter @@ -40,7 +41,7 @@ def locker(): @pytest.fixture def poetry(fixture_dir, locker): - p = Poetry.create(fixture_dir("sample_project")) + p = Poetry.create(fixture_dir("simple_project")) p._locker = locker return p @@ -799,3 +800,45 @@ def test_exporter_exports_requirements_txt_to_standard_output(tmp_dir, poetry, c """ assert out == expected + + +@pytest.mark.skipif( + sys.version_info < (3, 4), reason="python2.7 fails due to unicode issues" +) +def test_exporter_can_export_setup_py_with_standard_packages(tmp_dir, poetry): + exporter = Exporter(poetry) + + exporter.export("setup.py", Path(tmp_dir), "setup.py") + + with (Path(tmp_dir) / "setup.py").open(encoding="utf-8") as f: + content = f.read() + + expected = """# -*- coding: utf-8 -*- +from distutils.core import setup + +packages = \\ +['simple_project'] + +package_data = \\ +{'': ['*']} + +setup_kwargs = { + 'name': 'simple-project', + 'version': '1.2.3', + 'description': 'Some description.', + 'long_description': 'My Package\\n==========\\n', + 'author': 'Sébastien Eustace', + 'author_email': 'sebastien@eustace.io', + 'maintainer': None, + 'maintainer_email': None, + 'url': 'https://poetry.eustace.io', + 'packages': packages, + 'package_data': package_data, + 'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*', +} + + +setup(**setup_kwargs) +""" + + assert expected == content