@@ -89,34 +89,34 @@ pub async fn doctor(args: DoctorArgs) -> Result<()> {
8989
9090 println ! ( "{}" , style( "Toolchain" ) . bold( ) ) ;
9191 checks. push ( check_tool ( "rustc" , & [ "--version" ] , "Rust compiler" , true ) . await ) ;
92- checks. push ( check_tool (
93- "cargo" ,
94- & [ "--version" ] ,
95- "Cargo package manager ",
96- true ,
97- )
98- . await ) ;
99- checks . push ( check_tool (
100- "cargo" ,
101- & [ "watch" , "--version" ] ,
102- "cargo-watch (for hot reload)" ,
103- false ,
104- )
105- . await ) ;
106- checks . push ( check_tool (
107- "docker" ,
108- & [ "--version" ] ,
109- "Docker (for containerization)" ,
110- false ,
111- )
112- . await ) ;
113- checks . push ( check_tool (
114- "sqlx" ,
115- & [ "--version" ] ,
116- "sqlx-cli (for database migrations)" ,
117- false ,
118- )
119- . await ) ;
92+ checks. push ( check_tool ( "cargo" , & [ "--version" ] , "Cargo package manager" , true ) . await ) ;
93+ checks . push (
94+ check_tool (
95+ "cargo ",
96+ & [ "watch" , "--version" ] ,
97+ "cargo-watch (for hot reload)" ,
98+ false ,
99+ )
100+ . await ,
101+ ) ;
102+ checks . push (
103+ check_tool (
104+ "docker" ,
105+ & [ "--version" ] ,
106+ "Docker (for containerization)" ,
107+ false ,
108+ )
109+ . await ,
110+ ) ;
111+ checks . push (
112+ check_tool (
113+ "sqlx" ,
114+ & [ "--version" ] ,
115+ "sqlx-cli (for database migrations)" ,
116+ false ,
117+ )
118+ . await ,
119+ ) ;
120120
121121 for check in & checks {
122122 print_check ( check) ;
@@ -280,10 +280,7 @@ fn build_project_checks(workspace_root: &Path) -> Result<Vec<DoctorCheck>> {
280280 }
281281
282282 checks. push ( if signals. production_defaults {
283- DoctorCheck :: pass (
284- "Application baseline" ,
285- "production_defaults usage detected" ,
286- )
283+ DoctorCheck :: pass ( "Application baseline" , "production_defaults usage detected" )
287284 } else {
288285 DoctorCheck :: warn (
289286 "Application baseline" ,
@@ -327,17 +324,21 @@ fn build_project_checks(workspace_root: &Path) -> Result<Vec<DoctorCheck>> {
327324 )
328325 } ) ;
329326
330- checks. push ( if ( signals. production_defaults || signals. request_id ) && ( signals. production_defaults || signals. tracing ) {
331- DoctorCheck :: pass (
332- "Request IDs and tracing" ,
333- "Request ID and tracing signals detected" ,
334- )
335- } else {
336- DoctorCheck :: warn (
337- "Request IDs and tracing" ,
338- "RequestIdLayer/tracing signals were not clearly detected" ,
339- )
340- } ) ;
327+ checks. push (
328+ if ( signals. production_defaults || signals. request_id )
329+ && ( signals. production_defaults || signals. tracing )
330+ {
331+ DoctorCheck :: pass (
332+ "Request IDs and tracing" ,
333+ "Request ID and tracing signals detected" ,
334+ )
335+ } else {
336+ DoctorCheck :: warn (
337+ "Request IDs and tracing" ,
338+ "RequestIdLayer/tracing signals were not clearly detected" ,
339+ )
340+ } ,
341+ ) ;
341342
342343 checks. push ( if signals. structured_logging || signals. otel {
343344 DoctorCheck :: pass (
@@ -351,17 +352,19 @@ fn build_project_checks(workspace_root: &Path) -> Result<Vec<DoctorCheck>> {
351352 )
352353 } ) ;
353354
354- checks. push ( if signals. rate_limit || signals. security_headers || signals. timeout || signals. cors {
355- DoctorCheck :: pass (
356- "Edge protections" ,
357- "Detected timeout, rate limit, CORS, or security header configuration" ,
358- )
359- } else {
360- DoctorCheck :: warn (
361- "Edge protections" ,
362- "No timeout, rate limit, CORS, or security header configuration was detected" ,
363- )
364- } ) ;
355+ checks. push (
356+ if signals. rate_limit || signals. security_headers || signals. timeout || signals. cors {
357+ DoctorCheck :: pass (
358+ "Edge protections" ,
359+ "Detected timeout, rate limit, CORS, or security header configuration" ,
360+ )
361+ } else {
362+ DoctorCheck :: warn (
363+ "Edge protections" ,
364+ "No timeout, rate limit, CORS, or security header configuration was detected" ,
365+ )
366+ } ,
367+ ) ;
365368
366369 checks. push ( if signals. body_limit {
367370 DoctorCheck :: pass (
@@ -401,7 +404,11 @@ fn scan_workspace_signals(workspace_root: &Path) -> Result<WorkspaceSignals> {
401404 ) ;
402405 signals. health_endpoints |= contains_any (
403406 & contents,
404- & [ ".health_endpoints(" , ".health_endpoint_config(" , "HealthEndpointConfig" ] ,
407+ & [
408+ ".health_endpoints(" ,
409+ ".health_endpoint_config(" ,
410+ "HealthEndpointConfig" ,
411+ ] ,
405412 ) ;
406413 signals. health_checks |= contents. contains ( ".with_health_check(" ) ;
407414 signals. request_id |= contents. contains ( "RequestIdLayer" ) ;
@@ -414,10 +421,8 @@ fn scan_workspace_signals(workspace_root: &Path) -> Result<WorkspaceSignals> {
414421 ) ;
415422 signals. otel |= contains_any ( & contents, & [ "OtelLayer" , "otel(" ] ) ;
416423 signals. rate_limit |= contains_any ( & contents, & [ "RateLimitLayer" , "rate_limit(" ] ) ;
417- signals. security_headers |= contains_any (
418- & contents,
419- & [ "SecurityHeadersLayer" , "security_headers(" ] ,
420- ) ;
424+ signals. security_headers |=
425+ contains_any ( & contents, & [ "SecurityHeadersLayer" , "security_headers(" ] ) ;
421426 signals. timeout |= contains_any ( & contents, & [ "TimeoutLayer" , "timeout(" ] ) ;
422427 signals. cors |= contains_any ( & contents, & [ "CorsLayer" , "cors(" ] ) ;
423428 signals. body_limit |= contains_any ( & contents, & [ "BodyLimitLayer" , ".body_limit(" ] ) ;
@@ -463,7 +468,10 @@ fn should_scan(path: &Path) -> bool {
463468 return true ;
464469 } ;
465470
466- !matches ! ( name, ".git" | "target" | "node_modules" | ".next" | "dist" | "build" )
471+ !matches ! (
472+ name,
473+ ".git" | "target" | "node_modules" | ".next" | "dist" | "build"
474+ )
467475}
468476
469477fn is_scannable_file ( path : & Path ) -> bool {
@@ -500,7 +508,11 @@ mod tests {
500508 #[ test]
501509 fn scan_workspace_signals_detects_production_patterns ( ) {
502510 let dir = tempdir ( ) . unwrap ( ) ;
503- fs:: write ( dir. path ( ) . join ( "Cargo.toml" ) , "[package]\n name='demo'\n version='0.1.0'\n " ) . unwrap ( ) ;
511+ fs:: write (
512+ dir. path ( ) . join ( "Cargo.toml" ) ,
513+ "[package]\n name='demo'\n version='0.1.0'\n " ,
514+ )
515+ . unwrap ( ) ;
504516 fs:: write ( dir. path ( ) . join ( ".env" ) , "RUSTAPI_ENV=production\n " ) . unwrap ( ) ;
505517
506518 let src_dir = dir. path ( ) . join ( "src" ) ;
@@ -536,12 +548,20 @@ mod tests {
536548 #[ test]
537549 fn build_project_checks_warns_when_signals_are_missing ( ) {
538550 let dir = tempdir ( ) . unwrap ( ) ;
539- fs:: write ( dir. path ( ) . join ( "Cargo.toml" ) , "[package]\n name='demo'\n version='0.1.0'\n " ) . unwrap ( ) ;
551+ fs:: write (
552+ dir. path ( ) . join ( "Cargo.toml" ) ,
553+ "[package]\n name='demo'\n version='0.1.0'\n " ,
554+ )
555+ . unwrap ( ) ;
540556 fs:: create_dir_all ( dir. path ( ) . join ( "src" ) ) . unwrap ( ) ;
541557 fs:: write ( dir. path ( ) . join ( "src" ) . join ( "main.rs" ) , "fn main() {}\n " ) . unwrap ( ) ;
542558
543559 let checks = build_project_checks ( dir. path ( ) ) . unwrap ( ) ;
544- assert ! ( checks. iter( ) . any( |check| check. status == DoctorStatus :: Warn ) ) ;
545- assert ! ( checks. iter( ) . any( |check| check. name == "Application baseline" ) ) ;
560+ assert ! ( checks
561+ . iter( )
562+ . any( |check| check. status == DoctorStatus :: Warn ) ) ;
563+ assert ! ( checks
564+ . iter( )
565+ . any( |check| check. name == "Application baseline" ) ) ;
546566 }
547567}
0 commit comments