1- use crate :: utils:: { ClippyInfo , ErrAction , UpdateMode , panic_action, run_with_args_split, run_with_output} ;
1+ use crate :: utils:: {
2+ ErrAction , FileUpdater , UpdateMode , UpdateStatus , expect_action, run_with_output, split_args_for_threads,
3+ walk_dir_no_dot_or_target,
4+ } ;
25use itertools:: Itertools ;
36use rustc_lexer:: { TokenKind , tokenize} ;
7+ use std:: fmt:: Write ;
48use std:: fs;
59use std:: io:: { self , Read } ;
610use std:: ops:: ControlFlow ;
711use std:: path:: PathBuf ;
812use std:: process:: { self , Command , Stdio } ;
9- use walkdir:: WalkDir ;
1013
1114pub enum Error {
1215 Io ( io:: Error ) ,
@@ -225,49 +228,59 @@ fn fmt_conf(check: bool) -> Result<(), Error> {
225228 Ok ( ( ) )
226229}
227230
228- fn run_rustfmt ( clippy : & ClippyInfo , update_mode : UpdateMode ) {
231+ /// Format the symbols list
232+ fn fmt_syms ( update_mode : UpdateMode ) {
233+ FileUpdater :: default ( ) . update_file_checked (
234+ "cargo dev fmt" ,
235+ update_mode,
236+ "clippy_utils/src/sym.rs" ,
237+ & mut |_, text : & str , new_text : & mut String | {
238+ let ( pre, conf) = text. split_once ( "generate! {\n " ) . expect ( "can't find generate! call" ) ;
239+ let ( conf, post) = conf. split_once ( "\n }\n " ) . expect ( "can't find end of generate! call" ) ;
240+ let mut lines = conf
241+ . lines ( )
242+ . map ( |line| {
243+ let line = line. trim ( ) ;
244+ line. strip_suffix ( ',' ) . unwrap_or ( line) . trim_end ( )
245+ } )
246+ . collect :: < Vec < _ > > ( ) ;
247+ lines. sort_unstable ( ) ;
248+ write ! (
249+ new_text,
250+ "{pre}generate! {{\n {},\n }}\n {post}" ,
251+ lines. join( ",\n " ) ,
252+ )
253+ . unwrap ( ) ;
254+ if text == new_text {
255+ UpdateStatus :: Unchanged
256+ } else {
257+ UpdateStatus :: Changed
258+ }
259+ } ,
260+ ) ;
261+ }
262+
263+ fn run_rustfmt ( update_mode : UpdateMode ) {
229264 let mut rustfmt_path = String :: from_utf8 ( run_with_output (
230265 "rustup which rustfmt" ,
231266 Command :: new ( "rustup" ) . args ( [ "which" , "rustfmt" ] ) ,
232267 ) )
233268 . expect ( "invalid rustfmt path" ) ;
234269 rustfmt_path. truncate ( rustfmt_path. trim_end ( ) . len ( ) ) ;
235270
236- let mut cargo_path = String :: from_utf8 ( run_with_output (
237- "rustup which cargo" ,
238- Command :: new ( "rustup" ) . args ( [ "which" , "cargo" ] ) ,
239- ) )
240- . expect ( "invalid cargo path" ) ;
241- cargo_path. truncate ( cargo_path. trim_end ( ) . len ( ) ) ;
242-
243- // Start all format jobs first before waiting on the results.
244- let mut children = Vec :: with_capacity ( 16 ) ;
245- for & path in & [
246- "." ,
247- "clippy_config" ,
248- "clippy_dev" ,
249- "clippy_lints" ,
250- "clippy_utils" ,
251- "rustc_tools_util" ,
252- "lintcheck" ,
253- ] {
254- let mut cmd = Command :: new ( & cargo_path) ;
255- cmd. current_dir ( clippy. path . join ( path) )
256- . args ( [ "fmt" ] )
257- . env ( "RUSTFMT" , & rustfmt_path)
258- . stdout ( Stdio :: null ( ) )
259- . stdin ( Stdio :: null ( ) )
260- . stderr ( Stdio :: piped ( ) ) ;
261- if update_mode. is_check ( ) {
262- cmd. arg ( "--check" ) ;
263- }
264- match cmd. spawn ( ) {
265- Ok ( x) => children. push ( ( "cargo fmt" , x) ) ,
266- Err ( ref e) => panic_action ( & e, ErrAction :: Run , "cargo fmt" . as_ref ( ) ) ,
267- }
268- }
271+ let args: Vec < _ > = walk_dir_no_dot_or_target ( )
272+ . filter_map ( |e| {
273+ let e = expect_action ( e, ErrAction :: Read , "." ) ;
274+ e. path ( )
275+ . as_os_str ( )
276+ . as_encoded_bytes ( )
277+ . ends_with ( b".rs" )
278+ . then ( || e. into_path ( ) . into_os_string ( ) )
279+ } )
280+ . collect ( ) ;
269281
270- run_with_args_split (
282+ let mut children: Vec < _ > = split_args_for_threads (
283+ 32 ,
271284 || {
272285 let mut cmd = Command :: new ( & rustfmt_path) ;
273286 if update_mode. is_check ( ) {
@@ -276,67 +289,45 @@ fn run_rustfmt(clippy: &ClippyInfo, update_mode: UpdateMode) {
276289 cmd. stdout ( Stdio :: null ( ) )
277290 . stdin ( Stdio :: null ( ) )
278291 . stderr ( Stdio :: piped ( ) )
279- . args ( [ "--config " , "show_parse_errors=false " ] ) ;
292+ . args ( [ "--unstable-features " , "--skip-children " ] ) ;
280293 cmd
281294 } ,
282- |cmd| match cmd. spawn ( ) {
283- Ok ( x) => children. push ( ( "rustfmt" , x) ) ,
284- Err ( ref e) => panic_action ( & e, ErrAction :: Run , "rustfmt" . as_ref ( ) ) ,
285- } ,
286- WalkDir :: new ( "tests" )
287- . into_iter ( )
288- . filter_entry ( |p| p. path ( ) . file_name ( ) . is_none_or ( |x| x != "skip_rustfmt" ) )
289- . filter_map ( |e| {
290- let e = e. expect ( "error reading `tests`" ) ;
291- e. path ( )
292- . as_os_str ( )
293- . as_encoded_bytes ( )
294- . ends_with ( b".rs" )
295- . then ( || e. into_path ( ) . into_os_string ( ) )
296- } ) ,
297- ) ;
295+ args. iter ( ) ,
296+ )
297+ . map ( |mut cmd| expect_action ( cmd. spawn ( ) , ErrAction :: Run , "rustfmt" ) )
298+ . collect ( ) ;
298299
299- for ( name, child) in & mut children {
300- match child. wait ( ) {
301- Ok ( status) => match ( update_mode, status. exit_ok ( ) ) {
302- ( UpdateMode :: Check | UpdateMode :: Change , Ok ( ( ) ) ) => { } ,
303- ( UpdateMode :: Check , Err ( _) ) => {
304- let mut s = String :: new ( ) ;
305- if let Some ( mut stderr) = child. stderr . take ( )
306- && stderr. read_to_string ( & mut s) . is_ok ( )
307- {
308- eprintln ! ( "{s}" ) ;
309- }
310- eprintln ! ( "Formatting check failed!\n Run `cargo dev fmt` to update." ) ;
311- process:: exit ( 1 ) ;
312- } ,
313- ( UpdateMode :: Change , Err ( e) ) => {
314- let mut s = String :: new ( ) ;
315- if let Some ( mut stderr) = child. stderr . take ( )
316- && stderr. read_to_string ( & mut s) . is_ok ( )
317- {
318- eprintln ! ( "{s}" ) ;
319- }
320- panic_action ( & e, ErrAction :: Run , name. as_ref ( ) ) ;
321- } ,
300+ for child in & mut children {
301+ let status = expect_action ( child. wait ( ) , ErrAction :: Run , "rustfmt" ) ;
302+ match ( update_mode, status. exit_ok ( ) ) {
303+ ( UpdateMode :: Check | UpdateMode :: Change , Ok ( ( ) ) ) => { } ,
304+ ( UpdateMode :: Check , Err ( _) ) => {
305+ let mut s = String :: new ( ) ;
306+ if let Some ( mut stderr) = child. stderr . take ( )
307+ && stderr. read_to_string ( & mut s) . is_ok ( )
308+ {
309+ eprintln ! ( "{s}" ) ;
310+ }
311+ eprintln ! ( "Formatting check failed!\n Run `cargo dev fmt` to update." ) ;
312+ process:: exit ( 1 ) ;
313+ } ,
314+ ( UpdateMode :: Change , e) => {
315+ let mut s = String :: new ( ) ;
316+ if let Some ( mut stderr) = child. stderr . take ( )
317+ && stderr. read_to_string ( & mut s) . is_ok ( )
318+ {
319+ eprintln ! ( "{s}" ) ;
320+ }
321+ expect_action ( e, ErrAction :: Run , "rustfmt" ) ;
322322 } ,
323- Err ( ref e) => panic_action ( e, ErrAction :: Run , name. as_ref ( ) ) ,
324323 }
325324 }
326325}
327326
328327// the "main" function of cargo dev fmt
329- pub fn run ( clippy : & ClippyInfo , update_mode : UpdateMode ) {
330- if clippy. has_intellij_hook {
331- eprintln ! (
332- "error: a local rustc repo is enabled as path dependency via `cargo dev setup intellij`.\n \
333- Not formatting because that would format the local repo as well!\n \
334- Please revert the changes to `Cargo.toml`s with `cargo dev remove intellij`."
335- ) ;
336- return ;
337- }
338- run_rustfmt ( clippy, update_mode) ;
339-
328+ pub fn run ( update_mode : UpdateMode ) {
329+ run_rustfmt ( update_mode) ;
330+ fmt_syms ( update_mode) ;
340331 if let Err ( e) = fmt_conf ( update_mode. is_check ( ) ) {
341332 e. display ( ) ;
342333 process:: exit ( 1 ) ;
0 commit comments