@@ -65,7 +65,7 @@ impl OutputMode {
65
65
}
66
66
67
67
#[ derive( Clone , Debug , PartialEq , Eq , Hash , Default ) ]
68
- pub struct CommandCacheKey {
68
+ pub struct CommandFingerprint {
69
69
program : OsString ,
70
70
args : Vec < OsString > ,
71
71
envs : Vec < ( OsString , Option < OsString > ) > ,
@@ -244,20 +244,17 @@ impl<'a> BootstrapCommand {
244
244
}
245
245
}
246
246
247
- pub fn cache_key ( & self ) -> Option < CommandCacheKey > {
248
- if !self . should_cache {
249
- return None ;
250
- }
247
+ pub fn fingerprint ( & self ) -> CommandFingerprint {
251
248
let command = & self . command ;
252
- Some ( CommandCacheKey {
249
+ CommandFingerprint {
253
250
program : command. get_program ( ) . into ( ) ,
254
251
args : command. get_args ( ) . map ( OsStr :: to_os_string) . collect ( ) ,
255
252
envs : command
256
253
. get_envs ( )
257
254
. map ( |( k, v) | ( k. to_os_string ( ) , v. map ( |val| val. to_os_string ( ) ) ) )
258
255
. collect ( ) ,
259
256
cwd : command. get_current_dir ( ) . map ( Path :: to_path_buf) ,
260
- } )
257
+ }
261
258
}
262
259
}
263
260
@@ -435,7 +432,7 @@ pub struct ExecutionContext {
435
432
436
433
#[ derive( Default ) ]
437
434
pub struct CommandCache {
438
- cache : Mutex < HashMap < CommandCacheKey , CommandOutput > > ,
435
+ cache : Mutex < HashMap < CommandFingerprint , CommandOutput > > ,
439
436
}
440
437
441
438
enum CommandState < ' a > {
@@ -446,14 +443,17 @@ enum CommandState<'a> {
446
443
stdout : OutputMode ,
447
444
stderr : OutputMode ,
448
445
executed_at : & ' a Location < ' a > ,
449
- cache_key : Option < CommandCacheKey > ,
446
+ fingerprint : CommandFingerprint ,
447
+ start_time : Instant ,
450
448
} ,
451
449
}
452
450
453
451
pub struct StreamingCommand {
454
452
child : Child ,
455
453
pub stdout : Option < ChildStdout > ,
456
454
pub stderr : Option < ChildStderr > ,
455
+ fingerprint : CommandFingerprint ,
456
+ start_time : Instant ,
457
457
}
458
458
459
459
#[ must_use]
@@ -462,11 +462,11 @@ pub struct DeferredCommand<'a> {
462
462
}
463
463
464
464
impl CommandCache {
465
- pub fn get ( & self , key : & CommandCacheKey ) -> Option < CommandOutput > {
465
+ pub fn get ( & self , key : & CommandFingerprint ) -> Option < CommandOutput > {
466
466
self . cache . lock ( ) . unwrap ( ) . get ( key) . cloned ( )
467
467
}
468
468
469
- pub fn insert ( & self , key : CommandCacheKey , output : CommandOutput ) {
469
+ pub fn insert ( & self , key : CommandFingerprint , output : CommandOutput ) {
470
470
self . cache . lock ( ) . unwrap ( ) . insert ( key, output) ;
471
471
}
472
472
}
@@ -539,10 +539,9 @@ impl ExecutionContext {
539
539
stdout : OutputMode ,
540
540
stderr : OutputMode ,
541
541
) -> DeferredCommand < ' a > {
542
- let cache_key = command. cache_key ( ) ;
542
+ let fingerprint = command. fingerprint ( ) ;
543
543
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) {
546
545
command. mark_as_executed ( ) ;
547
546
self . verbose ( || println ! ( "Cache hit: {command:?}" ) ) ;
548
547
return DeferredCommand { state : CommandState :: Cached ( cached_output) } ;
@@ -559,7 +558,8 @@ impl ExecutionContext {
559
558
stdout,
560
559
stderr,
561
560
executed_at,
562
- cache_key,
561
+ fingerprint,
562
+ start_time : Instant :: now ( ) ,
563
563
} ,
564
564
} ;
565
565
}
@@ -575,6 +575,8 @@ impl ExecutionContext {
575
575
cmd. stdout ( stdout. stdio ( ) ) ;
576
576
cmd. stderr ( stderr. stdio ( ) ) ;
577
577
578
+ let start_time = Instant :: now ( ) ;
579
+
578
580
let child = cmd. spawn ( ) ;
579
581
580
582
DeferredCommand {
@@ -584,7 +586,8 @@ impl ExecutionContext {
584
586
stdout,
585
587
stderr,
586
588
executed_at,
587
- cache_key,
589
+ fingerprint,
590
+ start_time,
588
591
} ,
589
592
}
590
593
}
@@ -638,6 +641,8 @@ impl ExecutionContext {
638
641
if !command. run_in_dry_run && self . dry_run ( ) {
639
642
return None ;
640
643
}
644
+ let start_time = Instant :: now ( ) ;
645
+ let fingerprint = command. fingerprint ( ) ;
641
646
let cmd = & mut command. command ;
642
647
cmd. stdout ( stdout. stdio ( ) ) ;
643
648
cmd. stderr ( stderr. stdio ( ) ) ;
@@ -669,16 +674,26 @@ impl<'a> DeferredCommand<'a> {
669
674
pub fn wait_for_output ( self , exec_ctx : impl AsRef < ExecutionContext > ) -> CommandOutput {
670
675
match self . state {
671
676
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
+ } => {
673
686
let exec_ctx = exec_ctx. as_ref ( ) ;
674
687
675
688
let output =
676
689
Self :: finish_process ( process, command, stdout, stderr, executed_at, exec_ctx) ;
677
690
678
691
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
680
694
{
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) ;
682
697
}
683
698
684
699
output
0 commit comments