@@ -65,7 +65,7 @@ impl OutputMode {
6565}
6666
6767#[ derive( Clone , Debug , PartialEq , Eq , Hash , Default ) ]
68- pub struct CommandCacheKey {
68+ pub struct CommandFingerprint {
6969 program : OsString ,
7070 args : Vec < OsString > ,
7171 envs : Vec < ( OsString , Option < OsString > ) > ,
@@ -244,20 +244,17 @@ impl<'a> BootstrapCommand {
244244 }
245245 }
246246
247- pub fn cache_key ( & self ) -> Option < CommandCacheKey > {
248- if !self . should_cache {
249- return None ;
250- }
247+ pub fn fingerprint ( & self ) -> CommandFingerprint {
251248 let command = & self . command ;
252- Some ( CommandCacheKey {
249+ CommandFingerprint {
253250 program : command. get_program ( ) . into ( ) ,
254251 args : command. get_args ( ) . map ( OsStr :: to_os_string) . collect ( ) ,
255252 envs : command
256253 . get_envs ( )
257254 . map ( |( k, v) | ( k. to_os_string ( ) , v. map ( |val| val. to_os_string ( ) ) ) )
258255 . collect ( ) ,
259256 cwd : command. get_current_dir ( ) . map ( Path :: to_path_buf) ,
260- } )
257+ }
261258 }
262259}
263260
@@ -435,7 +432,7 @@ pub struct ExecutionContext {
435432
436433#[ derive( Default ) ]
437434pub struct CommandCache {
438- cache : Mutex < HashMap < CommandCacheKey , CommandOutput > > ,
435+ cache : Mutex < HashMap < CommandFingerprint , CommandOutput > > ,
439436}
440437
441438enum CommandState < ' a > {
@@ -446,14 +443,17 @@ enum CommandState<'a> {
446443 stdout : OutputMode ,
447444 stderr : OutputMode ,
448445 executed_at : & ' a Location < ' a > ,
449- cache_key : Option < CommandCacheKey > ,
446+ fingerprint : CommandFingerprint ,
447+ start_time : Instant ,
450448 } ,
451449}
452450
453451pub struct StreamingCommand {
454452 child : Child ,
455453 pub stdout : Option < ChildStdout > ,
456454 pub stderr : Option < ChildStderr > ,
455+ fingerprint : CommandFingerprint ,
456+ start_time : Instant ,
457457}
458458
459459#[ must_use]
@@ -462,11 +462,11 @@ pub struct DeferredCommand<'a> {
462462}
463463
464464impl CommandCache {
465- pub fn get ( & self , key : & CommandCacheKey ) -> Option < CommandOutput > {
465+ pub fn get ( & self , key : & CommandFingerprint ) -> Option < CommandOutput > {
466466 self . cache . lock ( ) . unwrap ( ) . get ( key) . cloned ( )
467467 }
468468
469- pub fn insert ( & self , key : CommandCacheKey , output : CommandOutput ) {
469+ pub fn insert ( & self , key : CommandFingerprint , output : CommandOutput ) {
470470 self . cache . lock ( ) . unwrap ( ) . insert ( key, output) ;
471471 }
472472}
@@ -539,10 +539,9 @@ impl ExecutionContext {
539539 stdout : OutputMode ,
540540 stderr : OutputMode ,
541541 ) -> DeferredCommand < ' a > {
542- let cache_key = command. cache_key ( ) ;
542+ let fingerprint = command. fingerprint ( ) ;
543543
544- if let Some ( cached_output) = cache_key. as_ref ( ) . and_then ( |key| self . command_cache . get ( key) )
545- {
544+ if let Some ( cached_output) = self . command_cache . get ( & fingerprint) {
546545 command. mark_as_executed ( ) ;
547546 self . verbose ( || println ! ( "Cache hit: {command:?}" ) ) ;
548547 return DeferredCommand { state : CommandState :: Cached ( cached_output) } ;
@@ -559,7 +558,8 @@ impl ExecutionContext {
559558 stdout,
560559 stderr,
561560 executed_at,
562- cache_key,
561+ fingerprint,
562+ start_time : Instant :: now ( ) ,
563563 } ,
564564 } ;
565565 }
@@ -575,6 +575,8 @@ impl ExecutionContext {
575575 cmd. stdout ( stdout. stdio ( ) ) ;
576576 cmd. stderr ( stderr. stdio ( ) ) ;
577577
578+ let start_time = Instant :: now ( ) ;
579+
578580 let child = cmd. spawn ( ) ;
579581
580582 DeferredCommand {
@@ -584,7 +586,8 @@ impl ExecutionContext {
584586 stdout,
585587 stderr,
586588 executed_at,
587- cache_key,
589+ fingerprint,
590+ start_time,
588591 } ,
589592 }
590593 }
@@ -638,6 +641,8 @@ impl ExecutionContext {
638641 if !command. run_in_dry_run && self . dry_run ( ) {
639642 return None ;
640643 }
644+ let start_time = Instant :: now ( ) ;
645+ let fingerprint = command. fingerprint ( ) ;
641646 let cmd = & mut command. command ;
642647 cmd. stdout ( stdout. stdio ( ) ) ;
643648 cmd. stderr ( stderr. stdio ( ) ) ;
@@ -669,16 +674,26 @@ impl<'a> DeferredCommand<'a> {
669674 pub fn wait_for_output ( self , exec_ctx : impl AsRef < ExecutionContext > ) -> CommandOutput {
670675 match self . state {
671676 CommandState :: Cached ( output) => output,
672- CommandState :: Deferred { process, command, stdout, stderr, executed_at, cache_key } => {
677+ CommandState :: Deferred {
678+ process,
679+ command,
680+ stdout,
681+ stderr,
682+ executed_at,
683+ fingerprint,
684+ start_time,
685+ } => {
673686 let exec_ctx = exec_ctx. as_ref ( ) ;
674687
675688 let output =
676689 Self :: finish_process ( process, command, stdout, stderr, executed_at, exec_ctx) ;
677690
678691 if ( !exec_ctx. dry_run ( ) || command. run_in_dry_run )
679- && let ( Some ( cache_key) , Some ( _) ) = ( & cache_key, output. status ( ) )
692+ && output. status ( ) . is_some ( )
693+ && command. should_cache
680694 {
681- exec_ctx. command_cache . insert ( cache_key. clone ( ) , output. clone ( ) ) ;
695+ exec_ctx. command_cache . insert ( fingerprint. clone ( ) , output. clone ( ) ) ;
696+ exec_ctx. profiler . record_execution ( fingerprint. clone ( ) , start_time) ;
682697 }
683698
684699 output
0 commit comments