@@ -10,12 +10,29 @@ use std::sync::Mutex;
1010use std:: time:: Instant ;
1111
1212pub ( crate ) struct Checksums {
13+ cache_path : Option < PathBuf > ,
1314 collected : Mutex < HashMap < PathBuf , String > > ,
1415}
1516
1617impl Checksums {
17- pub ( crate ) fn new ( ) -> Self {
18- Checksums { collected : Mutex :: new ( HashMap :: new ( ) ) }
18+ pub ( crate ) fn new ( ) -> Result < Self , Box < dyn Error > > {
19+ let cache_path = std:: env:: var_os ( "BUILD_MANIFEST_CHECKSUM_CACHE" ) . map ( PathBuf :: from) ;
20+
21+ let mut collected = HashMap :: new ( ) ;
22+ if let Some ( path) = & cache_path {
23+ if path. is_file ( ) {
24+ collected = serde_json:: from_slice ( & std:: fs:: read ( path) ?) ?;
25+ }
26+ }
27+
28+ Ok ( Checksums { cache_path, collected : Mutex :: new ( collected) } )
29+ }
30+
31+ pub ( crate ) fn store_cache ( & self ) -> Result < ( ) , Box < dyn Error > > {
32+ if let Some ( path) = & self . cache_path {
33+ std:: fs:: write ( path, & serde_json:: to_vec ( & self . collected ) ?) ?;
34+ }
35+ Ok ( ( ) )
1936 }
2037
2138 pub ( crate ) fn fill_missing_checksums ( & mut self , manifest : & mut Manifest ) {
@@ -27,10 +44,14 @@ impl Checksums {
2744 }
2845
2946 fn find_missing_checksums ( & mut self , manifest : & mut Manifest ) -> HashSet < PathBuf > {
47+ let collected = self . collected . lock ( ) . unwrap ( ) ;
3048 let mut need_checksums = HashSet :: new ( ) ;
3149 crate :: manifest:: visit_file_hashes ( manifest, |file_hash| {
3250 if let FileHash :: Missing ( path) = file_hash {
33- need_checksums. insert ( path. clone ( ) ) ;
51+ let path = std:: fs:: canonicalize ( path) . unwrap ( ) ;
52+ if !collected. contains_key ( & path) {
53+ need_checksums. insert ( path) ;
54+ }
3455 }
3556 } ) ;
3657 need_checksums
@@ -40,7 +61,8 @@ impl Checksums {
4061 let collected = self . collected . lock ( ) . unwrap ( ) ;
4162 crate :: manifest:: visit_file_hashes ( manifest, |file_hash| {
4263 if let FileHash :: Missing ( path) = file_hash {
43- match collected. get ( path) {
64+ let path = std:: fs:: canonicalize ( path) . unwrap ( ) ;
65+ match collected. get ( & path) {
4466 Some ( hash) => * file_hash = FileHash :: Present ( hash. clone ( ) ) ,
4567 None => panic ! ( "missing hash for file {}" , path. display( ) ) ,
4668 }
0 commit comments