summaryrefslogtreecommitdiff
path: root/cli/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/main.rs')
-rw-r--r--cli/main.rs108
1 files changed, 85 insertions, 23 deletions
diff --git a/cli/main.rs b/cli/main.rs
index 39c931349..0d55ea1df 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -30,6 +30,7 @@ mod diff;
mod disk_cache;
pub mod errors;
mod file_fetcher;
+mod file_watcher;
pub mod flags;
mod flags_allow_net;
mod fmt;
@@ -228,6 +229,8 @@ async fn cache_command(flags: Flags, files: Vec<String>) -> Result<(), ErrBox> {
for file in files {
let specifier = ModuleSpecifier::resolve_url_or_path(&file)?;
+ // TODO(bartlomieju): don't use `preload_module` in favor of calling "GlobalState::prepare_module_load()"
+ // explicitly? Seems wasteful to create multiple worker just to run TS compiler
worker.preload_module(&specifier).await.map(|_| ())?;
}
@@ -435,33 +438,29 @@ async fn run_repl(flags: Flags) -> Result<(), ErrBox> {
}
}
-async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
+async fn run_from_stdin(flags: Flags) -> Result<(), ErrBox> {
let global_state = GlobalState::new(flags.clone())?;
- let main_module = if script != "-" {
- ModuleSpecifier::resolve_url_or_path(&script).unwrap()
- } else {
- ModuleSpecifier::resolve_url_or_path("./__$deno$stdin.ts").unwrap()
- };
+ let main_module =
+ ModuleSpecifier::resolve_url_or_path("./__$deno$stdin.ts").unwrap();
let mut worker =
MainWorker::create(&global_state.clone(), main_module.clone())?;
- if script == "-" {
- let mut source = Vec::new();
- std::io::stdin().read_to_end(&mut source)?;
- let main_module_url = main_module.as_url().to_owned();
- // Create a dummy source file.
- let source_file = SourceFile {
- filename: main_module_url.to_file_path().unwrap(),
- url: main_module_url,
- types_header: None,
- media_type: MediaType::TypeScript,
- source_code: source.into(),
- };
- // Save our fake file into file fetcher cache
- // to allow module access by TS compiler
- global_state
- .file_fetcher
- .save_source_file_in_cache(&main_module, source_file);
+
+ let mut source = Vec::new();
+ std::io::stdin().read_to_end(&mut source)?;
+ let main_module_url = main_module.as_url().to_owned();
+ // Create a dummy source file.
+ let source_file = SourceFile {
+ filename: main_module_url.to_file_path().unwrap(),
+ url: main_module_url,
+ types_header: None,
+ media_type: MediaType::TypeScript,
+ source_code: source.into(),
};
+ // Save our fake file into file fetcher cache
+ // to allow module access by TS compiler
+ global_state
+ .file_fetcher
+ .save_source_file_in_cache(&main_module, source_file);
debug!("main_module {}", main_module);
worker.execute_module(&main_module).await?;
@@ -471,6 +470,69 @@ async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
Ok(())
}
+async fn run_with_watch(flags: Flags, script: String) -> Result<(), ErrBox> {
+ let main_module = ModuleSpecifier::resolve_url_or_path(&script)?;
+ let global_state = GlobalState::new(flags.clone())?;
+
+ let mut module_graph_loader = module_graph::ModuleGraphLoader::new(
+ global_state.file_fetcher.clone(),
+ global_state.maybe_import_map.clone(),
+ Permissions::allow_all(),
+ false,
+ false,
+ );
+ module_graph_loader.add_to_graph(&main_module, None).await?;
+ let module_graph = module_graph_loader.get_graph();
+
+ // Find all local files in graph
+ let paths_to_watch: Vec<PathBuf> = module_graph
+ .values()
+ .map(|f| Url::parse(&f.url).unwrap())
+ .filter(|url| url.scheme() == "file")
+ .map(|url| url.to_file_path().unwrap())
+ .collect();
+
+ // FIXME(bartlomieju): new file watcher is created on after each restart
+ file_watcher::watch_func(&paths_to_watch, move || {
+ // FIXME(bartlomieju): GlobalState must be created on each restart - otherwise file fetcher
+ // will use cached source files
+ let gs = GlobalState::new(flags.clone()).unwrap();
+ let main_module = main_module.clone();
+ async move {
+ let mut worker = MainWorker::create(&gs, main_module.clone())?;
+ debug!("main_module {}", main_module);
+ worker.execute_module(&main_module).await?;
+ worker.execute("window.dispatchEvent(new Event('load'))")?;
+ (&mut *worker).await?;
+ worker.execute("window.dispatchEvent(new Event('unload'))")?;
+ Ok(())
+ }
+ .boxed_local()
+ })
+ .await
+}
+
+async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
+ // Read script content from stdin
+ if script == "-" {
+ return run_from_stdin(flags).await;
+ }
+
+ if flags.watch {
+ return run_with_watch(flags, script).await;
+ }
+
+ let main_module = ModuleSpecifier::resolve_url_or_path(&script)?;
+ let global_state = GlobalState::new(flags.clone())?;
+ let mut worker = MainWorker::create(&global_state, main_module.clone())?;
+ debug!("main_module {}", main_module);
+ worker.execute_module(&main_module).await?;
+ worker.execute("window.dispatchEvent(new Event('load'))")?;
+ (&mut *worker).await?;
+ worker.execute("window.dispatchEvent(new Event('unload'))")?;
+ Ok(())
+}
+
async fn test_command(
flags: Flags,
include: Option<Vec<String>>,