max / goingson
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
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 |