diff options
Diffstat (limited to 'cli/main.rs')
-rw-r--r-- | cli/main.rs | 108 |
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>>, |