From bd0685eab6a947c04a5e9327ccb3eaf999d7a340 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 10:42:08 +0800 Subject: [PATCH 1/8] chore: configure clippy rules for non-vite crates via .non-vite.clippy.toml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Non-vite crates previously used blanket `#![allow(clippy::disallowed_types, disallowed_methods, disallowed_macros)]` to opt out of vite_str/vite_path rules, but this also silenced generic rules like HashMap→FxHashMap and cow_utils. Replace the blanket allows with a dedicated `.non-vite.clippy.toml` that keeps generic rules but omits vite-specific ones. Each non-vite crate gets a symlinked `.clippy.toml` pointing to the shared config. Co-Authored-By: Claude Opus 4.6 --- .non-vite.clippy.toml | 24 +++++++++++++++++++ Cargo.lock | 4 ++++ crates/fspy/.clippy.toml | 1 + crates/fspy/Cargo.toml | 1 + crates/fspy/build.rs | 7 ------ crates/fspy/examples/cli.rs | 7 ------ crates/fspy/src/command.rs | 6 ++--- crates/fspy/src/lib.rs | 6 ----- crates/fspy/tests/node_fs.rs | 7 ------ crates/fspy/tests/oxlint.rs | 7 ------ crates/fspy/tests/rust_std.rs | 7 ------ crates/fspy/tests/rust_tokio.rs | 7 ------ crates/fspy/tests/shebang.rs | 7 ------ crates/fspy/tests/static_executable.rs | 7 ------ crates/fspy/tests/winapi.rs | 7 ------ crates/fspy_detours_sys/.clippy.toml | 1 + crates/fspy_detours_sys/Cargo.toml | 1 + crates/fspy_detours_sys/src/lib.rs | 12 ++++------ crates/fspy_detours_sys/tests/bindings.rs | 18 ++++++-------- crates/fspy_e2e/.clippy.toml | 1 + crates/fspy_e2e/src/main.rs | 7 ------ crates/fspy_preload_unix/.clippy.toml | 1 + crates/fspy_preload_unix/src/lib.rs | 6 ----- crates/fspy_preload_windows/.clippy.toml | 1 + crates/fspy_preload_windows/src/lib.rs | 6 ----- crates/fspy_seccomp_unotify/.clippy.toml | 1 + crates/fspy_seccomp_unotify/src/lib.rs | 6 ----- .../fspy_seccomp_unotify/tests/arg_types.rs | 7 ------ crates/fspy_shared/.clippy.toml | 1 + crates/fspy_shared/Cargo.toml | 1 + crates/fspy_shared/src/ipc/channel/shm_io.rs | 4 ++-- crates/fspy_shared/src/lib.rs | 7 ------ crates/fspy_shared_unix/.clippy.toml | 1 + crates/fspy_shared_unix/src/lib.rs | 6 ----- crates/fspy_test_bin/.clippy.toml | 1 + crates/subprocess_test/.clippy.toml | 1 + crates/subprocess_test/Cargo.toml | 1 + crates/subprocess_test/src/lib.rs | 17 ++++--------- crates/vite_pty/.clippy.toml | 1 + crates/vite_pty/src/lib.rs | 7 ------ crates/vite_pty/tests/terminal.rs | 7 ------ 41 files changed, 64 insertions(+), 164 deletions(-) create mode 100644 .non-vite.clippy.toml create mode 120000 crates/fspy/.clippy.toml create mode 120000 crates/fspy_detours_sys/.clippy.toml create mode 120000 crates/fspy_e2e/.clippy.toml create mode 120000 crates/fspy_preload_unix/.clippy.toml create mode 120000 crates/fspy_preload_windows/.clippy.toml create mode 120000 crates/fspy_seccomp_unotify/.clippy.toml create mode 120000 crates/fspy_shared/.clippy.toml create mode 120000 crates/fspy_shared_unix/.clippy.toml create mode 120000 crates/fspy_test_bin/.clippy.toml create mode 120000 crates/subprocess_test/.clippy.toml create mode 120000 crates/vite_pty/.clippy.toml diff --git a/.non-vite.clippy.toml b/.non-vite.clippy.toml new file mode 100644 index 00000000..67d01cad --- /dev/null +++ b/.non-vite.clippy.toml @@ -0,0 +1,24 @@ +# Clippy configuration for non-vite crates (fspy_*, subprocess_test, vite_pty, etc.) +# that don't depend on vite_str/vite_path. +# +# This is a subset of the root .clippy.toml, with rules recommending vite_str/vite_path +# alternatives removed. Generic rules (cow_utils, rustc-hash) still apply. +# +# To use: symlink as `.clippy.toml` in the crate's directory: +# ln -s ../../.non-vite.clippy.toml .clippy.toml + +avoid-breaking-exported-api = false + +disallowed-methods = [ + { path = "str::to_ascii_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_lowercase` instead." }, + { path = "str::to_ascii_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_ascii_uppercase` instead." }, + { path = "str::to_lowercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_lowercase` instead." }, + { path = "str::to_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_uppercase` instead." }, + { path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replace` instead." }, + { path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replacen` instead." }, +] + +disallowed-types = [ + { path = "std::collections::HashMap", reason = "Use `rustc_hash::FxHashMap` instead, which is typically faster." }, + { path = "std::collections::HashSet", reason = "Use `rustc_hash::FxHashSet` instead, which is typically faster." }, +] diff --git a/Cargo.lock b/Cargo.lock index 2698c8da..d43f1adf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1129,6 +1129,7 @@ dependencies = [ "nix 0.30.1", "ouroboros", "rand 0.9.2", + "rustc-hash", "subprocess_test", "tar", "tempfile", @@ -1147,6 +1148,7 @@ version = "0.0.0" dependencies = [ "bindgen", "cc", + "cow-utils", "winapi", ] @@ -1221,6 +1223,7 @@ dependencies = [ "bytemuck", "ctor", "os_str_bytes", + "rustc-hash", "shared_memory", "subprocess_test", "thiserror 2.0.17", @@ -3024,6 +3027,7 @@ dependencies = [ "ctor", "fspy", "portable-pty", + "rustc-hash", ] [[package]] diff --git a/crates/fspy/.clippy.toml b/crates/fspy/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy/Cargo.toml b/crates/fspy/Cargo.toml index 497c7406..6b5869bc 100644 --- a/crates/fspy/Cargo.toml +++ b/crates/fspy/Cargo.toml @@ -16,6 +16,7 @@ futures-util = { workspace = true } libc = { workspace = true } ouroboros = { workspace = true } rand = { workspace = true } +rustc-hash = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } tokio = { workspace = true, features = ["net", "process", "io-util", "sync", "rt"] } diff --git a/crates/fspy/build.rs b/crates/fspy/build.rs index 8821e2c9..84987b42 100644 --- a/crates/fspy/build.rs +++ b/crates/fspy/build.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{ env::{self, current_dir}, fs, diff --git a/crates/fspy/examples/cli.rs b/crates/fspy/examples/cli.rs index 3ef6356f..3fa315a7 100644 --- a/crates/fspy/examples/cli.rs +++ b/crates/fspy/examples/cli.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{env::args_os, ffi::OsStr, path::PathBuf, pin::Pin}; use tokio::{ diff --git a/crates/fspy/src/command.rs b/crates/fspy/src/command.rs index e7852d7b..5e9900c9 100644 --- a/crates/fspy/src/command.rs +++ b/crates/fspy/src/command.rs @@ -1,5 +1,4 @@ use std::{ - collections::HashMap, ffi::{OsStr, OsString}, path::{Path, PathBuf}, process::Stdio, @@ -7,6 +6,7 @@ use std::{ #[cfg(unix)] use fspy_shared_unix::exec::Exec; +use rustc_hash::FxHashMap; use tokio::process::Command as TokioCommand; use crate::{SPY_IMPL, TrackedChild, error::SpawnError}; @@ -15,7 +15,7 @@ use crate::{SPY_IMPL, TrackedChild, error::SpawnError}; pub struct Command { program: OsString, args: Vec, - envs: HashMap, + envs: FxHashMap, cwd: Option, #[cfg(unix)] arg0: Option, @@ -37,7 +37,7 @@ impl Command { Self { program: program.as_ref().to_os_string(), args: Vec::new(), - envs: HashMap::new(), + envs: FxHashMap::default(), cwd: None, #[cfg(unix)] arg0: None, diff --git a/crates/fspy/src/lib.rs b/crates/fspy/src/lib.rs index 411112cc..cfcdb78c 100644 --- a/crates/fspy/src/lib.rs +++ b/crates/fspy/src/lib.rs @@ -1,11 +1,5 @@ #![cfg_attr(target_os = "windows", feature(windows_process_extensions_main_thread_handle))] #![feature(once_cell_try)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] // Persist the injected DLL/shared library somewhere in the filesystem. mod artifact; diff --git a/crates/fspy/tests/node_fs.rs b/crates/fspy/tests/node_fs.rs index 0c03972c..bbbb2bb5 100644 --- a/crates/fspy/tests/node_fs.rs +++ b/crates/fspy/tests/node_fs.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{ diff --git a/crates/fspy/tests/oxlint.rs b/crates/fspy/tests/oxlint.rs index 11454fe5..28a33a80 100644 --- a/crates/fspy/tests/oxlint.rs +++ b/crates/fspy/tests/oxlint.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{env::vars_os, ffi::OsString}; diff --git a/crates/fspy/tests/rust_std.rs b/crates/fspy/tests/rust_std.rs index 1f7d8051..e16b6e25 100644 --- a/crates/fspy/tests/rust_std.rs +++ b/crates/fspy/tests/rust_std.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{ diff --git a/crates/fspy/tests/rust_tokio.rs b/crates/fspy/tests/rust_tokio.rs index 9c16fea9..4c68526f 100644 --- a/crates/fspy/tests/rust_tokio.rs +++ b/crates/fspy/tests/rust_tokio.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{env::current_dir, process::Stdio}; diff --git a/crates/fspy/tests/shebang.rs b/crates/fspy/tests/shebang.rs index 1f912811..9195b5a8 100644 --- a/crates/fspy/tests/shebang.rs +++ b/crates/fspy/tests/shebang.rs @@ -1,11 +1,4 @@ #![cfg(unix)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{ diff --git a/crates/fspy/tests/static_executable.rs b/crates/fspy/tests/static_executable.rs index 52ede928..d2b02621 100644 --- a/crates/fspy/tests/static_executable.rs +++ b/crates/fspy/tests/static_executable.rs @@ -1,11 +1,4 @@ #![cfg(target_os = "linux")] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{ fs::{self, Permissions}, os::unix::fs::PermissionsExt as _, diff --git a/crates/fspy/tests/winapi.rs b/crates/fspy/tests/winapi.rs index 2c95e516..d2fe39ab 100644 --- a/crates/fspy/tests/winapi.rs +++ b/crates/fspy/tests/winapi.rs @@ -1,11 +1,4 @@ #![cfg(windows)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - mod test_utils; use std::{ffi::OsStr, os::windows::ffi::OsStrExt, path::Path, ptr::null_mut}; diff --git a/crates/fspy_detours_sys/.clippy.toml b/crates/fspy_detours_sys/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_detours_sys/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_detours_sys/Cargo.toml b/crates/fspy_detours_sys/Cargo.toml index f2c8b5b7..1f06517f 100644 --- a/crates/fspy_detours_sys/Cargo.toml +++ b/crates/fspy_detours_sys/Cargo.toml @@ -17,3 +17,4 @@ workspace = true [dev-dependencies] bindgen = { workspace = true } +cow-utils = { workspace = true } diff --git a/crates/fspy_detours_sys/src/lib.rs b/crates/fspy_detours_sys/src/lib.rs index dcd3c721..f147d4f9 100644 --- a/crates/fspy_detours_sys/src/lib.rs +++ b/crates/fspy_detours_sys/src/lib.rs @@ -1,13 +1,11 @@ #![cfg(windows)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - clippy::wildcard_imports, - reason = "non-vite crate; generated FFI bindings use wildcard imports" -)] #[expect(non_camel_case_types, non_snake_case, reason = "generated FFI bindings")] +#[expect( + clippy::allow_attributes, + reason = "can't use expect: wildcard_imports lint is unfulfilled in lib test mode" +)] +#[allow(clippy::wildcard_imports, reason = "generated FFI bindings use wildcard imports")] #[rustfmt::skip] // generated code is formatted by prettyplease, not rustfmt mod generated_bindings; diff --git a/crates/fspy_detours_sys/tests/bindings.rs b/crates/fspy_detours_sys/tests/bindings.rs index 4382eb58..362024a4 100644 --- a/crates/fspy_detours_sys/tests/bindings.rs +++ b/crates/fspy_detours_sys/tests/bindings.rs @@ -1,13 +1,8 @@ #![cfg(windows)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{env, fs}; +use cow_utils::CowUtils; + #[test] fn detours_bindings() { let bindings = bindgen::Builder::default() @@ -56,14 +51,15 @@ fn detours_bindings() { // bindgen produces raw_lines with \r\n line endings on Windows; // Git on Windows may check out files using CRLF line endings, depending on user config. // To avoid unnecessary diffs, normalize all line endings to \n. - let bindings_content = bindings.to_string().replace("\r\n", "\n"); + let bindings_string = bindings.to_string(); + let bindings_content = bindings_string.cow_replace("\r\n", "\n"); let bindings_path = "src/generated_bindings.rs"; if env::var("FSPY_DETOURS_WRITE_BINDINGS").as_deref() == Ok("1") { - fs::write(bindings_path, bindings_content).unwrap(); + fs::write(bindings_path, bindings_content.as_bytes()).unwrap(); } else { - let existing_bindings_content = - fs::read_to_string(bindings_path).unwrap_or_default().replace("\r\n", "\n"); + let existing_string = fs::read_to_string(bindings_path).unwrap_or_default(); + let existing_bindings_content = existing_string.cow_replace("\r\n", "\n"); assert_eq!( existing_bindings_content, bindings_content, "Bindings are out of date. Run this test with FSPY_DETOURS_WRITE_BINDINGS=1 to update them." diff --git a/crates/fspy_e2e/.clippy.toml b/crates/fspy_e2e/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_e2e/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_e2e/src/main.rs b/crates/fspy_e2e/src/main.rs index 7e5afc7c..40d734c6 100644 --- a/crates/fspy_e2e/src/main.rs +++ b/crates/fspy_e2e/src/main.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{ collections::{BTreeMap, btree_map::Entry}, env::{self, args}, diff --git a/crates/fspy_preload_unix/.clippy.toml b/crates/fspy_preload_unix/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_preload_unix/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_preload_unix/src/lib.rs b/crates/fspy_preload_unix/src/lib.rs index 8c482394..2e5a6b5b 100644 --- a/crates/fspy_preload_unix/src/lib.rs +++ b/crates/fspy_preload_unix/src/lib.rs @@ -1,12 +1,6 @@ #![cfg(unix)] // required for defining inteposed `open`/`openat`(https://man7.org/linux/man-pages/man2/open.2.html) #![feature(c_variadic)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] mod client; mod interceptions; diff --git a/crates/fspy_preload_windows/.clippy.toml b/crates/fspy_preload_windows/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_preload_windows/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_preload_windows/src/lib.rs b/crates/fspy_preload_windows/src/lib.rs index 32a9747e..04957cd8 100644 --- a/crates/fspy_preload_windows/src/lib.rs +++ b/crates/fspy_preload_windows/src/lib.rs @@ -1,10 +1,4 @@ #![cfg(windows)] #![feature(sync_unsafe_cell)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] pub mod windows; diff --git a/crates/fspy_seccomp_unotify/.clippy.toml b/crates/fspy_seccomp_unotify/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_seccomp_unotify/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_seccomp_unotify/src/lib.rs b/crates/fspy_seccomp_unotify/src/lib.rs index 44030b85..a70b0a81 100644 --- a/crates/fspy_seccomp_unotify/src/lib.rs +++ b/crates/fspy_seccomp_unotify/src/lib.rs @@ -1,10 +1,4 @@ #![cfg(target_os = "linux")] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] #[cfg(any(feature = "supervisor", feature = "target"))] mod bindings; diff --git a/crates/fspy_seccomp_unotify/tests/arg_types.rs b/crates/fspy_seccomp_unotify/tests/arg_types.rs index 42ec2a74..50aa83a5 100644 --- a/crates/fspy_seccomp_unotify/tests/arg_types.rs +++ b/crates/fspy_seccomp_unotify/tests/arg_types.rs @@ -1,11 +1,4 @@ #![cfg(target_os = "linux")] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "test file for non-vite crate" -)] - use std::{ env::{current_dir, set_current_dir}, error::Error, diff --git a/crates/fspy_shared/.clippy.toml b/crates/fspy_shared/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_shared/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_shared/Cargo.toml b/crates/fspy_shared/Cargo.toml index 2b1f7574..a5165e73 100644 --- a/crates/fspy_shared/Cargo.toml +++ b/crates/fspy_shared/Cargo.toml @@ -23,6 +23,7 @@ winapi = { workspace = true, features = ["std"] } [dev-dependencies] assert2 = { workspace = true } ctor = { workspace = true } +rustc-hash = { workspace = true } shared_memory = { workspace = true, features = ["logging"] } subprocess_test = { workspace = true } diff --git a/crates/fspy_shared/src/ipc/channel/shm_io.rs b/crates/fspy_shared/src/ipc/channel/shm_io.rs index f47872ca..3c6b8f3d 100644 --- a/crates/fspy_shared/src/ipc/channel/shm_io.rs +++ b/crates/fspy_shared/src/ipc/channel/shm_io.rs @@ -323,7 +323,6 @@ impl> ShmReader { #[cfg(test)] mod tests { use std::{ - collections::HashSet, env::current_exe, process::{Child, Command}, sync::Arc, @@ -332,6 +331,7 @@ mod tests { use assert2::assert; use bstr::BStr; + use rustc_hash::FxHashSet; use super::*; @@ -718,7 +718,7 @@ mod tests { // The shared memory is valid and fully written. let shm = unsafe { shm.as_slice() }; let reader = ShmReader::new(shm); - let frames = reader.iter_frames().map(BStr::new).collect::>(); + let frames = reader.iter_frames().map(BStr::new).collect::>(); assert_eq!(frames.len(), CHILD_COUNT * FRAME_COUNT_EACH_CHILD); for child_index in 0..CHILD_COUNT { for i in 0..FRAME_COUNT_EACH_CHILD { diff --git a/crates/fspy_shared/src/lib.rs b/crates/fspy_shared/src/lib.rs index c5736eab..e44d2b7e 100644 --- a/crates/fspy_shared/src/lib.rs +++ b/crates/fspy_shared/src/lib.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - pub mod ipc; #[cfg(windows)] diff --git a/crates/fspy_shared_unix/.clippy.toml b/crates/fspy_shared_unix/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_shared_unix/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/fspy_shared_unix/src/lib.rs b/crates/fspy_shared_unix/src/lib.rs index acc91bc9..5437a3ef 100644 --- a/crates/fspy_shared_unix/src/lib.rs +++ b/crates/fspy_shared_unix/src/lib.rs @@ -1,10 +1,4 @@ #![cfg(unix)] -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] pub mod exec; pub(crate) mod open_exec; diff --git a/crates/fspy_test_bin/.clippy.toml b/crates/fspy_test_bin/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/fspy_test_bin/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/subprocess_test/.clippy.toml b/crates/subprocess_test/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/subprocess_test/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/subprocess_test/Cargo.toml b/crates/subprocess_test/Cargo.toml index c87110b3..b107ee9c 100644 --- a/crates/subprocess_test/Cargo.toml +++ b/crates/subprocess_test/Cargo.toml @@ -13,6 +13,7 @@ bincode = { workspace = true } ctor = { workspace = true } fspy = { workspace = true, optional = true } portable-pty = { workspace = true, optional = true } +rustc-hash = { workspace = true } [features] default = [] diff --git a/crates/subprocess_test/src/lib.rs b/crates/subprocess_test/src/lib.rs index 3898cb65..ca418d77 100644 --- a/crates/subprocess_test/src/lib.rs +++ b/crates/subprocess_test/src/lib.rs @@ -1,17 +1,8 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "subprocess_test is a standalone test utility, not using vite_str/vite_path" -)] - -use std::{ - collections::HashMap, env::current_exe, ffi::OsString, path::PathBuf, - process::Command as StdCommand, -}; +use std::{env::current_exe, ffi::OsString, path::PathBuf, process::Command as StdCommand}; use base64::{Engine, prelude::BASE64_STANDARD_NO_PAD}; use bincode::{Decode, Encode, config}; +use rustc_hash::FxHashMap; /// A command configuration that can be converted to `std::process::Command` /// or `fspy::Command` for execution. @@ -19,7 +10,7 @@ use bincode::{Decode, Encode, config}; pub struct Command { pub program: OsString, pub args: Vec, - pub envs: HashMap, + pub envs: FxHashMap, pub cwd: PathBuf, } @@ -108,7 +99,7 @@ pub fn create_command(id: &str, arg: impl Encode) -> Command { let arg_base64 = BASE64_STANDARD_NO_PAD.encode(&arg_bytes); let args = vec![OsString::from(id), OsString::from(arg_base64)]; - let envs: HashMap = std::env::vars_os().collect(); + let envs: FxHashMap = std::env::vars_os().collect(); let cwd = std::env::current_dir().unwrap(); Command { program, args, envs, cwd } diff --git a/crates/vite_pty/.clippy.toml b/crates/vite_pty/.clippy.toml new file mode 120000 index 00000000..c7929b36 --- /dev/null +++ b/crates/vite_pty/.clippy.toml @@ -0,0 +1 @@ +../../.non-vite.clippy.toml \ No newline at end of file diff --git a/crates/vite_pty/src/lib.rs b/crates/vite_pty/src/lib.rs index 1347e2dd..07fe7a20 100644 --- a/crates/vite_pty/src/lib.rs +++ b/crates/vite_pty/src/lib.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "vite_pty is a standalone PTY crate, not using vite_str/vite_path" -)] - pub mod geo; pub mod terminal; diff --git a/crates/vite_pty/tests/terminal.rs b/crates/vite_pty/tests/terminal.rs index 19fa528e..3c9a2b85 100644 --- a/crates/vite_pty/tests/terminal.rs +++ b/crates/vite_pty/tests/terminal.rs @@ -1,10 +1,3 @@ -#![allow( - clippy::disallowed_types, - clippy::disallowed_methods, - clippy::disallowed_macros, - reason = "non-vite crate" -)] - use std::{ io::{IsTerminal, Write, stderr, stdin, stdout}, thread, From ebc4b1b84abf9b617e82557ae5768c84a34e40b7 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 11:15:52 +0800 Subject: [PATCH 2/8] chore: rename vite_pty to pty_terminal Co-Authored-By: Claude Opus 4.6 --- .clippy.toml | 2 + .non-vite.clippy.toml | 4 +- CLAUDE.md | 6 +- Cargo.lock | 892 ++++++++++-------- Cargo.toml | 2 +- .../{vite_pty => pty_terminal}/.clippy.toml | 0 crates/{vite_pty => pty_terminal}/Cargo.toml | 2 +- crates/pty_terminal/README.md | 25 + crates/{vite_pty => pty_terminal}/src/geo.rs | 0 crates/{vite_pty => pty_terminal}/src/lib.rs | 0 .../src/terminal.rs | 0 .../tests/terminal.rs | 51 +- crates/vite_task_bin/Cargo.toml | 2 +- .../vite_task_bin/tests/e2e_snapshots/main.rs | 6 +- crates/vite_tui/src/tui.rs | 4 + 15 files changed, 576 insertions(+), 420 deletions(-) rename crates/{vite_pty => pty_terminal}/.clippy.toml (100%) rename crates/{vite_pty => pty_terminal}/Cargo.toml (95%) create mode 100644 crates/pty_terminal/README.md rename crates/{vite_pty => pty_terminal}/src/geo.rs (100%) rename crates/{vite_pty => pty_terminal}/src/lib.rs (100%) rename crates/{vite_pty => pty_terminal}/src/terminal.rs (100%) rename crates/{vite_pty => pty_terminal}/tests/terminal.rs (91%) diff --git a/.clippy.toml b/.clippy.toml index 851f6fe5..cb12107d 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -8,6 +8,8 @@ disallowed-methods = [ { path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replace` instead." }, { path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replacen` instead." }, { path = "std::env::current_dir", reason = "To get an `AbsolutePathBuf`, Use `vite_path::current_dir` instead." }, + { path = "std::thread::sleep", reason = "Use proper synchronization (channels, condvars, etc.) instead of sleeping. Sleep is only acceptable for intentional user-facing delays (e.g. animations, debouncing)." }, + { path = "tokio::time::sleep", reason = "Use proper synchronization (channels, signals, etc.) instead of sleeping. Sleep is only acceptable for intentional user-facing delays (e.g. animations, debouncing)." }, ] disallowed-types = [ diff --git a/.non-vite.clippy.toml b/.non-vite.clippy.toml index 67d01cad..8f85a92f 100644 --- a/.non-vite.clippy.toml +++ b/.non-vite.clippy.toml @@ -1,4 +1,4 @@ -# Clippy configuration for non-vite crates (fspy_*, subprocess_test, vite_pty, etc.) +# Clippy configuration for non-vite crates (fspy_*, subprocess_test, pty_terminal, etc.) # that don't depend on vite_str/vite_path. # # This is a subset of the root .clippy.toml, with rules recommending vite_str/vite_path @@ -16,6 +16,8 @@ disallowed-methods = [ { path = "str::to_uppercase", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_to_uppercase` instead." }, { path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replace` instead." }, { path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replacen` instead." }, + { path = "std::thread::sleep", reason = "Use proper synchronization (channels, condvars, etc.) instead of sleeping. Sleep is only acceptable for intentional user-facing delays (e.g. animations, debouncing)." }, + { path = "tokio::time::sleep", reason = "Use proper synchronization (channels, signals, etc.) instead of sleeping. Sleep is only acceptable for intentional user-facing delays (e.g. animations, debouncing)." }, ] disallowed-types = [ diff --git a/CLAUDE.md b/CLAUDE.md index e297effe..086b3e59 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -53,8 +53,8 @@ Test fixtures and snapshots: cargo xtest --builder cargo-xwin --target aarch64-pc-windows-msvc -p --test # Examples: - cargo xtest --builder cargo-xwin --target aarch64-pc-windows-msvc -p vite_pty --test terminal - cargo xtest --builder cargo-xwin --target aarch64-pc-windows-msvc -p vite_pty --test terminal -- resize_terminal + cargo xtest --builder cargo-xwin --target aarch64-pc-windows-msvc -p pty_terminal --test terminal + cargo xtest --builder cargo-xwin --target aarch64-pc-windows-msvc -p pty_terminal --test terminal -- resize_terminal ``` 3. **Cross-Platform Test Design Patterns**: @@ -64,7 +64,7 @@ Test fixtures and snapshots: - **Unix**: SIGWINCH signals, ioctl, /dev/null, etc. - **Windows**: ConPTY, GetConsoleScreenBufferInfo, NUL, etc. -4. **Example**: The `vite_pty::resize_terminal` test demonstrates proper cross-platform testing: +4. **Example**: The `pty_terminal::resize_terminal` test demonstrates proper cross-platform testing: - Unix: Installs SIGWINCH handler to verify signal delivery - Windows: Acknowledges synchronous ConPTY resize behavior - Both: Query terminal size using cross-platform `terminal_size` crate diff --git a/Cargo.lock b/Cargo.lock index d43f1adf..8af34815 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -82,29 +82,29 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" [[package]] name = "arrayvec" @@ -132,14 +132,14 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "assertables" -version = "9.8.2" +version = "9.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59051ec02907378a67b0ba1b8631121f5388c8dbbb3cec8c749d8f93c2c3c211" +checksum = "4dcd1f7f2f608b9a888a851f234086946c2ca1dfeadf1431c5082fee0942eeb6" [[package]] name = "async-trait" @@ -149,7 +149,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -225,7 +225,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -269,9 +269,9 @@ dependencies = [ [[package]] name = "bon" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebeb9aaf9329dff6ceb65c689ca3db33dbf15f324909c60e4e5eef5701ce31b1" +checksum = "234655ec178edd82b891e262ea7cf71f6584bcd09eff94db786be23f1821825c" dependencies = [ "bon-macros", "rustversion", @@ -279,17 +279,17 @@ dependencies = [ [[package]] name = "bon-macros" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e9d642a7e3a318e37c2c9427b5a6a48aa1ad55dcd986f3034ab2239045a645" +checksum = "89ec27229c38ed0eb3c0feee3d2c1d6a4379ae44f418a29a658890e062d8f365" dependencies = [ - "darling 0.21.3", + "darling 0.23.0", "ident_case", "prettyplease", "proc-macro2", "quote", "rustversion", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -301,16 +301,16 @@ dependencies = [ "cached", "indenter", "peg", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "utf8-chars", ] [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "serde", @@ -318,18 +318,18 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" dependencies = [ "allocator-api2", ] [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" dependencies = [ "bytemuck_derive", ] @@ -342,14 +342,14 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cached" @@ -362,7 +362,7 @@ dependencies = [ "cached_proc_macro_types", "hashbrown 0.15.5", "once_cell", - "thiserror 2.0.17", + "thiserror 2.0.18", "web-time", ] @@ -375,7 +375,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -395,9 +395,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.39" +version = "1.2.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1354349954c6fc9cb0deab020f27f783cf0b604e8bb754dc4658ecf0d29c35f" +checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" dependencies = [ "find-msvc-tools", "shlex", @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -443,9 +443,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.53" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" dependencies = [ "clap_builder", "clap_derive", @@ -453,9 +453,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" dependencies = [ "anstream", "anstyle", @@ -465,21 +465,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "color-eyre" @@ -543,9 +543,9 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", "konst", @@ -570,9 +570,9 @@ checksum = "136d3e02915a2cea4d74caa8681e2d44b1c3254bdbf17d11d41d587ff858832c" [[package]] name = "convert_case" -version = "0.7.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ] @@ -665,9 +665,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -701,18 +701,18 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" dependencies = [ "memchr", ] [[package]] name = "ctor" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c9b8bdf64ee849747c1b12eb861d21aa47fa161564f48332f1afe2373bf899" +checksum = "424e0138278faeb2b401f174ad17e715c829512d74f3d1e81eb43365c2e0590e" dependencies = [ "ctor-proc-macro", "dtor", @@ -736,12 +736,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "darling_core 0.21.3", - "darling_macro 0.21.3", + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -755,21 +755,20 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "darling_core" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" dependencies = [ - "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -780,18 +779,18 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "darling_macro" -version = "0.21.3" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ - "darling_core 0.21.3", + "darling_core 0.23.0", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -811,23 +810,24 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.106", + "rustc_version 0.4.1", + "syn 2.0.114", "unicode-xid", ] @@ -887,14 +887,14 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] name = "document-features" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ "litrs", ] @@ -907,9 +907,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dtor" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e58a0764cddb55ab28955347b45be00ade43d4d6f3ba4bf3dc354e4ec9432934" +checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" dependencies = [ "dtor-proc-macro", ] @@ -940,9 +940,9 @@ checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", ] @@ -978,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -1041,21 +1041,20 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.26" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.60.2", ] [[package]] name = "find-msvc-tools" -version = "0.1.2" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ced73b1dacfc750a6db6c0a0c3a3853c8b41997e2e2c563dc90804ae6867959" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "finl_unicode" @@ -1077,9 +1076,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", @@ -1134,7 +1133,7 @@ dependencies = [ "tar", "tempfile", "test-log", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "which", "winapi", @@ -1226,7 +1225,7 @@ dependencies = [ "rustc-hash", "shared_memory", "subprocess_test", - "thiserror 2.0.17", + "thiserror 2.0.18", "tracing", "uuid", "winapi", @@ -1312,7 +1311,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -1357,25 +1356,38 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "getrandom" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.7+wasi-0.2.4", + "wasip2", + "wasip3", ] [[package]] @@ -1392,9 +1404,9 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.16" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" dependencies = [ "aho-corasick", "bstr", @@ -1452,6 +1464,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -1466,25 +1484,30 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] name = "indoc" -version = "2.0.6" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] [[package]] name = "insta" -version = "1.45.1" +version = "1.46.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983e3b24350c84ab8a65151f537d67afbbf7153bb9f1110e03e9fa9b07f67a5c" +checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4" dependencies = [ "console", "globset", @@ -1501,15 +1524,15 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +checksum = "357b7205c6cd18dd2c86ed312d1e70add149aea98e7ef72b9fdf0270e555c11d" dependencies = [ - "darling 0.20.11", + "darling 0.23.0", "indoc", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -1520,9 +1543,9 @@ checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -1553,15 +1576,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" -version = "0.3.81" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1584,7 +1607,7 @@ checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b" dependencies = [ "hashbrown 0.16.1", "portable-atomic", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -1614,11 +1637,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.176" +version = "0.2.181" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" +checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" [[package]] name = "libloading" @@ -1632,13 +1661,13 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ "bitflags 2.10.0", "libc", - "redox_syscall", + "redox_syscall 0.7.0", ] [[package]] @@ -1679,25 +1708,24 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litrs" -version = "0.4.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lru" @@ -1729,15 +1757,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] @@ -1779,18 +1807,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ] [[package]] @@ -1812,7 +1841,7 @@ checksum = "23f5b99488110875b5904839d396c2cdfaf241ff6622638acb879cc7effad5de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -1878,9 +1907,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" dependencies = [ "winapi", ] @@ -1920,11 +1949,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1974,7 +2003,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -2043,9 +2072,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "option-ext" @@ -2092,7 +2121,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -2103,9 +2132,9 @@ checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -2113,15 +2142,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec 1.15.1", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -2163,9 +2192,9 @@ checksum = "132dca9b868d927b35b5dd728167b2dee150eb1ad686008fc71ccb298b776fca" [[package]] name = "pest" -version = "2.8.4" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbcfd20a6d4eeba40179f05735784ad32bdaef05ce8e8af05f180d45bb3e7e22" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" dependencies = [ "memchr", "ucd-trie", @@ -2173,9 +2202,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.8.4" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f72981ade67b1ca6adc26ec221be9f463f2b5839c7508998daa17c23d94d7f" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" dependencies = [ "pest", "pest_generator", @@ -2183,22 +2212,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.8.4" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee9efd8cdb50d719a80088b76f81aec7c41ed6d522ee750178f83883d271625" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "pest_meta" -version = "2.8.4" +version = "2.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf1d70880e76bdc13ba52eafa6239ce793d85c8e43896507e43dd8984ff05b82" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" dependencies = [ "pest", "sha2", @@ -2257,7 +2286,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -2298,9 +2327,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "portable-pty" @@ -2355,7 +2384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -2369,9 +2398,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -2384,16 +2413,30 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", "version_check", "yansi", ] +[[package]] +name = "pty_terminal" +version = "0.0.0" +dependencies = [ + "anyhow", + "ctor", + "ntest", + "portable-pty", + "signal-hook", + "subprocess_test", + "terminal_size", + "vt100", +] + [[package]] name = "quote" -version = "1.0.41" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -2422,7 +2465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2442,7 +2485,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2451,16 +2494,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -2491,7 +2534,7 @@ dependencies = [ "kasuari", "lru", "strum", - "thiserror 2.0.17", + "thiserror 2.0.18", "unicode-segmentation", "unicode-truncate", "unicode-width", @@ -2570,9 +2613,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ "bitflags 2.10.0", ] @@ -2583,9 +2635,9 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2605,14 +2657,14 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "regex" -version = "1.11.3" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5288124840bee7b386bc413c487869b360b2b4ec421ea56425128692f2a82c" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" dependencies = [ "aho-corasick", "memchr", @@ -2622,9 +2674,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.11" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833eb9ce86d40ef33cb1306d8accf7bc8ec2bfea4355cbdebb3df68b40925cad" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" dependencies = [ "aho-corasick", "memchr", @@ -2633,9 +2685,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" [[package]] name = "ron" @@ -2667,9 +2719,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" +checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" @@ -2697,15 +2749,15 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -2716,9 +2768,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -2791,28 +2843,28 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap", "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] name = "serde_spanned" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -2895,9 +2947,9 @@ checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" [[package]] name = "shell-words" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" [[package]] name = "shlex" @@ -2917,9 +2969,9 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", "mio", @@ -2928,13 +2980,20 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "similar" version = "2.7.0" @@ -2943,15 +3002,15 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "siphasher" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" [[package]] name = "slab" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" @@ -2967,12 +3026,12 @@ checksum = "ef784004ca8777809dcdad6ac37629f0a97caee4c685fcea805278d81dd8b857" [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -3015,7 +3074,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -3052,9 +3111,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -3080,15 +3139,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.23.0" +version = "3.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.4.1", "once_cell", "rustix", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -3175,9 +3234,9 @@ dependencies = [ [[package]] name = "test-log" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e33b98a582ea0be1168eba097538ee8dd4bbe0f2b01b22ac92ea30054e5be7b" +checksum = "37d53ac171c92a39e4769491c4b4dde7022c60042254b5fc044ae409d34a24d4" dependencies = [ "env_logger", "test-log-macros", @@ -3186,13 +3245,13 @@ dependencies = [ [[package]] name = "test-log-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451b374529930d7601b1eef8d32bc79ae870b6079b069401709c2a8bf9e75f36" +checksum = "be35209fd0781c5401458ab66e4f98accf63553e8fae7425503e92fdd319783b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -3206,11 +3265,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3221,18 +3280,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] @@ -3246,9 +3305,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.46" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9da98b7d9b7dad93488a84b8248efc35352b0b2657397d4167e7ad67e5d535e5" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "libc", @@ -3267,9 +3326,9 @@ checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -3279,7 +3338,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -3290,14 +3349,14 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -3306,9 +3365,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -3319,9 +3378,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.7" +version = "0.9.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" dependencies = [ "indexmap", "serde_core", @@ -3334,18 +3393,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.2" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.6" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", "toml_datetime", @@ -3355,24 +3414,24 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.3" +version = "1.0.7+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627" +checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.0.3" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -3387,14 +3446,14 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -3423,9 +3482,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -3446,7 +3505,7 @@ version = "11.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4994acea2522cd2b3b85c1d9529a55991e3ad5e25cdcd3de9d505972c4379424" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", "ts-rs-macros", ] @@ -3458,7 +3517,7 @@ checksum = "ee6ff59666c9cbaec3533964505d39154dc4e0a56151fdea30a09ed0301f62e2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", "termcolor", ] @@ -3502,9 +3561,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-segmentation" @@ -3558,12 +3617,12 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "ee48d38b119b0cd71fe4141b30f5ba9c7c5d9f4e7a3a8b4a674e4b6ef789976f" dependencies = [ "atomic", - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -3605,7 +3664,7 @@ checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" name = "vite_glob" version = "0.0.0" dependencies = [ - "thiserror 2.0.17", + "thiserror 2.0.18", "vite_str", "wax", ] @@ -3628,25 +3687,11 @@ dependencies = [ "diff-struct", "ref-cast", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", "ts-rs", "vite_str", ] -[[package]] -name = "vite_pty" -version = "0.0.0" -dependencies = [ - "anyhow", - "ctor", - "ntest", - "portable-pty", - "signal-hook", - "subprocess_test", - "terminal_size", - "vt100", -] - [[package]] name = "vite_shell" version = "0.0.0" @@ -3692,7 +3737,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "tracing", "twox-hash", @@ -3715,6 +3760,7 @@ dependencies = [ "cow-utils", "insta", "jsonc-parser", + "pty_terminal", "regex", "rustc-hash", "serde", @@ -3723,7 +3769,6 @@ dependencies = [ "tokio", "toml", "vite_path", - "vite_pty", "vite_str", "vite_task", "vite_workspace", @@ -3743,7 +3788,7 @@ dependencies = [ "rustc-hash", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "ts-rs", "vec1", "vite_graph_ser", @@ -3773,7 +3818,7 @@ dependencies = [ "shell-escape", "supports-color", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "toml", "tracing", @@ -3818,7 +3863,7 @@ dependencies = [ "serde_json", "serde_yml", "tempfile", - "thiserror 2.0.17", + "thiserror 2.0.18", "vec1", "vite_glob", "vite_path", @@ -3873,28 +3918,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.7+wasi-0.2.4" +name = "wasip2" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ - "wasip2", + "wit-bindgen", ] [[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -3903,25 +3948,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3929,26 +3960,60 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.106", - "wasm-bindgen-backend", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.10.0", + "hashbrown 0.15.5", + "indexmap", + "semver 1.0.27", +] + [[package]] name = "wax" version = "0.6.0" @@ -3990,7 +4055,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692daff6d93d94e29e4114544ef6d5c942a7ed998b37abdc19b17136ea428eb7" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "mac_address", "sha2", "thiserror 1.0.69", @@ -4060,9 +4125,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" [[package]] name = "win-sys" @@ -4095,7 +4160,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.1", + "windows-sys 0.61.2", ] [[package]] @@ -4119,18 +4184,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-sys" @@ -4147,14 +4203,14 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.4", + "windows-targets 0.53.5", ] [[package]] name = "windows-sys" -version = "0.61.1" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] @@ -4177,19 +4233,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.4" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -4200,9 +4256,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -4218,9 +4274,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -4236,9 +4292,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -4248,9 +4304,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -4266,9 +4322,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -4284,9 +4340,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -4296,9 +4352,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -4314,15 +4370,15 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -4350,9 +4406,91 @@ checksum = "4271ae8f63c109d73bc6fcf352b117166757fabcce6a769649ef18303dbf2491" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap", + "prettyplease", + "syn 2.0.114", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.114", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.10.0", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver 1.0.27", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "xattr" @@ -4378,20 +4516,26 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.114", ] + +[[package]] +name = "zmij" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" diff --git a/Cargo.toml b/Cargo.toml index 7d31e081..d94d88a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -92,6 +92,7 @@ petgraph = "0.8.2" phf = { version = "0.11.3", features = ["macros"] } portable-pty = "0.9.0" pretty_assertions = "1.4.1" +pty_terminal = { path = "crates/pty_terminal" } rand = "0.9.1" ratatui = "0.30.0" rayon = "1.10.0" @@ -129,7 +130,6 @@ vec1 = "1.12.1" vite_glob = { path = "crates/vite_glob" } vite_graph_ser = { path = "crates/vite_graph_ser" } vite_path = { path = "crates/vite_path" } -vite_pty = { path = "crates/vite_pty" } vite_shell = { path = "crates/vite_shell" } vite_str = { path = "crates/vite_str" } vite_task = { path = "crates/vite_task" } diff --git a/crates/vite_pty/.clippy.toml b/crates/pty_terminal/.clippy.toml similarity index 100% rename from crates/vite_pty/.clippy.toml rename to crates/pty_terminal/.clippy.toml diff --git a/crates/vite_pty/Cargo.toml b/crates/pty_terminal/Cargo.toml similarity index 95% rename from crates/vite_pty/Cargo.toml rename to crates/pty_terminal/Cargo.toml index fd671c12..aa272390 100644 --- a/crates/vite_pty/Cargo.toml +++ b/crates/pty_terminal/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "vite_pty" +name = "pty_terminal" version = "0.0.0" authors.workspace = true edition.workspace = true diff --git a/crates/pty_terminal/README.md b/crates/pty_terminal/README.md new file mode 100644 index 00000000..442cf8dc --- /dev/null +++ b/crates/pty_terminal/README.md @@ -0,0 +1,25 @@ +# pty_terminal + +A headless terminal emulator built on top of [portable-pty](https://crates.io/crates/portable-pty) and [vt100](https://crates.io/crates/vt100). It spawns child processes inside a pseudo-terminal (PTY) and provides an API for reading, writing, and resizing the terminal programmatically. + +## Features + +- Cross-platform PTY support (Unix and Windows via ConPTY) +- Built-in VT100 terminal emulation with screen state tracking +- Synchronous read-until pattern matching for interactive process control +- Terminal resize with proper signal delivery (SIGWINCH on Unix) +- Ctrl+C support via PTY input + +## Usage + +```rust +use pty_terminal::{geo::ScreenSize, terminal::{CommandBuilder, Terminal}}; + +let cmd = CommandBuilder::new("echo"); +cmd.arg("hello"); + +let mut terminal = Terminal::spawn(ScreenSize { rows: 24, cols: 80 }, cmd)?; +terminal.read_until("hello")?; +let status = terminal.read_to_end()?; +assert!(status.success()); +``` diff --git a/crates/vite_pty/src/geo.rs b/crates/pty_terminal/src/geo.rs similarity index 100% rename from crates/vite_pty/src/geo.rs rename to crates/pty_terminal/src/geo.rs diff --git a/crates/vite_pty/src/lib.rs b/crates/pty_terminal/src/lib.rs similarity index 100% rename from crates/vite_pty/src/lib.rs rename to crates/pty_terminal/src/lib.rs diff --git a/crates/vite_pty/src/terminal.rs b/crates/pty_terminal/src/terminal.rs similarity index 100% rename from crates/vite_pty/src/terminal.rs rename to crates/pty_terminal/src/terminal.rs diff --git a/crates/vite_pty/tests/terminal.rs b/crates/pty_terminal/tests/terminal.rs similarity index 91% rename from crates/vite_pty/tests/terminal.rs rename to crates/pty_terminal/tests/terminal.rs index 3c9a2b85..fba9c596 100644 --- a/crates/vite_pty/tests/terminal.rs +++ b/crates/pty_terminal/tests/terminal.rs @@ -1,13 +1,9 @@ -use std::{ - io::{IsTerminal, Write, stderr, stdin, stdout}, - thread, - time::Duration, -}; +use std::io::{IsTerminal, Write, stderr, stdin, stdout}; use ntest::timeout; use portable_pty::CommandBuilder; +use pty_terminal::{geo::ScreenSize, terminal::Terminal}; use subprocess_test::command_for_fn; -use vite_pty::{geo::ScreenSize, terminal::Terminal}; #[test] #[timeout(5000)] @@ -45,7 +41,6 @@ fn read_until_single() { #[expect(clippy::print_stdout, reason = "subprocess test output")] fn read_until_multiple_sequential() { let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - thread::sleep(Duration::from_millis(10)); print!("first second third"); let _ = stdout().flush(); })); @@ -67,7 +62,6 @@ fn read_until_multiple_sequential() { #[expect(clippy::print_stdout, reason = "subprocess test output")] fn read_until_not_found() { let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - thread::sleep(Duration::from_millis(10)); print!("hello world"); let _ = stdout().flush(); })); @@ -83,7 +77,6 @@ fn read_until_not_found() { #[expect(clippy::print_stdout, reason = "subprocess test output")] fn read_until_with_read_to_end() { let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - thread::sleep(Duration::from_millis(10)); print!("prefix middle suffix"); let _ = stdout().flush(); })); @@ -106,23 +99,10 @@ fn read_until_boundary_spanning() { // Test case where expected string might span across read boundaries let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { // Write in small chunks to increase chance of boundary spanning - print!("a"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(5)); - print!("b"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(5)); - print!("c"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(5)); - print!("d"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(5)); - print!("e"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(5)); - print!("f"); - let _ = stdout().flush(); + for c in ['a', 'b', 'c', 'd', 'e', 'f'] { + print!("{c}"); + let _ = stdout().flush(); + } })); let mut terminal = Terminal::spawn(ScreenSize { rows: 80, cols: 80 }, cmd).unwrap(); @@ -139,10 +119,7 @@ fn read_until_boundary_spanning() { fn read_until_exact_boundary() { // Test where we search for something at the exact boundary let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - print!("first"); - let _ = stdout().flush(); - thread::sleep(Duration::from_millis(10)); - print!("second"); + print!("firstsecond"); let _ = stdout().flush(); })); @@ -386,7 +363,7 @@ fn resize_terminal() { #[expect(clippy::print_stdout, reason = "subprocess test output")] fn send_ctrl_c_interrupts_process() { let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - use std::io::{Write, stdout}; + use std::io::{Write, stdin, stdout}; #[cfg(unix)] use std::sync::Arc; #[cfg(unix)] @@ -410,8 +387,9 @@ fn send_ctrl_c_interrupts_process() { println!("ready"); stdout().flush().unwrap(); - // Wait briefly for Ctrl+C - thread::sleep(Duration::from_millis(100)); + // Block on stdin until the test sends a newline (after Ctrl+C) + let mut input = std::string::String::new(); + let _ = stdin().read_line(&mut input); #[cfg(unix)] { @@ -422,9 +400,7 @@ fn send_ctrl_c_interrupts_process() { #[cfg(windows)] { - // On Windows, we'll verify differently - the process may exit - // or handle the CTRL_C_EVENT depending on handler setup - // For this test, we just verify the mechanism works + // On Windows, Ctrl+C is delivered via ConPTY as CTRL_C_EVENT println!("INTERRUPTED"); } @@ -439,6 +415,9 @@ fn send_ctrl_c_interrupts_process() { // Send Ctrl+C terminal.send_ctrl_c().unwrap(); + // Signal the process to continue and check the interrupt flag + terminal.write(b"\n").unwrap(); + // Verify interruption was detected terminal.read_until("INTERRUPTED").unwrap(); diff --git a/crates/vite_task_bin/Cargo.toml b/crates/vite_task_bin/Cargo.toml index a97340ab..c4ca6962 100644 --- a/crates/vite_task_bin/Cargo.toml +++ b/crates/vite_task_bin/Cargo.toml @@ -27,12 +27,12 @@ which = { workspace = true } copy_dir = { workspace = true } cow-utils = { workspace = true } insta = { workspace = true, features = ["glob", "json", "redactions", "filters", "ron"] } +pty_terminal = { workspace = true } regex = { workspace = true } serde = { workspace = true, features = ["derive", "rc"] } tempfile = { workspace = true } toml = { workspace = true } vite_path = { workspace = true, features = ["absolute-redaction"] } -vite_pty = { workspace = true } vite_workspace = { workspace = true } [lints] diff --git a/crates/vite_task_bin/tests/e2e_snapshots/main.rs b/crates/vite_task_bin/tests/e2e_snapshots/main.rs index 0bcfb4c2..717dcc18 100644 --- a/crates/vite_task_bin/tests/e2e_snapshots/main.rs +++ b/crates/vite_task_bin/tests/e2e_snapshots/main.rs @@ -8,13 +8,13 @@ use std::{ }; use copy_dir::copy_dir; -use redact::redact_e2e_output; -use vite_path::{AbsolutePath, AbsolutePathBuf, RelativePathBuf}; -use vite_pty::{ +use pty_terminal::{ ExitStatus, geo::ScreenSize, terminal::{CommandBuilder, Terminal}, }; +use redact::redact_e2e_output; +use vite_path::{AbsolutePath, AbsolutePathBuf, RelativePathBuf}; use vite_str::Str; use vite_workspace::find_workspace_root; diff --git a/crates/vite_tui/src/tui.rs b/crates/vite_tui/src/tui.rs index fc074b51..d46cbd1b 100644 --- a/crates/vite_tui/src/tui.rs +++ b/crates/vite_tui/src/tui.rs @@ -144,6 +144,10 @@ impl Tui { cancellation_token.cancel(); } + #[expect( + clippy::disallowed_methods, + reason = "polling with short sleep is acceptable for TUI task shutdown" + )] pub fn stop(&self) { self.cancel(); let mut counter = 0; From 251c877e7c38d249fb198845d51c1562cbf47504 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 11:19:57 +0800 Subject: [PATCH 3/8] fix: pty_terminal boundary spanning test on Windows ConPTY MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConPTY reprocesses output and inserts escape sequences between individually-printed characters, so "abcd" never appears contiguous in the raw PTY stream. Print the full string at once instead — boundary spanning is still tested since the reader can return partial data. Co-Authored-By: Claude Opus 4.6 --- crates/pty_terminal/tests/terminal.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/pty_terminal/tests/terminal.rs b/crates/pty_terminal/tests/terminal.rs index fba9c596..1738fc62 100644 --- a/crates/pty_terminal/tests/terminal.rs +++ b/crates/pty_terminal/tests/terminal.rs @@ -96,13 +96,13 @@ fn read_until_with_read_to_end() { #[timeout(5000)] #[expect(clippy::print_stdout, reason = "subprocess test output")] fn read_until_boundary_spanning() { - // Test case where expected string might span across read boundaries + // Test that read_until works when the expected string may span across read() boundaries. + // Boundary spanning is about the reader side: the PTY reader may return partial data even + // from a single write. We print the full string at once because on Windows, ConPTY + // reprocesses output and can insert escape sequences between individually-printed characters. let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - // Write in small chunks to increase chance of boundary spanning - for c in ['a', 'b', 'c', 'd', 'e', 'f'] { - print!("{c}"); - let _ = stdout().flush(); - } + print!("abcdef"); + let _ = stdout().flush(); })); let mut terminal = Terminal::spawn(ScreenSize { rows: 80, cols: 80 }, cmd).unwrap(); From 34e93c0534ad938ca5bfeba2d858fb37ba5519eb Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 11:37:58 +0800 Subject: [PATCH 4/8] fix: close pty writer in read_to_end to eliminate race condition On Linux, writing to a PTY master after the child exits can succeed (kernel buffers the data), unlike macOS which returns EIO. The background thread sets writer=None after setting exit_status, but read_to_end returns right after exit_status is set, creating a window where write() still succeeds. Close the writer in read_to_end itself. Co-Authored-By: Claude Opus 4.6 --- crates/pty_terminal/src/terminal.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/pty_terminal/src/terminal.rs b/crates/pty_terminal/src/terminal.rs index e1d12254..d105cc18 100644 --- a/crates/pty_terminal/src/terminal.rs +++ b/crates/pty_terminal/src/terminal.rs @@ -194,6 +194,11 @@ impl Terminal { // Wait for exit status to be set by background thread let status = self.exit_status.wait().clone(); + // Close the writer since the child has exited and all output has been consumed. + // This ensures subsequent write() calls fail immediately, rather than racing + // with the background thread which also closes the writer. + *self.writer.lock().unwrap() = None; + Ok(status) } From 1767deee8a49572b47f55c252f34ad257f583468 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 11:48:29 +0800 Subject: [PATCH 5/8] fix: add panics doc to read_to_end for clippy missing_panics_doc Co-Authored-By: Claude Opus 4.6 --- crates/pty_terminal/src/terminal.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/pty_terminal/src/terminal.rs b/crates/pty_terminal/src/terminal.rs index d105cc18..858e2bee 100644 --- a/crates/pty_terminal/src/terminal.rs +++ b/crates/pty_terminal/src/terminal.rs @@ -177,6 +177,10 @@ impl Terminal { /// Returns an error if: /// - Reading from the PTY fails /// - The exit status is not available (should not happen in normal operation) + /// + /// # Panics + /// + /// Panics if the writer lock is poisoned. pub fn read_to_end(&mut self) -> anyhow::Result { // `read_to_end` will move cursor to the end, so clear any buffered data for `read_until` self.read_until_buffer.clear(); From 0491ad6afa7df4c30338349832e4ecef298d11d6 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 11:48:35 +0800 Subject: [PATCH 6/8] chore(ci): allow clippy failures to not abort test execution Make clippy non-blocking so tests still run even when clippy fails, while preserving the job failure via a deferred check at the end. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/ci.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac3a1a86..fb194f29 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,10 @@ jobs: env: RUSTFLAGS: '-D warnings --cfg tokio_unstable' # also update .cargo/config.toml - - run: cargo clippy --all-targets --all-features -- -D warnings + - name: Clippy + id: clippy + continue-on-error: true + run: cargo clippy --all-targets --all-features -- -D warnings # Set up node and pnpm for running tests # For x86_64-apple-darwin, use x64 node for fspy tests that verify Node.js fs accesses @@ -87,6 +90,10 @@ jobs: - run: cargo-zigbuild test --target x86_64-unknown-linux-gnu.2.17 if: ${{ matrix.os == 'ubuntu-latest' }} + - name: Check clippy result + if: ${{ steps.clippy.outcome == 'failure' }} + run: exit 1 + fmt: name: Format and Check Deps runs-on: ubuntu-latest From 2fc7fdb64b85acf9edaad8f9c105e56918531e84 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 12:58:35 +0800 Subject: [PATCH 7/8] fix: properly detect ctrl-c and resize in pty_terminal tests on Windows - resize_terminal: compare terminal size before/after instead of unconditionally printing RESIZE_DETECTED - send_ctrl_c: clear the "ignore CTRL_C" flag (set by Rust runtime) with SetConsoleCtrlHandler(None, 0) so CTRL_C_EVENT actually terminates the process via the default handler, proving send_ctrl_c delivers the signal. On Unix, verify via SIGINT handler as before. Co-Authored-By: Claude Opus 4.6 --- crates/pty_terminal/src/terminal.rs | 10 ++--- crates/pty_terminal/tests/terminal.rs | 61 +++++++++++++++++++-------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/crates/pty_terminal/src/terminal.rs b/crates/pty_terminal/src/terminal.rs index 858e2bee..31a2262d 100644 --- a/crates/pty_terminal/src/terminal.rs +++ b/crates/pty_terminal/src/terminal.rs @@ -249,14 +249,14 @@ impl Terminal { /// Sends Ctrl+C (SIGINT) to the child process. /// + /// Writes ETX (0x03) to the PTY. On Unix, the terminal driver converts this + /// to SIGINT for the child's process group. On Windows, `ConPTY` intercepts + /// the byte and generates `CTRL_C_EVENT` for the child. + /// /// # Errors /// - /// Returns an error if: - /// - The child process has already exited - /// - Writing to the PTY fails + /// Returns an error if the child process has already exited or writing fails. pub fn send_ctrl_c(&self) -> anyhow::Result<()> { - // ASCII 0x03 (ETX) is Ctrl+C - // Both Unix PTY and Windows ConPTY interpret this and signal the child self.write(&[0x03]) } diff --git a/crates/pty_terminal/tests/terminal.rs b/crates/pty_terminal/tests/terminal.rs index 1738fc62..faed366b 100644 --- a/crates/pty_terminal/tests/terminal.rs +++ b/crates/pty_terminal/tests/terminal.rs @@ -326,10 +326,13 @@ fn resize_terminal() { } } - // On Windows, resize happens synchronously via ConPTY + // On Windows, ConPTY resizes synchronously - detect by checking size change #[cfg(windows)] { - println!("RESIZE_DETECTED"); + let (new_rows, new_cols) = get_size(); + if (new_rows, new_cols) != (rows, cols) { + println!("RESIZE_DETECTED"); + } } // Print new size @@ -384,23 +387,37 @@ fn send_ctrl_c_interrupts_process() { .unwrap(); } + // On Windows, explicitly ensure Ctrl+C is NOT ignored, so that + // CTRL_C_EVENT terminates the process via the default handler. + #[cfg(windows)] + { + // SAFETY: Declaring correct signature for SetConsoleCtrlHandler from kernel32. + unsafe extern "system" { + fn SetConsoleCtrlHandler( + handler: Option i32>, + add: i32, + ) -> i32; + } + + // SAFETY: Clearing the "ignore CTRL_C" flag so the default handler runs. + unsafe { + SetConsoleCtrlHandler(None, 0); // FALSE = remove ignore + } + } + println!("ready"); stdout().flush().unwrap(); - // Block on stdin until the test sends a newline (after Ctrl+C) + // Block on stdin. On Unix, SIGINT interrupts read_line. On Windows, + // CTRL_C_EVENT terminates the process via the default handler. let mut input = std::string::String::new(); let _ = stdin().read_line(&mut input); + // On Unix, check if SIGINT was delivered via the signal handler. + // On Windows, this code is unreachable: the process is terminated + // by CTRL_C_EVENT before read_line returns. #[cfg(unix)] - { - if interrupted.load(Ordering::SeqCst) { - println!("INTERRUPTED"); - } - } - - #[cfg(windows)] - { - // On Windows, Ctrl+C is delivered via ConPTY as CTRL_C_EVENT + if interrupted.load(Ordering::SeqCst) { println!("INTERRUPTED"); } @@ -415,13 +432,23 @@ fn send_ctrl_c_interrupts_process() { // Send Ctrl+C terminal.send_ctrl_c().unwrap(); - // Signal the process to continue and check the interrupt flag - terminal.write(b"\n").unwrap(); + // On Unix, send newline to unblock read_line and verify SIGINT detection. + #[cfg(unix)] + { + terminal.write(b"\n").unwrap(); + terminal.read_until("INTERRUPTED").unwrap(); + } - // Verify interruption was detected - terminal.read_until("INTERRUPTED").unwrap(); + let status = terminal.read_to_end().unwrap(); - let _ = terminal.read_to_end().unwrap(); + // On Unix, the process exits normally after detecting SIGINT. + #[cfg(unix)] + assert!(status.success()); + + // On Windows, the default CTRL_C handler calls ExitProcess with + // STATUS_CONTROL_C_EXIT, resulting in a non-zero exit code. + #[cfg(windows)] + assert!(!status.success()); } #[test] From a00bca5aaa228766c37542b7a18c0f6b823c3c5e Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 11 Feb 2026 13:15:33 +0800 Subject: [PATCH 8/8] fix: use ctrlc crate for cross-platform Ctrl+C detection in pty test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace platform-divergent signal-hook (Unix) / default-handler (Windows) approach with the `ctrlc` crate on both platforms. The handler writes "INTERRUPTED" and exits directly, avoiding race conditions between the callback thread and main thread. On Windows, the Rust runtime sets SetConsoleCtrlHandler(NULL, TRUE) during init which ignores CTRL_C_EVENT — clear this flag before registering the handler so ConPTY-generated events reach it. Co-Authored-By: Claude Opus 4.6 --- Cargo.lock | 64 +++++++++++++++++++++++- Cargo.toml | 1 + crates/pty_terminal/Cargo.toml | 1 + crates/pty_terminal/tests/terminal.rs | 71 +++++++-------------------- 4 files changed, 83 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8af34815..4ced9c80 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,6 +267,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "bon" version = "3.8.2" @@ -724,6 +733,17 @@ version = "0.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" +[[package]] +name = "ctrlc" +version = "3.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162" +dependencies = [ + "dispatch2", + "nix 0.31.1", + "windows-sys 0.61.2", +] + [[package]] name = "darling" version = "0.20.11" @@ -890,6 +910,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", +] + [[package]] name = "document-features" version = "0.2.12" @@ -1645,9 +1677,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.181" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libloading" @@ -1895,6 +1927,18 @@ dependencies = [ "memoffset 0.9.1", ] +[[package]] +name = "nix" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225e7cfe711e0ba79a68baeddb2982723e4235247aefce1482f2f16c27865b66" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -2055,6 +2099,21 @@ dependencies = [ "libc", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + [[package]] name = "object" version = "0.37.3" @@ -2424,6 +2483,7 @@ version = "0.0.0" dependencies = [ "anyhow", "ctor", + "ctrlc", "ntest", "portable-pty", "signal-hook", diff --git a/Cargo.toml b/Cargo.toml index d94d88a5..1e85701b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,6 +62,7 @@ cow-utils = "0.1.3" crossterm = { version = "0.29.0", features = ["event-stream"] } csv-async = { version = "1.3.1", features = ["tokio"] } ctor = "0.6" +ctrlc = "3.5.2" derive_more = "2.0.1" diff-struct = "0.5.3" directories = "6.0.0" diff --git a/crates/pty_terminal/Cargo.toml b/crates/pty_terminal/Cargo.toml index aa272390..9e2acba7 100644 --- a/crates/pty_terminal/Cargo.toml +++ b/crates/pty_terminal/Cargo.toml @@ -14,6 +14,7 @@ vt100 = { workspace = true } [dev-dependencies] ctor = { workspace = true } +ctrlc = { workspace = true } ntest = "0.9.5" subprocess_test = { workspace = true, features = ["portable-pty"] } terminal_size = "0.4" diff --git a/crates/pty_terminal/tests/terminal.rs b/crates/pty_terminal/tests/terminal.rs index faed366b..c0de9be4 100644 --- a/crates/pty_terminal/tests/terminal.rs +++ b/crates/pty_terminal/tests/terminal.rs @@ -366,29 +366,10 @@ fn resize_terminal() { #[expect(clippy::print_stdout, reason = "subprocess test output")] fn send_ctrl_c_interrupts_process() { let cmd = CommandBuilder::from(command_for_fn!((), |(): ()| { - use std::io::{Write, stdin, stdout}; - #[cfg(unix)] - use std::sync::Arc; - #[cfg(unix)] - use std::sync::atomic::{AtomicBool, Ordering}; - - #[cfg(unix)] - let interrupted = Arc::new(AtomicBool::new(false)); - #[cfg(unix)] - let interrupted_clone = Arc::clone(&interrupted); + use std::io::{Write, stdout}; - // Install SIGINT handler on Unix - #[cfg(unix)] - // SAFETY: The closure only performs an atomic store, which is signal-safe. - unsafe { - signal_hook::low_level::register(signal_hook::consts::SIGINT, move || { - interrupted_clone.store(true, Ordering::SeqCst); - }) - .unwrap(); - } - - // On Windows, explicitly ensure Ctrl+C is NOT ignored, so that - // CTRL_C_EVENT terminates the process via the default handler. + // On Windows, clear the "ignore CTRL_C" flag set by Rust runtime + // so that CTRL_C_EVENT reaches the ctrlc handler. #[cfg(windows)] { // SAFETY: Declaring correct signature for SetConsoleCtrlHandler from kernel32. @@ -399,29 +380,28 @@ fn send_ctrl_c_interrupts_process() { ) -> i32; } - // SAFETY: Clearing the "ignore CTRL_C" flag so the default handler runs. + // SAFETY: Clearing the "ignore CTRL_C" flag so handlers are invoked. unsafe { SetConsoleCtrlHandler(None, 0); // FALSE = remove ignore } } + ctrlc::set_handler(move || { + // Write directly and exit from the handler to avoid races. + use std::io::Write; + let _ = write!(std::io::stdout(), "INTERRUPTED"); + let _ = std::io::stdout().flush(); + std::process::exit(0); + }) + .unwrap(); + println!("ready"); stdout().flush().unwrap(); - // Block on stdin. On Unix, SIGINT interrupts read_line. On Windows, - // CTRL_C_EVENT terminates the process via the default handler. - let mut input = std::string::String::new(); - let _ = stdin().read_line(&mut input); - - // On Unix, check if SIGINT was delivered via the signal handler. - // On Windows, this code is unreachable: the process is terminated - // by CTRL_C_EVENT before read_line returns. - #[cfg(unix)] - if interrupted.load(Ordering::SeqCst) { - println!("INTERRUPTED"); + // Block until Ctrl+C handler exits the process. + loop { + std::thread::park(); } - - stdout().flush().unwrap(); })); let mut terminal = Terminal::spawn(ScreenSize { rows: 80, cols: 80 }, cmd).unwrap(); @@ -432,23 +412,10 @@ fn send_ctrl_c_interrupts_process() { // Send Ctrl+C terminal.send_ctrl_c().unwrap(); - // On Unix, send newline to unblock read_line and verify SIGINT detection. - #[cfg(unix)] - { - terminal.write(b"\n").unwrap(); - terminal.read_until("INTERRUPTED").unwrap(); - } + // Verify interruption was detected + terminal.read_until("INTERRUPTED").unwrap(); - let status = terminal.read_to_end().unwrap(); - - // On Unix, the process exits normally after detecting SIGINT. - #[cfg(unix)] - assert!(status.success()); - - // On Windows, the default CTRL_C handler calls ExitProcess with - // STATUS_CONTROL_C_EXIT, resulting in a non-zero exit code. - #[cfg(windows)] - assert!(!status.success()); + let _ = terminal.read_to_end().unwrap(); } #[test]