Skip to content

Commit

Permalink
Sketch of overriding operations based on a CLI flag
Browse files Browse the repository at this point in the history
  • Loading branch information
cmyr committed Oct 14, 2024
1 parent 5472688 commit 9229093
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 20 deletions.
18 changes: 13 additions & 5 deletions Lib/gftools/builder/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from ninja.ninja_syntax import Writer, escape_path

from gftools.builder.file import File
from gftools.builder.operations import OperationBase, known_operations
from gftools.builder.operations import OperationBase, OperationRegistry
from gftools.builder.operations.copy import Copy
from gftools.builder.recipeproviders import get_provider
from gftools.builder.schema import BASE_SCHEMA
Expand All @@ -36,7 +36,7 @@ class GFBuilder:
config: dict
recipe: Recipe

def __init__(self, config: Union[dict, str]):
def __init__(self, config: Union[dict, str], use_fontc = False):
if isinstance(config, str):
parentpath = Path(config).resolve().parent
with open(config, "r") as file:
Expand All @@ -55,6 +55,7 @@ def __init__(self, config: Union[dict, str]):
self._orig_config = yaml.dump(config)
self.config = config

self.known_operations = OperationRegistry(use_fontc=use_fontc)
self.writer = Writer(open("build.ninja", "w"))
self.named_files = {}
self.used_operations = set([])
Expand Down Expand Up @@ -156,9 +157,10 @@ def glyphs_to_ufo(self, source):

def operation_step_to_object(self, step):
operation = step.get("operation") or step.get("postprocess")
if operation not in known_operations:
cls = self.known_operations.get(operation)
if cls is None:
raise ValueError(f"Unknown operation {operation}")
cls = known_operations[operation]

if operation not in self.used_operations:
self.used_operations.add(operation)
cls.write_rules(self.writer)
Expand Down Expand Up @@ -381,6 +383,12 @@ def main(args=None):
help="Just generate and output recipe from recipe builder",
action="store_true",
)
parser.add_argument(
"--experimental-fontc",
help="Use fontc instead of fontmake",
action="store_true",
)

parser.add_argument("config", help="Path to config file or source file", nargs="+")
args = parser.parse_args(args)
yaml_files = []
Expand All @@ -404,7 +412,7 @@ def main(args=None):
raise ValueError("Only one config file can be given for now")
config = args.config[0]

pd = GFBuilder(config)
pd = GFBuilder(config, use_fontc = args.experimental_fontc)
if args.generate:
config = pd.config
config["recipe"] = pd.recipe
Expand Down
56 changes: 41 additions & 15 deletions Lib/gftools/builder/operations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import sys
from os.path import dirname
from tempfile import NamedTemporaryFile
from typing import Dict

# from gftools.builder.operations.fontc import FontcBuildTTF, FontcBuildVariable
from gftools.builder.file import File
from gftools.utils import shell_quote

Expand Down Expand Up @@ -149,18 +151,42 @@ def variables(self):

return vars


known_operations = {}

for mod in pkgutil.iter_modules([dirname(__file__)]):
imp = importlib.import_module("gftools.builder.operations." + mod.name)
classes = [
(name, cls)
for name, cls in inspect.getmembers(sys.modules[imp.__name__], inspect.isclass)
if "OperationBase" not in name and issubclass(cls, OperationBase)
]
if len(classes) > 1:
raise ValueError(
f"Too many classes in module gftools.builder.operations.{mod.name}"
)
known_operations[mod.name] = classes[0][1]
# just pretend these live elsewhere, here now for illustration
class FontcBuildVariable(OperationBase):
description = "Build a variable font from a source file (with fontc)"
rule = "fontc -o $out $in"

class FontcBuildTTF(OperationBase):
description = "Build a TTF from a source file (with fontc)"
rule = "fontc -o $out $in"

class OperationRegistry:
def __init__(self, use_fontc: bool):
self.known_operations = get_known_operations()
if use_fontc:
self.known_operations["buildVariable"] = FontcBuildVariable
self.known_operations["buildTTF"] = FontcBuildTTF
print(self.known_operations, file=sys.stderr)

def get(self, operation_name: str):
return self.known_operations.get(operation_name)


def get_known_operations() -> Dict[str, OperationBase]:
known_operations = {}

for mod in pkgutil.iter_modules([dirname(__file__)]):
if "fontc" in mod.name:
continue
imp = importlib.import_module("gftools.builder.operations." + mod.name)
classes = [
(name, cls)
for name, cls in inspect.getmembers(sys.modules[imp.__name__], inspect.isclass)
if "OperationBase" not in name and issubclass(cls, OperationBase)
]
if len(classes) > 1:
raise ValueError(
f"Too many classes in module gftools.builder.operations.{mod.name}"
)
known_operations[mod.name] = classes[0][1]
return known_operations

0 comments on commit 9229093

Please sign in to comment.