From b43b45be8f2eb01161a389afeab56749fa82e459 Mon Sep 17 00:00:00 2001 From: Jack T <44332148+jackTabsCode@users.noreply.github.com> Date: Thu, 23 Nov 2023 16:16:43 -0800 Subject: [PATCH 1/7] Upgrade to Notify 6 (#816) --- Cargo.lock | 180 +++++++------------------------ Cargo.toml | 1 - crates/memofs/Cargo.toml | 2 +- crates/memofs/src/std_backend.rs | 70 ++++++------ tests/tests/serve.rs | 1 + 5 files changed, 74 insertions(+), 180 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e850ee23..87b5111b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -424,7 +424,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -549,41 +549,15 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" -[[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" version = "0.3.28" @@ -883,9 +857,9 @@ dependencies = [ [[package]] name = "inotify" -version = "0.7.1" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" dependencies = [ "bitflags 1.3.2", "inotify-sys", @@ -917,15 +891,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -963,13 +928,23 @@ dependencies = [ ] [[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 = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", ] [[package]] @@ -978,12 +953,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - [[package]] name = "libc" version = "0.2.148" @@ -1096,25 +1065,6 @@ dependencies = [ "adler", ] -[[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 = "0.8.8" @@ -1122,34 +1072,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.48.0", ] -[[package]] -name = "mio-extras" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" -dependencies = [ - "lazycell", - "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", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -1168,33 +1095,23 @@ dependencies = [ "tempfile", ] -[[package]] -name = "net2" -version = "0.2.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" -dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - [[package]] name = "notify" -version = "4.0.17" +version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", + "crossbeam-channel", "filetime", - "fsevent", "fsevent-sys", "inotify", + "kqueue", "libc", - "mio 0.6.23", - "mio-extras", + "log", + "mio", "walkdir", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] @@ -1204,7 +1121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1254,7 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005" dependencies = [ "bstr", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -1852,7 +1769,6 @@ dependencies = [ "log", "maplit", "memofs", - "notify", "num_cpus", "opener", "paste", @@ -2112,7 +2028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2275,7 +2191,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 0.8.8", + "mio", "num_cpus", "pin-project-lite", "socket2 0.5.4", @@ -2634,12 +2550,6 @@ dependencies = [ "wasm-bindgen", ] -[[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" @@ -2650,12 +2560,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" @@ -2668,7 +2572,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2824,7 +2728,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2833,7 +2737,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", + "winapi", ] [[package]] @@ -2846,16 +2750,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[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 = "xml-rs" version = "0.8.19" diff --git a/Cargo.toml b/Cargo.toml index 8c3ea003..1401d2e0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,7 +69,6 @@ hyper = { version = "0.14.13", features = ["server", "tcp", "http1"] } jod-thread = "0.1.2" log = "0.4.14" maplit = "1.0.2" -notify = "4.0.17" num_cpus = "1.15.0" opener = "0.5.0" rayon = "1.7.0" diff --git a/crates/memofs/Cargo.toml b/crates/memofs/Cargo.toml index 5cf5a733..b60a3038 100644 --- a/crates/memofs/Cargo.toml +++ b/crates/memofs/Cargo.toml @@ -13,5 +13,5 @@ homepage = "https://github.com/rojo-rbx/rojo/tree/master/memofs" [dependencies] crossbeam-channel = "0.5.1" fs-err = "2.3.0" -notify = "4.0.15" +notify = "6.1.1" serde = { version = "1.0", features = ["derive"] } diff --git a/crates/memofs/src/std_backend.rs b/crates/memofs/src/std_backend.rs index 01a554a5..4e95f110 100644 --- a/crates/memofs/src/std_backend.rs +++ b/crates/memofs/src/std_backend.rs @@ -1,25 +1,23 @@ use std::io; use std::path::Path; -use std::sync::mpsc; -use std::thread; -use std::time::Duration; use crossbeam_channel::Receiver; -use notify::{DebouncedEvent, RecursiveMode, Watcher}; + +use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; #[cfg(target_os = "macos")] -use notify::PollWatcher; -#[cfg(not(target_os = "macos"))] -use notify::{watcher, RecommendedWatcher}; +use notify::{Config, PollWatcher}; + +#[cfg(target_os = "macos")] +use std::time::Duration; use crate::{DirEntry, Metadata, ReadDir, VfsBackend, VfsEvent}; /// `VfsBackend` that uses `std::fs` and the `notify` crate. pub struct StdBackend { - // We use PollWatcher on macos because using the KQueue watcher - // can cause some gnarly performance problems. #[cfg(target_os = "macos")] watcher: PollWatcher, + #[cfg(not(target_os = "macos"))] watcher: RecommendedWatcher, @@ -28,37 +26,39 @@ pub struct StdBackend { impl StdBackend { pub fn new() -> StdBackend { - let (notify_tx, notify_rx) = mpsc::channel(); - - #[cfg(target_os = "macos")] - let watcher = PollWatcher::new(notify_tx, Duration::from_millis(50)).unwrap(); - #[cfg(not(target_os = "macos"))] - let watcher = watcher(notify_tx, Duration::from_millis(50)).unwrap(); - let (tx, rx) = crossbeam_channel::unbounded(); - thread::spawn(move || { - for event in notify_rx { - match event { - DebouncedEvent::Create(path) => { - tx.send(VfsEvent::Create(path))?; + let event_handler = move |res: Result| match res { + Ok(event) => match event.kind { + EventKind::Create(_) => { + for path in event.paths { + let _ = tx.send(VfsEvent::Create(path)); } - DebouncedEvent::Write(path) => { - tx.send(VfsEvent::Write(path))?; - } - DebouncedEvent::Remove(path) => { - tx.send(VfsEvent::Remove(path))?; - } - DebouncedEvent::Rename(from, to) => { - tx.send(VfsEvent::Remove(from))?; - tx.send(VfsEvent::Create(to))?; - } - _ => {} } - } + EventKind::Modify(_) => { + for path in event.paths { + let _ = tx.send(VfsEvent::Write(path)); + } + } + EventKind::Remove(_) => { + for path in event.paths { + let _ = tx.send(VfsEvent::Remove(path)); + } + } + _ => {} + }, + Err(e) => println!("watch error: {:?}", e), + }; - Result::<(), crossbeam_channel::SendError>::Ok(()) - }); + #[cfg(not(target_os = "macos"))] + let watcher = notify::recommended_watcher(event_handler).unwrap(); + + #[cfg(target_os = "macos")] + let watcher = PollWatcher::new( + event_handler, + Config::default().with_poll_interval(Duration::from_millis(200)), + ) + .unwrap(); Self { watcher, diff --git a/tests/tests/serve.rs b/tests/tests/serve.rs index d55d339b..9058c366 100644 --- a/tests/tests/serve.rs +++ b/tests/tests/serve.rs @@ -145,6 +145,7 @@ fn edit_init() { }); } +#[ignore = "Does not pass on Github's runner"] #[test] fn move_folder_of_stuff() { run_serve_test("move_folder_of_stuff", |session, mut redactions| { From 23327cb3ef25e47b8e20ebb91560721d7ba56301 Mon Sep 17 00:00:00 2001 From: Vee <106542812+cozywitchcraft@users.noreply.github.com> Date: Mon, 4 Dec 2023 11:02:25 -0500 Subject: [PATCH 2/7] Fix preloading assets in plugin (#819) `gatherAssetUrlsRecursive` now returns asset URLs deeper than one layer. --- plugin/src/preloadAssets.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/preloadAssets.lua b/plugin/src/preloadAssets.lua index c37ca032..1cf9b2d8 100644 --- a/plugin/src/preloadAssets.lua +++ b/plugin/src/preloadAssets.lua @@ -13,7 +13,7 @@ function gatherAssetUrlsRecursive(currentTable, currentUrls) if typeof(value) == "string" then table.insert(currentUrls, value) elseif typeof(value) == "table" then - gatherAssetUrlsRecursive(value) + gatherAssetUrlsRecursive(value, currentUrls) end end From 96987af71df1df3efa8fe7aabf9d16990e08c605 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Thu, 28 Dec 2023 15:17:00 -0800 Subject: [PATCH 3/7] Fix broken serve tests on macOS (#824) Right now, serve tests will fail when Rojo is built with the FSEvent backend. The cause is essentially due to the fact that `/var` (where temporary directories for serve tests are located) on macOS is actually a symlink to `/private/var`. Paths coming from FSEvent always have symlinks expanded, but Rojo never expands symlinks. So, Rojo's paths during these tests look like `/var/*` while the FSEvent paths look like `/private/var/*`. When Rojo's change processor receives these events, it considers them outside the project and does not apply any changes, causing serve tests to time out. To work around this, we can call `Path::canonicalize` before passing the project path to `rojo serve` during serve tests. Rojo does need to better support symlinks (which would also solve the problem), but I think that can be left for another day because it's larger in scope and I mostly just want working tests before addressing #609. --- tests/rojo_test/serve_util.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/rojo_test/serve_util.rs b/tests/rojo_test/serve_util.rs index d8253612..6f049020 100644 --- a/tests/rojo_test/serve_util.rs +++ b/tests/rojo_test/serve_util.rs @@ -66,7 +66,11 @@ impl TestServeSession { let source_path = Path::new(SERVE_TESTS_PATH).join(name); let dir = tempdir().expect("Couldn't create temporary directory"); - let project_path = dir.path().join(name); + let project_path = dir + .path() + .canonicalize() + .expect("Couldn't canonicalize temporary directory path") + .join(name); let source_is_file = fs::metadata(&source_path).unwrap().is_file(); From 11fa08e6d6962a3c54ddd16ecea552f8407bc066 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Fri, 29 Dec 2023 17:46:58 -0800 Subject: [PATCH 4/7] Run CI workflow on Windows and macOS (#825) This PR adds macOS and Windows jobs to the CI workflow. This allows us to see when changes break functionality on any supported platform, which is particularly important for changes that involve the file system or file watcher. --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad5a05d7..a9a39481 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,11 +12,12 @@ on: jobs: build: name: Build and Test - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: rust_version: [stable, 1.70.0] + os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v3 From 097d39e8ce74c42697296d772e0458b0e45fd0d4 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Sun, 31 Dec 2023 12:02:54 -0800 Subject: [PATCH 5/7] Fix move_folders_of_stuff (#826) This is a fairly important test verifying whether the action of moving a folder into a watched folder is correctly detected and processed. It was disabled in https://github.com/rojo-rbx/rojo/commit/b43b45be8f2eb01161a389afeab56749fa82e459. The fact that it failed indicates a possible bug in change processing, so in this PR, I'll re-enable the test, investigate why it fails, and fix it. --- src/change_processor.rs | 81 +++++++++++++++++------------------------ tests/tests/serve.rs | 1 - 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/change_processor.rs b/src/change_processor.rs index 2429b590..497ba4e7 100644 --- a/src/change_processor.rs +++ b/src/change_processor.rs @@ -1,6 +1,5 @@ use std::{ fs, - path::PathBuf, sync::{Arc, Mutex}, }; @@ -126,14 +125,41 @@ impl JobThreadContext { // For a given VFS event, we might have many changes to different parts // of the tree. Calculate and apply all of these changes. let applied_patches = match event { - VfsEvent::Write(path) => { - if path.is_dir() { - return; + VfsEvent::Create(path) | VfsEvent::Remove(path) | VfsEvent::Write(path) => { + let mut tree = self.tree.lock().unwrap(); + let mut applied_patches = Vec::new(); + + // Find the nearest ancestor to this path that has + // associated instances in the tree. This helps make sure + // that we handle additions correctly, especially if we + // receive events for descendants of a large tree being + // created all at once. + let mut current_path = path.as_path(); + let affected_ids = loop { + let ids = tree.get_ids_at_path(¤t_path); + + log::trace!("Path {} affects IDs {:?}", current_path.display(), ids); + + if !ids.is_empty() { + break ids.to_vec(); + } + + log::trace!("Trying parent path..."); + match current_path.parent() { + Some(parent) => current_path = parent, + None => break Vec::new(), + } + }; + + for id in affected_ids { + if let Some(patch) = compute_and_apply_changes(&mut tree, &self.vfs, id) { + if !patch.is_empty() { + applied_patches.push(patch); + } + } } - on_vfs_event(path, &self.tree, &self.vfs) - } - VfsEvent::Create(path) | VfsEvent::Remove(path) => { - on_vfs_event(path, &self.tree, &self.vfs) + + applied_patches } _ => { log::warn!("Unhandled VFS event: {:?}", event); @@ -236,45 +262,6 @@ impl JobThreadContext { } } -// Find the nearest ancestor to this path that has -// associated instances in the tree. This helps make sure -// that we handle additions correctly, especially if we -// receive events for descendants of a large tree being -// created all at once. -fn on_vfs_event( - path: PathBuf, - tree: &Arc>, - vfs: &Arc, -) -> Vec { - let mut tree = tree.lock().unwrap(); - let mut applied_patches = Vec::new(); - - let mut current_path = path.as_path(); - let affected_ids = loop { - let ids = tree.get_ids_at_path(current_path); - - log::trace!("Path {} affects IDs {:?}", current_path.display(), ids); - - if !ids.is_empty() { - break ids.to_vec(); - } - - log::trace!("Trying parent path..."); - match current_path.parent() { - Some(parent) => current_path = parent, - None => break Vec::new(), - } - }; - - for id in affected_ids { - if let Some(patch) = compute_and_apply_changes(&mut tree, vfs, id) { - if !patch.is_empty() { - applied_patches.push(patch); - } - } - } - applied_patches -} fn compute_and_apply_changes(tree: &mut RojoTree, vfs: &Vfs, id: Ref) -> Option { let metadata = tree .get_metadata(id) diff --git a/tests/tests/serve.rs b/tests/tests/serve.rs index 9058c366..d55d339b 100644 --- a/tests/tests/serve.rs +++ b/tests/tests/serve.rs @@ -145,7 +145,6 @@ fn edit_init() { }); } -#[ignore = "Does not pass on Github's runner"] #[test] fn move_folder_of_stuff() { run_serve_test("move_folder_of_stuff", |session, mut redactions| { From 3369b0d42980eb6c5c0c86f5972b8ce430a26ae3 Mon Sep 17 00:00:00 2001 From: Kenneth Loeffler Date: Tue, 2 Jan 2024 09:26:06 -0800 Subject: [PATCH 6/7] Downgrade to Notify 4, use FSEvents, use minimal recursive watches (#830) --- CHANGELOG.md | 5 +- Cargo.lock | 183 ++++++++++++++++++++++++------- crates/memofs/CHANGELOG.md | 4 +- crates/memofs/Cargo.toml | 2 +- crates/memofs/src/std_backend.rs | 85 +++++++------- 5 files changed, 192 insertions(+), 87 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2673f56..fe6fc377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Rojo Changelog ## Unreleased Changes +* Significantly improved performance of `rojo serve`, `rojo build --watch`, and `rojo sourcemap --watch` on macOS. [#830] + +[#830]: https://github.com/rojo-rbx/rojo/pull/830 ## [7.4.0-rc3] - October 25, 2023 * Changed `sourcemap --watch` to only generate the sourcemap when it's necessary ([#800]) @@ -138,7 +141,6 @@ * Add buttons for navigation on the Connected page ([#722]) ### Fixes -* Significantly improved performance of `rojo serve` and `rojo build` on macOS. [#783] * Significantly improved performance of `rojo sourcemap` ([#668]) * Fixed the diff visualizer of connected sessions. ([#674]) * Fixed disconnected session activity. ([#675]) @@ -172,7 +174,6 @@ [#770]: https://github.com/rojo-rbx/rojo/pull/770 [#771]: https://github.com/rojo-rbx/rojo/pull/771 [#774]: https://github.com/rojo-rbx/rojo/pull/774 -[#783]: https://github.com/rojo-rbx/rojo/pull/783 [rbx-dom#299]: https://github.com/rojo-rbx/rbx-dom/pull/299 [rbx-dom#296]: https://github.com/rojo-rbx/rbx-dom/pull/296 diff --git a/Cargo.lock b/Cargo.lock index 87b5111b..d0565dc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,7 +52,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi 0.1.19", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -424,7 +424,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -550,14 +550,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" [[package]] -name = "fsevent-sys" -version = "4.1.0" +name = "fsevent" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags 1.3.2", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" 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" version = "0.3.28" @@ -857,9 +883,9 @@ dependencies = [ [[package]] name = "inotify" -version = "0.9.6" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" dependencies = [ "bitflags 1.3.2", "inotify-sys", @@ -891,6 +917,15 @@ dependencies = [ "yaml-rust", ] +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + [[package]] name = "ipnet" version = "2.8.0" @@ -928,23 +963,13 @@ dependencies = [ ] [[package]] -name = "kqueue" -version = "1.0.8" +name = "kernel32-sys" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" dependencies = [ - "kqueue-sys", - "libc", -] - -[[package]] -name = "kqueue-sys" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" -dependencies = [ - "bitflags 1.3.2", - "libc", + "winapi 0.2.8", + "winapi-build", ] [[package]] @@ -953,6 +978,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "libc" version = "0.2.148" @@ -1065,6 +1096,25 @@ dependencies = [ "adler", ] +[[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 = "0.8.8" @@ -1072,11 +1122,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi", "windows-sys 0.48.0", ] +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "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", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -1096,22 +1169,32 @@ dependencies = [ ] [[package]] -name = "notify" -version = "6.1.1" +name = "net2" +version = "0.2.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +checksum = "b13b648036a2339d06de780866fbdfda0dde886de7b3af2ddeba8b14f4ee34ac" dependencies = [ - "bitflags 2.4.0", - "crossbeam-channel", + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags 1.3.2", "filetime", + "fsevent", "fsevent-sys", "inotify", - "kqueue", "libc", - "log", - "mio", + "mio 0.6.23", + "mio-extras", "walkdir", - "windows-sys 0.48.0", + "winapi 0.3.9", ] [[package]] @@ -1121,7 +1204,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ "overload", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1171,7 +1254,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005" dependencies = [ "bstr", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2028,7 +2111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2191,7 +2274,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio", + "mio 0.8.8", "num_cpus", "pin-project-lite", "socket2 0.5.4", @@ -2550,6 +2633,12 @@ dependencies = [ "wasm-bindgen", ] +[[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" @@ -2560,6 +2649,12 @@ 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" @@ -2572,7 +2667,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2728,7 +2823,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2737,7 +2832,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2750,6 +2845,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[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 = "xml-rs" version = "0.8.19" diff --git a/crates/memofs/CHANGELOG.md b/crates/memofs/CHANGELOG.md index 43516260..c9961d0e 100644 --- a/crates/memofs/CHANGELOG.md +++ b/crates/memofs/CHANGELOG.md @@ -1,7 +1,9 @@ # memofs Changelog ## Unreleased Changes -* Changed the `StdBackend` file watcher to use `PollWatcher` on macOS. +* Changed `StdBackend` file watching component to use minimal recursive watches. [#830] + +[#830]: https://github.com/rojo-rbx/rojo/pull/830 ## 0.2.0 (2021-08-23) * Updated to `crossbeam-channel` 0.5.1. diff --git a/crates/memofs/Cargo.toml b/crates/memofs/Cargo.toml index b60a3038..5cf5a733 100644 --- a/crates/memofs/Cargo.toml +++ b/crates/memofs/Cargo.toml @@ -13,5 +13,5 @@ homepage = "https://github.com/rojo-rbx/rojo/tree/master/memofs" [dependencies] crossbeam-channel = "0.5.1" fs-err = "2.3.0" -notify = "6.1.1" +notify = "4.0.15" serde = { version = "1.0", features = ["derive"] } diff --git a/crates/memofs/src/std_backend.rs b/crates/memofs/src/std_backend.rs index 4e95f110..0a8fb3b7 100644 --- a/crates/memofs/src/std_backend.rs +++ b/crates/memofs/src/std_backend.rs @@ -1,68 +1,55 @@ -use std::io; -use std::path::Path; +use std::path::{Path, PathBuf}; +use std::sync::mpsc; +use std::thread; +use std::time::Duration; +use std::{collections::HashSet, io}; use crossbeam_channel::Receiver; - -use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher}; - -#[cfg(target_os = "macos")] -use notify::{Config, PollWatcher}; - -#[cfg(target_os = "macos")] -use std::time::Duration; +use notify::{watcher, DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher}; use crate::{DirEntry, Metadata, ReadDir, VfsBackend, VfsEvent}; /// `VfsBackend` that uses `std::fs` and the `notify` crate. pub struct StdBackend { - #[cfg(target_os = "macos")] - watcher: PollWatcher, - - #[cfg(not(target_os = "macos"))] watcher: RecommendedWatcher, - watcher_receiver: Receiver, + watches: HashSet, } impl StdBackend { pub fn new() -> StdBackend { + let (notify_tx, notify_rx) = mpsc::channel(); + let watcher = watcher(notify_tx, Duration::from_millis(50)).unwrap(); + let (tx, rx) = crossbeam_channel::unbounded(); - let event_handler = move |res: Result| match res { - Ok(event) => match event.kind { - EventKind::Create(_) => { - for path in event.paths { - let _ = tx.send(VfsEvent::Create(path)); + thread::spawn(move || { + for event in notify_rx { + match event { + DebouncedEvent::Create(path) => { + tx.send(VfsEvent::Create(path))?; } - } - EventKind::Modify(_) => { - for path in event.paths { - let _ = tx.send(VfsEvent::Write(path)); + DebouncedEvent::Write(path) => { + tx.send(VfsEvent::Write(path))?; } - } - EventKind::Remove(_) => { - for path in event.paths { - let _ = tx.send(VfsEvent::Remove(path)); + DebouncedEvent::Remove(path) => { + tx.send(VfsEvent::Remove(path))?; } + DebouncedEvent::Rename(from, to) => { + tx.send(VfsEvent::Remove(from))?; + tx.send(VfsEvent::Create(to))?; + } + _ => {} } - _ => {} - }, - Err(e) => println!("watch error: {:?}", e), - }; + } - #[cfg(not(target_os = "macos"))] - let watcher = notify::recommended_watcher(event_handler).unwrap(); - - #[cfg(target_os = "macos")] - let watcher = PollWatcher::new( - event_handler, - Config::default().with_poll_interval(Duration::from_millis(200)), - ) - .unwrap(); + Result::<(), crossbeam_channel::SendError>::Ok(()) + }); Self { watcher, watcher_receiver: rx, + watches: HashSet::new(), } } } @@ -112,12 +99,22 @@ impl VfsBackend for StdBackend { } fn watch(&mut self, path: &Path) -> io::Result<()> { - self.watcher - .watch(path, RecursiveMode::NonRecursive) - .map_err(|inner| io::Error::new(io::ErrorKind::Other, inner)) + if self.watches.contains(path) + || path + .ancestors() + .any(|ancestor| self.watches.contains(ancestor)) + { + Ok(()) + } else { + self.watches.insert(path.to_path_buf()); + self.watcher + .watch(path, RecursiveMode::Recursive) + .map_err(|inner| io::Error::new(io::ErrorKind::Other, inner)) + } } fn unwatch(&mut self, path: &Path) -> io::Result<()> { + self.watches.remove(path); self.watcher .unwatch(path) .map_err(|inner| io::Error::new(io::ErrorKind::Other, inner)) From fd8bc8ae3fd7d8b80181ed5467d03df5a9beb416 Mon Sep 17 00:00:00 2001 From: boatbomber Date: Tue, 2 Jan 2024 12:32:37 -0500 Subject: [PATCH 7/7] Improve visualization for arrays (#829) --- CHANGELOG.md | 2 ++ .../Components/PatchVisualizer/DisplayValue.lua | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe6fc377..8021fac9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # Rojo Changelog ## Unreleased Changes +* Improved the visualization for array properties like Tags ([#829]) * Significantly improved performance of `rojo serve`, `rojo build --watch`, and `rojo sourcemap --watch` on macOS. [#830] +[#829]: https://github.com/rojo-rbx/rojo/pull/829 [#830]: https://github.com/rojo-rbx/rojo/pull/830 ## [7.4.0-rc3] - October 25, 2023 diff --git a/plugin/src/App/Components/PatchVisualizer/DisplayValue.lua b/plugin/src/App/Components/PatchVisualizer/DisplayValue.lua index 439c95d9..a231b879 100644 --- a/plugin/src/App/Components/PatchVisualizer/DisplayValue.lua +++ b/plugin/src/App/Components/PatchVisualizer/DisplayValue.lua @@ -53,8 +53,23 @@ local function DisplayValue(props) elseif next(props.value) == nil then -- If it's empty, show empty braces textRepresentation = "{}" + elseif next(props.value) == 1 then + -- We don't need to support mixed tables, so checking the first key is enough + -- to determine if it's a simple array + local out, i = table.create(#props.value), 0 + for k, v in props.value do + i += 1 + + -- Wrap strings in quotes + if type(v) == "string" then + v = '"' .. v .. '"' + end + + out[i] = tostring(v) + end + textRepresentation = "{ " .. table.concat(out, ", ") .. " }" else - -- If it has children, list them out + -- Otherwise, show the table contents as a dictionary local out, i = {}, 0 for k, v in pairs(props.value) do i += 1