Skip to content

Commit

Permalink
feat: add hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
TheWii committed Aug 2, 2022
1 parent bf1664f commit 060c78c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions integrity/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .api import Integrity as _Integrity
from .components import Components as _Components
from .hooks import Hook as _Hook
from .plugin import beet_default

__all__ = ["Component", "beet_default"]
63 changes: 63 additions & 0 deletions integrity/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from contextlib import contextmanager
from dataclasses import dataclass, field, replace
from typing import Dict, List
from beet import Context
from beet.core.utils import required_field
from bolt import Runtime
from mecha import AstChildren, AstNode, AstRoot, MutatingReducer, rule

from .api import Integrity


def beet_default(ctx: Context):
ctx.inject(Hook)


@dataclass
class Hook:
ctx: Context = field(repr=False)
api: Integrity = field(init=False, repr=False)
runtime: Runtime = field(init=False, repr=False)
commands: Dict[str, List[AstNode]] = field(default_factory=dict)

def __post_init__(self):
self.api = self.ctx.inject(Integrity)
self.runtime = self.api._runtime
mc = self.api._mc
mc.steps.insert(
mc.steps.index(self.runtime.evaluate) + 1, HookResolver(api=self)
)

def create(self, name: str):
node = AstHookLocation(name=name)
self.runtime.commands.append(node)

@contextmanager
def at(self, name: str):
with self.runtime.scope() as commands:
yield
self.commands.setdefault(name, []).extend(commands)


@dataclass(frozen=True)
class AstHookLocation(AstNode):
name: str = required_field()


@dataclass
class HookResolver(MutatingReducer):
api: Hook = required_field()

@rule(AstRoot)
def root(self, node: AstRoot):
if not any(isinstance(child, AstHookLocation) for child in node):
return node
commands = []
for child in node:
if isinstance(child, AstHookLocation):
hook_commands = self.api.commands.get(child.name, ())
child_node = self.invoke(AstRoot(commands=AstChildren(hook_commands)))
commands.extend(child_node)
else:
commands.append(child)
return replace(node, commands=AstChildren(commands))
1 change: 1 addition & 0 deletions integrity/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@

def beet_default(ctx: Context):
integ.Component = ctx.inject(integ._Components)
integ.Hook = ctx.inject(integ._Hook)
yield
integ.Component.generate_tags()

0 comments on commit 060c78c

Please sign in to comment.