From 43ec8f79dd8a760014024fec0388e846251f13bb Mon Sep 17 00:00:00 2001 From: David Vujic Date: Thu, 18 Jan 2024 13:30:18 +0100 Subject: [PATCH 1/3] fix(hatch): lookup bricks in another TOML section, preparing for library support using Hatch build hooks --- components/polylith/project/get.py | 21 +++++++- .../polylith/project/test_project_get.py | 49 ++++++++++++++++--- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/components/polylith/project/get.py b/components/polylith/project/get.py index c9102f7f..c03abc96 100644 --- a/components/polylith/project/get.py +++ b/components/polylith/project/get.py @@ -13,12 +13,31 @@ def transform_to_package(namespace: str, include: str) -> dict: return {"include": f"{namespace}/{brick}", "from": path} +def find_by_key(data: dict, key: str) -> dict: + if key in data.keys(): + return data[key] + + filtered = {k: v for k, v in data.items() if isinstance(data[k], dict)} + + res = (find_by_key(data[k], key) for k in filtered.keys()) + + return next((r for r in res if r), {}) + + +def get_hatch_project_packages(namespace: str, data) -> dict: + build_data = data["tool"]["hatch"].get("build", {}) + + force_included = build_data.get("force-include", {}) + + return force_included or find_by_key(build_data, "polylith").get("bricks", {}) + + def get_project_package_includes(namespace: str, data) -> List[dict]: if repo.is_poetry(data): return data["tool"]["poetry"].get("packages", []) if repo.is_hatch(data): - includes = data["tool"]["hatch"].get("build", {}).get("force-include", {}) + includes = get_hatch_project_packages(namespace, data) return [transform_to_package(namespace, key) for key in includes.keys()] diff --git a/test/components/polylith/project/test_project_get.py b/test/components/polylith/project/test_project_get.py index 7e31e218..051796bc 100644 --- a/test/components/polylith/project/test_project_get.py +++ b/test/components/polylith/project/test_project_get.py @@ -6,32 +6,65 @@ poetry_toml = """\ [tool.poetry] packages = [ - {include = "unittest/one",from = "../../components"} + {include = "unittest/one",from = "../../bases"}, + {include = "unittest/two",from = "../../components"} ] """ - hatch_toml = """\ [tool.hatch.build.force-include] "../../bases/unittest/one" = "unittest/one" "../../components/unittest/two" = "unittest/two" """ +hatch_toml_alternative = """\ +[tool.hatch.build.hooks.targets.wheel.polylith.bricks] +"../../bases/unittest/one" = "unittest/one" +"../../components/unittest/two" = "unittest/two" +""" + +hatch_toml_combined = """\ +[tool.hatch.build.force-include] +"../../bases/unittest/one" = "unittest/one" +"../../components/unittest/two" = "unittest/two" + +[tool.hatch.build.hooks.targets.wheel.polylith.bricks] +"something" = "else" +""" + +expected = [ + {"include": "unittest/one", "from": "../../bases"}, + {"include": "unittest/two", "from": "../../components"}, +] + def test_get_poetry_package_includes(): data = tomlkit.loads(poetry_toml) res = project.get.get_project_package_includes(namespace, data) - assert res == [{"include": "unittest/one", "from": "../../components"}] + assert res == expected -def test_get_pep_621_includes(): +def test_get_hatch_package_includes(): data = tomlkit.loads(hatch_toml) res = project.get.get_project_package_includes(namespace, data) - assert res == [ - {"include": "unittest/one", "from": "../../bases"}, - {"include": "unittest/two", "from": "../../components"}, - ] + assert res == expected + + +def test_get_hatch_package_includes_in_build_hook(): + data = tomlkit.loads(hatch_toml_alternative) + + res = project.get.get_project_package_includes(namespace, data) + + assert res == expected + + +def test_get_hatch_package_includes_from_default_when_in_both(): + data = tomlkit.loads(hatch_toml_combined) + + res = project.get.get_project_package_includes(namespace, data) + + assert res == expected From 7d5a0bec4ad457950050b09afa447259a48a4ecc Mon Sep 17 00:00:00 2001 From: David Vujic Date: Thu, 18 Jan 2024 13:47:53 +0100 Subject: [PATCH 2/3] fix(hatch): lookup bricks in another TOML section, preparing for library support using Hatch build hooks --- components/polylith/project/get.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/components/polylith/project/get.py b/components/polylith/project/get.py index c03abc96..df850743 100644 --- a/components/polylith/project/get.py +++ b/components/polylith/project/get.py @@ -1,7 +1,7 @@ import re from functools import lru_cache from pathlib import Path -from typing import List +from typing import Any, List import tomlkit from polylith import repo, workspace @@ -13,7 +13,7 @@ def transform_to_package(namespace: str, include: str) -> dict: return {"include": f"{namespace}/{brick}", "from": path} -def find_by_key(data: dict, key: str) -> dict: +def find_by_key(data: dict, key: str) -> Any: if key in data.keys(): return data[key] @@ -21,15 +21,20 @@ def find_by_key(data: dict, key: str) -> dict: res = (find_by_key(data[k], key) for k in filtered.keys()) - return next((r for r in res if r), {}) + return next((r for r in res if r), None) -def get_hatch_project_packages(namespace: str, data) -> dict: +def get_hatch_project_packages(data) -> dict: build_data = data["tool"]["hatch"].get("build", {}) - force_included = build_data.get("force-include", {}) + force_included = build_data.get("force-include") - return force_included or find_by_key(build_data, "polylith").get("bricks", {}) + if force_included: + return force_included + + found = find_by_key(build_data, "polylith") + + return found.get("bricks", {}) if isinstance(found, dict) else {} def get_project_package_includes(namespace: str, data) -> List[dict]: @@ -37,7 +42,7 @@ def get_project_package_includes(namespace: str, data) -> List[dict]: return data["tool"]["poetry"].get("packages", []) if repo.is_hatch(data): - includes = get_hatch_project_packages(namespace, data) + includes = get_hatch_project_packages(data) return [transform_to_package(namespace, key) for key in includes.keys()] From 30207a9cf72a6c8e6c2083cf2ca7d83febce2b0f Mon Sep 17 00:00:00 2001 From: David Vujic Date: Thu, 18 Jan 2024 14:02:52 +0100 Subject: [PATCH 3/3] fix(hatch): lookup bricks in another TOML section, preparing for library support using Hatch build hooks --- components/polylith/project/get.py | 6 ++++-- .../polylith/project/test_project_get.py | 14 +++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/components/polylith/project/get.py b/components/polylith/project/get.py index df850743..da4f5f07 100644 --- a/components/polylith/project/get.py +++ b/components/polylith/project/get.py @@ -25,7 +25,8 @@ def find_by_key(data: dict, key: str) -> Any: def get_hatch_project_packages(data) -> dict: - build_data = data["tool"]["hatch"].get("build", {}) + hatch_data = data["tool"]["hatch"] + build_data = hatch_data.get("build", {}) if isinstance(hatch_data, dict) else {} force_included = build_data.get("force-include") @@ -33,8 +34,9 @@ def get_hatch_project_packages(data) -> dict: return force_included found = find_by_key(build_data, "polylith") + bricks = found.get("bricks", {}) if isinstance(found, dict) else {} - return found.get("bricks", {}) if isinstance(found, dict) else {} + return bricks if isinstance(bricks, dict) else {} def get_project_package_includes(namespace: str, data) -> List[dict]: diff --git a/test/components/polylith/project/test_project_get.py b/test/components/polylith/project/test_project_get.py index 051796bc..0514161b 100644 --- a/test/components/polylith/project/test_project_get.py +++ b/test/components/polylith/project/test_project_get.py @@ -1,5 +1,5 @@ -from polylith import project import tomlkit +from polylith import project namespace = "unittest" @@ -68,3 +68,15 @@ def test_get_hatch_package_includes_from_default_when_in_both(): res = project.get.get_project_package_includes(namespace, data) assert res == expected + + +def test_get_hatch_package_includes_lookup_with_unexpected_format(): + unexpected = """\ +[tool.hatch.build.hooks.targets.wheel] +"polylith" = "this-is-unexpected" +""" + data = tomlkit.loads(unexpected) + + res = project.get.get_project_package_includes(namespace, data) + + assert res == []