Skip to main content

max / makenotwork

2.1 KB · 50 lines History Blame Raw
1 //! Forward fence, the frontend-globals ratchet.
2 //!
3 //! The legacy `static/*.js` files register behavior as `window.<name> = fn`
4 //! globals (the pre-module `data-action` dispatcher pattern). The frontend
5 //! restructure (`_private/docs/mnw/frontend/`) migrates these into typed ES
6 //! modules under `frontend/src`. This seal keeps the count monotonically
7 //! non-increasing: adding a new `window.*` global fails the build, and every
8 //! migrated file must lower `HIGH_WATER`. Same idea as the migration
9 //! HIGH_WATER seal.
10 //!
11 //! When you remove globals, lower `HIGH_WATER` to the new count (the failure
12 //! message reports it). Never raise it.
13
14 use std::fs;
15
16 /// Ratchets down only, never up. 115 at the start of the restructure
17 /// (2026-07-07); 113 after Phase 1 retired `mnw.js` (its 2 `window.*` globals
18 /// moved into the typed core module's bridge).
19 const HIGH_WATER: usize = 113;
20
21 /// Count `window.<ident> =` assignments (not `==`/`===` comparisons) across the
22 /// legacy `static/*.js` files.
23 fn count_window_globals() -> usize {
24 // `=[^=]` matches an assignment `=` while excluding the first `=` of a
25 // comparison operator. The regex crate has no lookahead, so this is the
26 // portable form.
27 let re = regex::Regex::new(r"window\.[A-Za-z_][A-Za-z0-9_]*\s*=[^=]").unwrap();
28 let static_dir = concat!(env!("CARGO_MANIFEST_DIR"), "/static");
29 let mut total = 0;
30 for entry in fs::read_dir(static_dir).expect("read static/ dir") {
31 let path = entry.expect("dir entry").path();
32 if path.extension().and_then(|e| e.to_str()) == Some("js") {
33 let src = fs::read_to_string(&path).unwrap_or_default();
34 total += re.find_iter(&src).count();
35 }
36 }
37 total
38 }
39
40 #[test]
41 fn frontend_globals_do_not_grow() {
42 let count = count_window_globals();
43 assert!(
44 count <= HIGH_WATER,
45 "window.* global assignments in static/*.js rose to {count} (HIGH_WATER {HIGH_WATER}). \
46 New frontend code must be a typed ES module in frontend/src registered through the \
47 dispatcher, not a `window.*` global. If you REMOVED globals, lower HIGH_WATER to {count}."
48 );
49 }
50