@@ -582,18 +582,35 @@ pub fn allocPrintCmd2(
582
582
return buf .toOwnedSlice (arena );
583
583
}
584
584
585
+ /// Prefer `cacheHitAndWatch` unless you already added watch inputs
586
+ /// separately from using the cache system.
585
587
pub fn cacheHit (s : * Step , man : * Build.Cache.Manifest ) ! bool {
586
588
s .result_cached = man .hit () catch | err | return failWithCacheError (s , man , err );
587
589
return s .result_cached ;
588
590
}
589
591
592
+ /// Clears previous watch inputs, if any, and then populates watch inputs from
593
+ /// the full set of files picked up by the cache manifest.
594
+ ///
595
+ /// Must be accompanied with `writeManifestAndWatch`.
596
+ pub fn cacheHitAndWatch (s : * Step , man : * Build.Cache.Manifest ) ! bool {
597
+ const is_hit = man .hit () catch | err | return failWithCacheError (s , man , err );
598
+ s .result_cached = is_hit ;
599
+ // The above call to hit() populates the manifest with files, so in case of
600
+ // a hit, we need to populate watch inputs.
601
+ if (is_hit ) try setWatchInputsFromManifest (s , man );
602
+ return is_hit ;
603
+ }
604
+
590
605
fn failWithCacheError (s : * Step , man : * const Build.Cache.Manifest , err : anyerror ) anyerror {
591
606
const i = man .failed_file_index orelse return err ;
592
607
const pp = man .files .keys ()[i ].prefixed_path ;
593
608
const prefix = man .cache .prefixes ()[pp .prefix ].path orelse "" ;
594
609
return s .fail ("{s}: {s}/{s}" , .{ @errorName (err ), prefix , pp .sub_path });
595
610
}
596
611
612
+ /// Prefer `writeManifestAndWatch` unless you already added watch inputs
613
+ /// separately from using the cache system.
597
614
pub fn writeManifest (s : * Step , man : * Build.Cache.Manifest ) ! void {
598
615
if (s .test_results .isSuccess ()) {
599
616
man .writeManifest () catch | err | {
@@ -602,6 +619,29 @@ pub fn writeManifest(s: *Step, man: *Build.Cache.Manifest) !void {
602
619
}
603
620
}
604
621
622
+ /// Clears previous watch inputs, if any, and then populates watch inputs from
623
+ /// the full set of files picked up by the cache manifest.
624
+ ///
625
+ /// Must be accompanied with `cacheHitAndWatch`.
626
+ pub fn writeManifestAndWatch (s : * Step , man : * Build.Cache.Manifest ) ! void {
627
+ try writeManifest (s , man );
628
+ try setWatchInputsFromManifest (s , man );
629
+ }
630
+
631
+ fn setWatchInputsFromManifest (s : * Step , man : * Build.Cache.Manifest ) ! void {
632
+ const arena = s .owner .allocator ;
633
+ const prefixes = man .cache .prefixes ();
634
+ clearWatchInputs (s );
635
+ for (man .files .keys ()) | file | {
636
+ // The file path data is freed when the cache manifest is cleaned up at the end of `make`.
637
+ const sub_path = try arena .dupe (u8 , file .prefixed_path .sub_path );
638
+ try addWatchInputFromPath (s , .{
639
+ .root_dir = prefixes [file .prefixed_path .prefix ],
640
+ .sub_path = std .fs .path .dirname (sub_path ) orelse "" ,
641
+ }, std .fs .path .basename (sub_path ));
642
+ }
643
+ }
644
+
605
645
/// For steps that have a single input that never changes when re-running `make`.
606
646
pub fn singleUnchangingWatchInput (step : * Step , lazy_path : Build.LazyPath ) Allocator.Error ! void {
607
647
if (! step .inputs .populated ()) try step .addWatchInput (lazy_path );
0 commit comments