diff --git a/pyproject.toml b/pyproject.toml index 2aac8ae..847f832 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,10 @@ classifiers = [ fontra-compile = "fontra_compile.__main__:main" +[project.entry-points."fontra.workflow.actions"] +fontra_compile = "fontra_compile.workflow_action" + + [tool.hatch.build.targets.wheel] packages = ["src/fontra_compile"] diff --git a/src/fontra_compile/workflow_action.py b/src/fontra_compile/workflow_action.py new file mode 100644 index 0000000..d53983e --- /dev/null +++ b/src/fontra_compile/workflow_action.py @@ -0,0 +1,34 @@ +import os +import pathlib +from contextlib import asynccontextmanager +from dataclasses import dataclass, field +from typing import AsyncGenerator + +from fontra.core.protocols import ReadableFontBackend +from fontra.workflow.actions import OutputActionProtocol, registerActionClass + +from .builder import Builder + + +@registerActionClass("fontra-compile") +@dataclass(kw_only=True) +class FontraCompileAction: + destination: str + input: ReadableFontBackend | None = field(init=False, default=None) + + @asynccontextmanager + async def connect( + self, input: ReadableFontBackend + ) -> AsyncGenerator[ReadableFontBackend | OutputActionProtocol, None]: + self.input = input + try: + yield self + finally: + self.input = None + + async def process(self, outputDir: os.PathLike = pathlib.Path()) -> None: + outputFontPath = outputDir / self.destination + builder = Builder(self.input) + await builder.setup() + ttFont = await builder.build() + ttFont.save(outputFontPath) diff --git a/tests/test_workflow.py b/tests/test_workflow.py new file mode 100644 index 0000000..a556a3f --- /dev/null +++ b/tests/test_workflow.py @@ -0,0 +1,39 @@ +import pathlib +import subprocess + +import yaml +from fontra.workflow.workflow import Workflow +from test_compile import cleanupTTX + +testDir = pathlib.Path(__file__).resolve().parent +dataDir = testDir / "data" + + +testWorkFlow = """ +steps: +- action: input + source: "tests/data/MutatorSans.fontra" +- action: fontra-compile + destination: "output1.ttf" +""" + + +async def test_workflow(tmpdir): + tmpdir = pathlib.Path(tmpdir) + config = yaml.safe_load(testWorkFlow) + + workflow = Workflow(config=config) + + async with workflow.endPoints() as endPoints: + assert endPoints.endPoint is not None + + for output in endPoints.outputs: + await output.process(tmpdir) + ttxPath = dataDir / "MutatorSans.ttx" + outPath = tmpdir / output.destination + outTTXPath = tmpdir / (outPath.stem + ".ttx") + subprocess.run(["ttx", outPath], check=True) + + ttxLines = cleanupTTX(outTTXPath.read_text()) + expectedLines = cleanupTTX(ttxPath.read_text()) + assert expectedLines == ttxLines