Skip to main content

max / goingson

Seal goingson's dead makeover vocabulary at 18 of 42 check_vocabulary_use shipped in makeover-build 0.22.0 and nothing called it, because the file set it takes is different in every app and picking it wrong is worse than not having the check: too small a list records a ceiling that never bites, too large a one counts prose as usage. This app's list is index.html, compose.html and frontend/js. The css/ directory is out on purpose -- a class in a stylesheet is that class being styled, not that class being emitted, and counting it would mark the whole vocabulary used by definition. src/quasi/** is out too, and it is the one real gap. Those screens go through quasi-webview, which emits makeover's classes from the renderer rather than from any string in this repo, so a class only a described screen uses reads as dead. Twelve of the eighteen are exactly that -- the .cell-* and .figure-* families, which the described tasks and contacts screens do use. The number is therefore loose rather than wrong, in the direction that cannot fail a correct build, and it tightens on its own as the renderer learns to report what it emitted. The seal only ratchets down: over it fails, under it warns and asks for the number to be lowered.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-12 14:51 UTC
Signed with PGP, not checked
Commit: cd978c9c5c636bdebf86af06195fa49ee25de9bc
Parent: 228c0b8
1 file changed, +45 insertions, -1 deletion
@@ -1,6 +1,6 @@
1 1 use std::fmt::Write as _;
2 2 use std::fs;
3 - use std::path::Path;
3 + use std::path::{Path, PathBuf};
4 4
5 5 use makeover_geometry::SizeClass;
6 6 use makeover_layout::{Column, Priority, Width};
@@ -453,6 +453,45 @@
453 453 ("tab", "color"),
454 454 ];
455 455
456 + /// How many generated classes may go unused before the build fails.
457 + ///
458 + /// One-sided: over this fails, under it warns and asks for the seal to be
459 + /// lowered. A build that broke on deleting dead CSS would teach the wrong
460 + /// lesson, so the number only ever ratchets down.
461 + ///
462 + /// Measured against [`markup_files`], which is the whole of what this app can
463 + /// write a class from: `index.html`, `compose.html` and every `frontend/js`
464 + /// file. Sealing against too small a list records a number so high the seal
465 + /// never bites; against too large a list it counts prose as usage. The `css/`
466 + /// directory is deliberately out -- a class in a stylesheet is that class being
467 + /// styled, not that class being emitted, and counting it would mark the whole
468 + /// vocabulary used by definition.
469 + ///
470 + /// `src/quasi/**` is out for the opposite reason and is the one real gap here.
471 + /// Those screens go through quasi-webview, which emits makeover's classes from
472 + /// the renderer rather than from any string in this repo, so a class only a
473 + /// described screen uses reads as dead. That inflates the number, which is safe
474 + /// in the direction that matters -- it makes the ceiling looser, never a build
475 + /// falsely red -- and it tightens on its own as the renderer learns to report
476 + /// what it emitted.
477 + const DEAD_VOCABULARY_HIGH_WATER: usize = 18;
478 +
479 + /// Every file that can carry a class name.
480 + fn markup_files(frontend: &Path) -> Vec<PathBuf> {
481 + let mut files = vec![frontend.join("index.html"), frontend.join("compose.html")];
482 + let js = fs::read_dir(frontend.join("js")).expect("read frontend/js");
483 + let mut scripts: Vec<PathBuf> = js
484 + .map(|entry| entry.expect("read frontend/js entry").path())
485 + .filter(|path| path.extension().is_some_and(|ext| ext == "js"))
486 + .collect();
487 + // Sorted, or the order is the filesystem's and two machines seal against
488 + // the same set in a different order. It makes no difference to the count
489 + // and every difference to reading a diff of the warning.
490 + scripts.sort();
491 + files.extend(scripts);
492 + files
493 + }
494 +
456 495 /// Widths that are tuning inside the wide shell, not a shell boundary.
457 496 ///
458 497 /// A shell boundary is a [`SizeClass`] edge and belongs to makeover-geometry.
@@ -494,6 +533,11 @@
494 533 &["geometry.css", "layout.css", "tables.css"],
495 534 REVIEWED_OVERLAPS,
496 535 );
536 + makeover_build::check_vocabulary_use(
537 + &markup_files(&frontend),
538 + &makeover_build::Emit::default(),
539 + DEAD_VOCABULARY_HIGH_WATER,
540 + );
497 541 makeover_build::check_touch_density(frontend.join("js"));
498 542 check_sortable_headers(&frontend);
499 543