summaryrefslogtreecommitdiff
path: root/cli/graph_util.rs
diff options
context:
space:
mode:
authorDavid Sherret <dsherret@users.noreply.github.com>2023-06-14 18:29:19 -0400
committerGitHub <noreply@github.com>2023-06-14 22:29:19 +0000
commit84c793275b324c262dde02a432462565584c83f7 (patch)
treea5995a842fabb37b2ecdab794dbbce76b530ac3a /cli/graph_util.rs
parent48c6f7178703d448da229a5baf19efb403416da0 (diff)
fix: reload config files on watcher restarts (#19487)
Closes #19468
Diffstat (limited to 'cli/graph_util.rs')
-rw-r--r--cli/graph_util.rs87
1 files changed, 79 insertions, 8 deletions
diff --git a/cli/graph_util.rs b/cli/graph_util.rs
index 530b0a974..0d3548205 100644
--- a/cli/graph_util.rs
+++ b/cli/graph_util.rs
@@ -34,6 +34,7 @@ use deno_runtime::permissions::PermissionsContainer;
use import_map::ImportMapError;
use std::collections::HashMap;
use std::collections::HashSet;
+use std::path::PathBuf;
use std::sync::Arc;
#[derive(Clone, Copy)]
@@ -169,6 +170,7 @@ pub struct ModuleGraphBuilder {
npm_resolver: Arc<CliNpmResolver>,
parsed_source_cache: Arc<ParsedSourceCache>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
+ maybe_file_watcher_reporter: Option<FileWatcherReporter>,
emit_cache: cache::EmitCache,
file_fetcher: Arc<FileFetcher>,
type_checker: Arc<TypeChecker>,
@@ -182,6 +184,7 @@ impl ModuleGraphBuilder {
npm_resolver: Arc<CliNpmResolver>,
parsed_source_cache: Arc<ParsedSourceCache>,
lockfile: Option<Arc<Mutex<Lockfile>>>,
+ maybe_file_watcher_reporter: Option<FileWatcherReporter>,
emit_cache: cache::EmitCache,
file_fetcher: Arc<FileFetcher>,
type_checker: Arc<TypeChecker>,
@@ -192,6 +195,7 @@ impl ModuleGraphBuilder {
npm_resolver,
parsed_source_cache,
lockfile,
+ maybe_file_watcher_reporter,
emit_cache,
file_fetcher,
type_checker,
@@ -210,6 +214,10 @@ impl ModuleGraphBuilder {
let graph_resolver = cli_resolver.as_graph_resolver();
let graph_npm_resolver = cli_resolver.as_graph_npm_resolver();
let analyzer = self.parsed_source_cache.as_analyzer();
+ let maybe_file_watcher_reporter = self
+ .maybe_file_watcher_reporter
+ .as_ref()
+ .map(|r| r.as_reporter());
let mut graph = ModuleGraph::new(graph_kind);
self
@@ -223,7 +231,7 @@ impl ModuleGraphBuilder {
resolver: Some(graph_resolver),
npm_resolver: Some(graph_npm_resolver),
module_analyzer: Some(&*analyzer),
- reporter: None,
+ reporter: maybe_file_watcher_reporter,
},
)
.await?;
@@ -250,6 +258,11 @@ impl ModuleGraphBuilder {
let analyzer = self.parsed_source_cache.as_analyzer();
let graph_kind = self.options.type_check_mode().as_graph_kind();
let mut graph = ModuleGraph::new(graph_kind);
+ let maybe_file_watcher_reporter = self
+ .maybe_file_watcher_reporter
+ .as_ref()
+ .map(|r| r.as_reporter());
+
self
.build_graph_with_npm_resolution(
&mut graph,
@@ -261,7 +274,7 @@ impl ModuleGraphBuilder {
resolver: Some(graph_resolver),
npm_resolver: Some(graph_npm_resolver),
module_analyzer: Some(&*analyzer),
- reporter: None,
+ reporter: maybe_file_watcher_reporter,
},
)
.await?;
@@ -415,7 +428,6 @@ struct GraphData {
/// Holds the `ModuleGraph` and what parts of it are type checked.
pub struct ModuleGraphContainer {
- graph_kind: GraphKind,
// Allow only one request to update the graph data at a time,
// but allow other requests to read from it at any time even
// while another request is updating the data.
@@ -426,7 +438,6 @@ pub struct ModuleGraphContainer {
impl ModuleGraphContainer {
pub fn new(graph_kind: GraphKind) -> Self {
Self {
- graph_kind,
update_queue: Default::default(),
graph_data: Arc::new(RwLock::new(GraphData {
graph: Arc::new(ModuleGraph::new(graph_kind)),
@@ -435,10 +446,6 @@ impl ModuleGraphContainer {
}
}
- pub fn clear(&self) {
- self.graph_data.write().graph = Arc::new(ModuleGraph::new(self.graph_kind));
- }
-
/// Acquires a permit to modify the module graph without other code
/// having the chance to modify it. In the meantime, other code may
/// still read from the existing module graph.
@@ -496,6 +503,33 @@ impl ModuleGraphContainer {
}
}
+/// Gets if any of the specified root's "file:" dependents are in the
+/// provided changed set.
+pub fn has_graph_root_local_dependent_changed(
+ graph: &ModuleGraph,
+ root: &ModuleSpecifier,
+ changed_specifiers: &HashSet<ModuleSpecifier>,
+) -> bool {
+ let roots = vec![root.clone()];
+ let mut dependent_specifiers = graph.walk(
+ &roots,
+ deno_graph::WalkOptions {
+ follow_dynamic: true,
+ follow_type_only: true,
+ check_js: true,
+ },
+ );
+ while let Some((s, _)) = dependent_specifiers.next() {
+ if s.scheme() != "file" {
+ // skip walking this remote module's dependencies
+ dependent_specifiers.skip_previous_dependencies();
+ } else if changed_specifiers.contains(s) {
+ return true;
+ }
+ }
+ false
+}
+
/// A permit for updating the module graph. When complete and
/// everything looks fine, calling `.commit()` will store the
/// new graph in the ModuleGraphContainer.
@@ -521,6 +555,43 @@ impl<'a> ModuleGraphUpdatePermit<'a> {
}
}
+#[derive(Clone, Debug)]
+pub struct FileWatcherReporter {
+ sender: tokio::sync::mpsc::UnboundedSender<Vec<PathBuf>>,
+ file_paths: Arc<Mutex<Vec<PathBuf>>>,
+}
+
+impl FileWatcherReporter {
+ pub fn new(sender: tokio::sync::mpsc::UnboundedSender<Vec<PathBuf>>) -> Self {
+ Self {
+ sender,
+ file_paths: Default::default(),
+ }
+ }
+
+ pub fn as_reporter(&self) -> &dyn deno_graph::source::Reporter {
+ self
+ }
+}
+
+impl deno_graph::source::Reporter for FileWatcherReporter {
+ fn on_load(
+ &self,
+ specifier: &ModuleSpecifier,
+ modules_done: usize,
+ modules_total: usize,
+ ) {
+ let mut file_paths = self.file_paths.lock();
+ if specifier.scheme() == "file" {
+ file_paths.push(specifier.to_file_path().unwrap());
+ }
+
+ if modules_done == modules_total {
+ self.sender.send(file_paths.drain(..).collect()).unwrap();
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use std::sync::Arc;