@@ -10,12 +10,29 @@ use std::sync::Mutex;
10
10
use std:: time:: Instant ;
11
11
12
12
pub ( crate ) struct Checksums {
13
+ cache_path : Option < PathBuf > ,
13
14
collected : Mutex < HashMap < PathBuf , String > > ,
14
15
}
15
16
16
17
impl 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 ( ( ) )
19
36
}
20
37
21
38
pub ( crate ) fn fill_missing_checksums ( & mut self , manifest : & mut Manifest ) {
@@ -27,10 +44,14 @@ impl Checksums {
27
44
}
28
45
29
46
fn find_missing_checksums ( & mut self , manifest : & mut Manifest ) -> HashSet < PathBuf > {
47
+ let collected = self . collected . lock ( ) . unwrap ( ) ;
30
48
let mut need_checksums = HashSet :: new ( ) ;
31
49
crate :: manifest:: visit_file_hashes ( manifest, |file_hash| {
32
50
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
+ }
34
55
}
35
56
} ) ;
36
57
need_checksums
@@ -40,7 +61,8 @@ impl Checksums {
40
61
let collected = self . collected . lock ( ) . unwrap ( ) ;
41
62
crate :: manifest:: visit_file_hashes ( manifest, |file_hash| {
42
63
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) {
44
66
Some ( hash) => * file_hash = FileHash :: Present ( hash. clone ( ) ) ,
45
67
None => panic ! ( "missing hash for file {}" , path. display( ) ) ,
46
68
}
0 commit comments