diff --git a/src/zona/builder.py b/src/zona/builder.py index a340aec..e8d0d58 100644 --- a/src/zona/builder.py +++ b/src/zona/builder.py @@ -6,7 +6,9 @@ from dacite import from_dict def split_metadata(path: Path) -> tuple[Metadata, str]: post = frontmatter.load(str(path)) + # TODO: handle missing metadata meta = post.metadata + # TODO: handle malformed metadata metadata = from_dict( data_class=Metadata, data=meta, @@ -14,23 +16,33 @@ def split_metadata(path: Path) -> tuple[Metadata, str]: return metadata, post.content -def discover(root: str, out_dir: str) -> list[Item]: - root_path = Path(root) - required_dirs = {"content", "static", "templates"} - found_dirs = {p.name for p in root_path.iterdir() if p.is_dir()} +def discover(root: Path, out_dir: Path) -> list[Item]: + required_dirs = {"content", "templates"} + found_dirs = {p.name for p in root.iterdir() if p.is_dir()} missing = required_dirs - found_dirs assert not missing, f"Missing required directories: {', '.join(missing)}" items: list[Item] = [] - for subdir in required_dirs: - base = root_path / subdir - for path in base.rglob("*"): - if path.is_file(): - print(f"{subdir}: {path.relative_to(root_path)}") - if path.name.endswith(".md"): - pass - # page = Frontmatter.read_file(path.name) - # TODO: build Item here - # items.append(...) + subdir = "content" + base = root / subdir + for path in base.rglob("*"): + if path.is_file(): + print(f"{subdir}: {path.relative_to(root)}") + if path.name.endswith(".md") and not path.is_relative_to( + root / "content" / "static" + ): + meta, content = split_metadata(path) + else: + meta = None + content = path.read_bytes() + destination = out_dir / path.relative_to(base) + item = Item( + source=path, + destination=destination, + url=str(destination.relative_to(out_dir)), + metadata=meta, + content=content, + ) + items.append(item) return items diff --git a/src/zona/models.py b/src/zona/models.py index 90b4183..7f4d5bb 100644 --- a/src/zona/models.py +++ b/src/zona/models.py @@ -17,3 +17,4 @@ class Item: destination: Path url: str # relative to site root metadata: Metadata | None # frontmatter + content: str | bytes diff --git a/tests/test_metadata.py b/tests/test_metadata.py index a591aa2..1c73f37 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -1,6 +1,6 @@ from datetime import date from zona.models import Metadata -from zona.builder import split_metadata +from zona.builder import split_metadata, discover from pathlib import Path @@ -22,3 +22,50 @@ description: This is a test. assert meta.description == "This is a test." assert meta.date == date(2025, 6, 3) assert content == "# Hello World" + + +def test_discover(tmp_path: Path): + contentd = tmp_path / "content" + staticd = contentd / "static" + templatesd = tmp_path / "templates" + outd = tmp_path / "out" + + for d in [contentd, staticd, templatesd, outd]: + d.mkdir() + md_file = contentd / "post.md" + md_file.write_text("""--- +title: Test Post +date: 2025-06-03 +description: This is a test. +--- + +# Hello World + """) + + style = staticd / "style.css" + style.write_text(""" +p { + color: red; + text-align: center; +} +""") + + items = discover(tmp_path, outd) + + assert len(items) == 2 + + md_item = items[0] + assert md_item.source == md_file + assert md_item.destination.name == "post.md" + assert md_item.destination.is_relative_to(outd) + assert md_item.url == "post.md" + assert isinstance(md_item.metadata, Metadata) + assert md_item.metadata.title == "Test Post" + assert md_item.content.strip() == "# Hello World" + + st_item = items[1] + assert st_item.source == style + assert st_item.destination.name == "style.css" + assert st_item.destination.is_relative_to(outd) + assert st_item.url == "static/style.css" + assert st_item.metadata is None