diff --git a/Cargo.lock b/Cargo.lock index 38bcdd6f6..ea3c70c7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,6 +171,7 @@ dependencies = [ "unic-ucd-category", "unicase", "unicode-normalization", + "utime", "windows 0.56.0", "wiremock", "zip", @@ -6421,6 +6422,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "utime" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91baa0c65eabd12fcbdac8cc35ff16159cab95cae96d0222d6d0271db6193cef" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "uuid" version = "1.10.0" diff --git a/Cargo.toml b/Cargo.toml index 8d3c0052b..6d86959f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,6 +52,7 @@ ninja_gen = { "path" = "build/ninja_gen" } # pinned unicase = "=2.6.0" # any changes could invalidate sqlite indexes +utime = "=0.3.1" # marked as deprecated, but no native solution for folder mtimes exists # normal ammonia = "4.0.0" diff --git a/cargo/licenses.json b/cargo/licenses.json index 83bbcf653..911b0944c 100644 --- a/cargo/licenses.json +++ b/cargo/licenses.json @@ -4238,6 +4238,15 @@ "license_file": null, "description": "Incremental, zero-copy UTF-8 decoding with error handling" }, + { + "name": "utime", + "version": "0.3.1", + "authors": "Hyeon Kim ", + "repository": "https://github.com/simnalamburt/utime", + "license": "Apache-2.0 OR MIT", + "license_file": null, + "description": "A missing utime function for Rust." + }, { "name": "uuid", "version": "1.10.0", diff --git a/rslib/Cargo.toml b/rslib/Cargo.toml index 1c4abf46f..fb14826b4 100644 --- a/rslib/Cargo.toml +++ b/rslib/Cargo.toml @@ -103,6 +103,7 @@ tracing-subscriber.workspace = true unic-ucd-category.workspace = true unicase.workspace = true unicode-normalization.workspace = true +utime.workspace = true zip.workspace = true zstd.workspace = true diff --git a/rslib/io/src/lib.rs b/rslib/io/src/lib.rs index c6a6a0c51..f9ee9758a 100644 --- a/rslib/io/src/lib.rs +++ b/rslib/io/src/lib.rs @@ -53,9 +53,10 @@ pub fn write_file(path: impl AsRef, contents: impl AsRef<[u8]>) -> Result< op: FileOp::Write, }) } -/// See [File::set_times]. +/// See [File::set_times]. Note that this won't work on folders. pub fn set_file_times(path: impl AsRef, times: FileTimes) -> Result<()> { - open_file(&path)?.set_times(times).context(FileIoSnafu { + let file = open_file_ext(&path, OpenOptions::new().write(true).to_owned())?; + file.set_times(times).context(FileIoSnafu { path: path.as_ref(), op: FileOp::SetFileTimes, }) diff --git a/rslib/src/sync/media/database/client/changetracker.rs b/rslib/src/sync/media/database/client/changetracker.rs index 2d2220c7c..7f9b3f3cd 100644 --- a/rslib/src/sync/media/database/client/changetracker.rs +++ b/rslib/src/sync/media/database/client/changetracker.rs @@ -239,13 +239,11 @@ where #[cfg(test)] mod test { use std::fs; - use std::fs::FileTimes; use std::path::Path; use std::time; use std::time::Duration; use anki_io::create_dir; - use anki_io::set_file_times; use anki_io::write_file; use tempfile::tempdir; @@ -259,10 +257,13 @@ mod test { fn change_mtime(p: &Path) { let mtime = p.metadata().unwrap().modified().unwrap(); let new_mtime = mtime - Duration::from_secs(3); - let times = FileTimes::new() - .set_accessed(new_mtime) - .set_modified(new_mtime); - set_file_times(p, times).unwrap(); + let secs = new_mtime + .duration_since(time::UNIX_EPOCH) + .unwrap() + .as_secs() as i64; + // we rely on an external crate, as Rust's File::set_times() does not work + // on directories + utime::set_file_times(p, secs, secs).unwrap(); } #[test]