Skip to content

Commit

Permalink
fix: Hatchling dev-mode and editable installations (#308)
Browse files Browse the repository at this point in the history
* fix(hatchling): filter project-specific bricks when in editable mode and with dev-mode-dirs enabled

* bump Hatch hook to 1.3.1
  • Loading branch information
DavidVujic authored Dec 3, 2024
1 parent 467cb32 commit 5c3d8ca
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 4 deletions.
33 changes: 30 additions & 3 deletions components/polylith/hatch/hooks/bricks.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
import shutil
from pathlib import Path
from typing import Any, Dict
from typing import Any, Dict, List

from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from polylith import parsing, repo, toml
from polylith.hatch import core


def get_build_section(data: dict) -> dict:
return data.get("tool", {}).get("hatch", {}).get("build", {})


def is_in_path(key: str, paths: List[str]) -> bool:
return any(key.startswith(p) for p in paths)


def filter_dev_mode_bricks(data: dict, bricks: dict) -> dict:
build_section = get_build_section(data)
dev_mode_dirs = build_section.get("dev-mode-dirs")

if not dev_mode_dirs:
return bricks

return {k: v for k, v in bricks.items() if not is_in_path(k, dev_mode_dirs)}


def filtered_bricks(data: dict, version: str) -> dict:
bricks = toml.get_project_packages_from_polylith_section(data)

if version == "editable":
return filter_dev_mode_bricks(data, bricks)

return bricks


class PolylithBricksHook(BuildHookInterface):
PLUGIN_NAME = "polylith-bricks"

def initialize(self, version: str, build_data: Dict[str, Any]) -> None:
include_key = "force_include_editable" if version == "editable" else "force_include"
include_key = "force_include"
root = self.root
pyproject = Path(f"{root}/{repo.default_toml}")

data = toml.read_toml_document(pyproject)
bricks = toml.get_project_packages_from_polylith_section(data)
bricks = filtered_bricks(data, version)
found_bricks = {k: v for k, v in bricks.items() if Path(f"{root}/{k}").exists()}

if not bricks or not found_bricks:
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.3.0"
version = "1.3.1"
description = "Hatch build hook plugin for Polylith"
authors = ['David Vujic']
homepage = "https://davidvujic.github.io/python-polylith-docs/"
Expand Down
41 changes: 41 additions & 0 deletions test/components/polylith/hatch/test_hook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import tomlkit
from polylith.hatch.hooks.bricks import filtered_bricks

project_toml = """\
[tool.polylith.bricks]
"../../bases/unittest/one" = "unittest/one"
"../../components/unittest/two" = "unittest/two"
"""

project_toml_dev_mode = """\
[tool.hatch.build]
dev-mode-dirs = ["../../components", "../../bases"]
[tool.polylith.bricks]
"../../bases/unittest/one" = "unittest/one"
"../../components/unittest/two" = "unittest/two"
"""


def test_filtered_bricks():
data = tomlkit.loads(project_toml)

expected = data["tool"]["polylith"]["bricks"]

first = filtered_bricks(data, version="standard")
second = filtered_bricks(data, version="editable")

assert first == expected
assert second == expected


def test_filtered_bricks_in_project_with_dev_mode_dirs():
data = tomlkit.loads(project_toml_dev_mode)

expected = data["tool"]["polylith"]["bricks"]

first = filtered_bricks(data, version="standard")
second = filtered_bricks(data, version="editable")

assert first == expected
assert second == {}

0 comments on commit 5c3d8ca

Please sign in to comment.