feat: use .gitignore

This commit is contained in:
2026-08-06 01:20:58 +03:00
parent d062447e6d
commit 9d15380443
13 changed files with 183 additions and 130 deletions
+19
View File
@@ -0,0 +1,19 @@
from pathlib import Path
from pathspec import PathSpec
DEFAULT_IGNORE = [
".git",
"node_modules",
".venv",
"__pycache__",
]
def create_ignore(basepath: Path) -> PathSpec:
lines = DEFAULT_IGNORE.copy()
gitignore = basepath / ".gitignore"
if gitignore.exists():
with open(gitignore, "r") as fd:
lines += fd.readlines()
return PathSpec.from_lines("gitignore", lines)
+83
View File
@@ -0,0 +1,83 @@
import json
import re
import tomllib
from pathlib import Path
import dotenv
from jinja2 import Environment
from ..preset.model import Variables
def _build_env(basepath: Path) -> Environment:
env = Environment()
def do_file(filename: str) -> Path | None:
result = Path(filename)
if not result.is_absolute():
result = basepath / result
if result.exists():
return result
return None
def do_read(filename: str) -> dict | None:
path = do_file(filename)
if path:
if path.suffix == ".toml":
return tomllib.loads(path.read_text())
if path.suffix == ".json":
return json.loads(path.read_text())
if path.suffix == ".env" or path.name == ".env":
return dotenv.dotenv_values(path)
return None
def do_get(data: dict | None, keypath: str) -> str | None:
if not data:
return None
path = keypath.split(".")
result = data.get(path[0])
for key in path[1:]:
if result:
result = result.get(key)
return result
def do_search(data: str | None, pattern: str, position: int = 1) -> str | None:
if not data:
return None
matched = re.compile(pattern).search(data)
if matched:
return matched.group(position)
return None
def do_key(data: dict | None, keyindex: int = 0) -> str | None:
if not data:
return None
keys = list(data.keys())
return keys[keyindex]
env.filters["file"] = do_file
env.filters["read"] = do_read
env.filters["get"] = do_get
env.filters["search"] = do_search
env.filters["key"] = do_key
return env
class PathTemplate:
def __init__(self, basepath: Path):
self._basepath = basepath
self._env = _build_env(basepath)
def update_variables(self, templates: Variables, variables: Variables):
for k, v in templates.items():
variables[k] = self._env.from_string(v).render(**variables)
def fill_template(self, template: str, variables: Variables) -> str:
return self._env.from_string(template).render(**variables)
def check_conditions(self, templates: list[str], variables: Variables) -> bool:
for template in templates:
value = self.fill_template(template, variables)
if value.lower() in ["false", "null", "none", "0", ""]:
return False
return True
+11
View File
@@ -0,0 +1,11 @@
def merge_dicts(target: dict, enhancer: dict) -> dict:
for key, val in enhancer.items():
if key not in target:
target[key] = val
continue
if isinstance(val, dict):
merge_dicts(target[key], val)
else:
target[key] = val
return target