Skip to content

Commit

Permalink
feat(poetry plugin): add support for upcoming Poetry PEP 621 projects (
Browse files Browse the repository at this point in the history
…#278)

* feat(poetry plugin): add support for upcoming Poetry PEP 621 projects

* bump Poetry plugin to 1.31.0

* bump CLI to 1.20.2

* bump hatch hook to 1.2.7

* bump PDM brick hook to 1.0.9

* bump PDM workspace hook to 1.0.9

* fix(project type): raise ValueError for unknown Project type
  • Loading branch information
DavidVujic authored Oct 28, 2024
1 parent f6b2390 commit 7b0f84f
Show file tree
Hide file tree
Showing 14 changed files with 146 additions and 28 deletions.
10 changes: 2 additions & 8 deletions bases/polylith/cli/create.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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")
Expand Down
3 changes: 2 additions & 1 deletion components/polylith/poetry/commands/create_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
8 changes: 7 additions & 1 deletion components/polylith/project/__init__.py
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
27 changes: 27 additions & 0 deletions components/polylith/project/get.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import tomlkit
from polylith import configuration, repo, toml
from polylith.project import templates


def get_project_name(toml_data) -> str:
Expand Down Expand Up @@ -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)
19 changes: 19 additions & 0 deletions components/polylith/project/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
3 changes: 0 additions & 3 deletions components/polylith/repo/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 5 additions & 1 deletion components/polylith/toml/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(), {})

Expand Down
2 changes: 1 addition & 1 deletion projects/hatch_polylith_bricks/pyproject.toml
Original file line number Diff line number Diff line change
@@ -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/"
Expand Down
2 changes: 1 addition & 1 deletion projects/pdm_polylith_bricks/pyproject.toml
Original file line number Diff line number Diff line change
@@ -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/"
Expand Down
2 changes: 1 addition & 1 deletion projects/pdm_polylith_workspace/pyproject.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
2 changes: 1 addition & 1 deletion projects/poetry_polylith_plugin/pyproject.toml
Original file line number Diff line number Diff line change
@@ -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/"
Expand Down
2 changes: 1 addition & 1 deletion projects/polylith_cli/pyproject.toml
Original file line number Diff line number Diff line change
@@ -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/"
Expand Down
79 changes: 75 additions & 4 deletions test/components/polylith/project/test_project_get.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from pathlib import Path

import pytest
import tomlkit
from polylith.project import get
import pytest


poetry_toml = """\
[tool.poetry]
Expand All @@ -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"
Expand All @@ -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()}
Expand All @@ -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"

Expand All @@ -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)
9 changes: 4 additions & 5 deletions test/components/polylith/repo/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 7b0f84f

Please sign in to comment.