diff --git a/Cargo.lock b/Cargo.lock index 915301e..b951530 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,7 +496,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", @@ -593,12 +593,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - [[package]] name = "cfg-if" version = "1.0.0" @@ -607,18 +601,18 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.23" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd" dependencies = [ "anstream", "anstyle", @@ -650,7 +644,7 @@ dependencies = [ "hyper-staticfile", "hyper-util", "log", - "notify", + "notify-debouncer-full", "sha2", "tar", "tokio", @@ -709,7 +703,7 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -878,13 +872,22 @@ dependencies = [ "subtle", ] +[[package]] +name = "file-id" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bc904b9bbefcadbd8e3a9fb0d464a9b979de6324c03b3c663e8994f46a5be36" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "filetime" version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "libredox", "windows-sys 0.59.0", @@ -921,41 +924,15 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fsevent" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" -dependencies = [ - "bitflags 1.3.2", - "fsevent-sys", -] - [[package]] name = "fsevent-sys" -version = "2.0.1" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" dependencies = [ "libc", ] -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags 1.3.2", - "fuchsia-zircon-sys", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - [[package]] name = "futures-channel" version = "0.3.31" @@ -1024,7 +1001,7 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] @@ -1246,7 +1223,7 @@ dependencies = [ "rand", "tokio", "url", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1415,9 +1392,9 @@ dependencies = [ [[package]] name = "inotify" -version = "0.7.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc" dependencies = [ "bitflags 1.3.2", "inotify-sys", @@ -1434,12 +1411,12 @@ dependencies = [ ] [[package]] -name = "iovec" -version = "0.1.4" +name = "instant" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "libc", + "cfg-if", ] [[package]] @@ -1455,20 +1432,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "kqueue" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" dependencies = [ - "winapi 0.2.8", - "winapi-build", + "kqueue-sys", + "libc", ] [[package]] -name = "lazycell" -version = "1.3.0" +name = "kqueue-sys" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] [[package]] name = "libc" @@ -1489,9 +1470,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "litemap" @@ -1530,7 +1511,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "digest", ] @@ -1565,25 +1546,6 @@ dependencies = [ "adler2", ] -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "1.0.3" @@ -1591,61 +1553,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.52.0", ] [[package]] -name = "mio-extras" -version = "2.0.6" +name = "notify" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009" dependencies = [ - "lazycell", + "bitflags 2.6.0", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", "log", - "mio 0.6.23", - "slab", -] - -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.52.0", ] [[package]] -name = "net2" -version = "0.2.39" +name = "notify-debouncer-full" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" +checksum = "9dcf855483228259b2353f89e99df35fc639b2b2510d1166e4858e3f67ec1afb" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "file-id", + "log", + "notify", + "notify-types", + "walkdir", ] [[package]] -name = "notify" -version = "4.0.18" +name = "notify-types" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b72dd35279a5dc895a30965e247b0961ba36c233dc48454a2de8ccd459f1afd3" +checksum = "585d3cb5e12e01aed9e8a1f70d5c6b5e86fe2a6e48fc8cd0b3e0b8df6f6eb174" dependencies = [ - "bitflags 1.3.2", - "filetime", - "fsevent", - "fsevent-sys", - "inotify", - "libc", - "mio 0.6.23", - "mio-extras", - "walkdir", - "winapi 0.3.9", + "instant", ] [[package]] @@ -1726,7 +1677,7 @@ version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall", "smallvec", @@ -1886,7 +1837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "cfg-if 1.0.0", + "cfg-if", "getrandom", "libc", "spin", @@ -1911,9 +1862,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.42" +version = "0.38.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" dependencies = [ "bitflags 2.6.0", "errno", @@ -2034,9 +1985,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.13.0" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1863fd3768cd83c56a7f60faa4dc0d403f1b6df0a38c3c25f44b7894e45370d5" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -2074,7 +2025,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", ] @@ -2085,7 +2036,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest", ] @@ -2249,14 +2200,14 @@ dependencies = [ [[package]] name = "tokio" -version = "1.42.0" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -2267,9 +2218,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -2444,12 +2395,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -2460,12 +2405,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2581,16 +2520,6 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "xattr" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index caa15ae..ab29451 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,7 @@ hyper = { version = "1.5.2", features = ["http1", "server"] } hyper-staticfile = "0.10.1" hyper-util = { version = "0.1.10", features = ["tokio"] } log = "0.4.22" -notify = "4.0.18" +notify-debouncer-full = "0.4.0" sha2 = "0.10.8" tar = "0.4.43" tokio = { version = "1.42.0", features = ["full"] } diff --git a/src/watcher.rs b/src/watcher.rs index 286bf7b..05e3bb9 100644 --- a/src/watcher.rs +++ b/src/watcher.rs @@ -5,7 +5,8 @@ use blake2::{Blake2b512, Digest}; use flate2::read::GzDecoder; use hex::ToHex; use log::{debug, info, trace}; -use notify::{DebouncedEvent, RecommendedWatcher, Watcher}; +use notify_debouncer_full::notify::{self, EventKind, RecommendedWatcher}; +use notify_debouncer_full::Debouncer; use std::collections::HashMap; use std::fs; use std::io::{Read, Seek}; @@ -147,65 +148,100 @@ pub(crate) fn watch_dir( let digest_salt = digest_salt.map(|s| s.to_owned()); move || { let (watcher_tx, watcher_rx) = std::sync::mpsc::channel(); - let mut watcher: RecommendedWatcher = Watcher::new(watcher_tx, Duration::from_secs(2)) + let notify_config = + notify::Config::default().with_poll_interval(Duration::from_secs(2)); + let mut watcher: Debouncer = + notify_debouncer_full::new_debouncer_opt( + Duration::from_secs(2), + None, + watcher_tx, + notify_debouncer_full::RecommendedCache::new(), + notify_config, + ) .expect("Failed to create file watcher"); watcher .watch(&artifact_dir, notify::RecursiveMode::NonRecursive) .expect("Failed to start file watcher"); loop { match watcher_rx.recv() { - Ok(event) => { - trace!("Detected file event: {:?}", event); - match event { - DebouncedEvent::Create(p) => { - if let Some(build_id) = - is_artifact_tarball(&p, digest_salt.as_deref()) - { - info!("Creating artifact cache for build {}", build_id); - let mut cache_dir = PathBuf::from(&cache_dir); - cache_dir.push(&build_id); - extract_to(&cache_dir, &p).unwrap_or_else(|_| { - panic!("Failed to extract artifact tarball {}", p.display()) - }); - tx.blocking_send(BuildEvent::Create(build_id)) - .expect("Failed to send build event"); + Ok(event_result) => match event_result { + Ok(events) => { + for event in events { + trace!("Detected file event: {:?}", event); + match event.kind { + EventKind::Create(_) => { + for path in &event.paths { + if let Some(build_id) = + is_artifact_tarball(path, digest_salt.as_deref()) + { + info!( + "Creating artifact cache for build {}", + build_id + ); + let mut cache_dir = PathBuf::from(&cache_dir); + cache_dir.push(&build_id); + extract_to(&cache_dir, path).unwrap_or_else(|_| { + panic!( + "Failed to extract artifact tarball {}", + path.display() + ) + }); + tx.blocking_send(BuildEvent::Create(build_id)) + .expect("Failed to send build event"); + } + } + } + EventKind::Modify(_) => { + for path in &event.paths { + if let Some(build_id) = + is_artifact_tarball(path, digest_salt.as_deref()) + { + info!( + "Updating artifact cache for build {}", + build_id + ); + let mut cache_dir = PathBuf::from(&cache_dir); + cache_dir.push(&build_id); + extract_to(&cache_dir, path).unwrap_or_else(|_| { + panic!( + "Failed to extract artifact tarball {}", + path.display() + ) + }); + tx.blocking_send(BuildEvent::Update(build_id)) + .expect("Failed to send build event"); + } + } + } + EventKind::Remove(_) => { + for path in &event.paths { + if let Some(build_id) = + is_artifact_tarball(path, digest_salt.as_deref()) + { + info!( + "Deleting artifact cache for build {}", + build_id + ); + let mut cache_dir = PathBuf::from(&cache_dir); + cache_dir.push(&build_id); + maybe_remove_dir(&cache_dir).unwrap_or_else(|_| { + panic!( + "Failed to remove cache directory {}", + cache_dir.display() + ) + }); + tx.blocking_send(BuildEvent::Delete(build_id)) + .expect("Failed to send build event"); + } + } + } + _ => (), } } - DebouncedEvent::Write(p) => { - if let Some(build_id) = - is_artifact_tarball(&p, digest_salt.as_deref()) - { - info!("Updating artifact cache for build {}", build_id); - let mut cache_dir = PathBuf::from(&cache_dir); - cache_dir.push(&build_id); - extract_to(&cache_dir, &p).unwrap_or_else(|_| { - panic!("Failed to extract artifact tarball {}", p.display()) - }); - tx.blocking_send(BuildEvent::Update(build_id)) - .expect("Failed to send build event"); - } - } - DebouncedEvent::Remove(p) => { - if let Some(build_id) = - is_artifact_tarball(&p, digest_salt.as_deref()) - { - info!("Deleting artifact cache for build {}", build_id); - let mut cache_dir = PathBuf::from(&cache_dir); - cache_dir.push(&build_id); - maybe_remove_dir(&cache_dir).unwrap_or_else(|_| { - panic!( - "Failed to remove cache directory {}", - cache_dir.display() - ) - }); - tx.blocking_send(BuildEvent::Delete(build_id)) - .expect("Failed to send build event"); - } - } - _ => (), } - } - Err(e) => panic!("File watcher error: {e:?}"), + Err(errors) => panic!("file watcher errors: {errors:?}"), + }, + Err(e) => panic!("watcher channel receive error: {e:?}"), } } }