googlefonts / googlefonts/gftools

Add preCompile config key to gftools-builder

Open
#1,170 5 comments 0 reactions 1 assignee Claimed by @simoncozens View on GitHub
Dominant language
Python
Stars
283
Forks
73
Avg merge
21h 25m
Merged PRs (30d)
8

Description

> [!IMPORTANT]
> This issue was written by an AI agent (Claude Code) working under the guidance of @felipesanches.

## Summary

Many upstream Google Fonts repos need to run preparation scripts before invoking `gftools-builder`. Currently 61 repos use custom Python build scripts and 19 use custom shell scripts as wrappers around the build process. Adding a `preCompile` configuration key would let these projects move to a pure `config.yaml`-driven build.

## Proposed Design

A new `preCompile` key in `config.yaml` that takes a list of shell commands to run before the build process begins:

```yaml
sources:
- MyFont.glyphs
preCompile:
- python3 scripts/fix_sources.py
- bash scripts/generate_data.sh
```

### How it differs from `postCompile`

- **`preCompile`**: Shell commands that run as subprocesses *before* the build graph is created. They can modify source files, generate data, etc. They run after `chdir` to the config directory but before the recipe provider reads sources.
- **`postCompile`**: Build operations that run on compiled font binaries *within* the ninja build graph.

This distinction is intentional — `preCompile` commands operate on source files (before fontmake runs), so they don't fit naturally into the ninja dependency graph as operations with `$in`/`$out`.

### Implementation sketch

1. **Schema**: Add `Optional("preCompile"): Seq(Str())` to `GOOGLEFONTS_SCHEMA`
2. **Builder `__init__`**: Run each command via `subprocess.run(cmd, shell=True, check=True)` after config parsing + chdir, but before calling the recipe provider
3. **Docs**: Add documentation alongside the existing `postCompile` entry

## Questions for @simoncozens

1. Does running `preCompile` commands as subprocesses (outside the ninja graph) seem like the right approach, or would you prefer them integrated into the build graph somehow?
2. Is `Seq(Str())` (list of shell command strings) the right schema, or should it support operation dicts like `postCompile` does?
3. Any concerns about `shell=True` for running these commands? (It's needed for things like pipes and shell builtins, and matches what users would type in a terminal.)

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.