diff --git a/bases/polylith/cli/create.py b/bases/polylith/cli/create.py index 667a7cf8..6658c0cf 100644 --- a/bases/polylith/cli/create.py +++ b/bases/polylith/cli/create.py @@ -1,6 +1,6 @@ from pathlib import Path -from polylith import project, repo +from polylith import project from polylith.bricks import base, component from polylith.commands.create import create from polylith.workspace.create import create_workspace @@ -29,16 +29,10 @@ def component_command( def _create_project(root: Path, options: dict): - root_pyproject: dict = project.get_toml(root / repo.default_toml) name = options["package"] description = options["description"] - if repo.is_poetry(root_pyproject): - template = project.templates.poetry_pyproject - elif repo.is_hatch(root_pyproject): - template = project.templates.hatch_pyproject - elif repo.is_pdm(root_pyproject): - template = project.templates.pdm_pyproject + template = project.get_project_template(root) if not template: print("Failed to guess the used Package & Dependency Management") diff --git a/components/polylith/poetry/commands/create_project.py b/components/polylith/poetry/commands/create_project.py index 4bfd1bb4..800a64d8 100644 --- a/components/polylith/poetry/commands/create_project.py +++ b/components/polylith/poetry/commands/create_project.py @@ -12,7 +12,8 @@ def create_project(root: Path, options: dict): package = options["package"] desc = options["description"] or "" - project.create_project(root, project.templates.poetry_pyproject, package, desc) + template = project.get_project_template(root) + project.create_project(root, template, package, desc) class CreateProjectCommand(Command): diff --git a/components/polylith/project/__init__.py b/components/polylith/project/__init__.py index 45309b8e..f9d975f5 100644 --- a/components/polylith/project/__init__.py +++ b/components/polylith/project/__init__.py @@ -1,12 +1,18 @@ from polylith.project import templates from polylith.project.create import create_project -from polylith.project.get import get_packages_for_projects, get_project_name, get_toml +from polylith.project.get import ( + get_packages_for_projects, + get_project_name, + get_project_template, + get_toml, +) from polylith.project.parser import parse_package_paths __all__ = [ "create_project", "get_packages_for_projects", "get_project_name", + "get_project_template", "get_toml", "parse_package_paths", "templates", diff --git a/components/polylith/project/get.py b/components/polylith/project/get.py index 50f6df06..94010f3f 100644 --- a/components/polylith/project/get.py +++ b/components/polylith/project/get.py @@ -4,6 +4,7 @@ import tomlkit from polylith import configuration, repo, toml +from polylith.project import templates def get_project_name(toml_data) -> str: @@ -64,3 +65,29 @@ def get_packages_for_projects(root: Path) -> List[dict]: } for d in toml_files ] + + +def _get_poetry_template(pyproject: dict) -> str: + if repo.is_pep_621_ready(pyproject): + return templates.poetry_pep621_pyproject + + return templates.poetry_pyproject + + +def guess_project_template(pyproject: dict) -> str: + if repo.is_poetry(pyproject): + template = _get_poetry_template(pyproject) + elif repo.is_hatch(pyproject): + template = templates.hatch_pyproject + elif repo.is_pdm(pyproject): + template = templates.pdm_pyproject + else: + raise ValueError("Failed to guess the type of Project") + + return template + + +def get_project_template(root: Path) -> str: + root_pyproject = get_toml(root / repo.default_toml) + + return guess_project_template(root_pyproject) diff --git a/components/polylith/project/templates.py b/components/polylith/project/templates.py index 695a93a4..34950f43 100644 --- a/components/polylith/project/templates.py +++ b/components/polylith/project/templates.py @@ -16,6 +16,25 @@ build-backend = "poetry.core.masonry.api" """ +poetry_pep621_pyproject = """\ +[tool.poetry] +packages = [] + +[project] +name = "{name}" +version = "0.1.0" +{description} +{authors} + +requires-python = "{python_version}" + +dependencies = [] + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" +""" + hatch_pyproject = """\ [build-system] requires = ["hatchling", "hatch-polylith-bricks"] diff --git a/components/polylith/repo/repo.py b/components/polylith/repo/repo.py index 37894d51..57521435 100644 --- a/components/polylith/repo/repo.py +++ b/components/polylith/repo/repo.py @@ -80,7 +80,4 @@ def is_pdm(pyproject: dict) -> bool: def is_pep_621_ready(pyproject: dict) -> bool: - if is_poetry(pyproject): - return False - return pyproject.get("project", {}).get("name") is not None diff --git a/components/polylith/toml/core.py b/components/polylith/toml/core.py index aa9124f9..e2fc9f50 100644 --- a/components/polylith/toml/core.py +++ b/components/polylith/toml/core.py @@ -93,8 +93,12 @@ def get_pep_621_optional_dependencies(data) -> List[str]: return sum(matrix, []) +def is_poetry_without_pep_621_support(data) -> bool: + return repo.is_poetry(data) and not repo.is_pep_621_ready(data) + + def parse_project_dependencies(data) -> dict: - if repo.is_poetry(data): + if is_poetry_without_pep_621_support(data): deps = data["tool"]["poetry"].get("dependencies", {}) res: dict = reduce(parse_poetry_dependency, deps.items(), {}) diff --git a/projects/hatch_polylith_bricks/pyproject.toml b/projects/hatch_polylith_bricks/pyproject.toml index 48e9d8d9..2db81d36 100644 --- a/projects/hatch_polylith_bricks/pyproject.toml +++ b/projects/hatch_polylith_bricks/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "hatch-polylith-bricks" -version = "1.2.6" +version = "1.2.7" description = "Hatch build hook plugin for Polylith" authors = ['David Vujic'] homepage = "https://davidvujic.github.io/python-polylith-docs/" diff --git a/projects/pdm_polylith_bricks/pyproject.toml b/projects/pdm_polylith_bricks/pyproject.toml index 25ba92d5..029151ea 100644 --- a/projects/pdm_polylith_bricks/pyproject.toml +++ b/projects/pdm_polylith_bricks/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pdm-polylith-bricks" -version = "1.0.8" +version = "1.0.9" description = "a PDM build hook for Polylith" authors = ["David Vujic"] homepage = "https://davidvujic.github.io/python-polylith-docs/" diff --git a/projects/pdm_polylith_workspace/pyproject.toml b/projects/pdm_polylith_workspace/pyproject.toml index a422dc4d..1742342d 100644 --- a/projects/pdm_polylith_workspace/pyproject.toml +++ b/projects/pdm_polylith_workspace/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pdm-polylith-workspace" -version = "1.0.8" +version = "1.0.9" description = "a PDM build hook for a Polylith workspace" homepage = "https://davidvujic.github.io/python-polylith-docs/" repository = "https://github.com/davidvujic/python-polylith" diff --git a/projects/poetry_polylith_plugin/pyproject.toml b/projects/poetry_polylith_plugin/pyproject.toml index 70b5d9c6..97b5a819 100644 --- a/projects/poetry_polylith_plugin/pyproject.toml +++ b/projects/poetry_polylith_plugin/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "poetry-polylith-plugin" -version = "1.30.3" +version = "1.31.0" description = "A Poetry plugin that adds tooling support for the Polylith Architecture" authors = ["David Vujic"] homepage = "https://davidvujic.github.io/python-polylith-docs/" diff --git a/projects/polylith_cli/pyproject.toml b/projects/polylith_cli/pyproject.toml index 4cd9543b..7e69eb10 100644 --- a/projects/polylith_cli/pyproject.toml +++ b/projects/polylith_cli/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "polylith-cli" -version = "1.20.1" +version = "1.20.2" description = "Python tooling support for the Polylith Architecture" authors = ['David Vujic'] homepage = "https://davidvujic.github.io/python-polylith-docs/" diff --git a/test/components/polylith/project/test_project_get.py b/test/components/polylith/project/test_project_get.py index 32b7aa7a..b923c569 100644 --- a/test/components/polylith/project/test_project_get.py +++ b/test/components/polylith/project/test_project_get.py @@ -1,9 +1,8 @@ from pathlib import Path +import pytest import tomlkit from polylith.project import get -import pytest - poetry_toml = """\ [tool.poetry] @@ -14,7 +13,19 @@ build-backend = "poetry.core.masonry.api" """ -pep_621_toml = """\ +poetry_pep_621_toml = """\ +[tool.poetry] +packages = [] + +[project] +name = "unit-test" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" +""" + +hatch_toml = """\ [project] name = "unit-test" @@ -23,6 +34,24 @@ build-backend = "hatchling.build" """ +pdm_toml = """\ +[project] +name = "unit-test" + +[build-system] +requires = ["pdm-backend"] +build-backend = "pdm.backend" +""" + +unknown_toml = """\ +[project] +name = "unit-test" + +[build-system] +requires = ["some-backend"] +build-backend = "some.backend" +""" + def test_get_project_name_from_poetry_project(): data = {"toml": tomlkit.loads(poetry_toml), "path": Path.cwd()} @@ -31,7 +60,7 @@ def test_get_project_name_from_poetry_project(): def test_get_project_name_from_pep_621_project(): - data = {"toml": tomlkit.loads(pep_621_toml), "path": Path.cwd()} + data = {"toml": tomlkit.loads(hatch_toml), "path": Path.cwd()} assert get.get_project_name_from_toml(data) == "unit-test" @@ -45,3 +74,45 @@ def test_fetching_project_name_from_empty_project_raises_error(): get.get_project_name_from_toml(data) assert str(path) in str(e.value) + + +def test_get_project_template_returns_poetry_template(): + data = tomlkit.loads(poetry_toml) + + res = get.guess_project_template(data) + + assert 'requires = ["poetry-core>=1.0.0"]' in res + assert '[tool.poetry.dependencies]\npython = "{python_version}"' in res + assert '[project]\nname = "{name}"' not in res + + +def test_get_project_template_returns_poetry_with_pep_621_support_template(): + data = tomlkit.loads(poetry_pep_621_toml) + + res = get.guess_project_template(data) + + assert 'requires = ["poetry-core>=1.0.0"]' in res + assert '[project]\nname = "{name}"' in res + + +def test_get_project_template_returns_hatch_template(): + data = tomlkit.loads(hatch_toml) + + res = get.guess_project_template(data) + + assert 'requires = ["hatchling", "hatch-polylith-bricks"]' in res + + +def test_get_project_template_returns_pdm_template(): + data = tomlkit.loads(pdm_toml) + + res = get.guess_project_template(data) + + assert 'requires = ["pdm-backend", "pdm-polylith-bricks"]' in res + + +def test_get_project_template_for_unknown_raise_error(): + data = tomlkit.loads(unknown_toml) + + with pytest.raises(ValueError): + get.guess_project_template(data) diff --git a/test/components/polylith/repo/test_repo.py b/test/components/polylith/repo/test_repo.py index 251571d5..3a9f5179 100644 --- a/test/components/polylith/repo/test_repo.py +++ b/test/components/polylith/repo/test_repo.py @@ -2,11 +2,10 @@ def test_is_pep_621_ready(): - poetry_section = {"build-system": {"build-backend": "poetry.core.masonry.api"}} - project_section = {"project": {"name": "hello world"}} - both = {**poetry_section, **project_section} + name = {"name": "hello world"} + + poetry_section = {"tool": {"poetry": name}} + project_section = {"project": name} assert repo.is_pep_621_ready(poetry_section) is False assert repo.is_pep_621_ready(project_section) is True - - assert repo.is_pep_621_ready(both) is False