feat: add presets

This commit is contained in:
2023-03-16 15:07:11 +03:00
parent 23ca8c0cac
commit 8b718fda79
15 changed files with 357 additions and 142 deletions
View File
+28
View File
@@ -0,0 +1,28 @@
from collections import defaultdict
from pathlib import Path
from typing import Optional
from ..entry import Entry, EntryDetector
from .util import PresetUtil
__all__ = ("PresetEntryDetector",)
class PresetEntryDetector(EntryDetector):
def __init__(self, filename: Path):
self._preset = PresetUtil.resolve_preset(filename)
def detect_entry(self, basepath: Path) -> Optional["Entry"]:
tasks = defaultdict(list)
for preset_name, preset in self._preset.presets.items():
filename = basepath / preset.filename
if filename.exists():
loader = PresetUtil.resolve_loader(preset.loader)
with open(filename, "rb") as fd:
data = loader(fd)
for task_name, task_pack in preset.tasks.items():
for task_item_name, task in task_pack.items():
if PresetUtil.check_conditions(data, task.conditions):
tasks[task_name] += task.commands
if tasks:
return Entry(tasks, basepath)
+20
View File
@@ -0,0 +1,20 @@
from typing import Dict, List
from pydantic import BaseModel
__all__ = ("TaskPreset", "FilePreset", "Preset")
class TaskPreset(BaseModel):
conditions: Dict[str, str]
commands: List[str]
class FilePreset(BaseModel):
filename: str
loader: str
tasks: Dict[str, Dict[str, TaskPreset]]
class Preset(BaseModel):
presets: Dict[str, FilePreset]
+45
View File
@@ -0,0 +1,45 @@
__all__ = ("PresetUtil",)
import importlib
from pathlib import Path
from typing import Any, Dict
import tomli
from .model import Preset
class PresetUtil:
@classmethod
def resolve_loader(cls, loader: str) -> Any:
module_name, item_name = loader.split(":")
module = importlib.import_module(module_name)
return getattr(module, item_name)
@classmethod
def get_key_path_value(cls, key_path: str, data: dict):
path = key_path.split(".")
value = data.get(path[0])
for key in path[1:]:
if value:
value = value.get(key)
return value
@classmethod
def match_condition_value(cls, value: Any, pattern: str) -> bool:
if pattern == "*":
return bool(value)
return value == pattern
@classmethod
def check_conditions(cls, data: dict, conditions: Dict[str, str]) -> bool:
for key, value in conditions.items():
if not cls.match_condition_value(cls.get_key_path_value(key, data), value):
return False
return True
@classmethod
def resolve_preset(cls, filename: Path) -> Preset:
with open(filename, "rb") as fd:
preset_data = tomli.load(fd)
return Preset(**preset_data)