summaryrefslogtreecommitdiff
path: root/dots_manager/template.py
diff options
context:
space:
mode:
Diffstat (limited to 'dots_manager/template.py')
-rw-r--r--dots_manager/template.py73
1 files changed, 73 insertions, 0 deletions
diff --git a/dots_manager/template.py b/dots_manager/template.py
new file mode 100644
index 0000000..a88158a
--- /dev/null
+++ b/dots_manager/template.py
@@ -0,0 +1,73 @@
+from pathlib import Path
+from typing import Optional
+import shutil
+import jinja2
+from .config import Config
+from .parallel import parallelize
+from .utils import is_some
+from .env import Environment
+
+
+def is_template(path: Path) -> bool:
+ return path.suffix == Config.template_extension
+
+
+def find_templates_under(destination: Path) -> list[Path]:
+ return [
+ t
+ for t in destination.glob("**/*" + Config.template_extension)
+ if t.is_file() and is_template(t)
+ ]
+
+
+def render_template_to(
+ template: Path, destination: Path, env: Environment
+) -> Optional[Path]:
+ env.logger.debug(f"rendering template {template} to {destination} ✧*ฺ")
+ if not is_template(template):
+ env.logger.error(f"{template} is not a valid template D:")
+ return None
+
+ jinja_env = jinja2.Environment(
+ loader=jinja2.BaseLoader,
+ undefined=jinja2.StrictUndefined,
+ trim_blocks=True,
+ lstrip_blocks=True,
+ )
+ rendered = render(template, jinja_env, env)
+ if not rendered:
+ env.logger.error(f"failed to render template {template}")
+ return None
+
+ destination.write_text(rendered)
+ return destination
+
+
+def render(
+ source: Path, jinja_env: jinja2.Environment, env: Environment
+) -> Optional[str]:
+ try:
+ env.logger.debug(f"rendering template {source} ✿.。.:・")
+ return jinja_env.from_string(source.read_text()).render(**env.context)
+ except Exception as e:
+ env.logger.error(f"couldn’t render {source}: {e}")
+ return None
+
+
+def compile_dotfiles(source: Path, output: Path, env: Environment) -> bool:
+ env.logger.info(f"compiling {source} to {output}")
+ output.mkdir(exist_ok=True, parents=True)
+ shutil.copytree(source, output, dirs_exist_ok=True)
+
+ tasks = parallelize(
+ lambda template: is_some(
+ render_template_to,
+ template,
+ template.with_suffix(""),
+ env,
+ )[0]
+ and (template.unlink() is None),
+ find_templates_under(output),
+ env,
+ )
+ return all(tasks)