diff options
author | Ćukasz Czerniawski <33061335+lczerniawski@users.noreply.github.com> | 2024-03-27 23:47:46 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-27 22:47:46 +0000 |
commit | 08d5d32dfccc4dc38c2aa95c81229bf031d3ac7f (patch) | |
tree | fea28ed1489f468e1e7b26b7c6d93117fb469eb8 /cli/util/file_watcher.rs | |
parent | d31f2307eee6e2a0f96342a58159d265ea03c58e (diff) |
feat: add `--watch-exclude` flag (#21935)
This PR introduces the ability to exclude certain paths from the file watcher
in Deno. This is particularly useful when running scripts in watch mode,
as it allows developers to prevent unnecessary restarts when changes are
made to files that do not affect the running script, or when executing
scripts that generate new files which results in an infinite restart
loop.
---------
Co-authored-by: David Sherret <dsherret@gmail.com>
Diffstat (limited to 'cli/util/file_watcher.rs')
-rw-r--r-- | cli/util/file_watcher.rs | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/cli/util/file_watcher.rs b/cli/util/file_watcher.rs index 33b764bbf..50ae7c233 100644 --- a/cli/util/file_watcher.rs +++ b/cli/util/file_watcher.rs @@ -4,6 +4,7 @@ use crate::args::Flags; use crate::colors; use crate::util::fs::canonicalize_path; +use deno_config::glob::PathOrPatternSet; use deno_core::error::AnyError; use deno_core::error::JsError; use deno_core::futures::Future; @@ -244,6 +245,7 @@ where ) -> Result<F, AnyError>, F: Future<Output = Result<(), AnyError>>, { + let exclude_set = flags.resolve_watch_exclude_set()?; let (paths_to_watch_tx, mut paths_to_watch_rx) = tokio::sync::mpsc::unbounded_channel(); let (restart_tx, mut restart_rx) = tokio::sync::mpsc::unbounded_channel(); @@ -297,12 +299,12 @@ where } let mut watcher = new_watcher(watcher_sender.clone())?; - consume_paths_to_watch(&mut watcher, &mut paths_to_watch_rx); + consume_paths_to_watch(&mut watcher, &mut paths_to_watch_rx, &exclude_set); let receiver_future = async { loop { let maybe_paths = paths_to_watch_rx.recv().await; - add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap()); + add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap(), &exclude_set); } }; let operation_future = error_handler(operation( @@ -321,7 +323,7 @@ where continue; }, success = operation_future => { - consume_paths_to_watch(&mut watcher, &mut paths_to_watch_rx); + consume_paths_to_watch(&mut watcher, &mut paths_to_watch_rx, &exclude_set); // TODO(bartlomieju): print exit code here? info!( "{} {} {}. Restarting on file change...", @@ -334,11 +336,11 @@ where } ); }, - }; + } let receiver_future = async { loop { let maybe_paths = paths_to_watch_rx.recv().await; - add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap()); + add_paths_to_watcher(&mut watcher, &maybe_paths.unwrap(), &exclude_set); } }; @@ -351,7 +353,7 @@ where print_after_restart(); continue; }, - }; + } } } @@ -376,28 +378,41 @@ fn new_watcher( .iter() .filter_map(|path| canonicalize_path(path).ok()) .collect(); + sender.send(paths).unwrap(); }, Default::default(), )?) } -fn add_paths_to_watcher(watcher: &mut RecommendedWatcher, paths: &[PathBuf]) { +fn add_paths_to_watcher( + watcher: &mut RecommendedWatcher, + paths: &[PathBuf], + paths_to_exclude: &PathOrPatternSet, +) { // Ignore any error e.g. `PathNotFound` + let mut watched_paths = Vec::new(); + for path in paths { + if paths_to_exclude.matches_path(path) { + continue; + } + + watched_paths.push(path.clone()); let _ = watcher.watch(path, RecursiveMode::Recursive); } - log::debug!("Watching paths: {:?}", paths); + log::debug!("Watching paths: {:?}", watched_paths); } fn consume_paths_to_watch( watcher: &mut RecommendedWatcher, receiver: &mut UnboundedReceiver<Vec<PathBuf>>, + exclude_set: &PathOrPatternSet, ) { loop { match receiver.try_recv() { Ok(paths) => { - add_paths_to_watcher(watcher, &paths); + add_paths_to_watcher(watcher, &paths, exclude_set); } Err(e) => match e { mpsc::error::TryRecvError::Empty => { |