summaryrefslogtreecommitdiff
path: root/cli/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lib.rs')
-rw-r--r--cli/lib.rs645
1 files changed, 0 insertions, 645 deletions
diff --git a/cli/lib.rs b/cli/lib.rs
deleted file mode 100644
index 0b88d7346..000000000
--- a/cli/lib.rs
+++ /dev/null
@@ -1,645 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-#![deny(warnings)]
-
-#[macro_use]
-extern crate lazy_static;
-#[macro_use]
-extern crate log;
-extern crate futures;
-#[macro_use]
-extern crate serde_json;
-extern crate clap;
-extern crate deno_core;
-extern crate indexmap;
-#[cfg(unix)]
-extern crate nix;
-extern crate rand;
-extern crate regex;
-extern crate reqwest;
-extern crate serde;
-extern crate serde_derive;
-extern crate tokio;
-extern crate url;
-
-mod checksum;
-pub mod colors;
-pub mod deno_dir;
-pub mod diagnostics;
-mod disk_cache;
-mod doc;
-mod file_fetcher;
-pub mod flags;
-mod fmt;
-pub mod fmt_errors;
-mod fs;
-pub mod global_state;
-mod global_timer;
-pub mod http_cache;
-mod http_util;
-mod import_map;
-mod inspector;
-pub mod installer;
-mod js;
-mod lockfile;
-mod metrics;
-pub mod msg;
-pub mod op_error;
-pub mod ops;
-pub mod permissions;
-mod repl;
-pub mod resolve_addr;
-pub mod signal;
-pub mod source_maps;
-mod startup_data;
-pub mod state;
-mod swc_util;
-mod test_runner;
-pub mod test_util;
-mod tokio_util;
-mod tsc;
-mod upgrade;
-pub mod version;
-mod web_worker;
-pub mod worker;
-
-pub use dprint_plugin_typescript::swc_common;
-pub use dprint_plugin_typescript::swc_ecma_ast;
-pub use dprint_plugin_typescript::swc_ecma_parser;
-
-use crate::doc::parser::DocFileLoader;
-use crate::file_fetcher::SourceFile;
-use crate::file_fetcher::SourceFileFetcher;
-use crate::global_state::GlobalState;
-use crate::msg::MediaType;
-use crate::op_error::OpError;
-use crate::ops::io::get_stdio;
-use crate::permissions::Permissions;
-use crate::state::DebugType;
-use crate::state::State;
-use crate::tsc::TargetLib;
-use crate::worker::MainWorker;
-use deno_core::v8_set_flags;
-use deno_core::ErrBox;
-use deno_core::ModuleSpecifier;
-use flags::DenoSubcommand;
-use flags::Flags;
-use futures::future::FutureExt;
-use futures::Future;
-use log::Level;
-use log::Metadata;
-use log::Record;
-use std::env;
-use std::io::Write;
-use std::path::PathBuf;
-use std::pin::Pin;
-use upgrade::upgrade_command;
-use url::Url;
-
-static LOGGER: Logger = Logger;
-
-// TODO(ry) Switch to env_logger or other standard crate.
-struct Logger;
-
-impl log::Log for Logger {
- fn enabled(&self, metadata: &Metadata) -> bool {
- metadata.level() <= log::max_level()
- }
-
- fn log(&self, record: &Record) {
- if self.enabled(record.metadata()) {
- let mut target = record.target().to_string();
-
- if let Some(line_no) = record.line() {
- target.push_str(":");
- target.push_str(&line_no.to_string());
- }
-
- if record.level() >= Level::Info {
- eprintln!("{}", record.args());
- } else {
- eprintln!("{} RS - {} - {}", record.level(), target, record.args());
- }
- }
- }
- fn flush(&self) {}
-}
-
-fn write_to_stdout_ignore_sigpipe(bytes: &[u8]) -> Result<(), std::io::Error> {
- use std::io::ErrorKind;
-
- match std::io::stdout().write_all(bytes) {
- Ok(()) => Ok(()),
- Err(e) => match e.kind() {
- ErrorKind::BrokenPipe => Ok(()),
- _ => Err(e),
- },
- }
-}
-
-fn create_main_worker(
- global_state: GlobalState,
- main_module: ModuleSpecifier,
-) -> Result<MainWorker, ErrBox> {
- let state = State::new(global_state, None, main_module, DebugType::Main)?;
-
- let mut worker = MainWorker::new(
- "main".to_string(),
- startup_data::deno_isolate_init(),
- state,
- );
-
- {
- let (stdin, stdout, stderr) = get_stdio();
- let mut t = worker.resource_table.borrow_mut();
- t.add("stdin", Box::new(stdin));
- t.add("stdout", Box::new(stdout));
- t.add("stderr", Box::new(stderr));
- }
-
- worker.execute("bootstrap.mainRuntime()")?;
- Ok(worker)
-}
-
-fn print_cache_info(state: &GlobalState) {
- println!(
- "{} {:?}",
- colors::bold("DENO_DIR location:".to_string()),
- state.dir.root
- );
- println!(
- "{} {:?}",
- colors::bold("Remote modules cache:".to_string()),
- state.file_fetcher.http_cache.location
- );
- println!(
- "{} {:?}",
- colors::bold("TypeScript compiler cache:".to_string()),
- state.dir.gen_cache.location
- );
-}
-
-// TODO(bartlomieju): this function de facto repeats
-// whole compilation stack. Can this be done better somehow?
-async fn print_file_info(
- worker: &MainWorker,
- module_specifier: ModuleSpecifier,
-) -> Result<(), ErrBox> {
- let global_state = worker.state.borrow().global_state.clone();
-
- let out = global_state
- .file_fetcher
- .fetch_source_file(&module_specifier, None, Permissions::allow_all())
- .await?;
-
- println!(
- "{} {}",
- colors::bold("local:".to_string()),
- out.filename.to_str().unwrap()
- );
-
- println!(
- "{} {}",
- colors::bold("type:".to_string()),
- msg::enum_name_media_type(out.media_type)
- );
-
- let module_specifier_ = module_specifier.clone();
- global_state
- .clone()
- .fetch_compiled_module(
- module_specifier_,
- None,
- TargetLib::Main,
- Permissions::allow_all(),
- )
- .await?;
-
- if out.media_type == msg::MediaType::TypeScript
- || (out.media_type == msg::MediaType::JavaScript
- && global_state.ts_compiler.compile_js)
- {
- let compiled_source_file = global_state
- .ts_compiler
- .get_compiled_source_file(&out.url)
- .unwrap();
-
- println!(
- "{} {}",
- colors::bold("compiled:".to_string()),
- compiled_source_file.filename.to_str().unwrap(),
- );
- }
-
- if let Ok(source_map) = global_state
- .clone()
- .ts_compiler
- .get_source_map_file(&module_specifier)
- {
- println!(
- "{} {}",
- colors::bold("map:".to_string()),
- source_map.filename.to_str().unwrap()
- );
- }
-
- if let Some(deps) = worker.isolate.modules.deps(&module_specifier) {
- println!("{}{}", colors::bold("deps:\n".to_string()), deps.name);
- if let Some(ref depsdeps) = deps.deps {
- for d in depsdeps {
- println!("{}", d);
- }
- }
- } else {
- println!(
- "{} cannot retrieve full dependency graph",
- colors::bold("deps:".to_string()),
- );
- }
-
- Ok(())
-}
-
-fn get_types(unstable: bool) -> String {
- if unstable {
- format!(
- "{}\n{}\n{}\n{}",
- crate::js::DENO_NS_LIB,
- crate::js::SHARED_GLOBALS_LIB,
- crate::js::WINDOW_LIB,
- crate::js::UNSTABLE_NS_LIB,
- )
- } else {
- format!(
- "{}\n{}\n{}",
- crate::js::DENO_NS_LIB,
- crate::js::SHARED_GLOBALS_LIB,
- crate::js::WINDOW_LIB,
- )
- }
-}
-
-async fn info_command(
- flags: Flags,
- file: Option<String>,
-) -> Result<(), ErrBox> {
- let global_state = GlobalState::new(flags)?;
- // If it was just "deno info" print location of caches and exit
- if file.is_none() {
- print_cache_info(&global_state);
- return Ok(());
- }
-
- let main_module = ModuleSpecifier::resolve_url_or_path(&file.unwrap())?;
- let mut worker = create_main_worker(global_state, main_module.clone())?;
- worker.preload_module(&main_module).await?;
- print_file_info(&worker, main_module.clone()).await
-}
-
-async fn install_command(
- flags: Flags,
- module_url: String,
- args: Vec<String>,
- name: Option<String>,
- root: Option<PathBuf>,
- force: bool,
-) -> Result<(), ErrBox> {
- // Firstly fetch and compile module, this step ensures that module exists.
- let mut fetch_flags = flags.clone();
- fetch_flags.reload = true;
- let global_state = GlobalState::new(fetch_flags)?;
- let main_module = ModuleSpecifier::resolve_url_or_path(&module_url)?;
- let mut worker = create_main_worker(global_state, main_module.clone())?;
- worker.preload_module(&main_module).await?;
- installer::install(flags, &module_url, args, name, root, force)
- .map_err(ErrBox::from)
-}
-
-async fn cache_command(flags: Flags, files: Vec<String>) -> Result<(), ErrBox> {
- let main_module =
- ModuleSpecifier::resolve_url_or_path("./__$deno$fetch.ts").unwrap();
- let global_state = GlobalState::new(flags)?;
- let mut worker =
- create_main_worker(global_state.clone(), main_module.clone())?;
-
- for file in files {
- let specifier = ModuleSpecifier::resolve_url_or_path(&file)?;
- worker.preload_module(&specifier).await.map(|_| ())?;
- }
-
- if global_state.flags.lock_write {
- if let Some(ref lockfile) = global_state.lockfile {
- let g = lockfile.lock().unwrap();
- g.write()?;
- } else {
- eprintln!("--lock flag must be specified when using --lock-write");
- std::process::exit(11);
- }
- }
-
- Ok(())
-}
-
-async fn eval_command(
- flags: Flags,
- code: String,
- as_typescript: bool,
-) -> Result<(), ErrBox> {
- // Force TypeScript compile.
- let main_module =
- ModuleSpecifier::resolve_url_or_path("./__$deno$eval.ts").unwrap();
- let global_state = GlobalState::new(flags)?;
- let mut worker = create_main_worker(global_state, main_module.clone())?;
- 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_url: None,
- media_type: if as_typescript {
- MediaType::TypeScript
- } else {
- MediaType::JavaScript
- },
- source_code: code.clone().into_bytes(),
- };
- // Save our fake file into file fetcher cache
- // to allow module access by TS compiler (e.g. op_fetch_source_files)
- worker
- .state
- .borrow()
- .global_state
- .file_fetcher
- .save_source_file_in_cache(&main_module, source_file);
- 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 bundle_command(
- flags: Flags,
- source_file: String,
- out_file: Option<PathBuf>,
-) -> Result<(), ErrBox> {
- let module_name = ModuleSpecifier::resolve_url_or_path(&source_file)?;
- let global_state = GlobalState::new(flags)?;
- debug!(">>>>> bundle START");
- let bundle_result = global_state
- .ts_compiler
- .bundle(global_state.clone(), module_name.to_string(), out_file)
- .await;
- debug!(">>>>> bundle END");
- bundle_result
-}
-
-async fn doc_command(
- flags: Flags,
- source_file: Option<String>,
- json: bool,
- maybe_filter: Option<String>,
-) -> Result<(), ErrBox> {
- let global_state = GlobalState::new(flags.clone())?;
- let source_file = source_file.unwrap_or_else(|| "--builtin".to_string());
-
- impl DocFileLoader for SourceFileFetcher {
- fn load_source_code(
- &self,
- specifier: &str,
- ) -> Pin<Box<dyn Future<Output = Result<String, OpError>>>> {
- let specifier =
- ModuleSpecifier::resolve_url_or_path(specifier).expect("Bad specifier");
- let fetcher = self.clone();
-
- async move {
- let source_file = fetcher
- .fetch_source_file(&specifier, None, Permissions::allow_all())
- .await?;
- String::from_utf8(source_file.source_code)
- .map_err(|_| OpError::other("failed to parse".to_string()))
- }
- .boxed_local()
- }
- }
-
- let loader = Box::new(global_state.file_fetcher.clone());
- let doc_parser = doc::DocParser::new(loader);
-
- let parse_result = if source_file == "--builtin" {
- doc_parser.parse_source("lib.deno.d.ts", get_types(flags.unstable).as_str())
- } else {
- let module_specifier =
- ModuleSpecifier::resolve_url_or_path(&source_file).unwrap();
- doc_parser
- .parse_with_reexports(&module_specifier.to_string())
- .await
- };
-
- let doc_nodes = match parse_result {
- Ok(nodes) => nodes,
- Err(e) => {
- eprintln!("{}", e);
- std::process::exit(1);
- }
- };
-
- if json {
- let writer = std::io::BufWriter::new(std::io::stdout());
- serde_json::to_writer_pretty(writer, &doc_nodes).map_err(ErrBox::from)
- } else {
- let details = if let Some(filter) = maybe_filter {
- let node = doc::find_node_by_name_recursively(doc_nodes, filter.clone());
- if let Some(node) = node {
- doc::printer::format_details(node)
- } else {
- eprintln!("Node {} was not found!", filter);
- std::process::exit(1);
- }
- } else {
- doc::printer::format(doc_nodes)
- };
-
- write_to_stdout_ignore_sigpipe(details.as_bytes()).map_err(ErrBox::from)
- }
-}
-
-async fn run_repl(flags: Flags) -> Result<(), ErrBox> {
- let main_module =
- ModuleSpecifier::resolve_url_or_path("./__$deno$repl.ts").unwrap();
- let global_state = GlobalState::new(flags)?;
- let mut worker = create_main_worker(global_state, main_module)?;
- loop {
- (&mut *worker).await?;
- }
-}
-
-async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
- let global_state = GlobalState::new(flags.clone())?;
- let main_module = ModuleSpecifier::resolve_url_or_path(&script).unwrap();
- let mut worker =
- create_main_worker(global_state.clone(), 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'))")?;
- if global_state.flags.lock_write {
- if let Some(ref lockfile) = global_state.lockfile {
- let g = lockfile.lock().unwrap();
- g.write()?;
- } else {
- eprintln!("--lock flag must be specified when using --lock-write");
- std::process::exit(11);
- }
- }
- Ok(())
-}
-
-async fn test_command(
- flags: Flags,
- include: Option<Vec<String>>,
- fail_fast: bool,
- quiet: bool,
- allow_none: bool,
- filter: Option<String>,
-) -> Result<(), ErrBox> {
- let global_state = GlobalState::new(flags.clone())?;
- let cwd = std::env::current_dir().expect("No current directory");
- let include = include.unwrap_or_else(|| vec![".".to_string()]);
- let test_modules = test_runner::prepare_test_modules_urls(include, &cwd)?;
-
- if test_modules.is_empty() {
- println!("No matching test modules found");
- if !allow_none {
- std::process::exit(1);
- }
- return Ok(());
- }
-
- let test_file_path = cwd.join(".deno.test.ts");
- let test_file_url =
- Url::from_file_path(&test_file_path).expect("Should be valid file url");
- let test_file =
- test_runner::render_test_file(test_modules, fail_fast, quiet, filter);
- let main_module =
- ModuleSpecifier::resolve_url(&test_file_url.to_string()).unwrap();
- let mut worker =
- create_main_worker(global_state.clone(), main_module.clone())?;
- // Create a dummy source file.
- let source_file = SourceFile {
- filename: test_file_url.to_file_path().unwrap(),
- url: test_file_url,
- types_url: None,
- media_type: MediaType::TypeScript,
- source_code: test_file.clone().into_bytes(),
- };
- // Save our fake file into file fetcher cache
- // to allow module access by TS compiler (e.g. op_fetch_source_files)
- worker
- .state
- .borrow()
- .global_state
- .file_fetcher
- .save_source_file_in_cache(&main_module, source_file);
- let execute_result = worker.execute_module(&main_module).await;
- execute_result?;
- worker.execute("window.dispatchEvent(new Event('load'))")?;
- (&mut *worker).await?;
- worker.execute("window.dispatchEvent(new Event('unload'))")
-}
-
-pub fn main() {
- #[cfg(windows)]
- colors::enable_ansi(); // For Windows 10
-
- log::set_logger(&LOGGER).unwrap();
- let args: Vec<String> = env::args().collect();
- let flags = flags::flags_from_vec(args);
-
- if let Some(ref v8_flags) = flags.v8_flags {
- let mut v8_flags_ = v8_flags.clone();
- v8_flags_.insert(0, "UNUSED_BUT_NECESSARY_ARG0".to_string());
- v8_set_flags(v8_flags_);
- }
-
- let log_level = match flags.log_level {
- Some(level) => level,
- None => Level::Info, // Default log level
- };
- log::set_max_level(log_level.to_level_filter());
-
- let fut = match flags.clone().subcommand {
- DenoSubcommand::Bundle {
- source_file,
- out_file,
- } => bundle_command(flags, source_file, out_file).boxed_local(),
- DenoSubcommand::Doc {
- source_file,
- json,
- filter,
- } => doc_command(flags, source_file, json, filter).boxed_local(),
- DenoSubcommand::Eval {
- code,
- as_typescript,
- } => eval_command(flags, code, as_typescript).boxed_local(),
- DenoSubcommand::Cache { files } => {
- cache_command(flags, files).boxed_local()
- }
- DenoSubcommand::Fmt { check, files } => {
- fmt::format(files, check).boxed_local()
- }
- DenoSubcommand::Info { file } => info_command(flags, file).boxed_local(),
- DenoSubcommand::Install {
- module_url,
- args,
- name,
- root,
- force,
- } => {
- install_command(flags, module_url, args, name, root, force).boxed_local()
- }
- DenoSubcommand::Repl => run_repl(flags).boxed_local(),
- DenoSubcommand::Run { script } => run_command(flags, script).boxed_local(),
- DenoSubcommand::Test {
- fail_fast,
- quiet,
- include,
- allow_none,
- filter,
- } => test_command(flags, include, fail_fast, quiet, allow_none, filter)
- .boxed_local(),
- DenoSubcommand::Completions { buf } => {
- if let Err(e) = write_to_stdout_ignore_sigpipe(&buf) {
- eprintln!("{}", e);
- std::process::exit(1);
- }
- return;
- }
- DenoSubcommand::Types => {
- let types = get_types(flags.unstable);
- if let Err(e) = write_to_stdout_ignore_sigpipe(types.as_bytes()) {
- eprintln!("{}", e);
- std::process::exit(1);
- }
- return;
- }
- DenoSubcommand::Upgrade {
- force,
- dry_run,
- version,
- } => upgrade_command(dry_run, force, version).boxed_local(),
- _ => unreachable!(),
- };
-
- let result = tokio_util::run_basic(fut);
- if let Err(err) = result {
- let msg = format!(
- "{}: {}",
- colors::red_bold("error".to_string()),
- err.to_string(),
- );
- eprintln!("{}", msg);
- std::process::exit(1);
- }
-}