fix(compile): ensure atime/birthtime/mtime/ctime is set in vfs (#28731)

Co-authored-by: XYCode <xycode-xyc@outlook.com>
This commit is contained in:
David Sherret 2025-04-04 09:50:44 -04:00 committed by GitHub
parent dca9f7c0c3
commit becf24c8c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 96 additions and 38 deletions

View file

@ -1231,6 +1231,7 @@ pub struct FileBackedVfsMetadata {
pub name: String,
pub file_type: sys_traits::FileType,
pub len: u64,
pub mtime: Option<u128>,
}
impl FileBackedVfsMetadata {
@ -1247,17 +1248,23 @@ impl FileBackedVfsMetadata {
VfsEntryRef::File(file) => file.offset.len,
VfsEntryRef::Symlink(_) => 0,
},
mtime: match vfs_entry {
VfsEntryRef::Dir(_) => None,
VfsEntryRef::File(file) => file.mtime,
VfsEntryRef::Symlink(_) => None,
},
}
}
pub fn as_fs_stat(&self) -> FsStat {
// to use lower overhead, use mtime instead of all time params
FsStat {
is_directory: self.file_type == sys_traits::FileType::Dir,
is_file: self.file_type == sys_traits::FileType::File,
is_symlink: self.file_type == sys_traits::FileType::Symlink,
atime: None,
birthtime: None,
mtime: None,
ctime: None,
atime: Some(self.get_mtime()),
birthtime: Some(self.get_mtime()),
mtime: Some(self.get_mtime()),
ctime: Some(self.get_mtime()),
blksize: 0,
size: self.len,
dev: 0,
@ -1274,6 +1281,13 @@ impl FileBackedVfsMetadata {
is_socket: false,
}
}
/// if `mtime` is `None`, return `0`.
///
/// if `mtime` is greater than `u64::MAX`, return `u64::MAX`.
fn get_mtime(&self) -> u64 {
self.mtime.unwrap_or(0).try_into().unwrap_or(u64::MAX)
}
}
#[derive(Debug)]
@ -1480,19 +1494,28 @@ mod test {
let src_path = src_path.to_path_buf();
let mut builder = VfsBuilder::new();
builder
.add_file_with_data_raw(&src_path.join("a.txt"), "data".into())
.add_file_with_data_raw(&src_path.join("a.txt"), "data".into(), None)
.unwrap();
builder
.add_file_with_data_raw(&src_path.join("b.txt"), "data".into())
.add_file_with_data_raw(
&src_path.join("b.txt"),
"data".into(),
Some(
SystemTime::UNIX_EPOCH
.checked_add(Duration::from_secs(2))
.unwrap(),
),
)
.unwrap();
assert_eq!(builder.files_len(), 1); // because duplicate data
builder
.add_file_with_data_raw(&src_path.join("c.txt"), "c".into())
.add_file_with_data_raw(&src_path.join("c.txt"), "c".into(), None)
.unwrap();
builder
.add_file_with_data_raw(
&src_path.join("sub_dir").join("d.txt"),
"d".into(),
None,
)
.unwrap();
builder.add_file_at_path(&src_path.join("e.txt")).unwrap();
@ -1528,6 +1551,10 @@ mod test {
.file_type,
sys_traits::FileType::Symlink,
);
assert_eq!(
virtual_fs.lstat(&dest_path.join("b.txt")).unwrap().mtime,
Some(2_000),
);
assert_eq!(
virtual_fs
.stat(&dest_path.join("sub_dir").join("e.txt"))
@ -1653,6 +1680,7 @@ mod test {
.add_file_with_data_raw(
temp_path.join("a.txt").as_path(),
"0123456789".to_string().into_bytes(),
None,
)
.unwrap();
let (dest_path, virtual_fs) = into_virtual_fs(builder, &temp_dir);