fix(text): don't rebuild every time a craft-fonts manifest is missing (#228)

crates/text/build.rs asked cargo to watch both craft-fonts manifests
whether or not they existed. Cargo takes a watched path that doesn't
exist as changed, so figcraft-text and every crate above it were rebuilt
on every build: with no craft-fonts checkout, and also with a checkout
of craft-fonts' main branch, which has no fonts/latin-manifest.txt.

Watch a manifest only when it exists, and its folder while it is
missing, so a manifest added later is still noticed. With no checkout
at all there is nothing to watch; the build warning and the README now
say how to pick one up after a first build.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jeremy Yao 2026-10-13 22:30:03 -04:00 committed by GitHub
parent 7d589c4456
commit f7e726714a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 18 additions and 2 deletions

View File

@ -251,6 +251,8 @@ Fonts for the UI and the Text tool come from [craft-fonts](https://github.com/st
git clone https://github.com/storytold/craft-fonts ../craft-fonts
```
If you clone it after a first build, run `cargo clean -p figcraft-text` once so the next build embeds the fonts.
**Start from a template.** The home screen's Templates tab has eight starter files (a mobile app, a landing page, a dashboard, a design system starter, a wireframe kit, social post sizes, presentation slides and an icon set starter), also under File ▸ New from template…. They are built in code from original, synthetic content, so scripts and agents can open them too: `file.newFromTemplate {template}` ([`docs/mcp.md`](docs/mcp.md#starter-templates)).
For the web build, install [trunk](https://trunkrs.dev/) and run `cargo xtask wasm`.

View File

@ -25,7 +25,7 @@ fn main() {
}
}
if !ok {
println!("cargo::warning=building without craft-fonts");
println!("cargo::warning=building without craft-fonts (once it is there, `cargo clean -p figcraft-text` makes the next build use it)");
}
}
src.push_str("];\n");
@ -35,9 +35,23 @@ fn main() {
}
}
/// Rebuild when `manifest` changes or, while it is missing, when it is added to its folder.
///
/// Cargo takes a watched path that doesn't exist as changed on every build, and then rebuilds this
/// crate and every crate that depends on it each time. So a missing manifest is never watched
/// itself: its folder is, when there is one (a craft-fonts checkout without the Latin manifest).
/// With no craft-fonts at all there is nothing to watch, so the build can't notice it arriving:
/// the warning in `main` says how to pick it up.
fn watch(manifest: &std::path::Path) {
let watched = if manifest.exists() { Some(manifest) } else { manifest.parent().filter(|folder| folder.is_dir()) };
if let Some(path) = watched {
println!("cargo::rerun-if-changed={}", path.display());
}
}
fn craft_fonts(dir: &std::path::Path, manifest_rel: &str) -> Result<String, String> {
let manifest = dir.join(manifest_rel);
println!("cargo::rerun-if-changed={}", manifest.display());
watch(&manifest);
let text = std::fs::read_to_string(&manifest).map_err(|e| format!("{}: {e}", manifest.display()))?;
let wasm = std::env::var("CARGO_CFG_TARGET_ARCH").is_ok_and(|a| a == "wasm32");
let mut out = String::new();