@@ -86,6 +86,89 @@ def latest_mtime(paths: list[Path]) -> float:
8686 return latest
8787
8888
89+ def check_warning_hygiene (project : Path ) -> list [Finding ]:
90+ findings : list [Finding ] = []
91+
92+ checks : list [tuple [str , str ]] = [
93+ (
94+ "lib/vendor/crossterm/src/lib.rs" ,
95+ 'cfg(all(winapi, not(feature = "winapi")))' ,
96+ ),
97+ (
98+ "lib/vendor/crossterm/src/lib.rs" ,
99+ 'cfg(all(crossterm_winapi, not(feature = "crossterm_winapi")))' ,
100+ ),
101+ (
102+ "lib/vendor/crossterm/src/terminal/sys/unix.rs" ,
103+ "map(|file| (FileDesc::Owned(file.into())))" ,
104+ ),
105+ (
106+ "lib/vendor/portable-pty/src/unix.rs" ,
107+ 'feature = "cargo-clippy"' ,
108+ ),
109+ (
110+ "lib/vendor/x25519-dalek/src/lib.rs" ,
111+ 'cfg_attr(feature = "bench", feature(test))' ,
112+ ),
113+ (
114+ "lib/vendor/ratatui/src/terminal/terminal.rs" ,
115+ "pub fn get_frame(&mut self) -> Frame {" ,
116+ ),
117+ (
118+ "lib/vendor/ratatui/src/terminal/terminal.rs" ,
119+ "pub fn draw<F>(&mut self, render_callback: F) -> io::Result<CompletedFrame>" ,
120+ ),
121+ (
122+ "lib/vendor/ratatui/src/terminal/terminal.rs" ,
123+ "pub fn try_draw<F, E>(&mut self, render_callback: F) -> io::Result<CompletedFrame>" ,
124+ ),
125+ (
126+ "lib/vendor/ratatui/src/text/line.rs" ,
127+ "pub fn iter(&self) -> std::slice::Iter<Span<'a>> {" ,
128+ ),
129+ (
130+ "lib/vendor/ratatui/src/text/line.rs" ,
131+ "pub fn iter_mut(&mut self) -> std::slice::IterMut<Span<'a>> {" ,
132+ ),
133+ (
134+ "lib/vendor/ratatui/src/text/text.rs" ,
135+ "pub fn iter(&self) -> std::slice::Iter<Line<'a>> {" ,
136+ ),
137+ (
138+ "lib/vendor/ratatui/src/text/text.rs" ,
139+ "pub fn iter_mut(&mut self) -> std::slice::IterMut<Line<'a>> {" ,
140+ ),
141+ (
142+ "lib/vendor/ratatui/src/text/text.rs" ,
143+ "fn to_text(&self) -> Text {" ,
144+ ),
145+ (
146+ "lib/vendor/ratatui/src/widgets/block.rs" ,
147+ ") -> impl DoubleEndedIterator<Item = &Line> {" ,
148+ ),
149+ ]
150+
151+ for rel_path , needle in checks :
152+ path = project / rel_path
153+ if not path .is_file ():
154+ continue
155+ try :
156+ content = path .read_text (encoding = "utf-8" )
157+ except Exception :
158+ continue
159+ if needle in content :
160+ findings .append (
161+ Finding (
162+ "warn" ,
163+ "warning_hygiene_regression" ,
164+ f"{ rel_path } : found stale warning pattern `{ needle } `" ,
165+ "run scripts/vendor/apply-trims.sh (or hydrate) to re-apply warning hygiene patches" ,
166+ )
167+ )
168+
169+ return findings
170+
171+
89172def build_report (project : Path ) -> tuple [dict [str , Any ], list [Finding ]]:
90173 findings : list [Finding ] = []
91174 metrics : dict [str , Any ] = {
@@ -96,6 +179,7 @@ def build_report(project: Path) -> tuple[dict[str, Any], list[Finding]]:
96179 "direct_dependencies" : 0 ,
97180 "direct_non_vendored_dependencies" : 0 ,
98181 "direct_non_vendored_list" : [],
182+ "warning_hygiene_regressions" : 0 ,
99183 }
100184
101185 vendor_lock_path = project / "vendor.lock.toml"
@@ -401,6 +485,10 @@ def build_report(project: Path) -> tuple[dict[str, Any], list[Finding]]:
401485 )
402486 )
403487
488+ warning_hygiene_findings = check_warning_hygiene (project )
489+ metrics ["warning_hygiene_regressions" ] = len (warning_hygiene_findings )
490+ findings .extend (warning_hygiene_findings )
491+
404492 return metrics , findings
405493
406494
@@ -411,6 +499,7 @@ def print_text(metrics: dict[str, Any], findings: list[Finding]) -> None:
411499 print (f"vendor patch entries: { metrics ['vendor_patch_entries' ]} " )
412500 print (f"direct deps: { metrics ['direct_dependencies' ]} " )
413501 print (f"direct deps not yet vendored: { metrics ['direct_non_vendored_dependencies' ]} " )
502+ print (f"warning hygiene regressions: { metrics ['warning_hygiene_regressions' ]} " )
414503 if metrics ["direct_non_vendored_list" ]:
415504 preview = ", " .join (metrics ["direct_non_vendored_list" ][:12 ])
416505 suffix = " ..." if len (metrics ["direct_non_vendored_list" ]) > 12 else ""
0 commit comments