Add Pallet Watch #25
66
Cargo.lock
generated
66
Cargo.lock
generated
@@ -84,6 +84,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 = "bytes"
|
||||
version = "1.11.1"
|
||||
@@ -96,6 +105,12 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.6.0"
|
||||
@@ -189,6 +204,17 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0b1fab2ae45819af2d0731d60f2afe17227ebb1a1538a236da84c93e9a60162"
|
||||
dependencies = [
|
||||
"dispatch2",
|
||||
"nix",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@@ -199,6 +225,18 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch2"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2",
|
||||
"libc",
|
||||
"objc2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
@@ -340,6 +378,18 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.31.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "8.2.0"
|
||||
@@ -367,6 +417,21 @@ dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
|
||||
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 = "once_cell_polyfill"
|
||||
version = "1.70.2"
|
||||
@@ -381,6 +446,7 @@ dependencies = [
|
||||
"clap_complete",
|
||||
"clap_complete_nushell",
|
||||
"colored",
|
||||
"ctrlc",
|
||||
"glob",
|
||||
"notify",
|
||||
"serde",
|
||||
|
||||
@@ -9,6 +9,7 @@ clap = { version = "4.6.0", features = ["derive"] }
|
||||
clap_complete = "4.6.0"
|
||||
clap_complete_nushell = "4.6.0"
|
||||
colored = "3.1.1"
|
||||
ctrlc = "3.5.2"
|
||||
glob = "0.3.3"
|
||||
notify = "8.2.0"
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
|
||||
37
src/app.rs
37
src/app.rs
@@ -2,6 +2,7 @@ use std::{
|
||||
env::set_current_dir,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
sync::{Arc, atomic::Ordering},
|
||||
};
|
||||
|
||||
use clap::CommandFactory;
|
||||
@@ -206,25 +207,37 @@ impl App {
|
||||
|
||||
fn watch(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Result<()> {
|
||||
use std::io::Write;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
// save terminal state
|
||||
let mut stdout = std::io::stdout();
|
||||
// enter alternate screen — this is a separate terminal buffer,
|
||||
// exiting it restores everything exactly as it was
|
||||
|
||||
// enter alternate screen
|
||||
write!(stdout, "\x1b[?1049h")?;
|
||||
stdout.flush()?;
|
||||
|
||||
// make sure we always restore the terminal, even on panic
|
||||
let result = watch_inner(mode, args);
|
||||
// set up ctrl+c handler BEFORE doing anything else
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
let running_clone = running.clone();
|
||||
ctrlc::set_handler(move || {
|
||||
running_clone.store(false, Ordering::SeqCst);
|
||||
})
|
||||
.map_err(|e| std::io::Error::other(format!("{e}")))?;
|
||||
|
||||
// exit alternate screen
|
||||
let result = watch_inner(mode, args, running);
|
||||
|
||||
// exit alternate screen — guaranteed to run now
|
||||
write!(stdout, "\x1b[?1049l")?;
|
||||
stdout.flush()?;
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Result<()> {
|
||||
fn watch_inner(
|
||||
mode: &Option<String>,
|
||||
args: Option<Vec<String>>,
|
||||
running: Arc<std::sync::atomic::AtomicBool>,
|
||||
) -> std::io::Result<()> {
|
||||
use notify::{Event, RecursiveMode, Watcher, recommended_watcher};
|
||||
use std::io::Write;
|
||||
use std::sync::mpsc;
|
||||
@@ -294,8 +307,8 @@ fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Res
|
||||
.checked_sub(Duration::from_secs(1))
|
||||
.unwrap_or(Instant::now());
|
||||
|
||||
loop {
|
||||
match rx.recv() {
|
||||
while running.load(Ordering::SeqCst) {
|
||||
match rx.recv_timeout(Duration::from_millis(100)) {
|
||||
Ok(Ok(event)) => {
|
||||
let is_relevant = matches!(
|
||||
event.kind,
|
||||
@@ -332,10 +345,8 @@ fn watch_inner(mode: &Option<String>, args: Option<Vec<String>>) -> std::io::Res
|
||||
}
|
||||
}
|
||||
Ok(Err(e)) => eprintln!(" {} watch error: {e}", "Error".red().bold()),
|
||||
Err(e) => {
|
||||
eprintln!(" {} channel error: {e}", "Error".red().bold());
|
||||
break;
|
||||
}
|
||||
Err(mpsc::RecvTimeoutError::Timeout) => continue, // check running flag and loop
|
||||
Err(mpsc::RecvTimeoutError::Disconnected) => break,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user