feat: add presets
This commit is contained in:
@@ -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)
|
||||
@@ -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]
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user