diff --git a/src/zona/cli.py b/src/zona/cli.py index ca88713..d02b840 100644 --- a/src/zona/cli.py +++ b/src/zona/cli.py @@ -1,7 +1,7 @@ import typer from pathlib import Path from zona import builder, server -from zona.layout import Layout, discover_layout +from zona.layout import Layout, discover_layout, initialize_site app = typer.Typer() @@ -22,10 +22,10 @@ def serve(dir: Path = Path("public")): @app.command() -def init(): +def init(root: Path | None = None): # init will populate the current directory with # the required folders and their default values - print("Init logic here...") + initialize_site(root) def main(): diff --git a/src/zona/config.py b/src/zona/config.py index 8b13789..5480cea 100644 --- a/src/zona/config.py +++ b/src/zona/config.py @@ -1 +1,28 @@ +from dataclasses import dataclass, field + +@dataclass +class MarkdownConfig: + image_labels: bool = True + + +@dataclass +class ThemeConfig: + name: str = "default" + syntax_highlighting: bool = True + + +@dataclass +class BuildConfig: + clean_output_dir: bool = True + include_drafts: bool = False + + +@dataclass +class ZonaConfig: + title: str = "Zona Blog" + base_url: str = "https://example.com" + language: str = "en" + markdown: MarkdownConfig = field(default_factory=MarkdownConfig) + theme: ThemeConfig = field(default_factory=ThemeConfig) + build: BuildConfig = field(default_factory=BuildConfig) diff --git a/src/zona/layout.py b/src/zona/layout.py index 5bfa71e..2922418 100644 --- a/src/zona/layout.py +++ b/src/zona/layout.py @@ -1,5 +1,7 @@ from pathlib import Path -from dataclasses import dataclass +from dataclasses import dataclass, asdict +from zona.config import ZonaConfig +import yaml @dataclass @@ -10,16 +12,21 @@ class Layout: output: Path @classmethod - def from_input(cls, root: Path, output: Path | None = None) -> "Layout": + def from_input( + cls, root: Path, output: Path | None = None, validate: bool = True + ) -> "Layout": layout = cls( root=root.resolve(), content=(root / "content").resolve(), templates=(root / "templates").resolve(), output=(root / "public").resolve() if not output else output, ) - for path in [layout.content, layout.templates]: - if not path.is_dir(): - raise FileNotFoundError(f"Missing required directory: {path}") + if validate: + for path in [layout.content, layout.templates]: + if not path.is_dir(): + raise FileNotFoundError( + f"Missing required directory: {path}" + ) return layout @@ -45,3 +52,28 @@ def discover_layout( else: root = Path.cwd() return Layout.from_input(root, cli_output) + + +def initialize_site(root: Path | None = None): + # initialize a new project + if not root: + root = Path.cwd() + root = root.absolute().resolve() + config = find_config(root) + if config is not None: + raise FileExistsError(f"Config file already exists at {config}") + # create requires layout + layout = Layout.from_input(root=root, validate=False) + for dir in [layout.root, layout.content, layout.templates]: + if not dir.is_dir(): + dir.mkdir() + config_path = layout.root / "config.yml" + config = ZonaConfig() + with open(config_path, "w") as f: + yaml.dump( + asdict(config), + f, + sort_keys=False, + default_flow_style=False, + indent=2, + )