Populate the file index for all tracked files after a materialize. Stats each tracked file from disk and stores its mtime + size + content hash in the pristine database. Errors are silently ignored (best-effort). Why we ignore `result.file_results` and walk the tracked set: the `MaterializeResult.file_results` map is only populated when `merge_file_result(_, store_result=true)` is called, and th
(&self, _result: &MaterializeResult)
| 900 | /// view's recorded state — every tracked file's on-disk content is |
| 901 | /// the authoritative baseline FILE_INDEX should cache. |
| 902 | fn populate_file_index(&self, _result: &MaterializeResult) { |
| 903 | use std::time::SystemTime; |
| 904 | |
| 905 | let tracked = match self.list_tracked_files() { |
| 906 | Ok(t) => t, |
| 907 | Err(_) => return, |
| 908 | }; |
| 909 | |
| 910 | let mut entries: Vec<(String, i64, u32, u64, Hash)> = Vec::with_capacity(tracked.len()); |
| 911 | |
| 912 | for file in &tracked { |
| 913 | let abs_path = self.root.join(&file.path); |
| 914 | let metadata = match std::fs::metadata(&abs_path) { |
| 915 | Ok(m) if m.is_file() => m, |
| 916 | _ => continue, |
| 917 | }; |
| 918 | |
| 919 | let mtime = metadata.modified().unwrap_or(SystemTime::UNIX_EPOCH); |
| 920 | let duration = mtime |
| 921 | .duration_since(SystemTime::UNIX_EPOCH) |
| 922 | .unwrap_or_default(); |
| 923 | let secs = duration.as_secs() as i64; |
| 924 | let nanos = duration.subsec_nanos(); |
| 925 | let size = metadata.len(); |
| 926 | |
| 927 | let content_hash = match std::fs::read(&abs_path) { |
| 928 | Ok(bytes) => Hash::of(&bytes), |
| 929 | Err(_) => continue, |
| 930 | }; |
| 931 | |
| 932 | let normalized = file.path.to_string_lossy().replace('\\', "/"); |
| 933 | entries.push((normalized, secs, nanos, size, content_hash)); |
| 934 | } |
| 935 | |
| 936 | if !entries.is_empty() { |
| 937 | let _ = self.update_file_index(&entries); |
| 938 | } |
| 939 | } |
| 940 | |
| 941 | /// Update FILE_INDEX for a specific set of paths. |
| 942 | /// |
no test coverage detected