2024-01-01 14:58:21 -05:00
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2019-09-03 22:12:21 -04:00
2022-06-27 16:54:09 -04:00
mod args ;
2021-02-15 21:50:27 -05:00
mod auth_tokens ;
2021-10-10 17:26:22 -04:00
mod cache ;
2023-11-05 17:58:59 -05:00
mod cdp ;
2021-10-10 17:26:22 -04:00
mod emit ;
2020-10-12 07:25:25 -04:00
mod errors ;
2023-05-01 14:35:23 -04:00
mod factory ;
2020-05-11 17:33:36 -04:00
mod file_fetcher ;
2024-05-16 03:09:35 -04:00
mod graph_container ;
2021-12-16 05:45:41 -05:00
mod graph_util ;
2020-05-11 17:33:36 -04:00
mod http_util ;
2022-11-21 08:36:26 -05:00
mod js ;
2024-03-01 16:34:13 -05:00
mod jsr ;
2020-12-07 05:46:39 -05:00
mod lsp ;
2020-10-13 07:35:35 -04:00
mod module_loader ;
2024-07-22 20:01:31 -04:00
mod napi ;
2022-08-20 11:31:33 -04:00
mod node ;
2022-08-10 15:23:58 -04:00
mod npm ;
2020-10-12 07:25:25 -04:00
mod ops ;
2021-10-10 17:26:22 -04:00
mod resolver ;
2024-08-15 15:59:16 -04:00
mod shared ;
2020-11-30 14:35:12 -05:00
mod standalone ;
2024-07-09 23:06:08 -04:00
mod task_runner ;
2020-11-19 13:19:34 -05:00
mod tools ;
2020-11-02 14:41:20 -05:00
mod tsc ;
2022-11-28 17:28:54 -05:00
mod util ;
2020-10-12 07:25:25 -04:00
mod version ;
2022-08-11 16:59:12 -04:00
mod worker ;
2020-05-11 17:33:36 -04:00
2022-06-27 16:54:09 -04:00
use crate ::args ::flags_from_vec ;
use crate ::args ::DenoSubcommand ;
use crate ::args ::Flags ;
2022-11-28 17:28:54 -05:00
use crate ::util ::display ;
2023-01-24 23:03:03 -05:00
use crate ::util ::v8 ::get_v8_flags_from_env ;
use crate ::util ::v8 ::init_v8_flags ;
2022-06-27 16:54:09 -04:00
2024-08-06 11:05:30 -04:00
use args ::TaskFlags ;
2024-04-24 15:45:49 -04:00
use deno_runtime ::WorkerExecutionMode ;
2024-01-23 09:33:07 -05:00
pub use deno_runtime ::UNSTABLE_GRANULAR_FLAGS ;
2022-12-09 09:40:48 -05:00
use deno_core ::anyhow ::Context ;
2020-09-14 12:48:57 -04:00
use deno_core ::error ::AnyError ;
2022-04-26 19:06:10 -04:00
use deno_core ::error ::JsError ;
2023-05-17 17:49:57 -04:00
use deno_core ::futures ::FutureExt ;
2023-08-23 19:03:05 -04:00
use deno_core ::unsync ::JoinHandle ;
2024-01-22 16:31:12 -05:00
use deno_npm ::resolution ::SnapshotFromLockfileError ;
2024-09-05 08:49:07 -04:00
use deno_runtime ::fmt_errors ::format_js_error_with_suggestions ;
use deno_runtime ::fmt_errors ::FixSuggestion ;
2023-06-09 07:52:51 -04:00
use deno_runtime ::tokio_util ::create_and_run_current_thread_with_maybe_metrics ;
2024-02-07 11:25:14 -05:00
use deno_terminal ::colors ;
2023-05-01 14:35:23 -04:00
use factory ::CliFactory ;
2024-08-06 11:05:30 -04:00
use standalone ::MODULE_NOT_FOUND ;
2024-08-27 05:27:10 -04:00
use standalone ::UNSUPPORTED_SCHEME ;
2020-05-11 17:33:36 -04:00
use std ::env ;
2023-05-17 17:49:57 -04:00
use std ::future ::Future ;
2024-08-06 11:05:30 -04:00
use std ::ops ::Deref ;
2020-05-11 17:33:36 -04:00
use std ::path ::PathBuf ;
2024-07-23 19:00:48 -04:00
use std ::sync ::Arc ;
2022-02-16 13:14:19 -05:00
2023-05-17 17:49:57 -04:00
/// Ensures that all subcommands return an i32 exit code and an [`AnyError`] error type.
trait SubcommandOutput {
fn output ( self ) -> Result < i32 , AnyError > ;
}
impl SubcommandOutput for Result < i32 , AnyError > {
fn output ( self ) -> Result < i32 , AnyError > {
self
}
}
impl SubcommandOutput for Result < ( ) , AnyError > {
fn output ( self ) -> Result < i32 , AnyError > {
self . map ( | _ | 0 )
}
}
impl SubcommandOutput for Result < ( ) , std ::io ::Error > {
fn output ( self ) -> Result < i32 , AnyError > {
self . map ( | _ | 0 ) . map_err ( | e | e . into ( ) )
}
}
/// Ensure that the subcommand runs in a task, rather than being directly executed. Since some of these
/// futures are very large, this prevents the stack from getting blown out from passing them by value up
/// the callchain (especially in debug mode when Rust doesn't have a chance to elide copies!).
#[ inline(always) ]
fn spawn_subcommand < F : Future < Output = T > + 'static , T : SubcommandOutput > (
f : F ,
) -> JoinHandle < Result < i32 , AnyError > > {
2023-09-30 12:06:38 -04:00
// the boxed_local() is important in order to get windows to not blow the stack in debug
deno_core ::unsync ::spawn (
async move { f . map ( | r | r . output ( ) ) . await } . boxed_local ( ) ,
)
2023-05-17 17:49:57 -04:00
}
2024-07-23 19:00:48 -04:00
async fn run_subcommand ( flags : Arc < Flags > ) -> Result < i32 , AnyError > {
2023-05-17 17:49:57 -04:00
let handle = match flags . subcommand . clone ( ) {
2024-02-29 14:12:04 -05:00
DenoSubcommand ::Add ( add_flags ) = > spawn_subcommand ( async {
2024-08-09 10:29:11 -04:00
tools ::registry ::add ( flags , add_flags , tools ::registry ::AddCommandName ::Add ) . await
2024-02-29 14:12:04 -05:00
} ) ,
2024-08-12 16:17:25 -04:00
DenoSubcommand ::Remove ( remove_flags ) = > spawn_subcommand ( async {
tools ::registry ::remove ( flags , remove_flags ) . await
} ) ,
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Bench ( bench_flags ) = > spawn_subcommand ( async {
2023-06-15 13:09:37 -04:00
if bench_flags . watch . is_some ( ) {
2023-06-14 18:29:19 -04:00
tools ::bench ::run_benchmarks_with_watch ( flags , bench_flags ) . await
2022-12-09 09:40:48 -05:00
} else {
2023-06-14 18:29:19 -04:00
tools ::bench ::run_benchmarks ( flags , bench_flags ) . await
2022-12-09 09:40:48 -05:00
}
2023-05-17 17:49:57 -04:00
} ) ,
2024-09-02 11:27:37 -04:00
DenoSubcommand ::Bundle = > exit_with_message ( " ⚠️ `deno bundle` was removed in Deno 2. \n \n See the Deno 1.x to 2.x Migration Guide for migration instructions: https://docs.deno.com/runtime/manual/advanced/migrate_deprecations " , 1 ) ,
2021-09-03 19:33:35 -04:00
DenoSubcommand ::Doc ( doc_flags ) = > {
2023-11-01 11:25:05 -04:00
spawn_subcommand ( async { tools ::doc ::doc ( flags , doc_flags ) . await } )
2021-09-03 19:33:35 -04:00
}
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Eval ( eval_flags ) = > spawn_subcommand ( async {
2022-12-09 09:40:48 -05:00
tools ::run ::eval_command ( flags , eval_flags ) . await
2023-05-17 17:49:57 -04:00
} ) ,
DenoSubcommand ::Cache ( cache_flags ) = > spawn_subcommand ( async move {
2024-09-04 16:06:16 -04:00
tools ::installer ::install_from_entrypoints ( flags , & cache_flags . files ) . await
2023-05-17 17:49:57 -04:00
} ) ,
DenoSubcommand ::Check ( check_flags ) = > spawn_subcommand ( async move {
2024-07-23 19:00:48 -04:00
let factory = CliFactory ::from_flags ( flags ) ;
2024-05-16 03:09:35 -04:00
let main_graph_container =
factory . main_module_graph_container ( ) . await ? ;
main_graph_container
2023-04-14 16:22:33 -04:00
. load_and_type_check_files ( & check_flags . files )
2023-05-17 17:49:57 -04:00
. await
} ) ,
2024-08-08 09:22:18 -04:00
DenoSubcommand ::Clean = > spawn_subcommand ( async move {
2024-08-14 07:04:07 -04:00
tools ::clean ::clean ( )
2024-08-08 09:22:18 -04:00
} ) ,
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Compile ( compile_flags ) = > spawn_subcommand ( async {
tools ::compile ::compile ( flags , compile_flags ) . await
} ) ,
DenoSubcommand ::Coverage ( coverage_flags ) = > spawn_subcommand ( async {
tools ::coverage ::cover_files ( flags , coverage_flags ) . await
} ) ,
2023-06-14 18:29:19 -04:00
DenoSubcommand ::Fmt ( fmt_flags ) = > {
spawn_subcommand (
async move { tools ::fmt ::format ( flags , fmt_flags ) . await } ,
)
}
2022-08-19 19:37:05 -04:00
DenoSubcommand ::Init ( init_flags ) = > {
2024-03-11 23:48:00 -04:00
spawn_subcommand ( async {
// make compiler happy since init_project is sync
tokio ::task ::yield_now ( ) . await ;
tools ::init ::init_project ( init_flags )
} )
2022-08-19 19:37:05 -04:00
}
2021-09-03 19:33:35 -04:00
DenoSubcommand ::Info ( info_flags ) = > {
2023-05-17 17:49:57 -04:00
spawn_subcommand ( async { tools ::info ::info ( flags , info_flags ) . await } )
}
DenoSubcommand ::Install ( install_flags ) = > spawn_subcommand ( async {
tools ::installer ::install_command ( flags , install_flags ) . await
} ) ,
2024-08-12 11:55:33 -04:00
DenoSubcommand ::JSONReference ( json_reference ) = > spawn_subcommand ( async move {
display ::write_to_stdout_ignore_sigpipe ( & deno_core ::serde_json ::to_vec_pretty ( & json_reference . json ) . unwrap ( ) )
} ) ,
2023-09-15 20:42:09 -04:00
DenoSubcommand ::Jupyter ( jupyter_flags ) = > spawn_subcommand ( async {
tools ::jupyter ::kernel ( flags , jupyter_flags ) . await
} ) ,
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Uninstall ( uninstall_flags ) = > spawn_subcommand ( async {
2024-09-05 07:51:37 -04:00
tools ::installer ::uninstall ( flags , uninstall_flags ) . await
2023-05-17 17:49:57 -04:00
} ) ,
DenoSubcommand ::Lsp = > spawn_subcommand ( async { lsp ::start ( ) . await } ) ,
DenoSubcommand ::Lint ( lint_flags ) = > spawn_subcommand ( async {
2022-12-09 09:40:48 -05:00
if lint_flags . rules {
2023-07-25 17:24:06 -04:00
tools ::lint ::print_rules_list (
lint_flags . json ,
lint_flags . maybe_rules_tags ,
) ;
2023-05-17 17:49:57 -04:00
Ok ( ( ) )
2022-12-09 09:40:48 -05:00
} else {
2023-06-14 18:29:19 -04:00
tools ::lint ::lint ( flags , lint_flags ) . await
2022-12-09 09:40:48 -05:00
}
2023-05-17 17:49:57 -04:00
} ) ,
2021-09-03 19:33:35 -04:00
DenoSubcommand ::Repl ( repl_flags ) = > {
2023-05-17 17:49:57 -04:00
spawn_subcommand ( async move { tools ::repl ::run ( flags , repl_flags ) . await } )
2021-09-03 19:33:35 -04:00
}
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Run ( run_flags ) = > spawn_subcommand ( async move {
2022-12-09 09:40:48 -05:00
if run_flags . is_stdin ( ) {
2024-08-06 11:05:30 -04:00
tools ::run ::run_from_stdin ( flags . clone ( ) ) . await
2022-12-09 09:40:48 -05:00
} else {
2024-08-06 11:05:30 -04:00
let result = tools ::run ::run_script ( WorkerExecutionMode ::Run , flags . clone ( ) , run_flags . watch ) . await ;
2024-08-12 11:55:33 -04:00
match result {
Ok ( v ) = > Ok ( v ) ,
Err ( script_err ) = > {
2024-08-27 05:27:10 -04:00
let script_err_msg = script_err . to_string ( ) ;
if script_err_msg . starts_with ( MODULE_NOT_FOUND ) | | script_err_msg . starts_with ( UNSUPPORTED_SCHEME ) {
2024-08-12 11:55:33 -04:00
if run_flags . bare {
let mut cmd = args ::clap_root ( ) ;
cmd . build ( ) ;
let command_names = cmd . get_subcommands ( ) . map ( | command | command . get_name ( ) ) . collect ::< Vec < _ > > ( ) ;
let suggestions = args ::did_you_mean ( & run_flags . script , command_names ) ;
if ! suggestions . is_empty ( ) {
let mut error = clap ::error ::Error ::< clap ::error ::DefaultFormatter > ::new ( clap ::error ::ErrorKind ::InvalidSubcommand ) . with_cmd ( & cmd ) ;
error . insert (
clap ::error ::ContextKind ::SuggestedSubcommand ,
clap ::error ::ContextValue ::Strings ( suggestions ) ,
) ;
Err ( error . into ( ) )
} else {
2024-08-06 11:05:30 -04:00
Err ( script_err )
2024-08-12 11:55:33 -04:00
}
} else {
let mut new_flags = flags . deref ( ) . clone ( ) ;
let task_flags = TaskFlags {
cwd : None ,
task : Some ( run_flags . script . clone ( ) ) ,
2024-08-21 09:54:59 -04:00
is_run : true ,
2024-08-12 11:55:33 -04:00
} ;
new_flags . subcommand = DenoSubcommand ::Task ( task_flags . clone ( ) ) ;
2024-08-21 09:54:59 -04:00
let result = tools ::task ::execute_script ( Arc ::new ( new_flags ) , task_flags . clone ( ) ) . await ;
2024-08-12 11:55:33 -04:00
match result {
Ok ( v ) = > Ok ( v ) ,
Err ( _ ) = > {
// Return script error for backwards compatibility.
Err ( script_err )
}
}
2024-08-06 11:05:30 -04:00
}
2024-08-12 11:55:33 -04:00
} else {
Err ( script_err )
2024-08-06 11:05:30 -04:00
}
}
2024-08-12 11:55:33 -04:00
}
2022-12-09 09:40:48 -05:00
}
2023-05-17 17:49:57 -04:00
} ) ,
2024-04-24 15:45:49 -04:00
DenoSubcommand ::Serve ( serve_flags ) = > spawn_subcommand ( async move {
2024-08-14 18:26:21 -04:00
tools ::serve ::serve ( flags , serve_flags ) . await
2024-04-24 15:45:49 -04:00
} ) ,
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Task ( task_flags ) = > spawn_subcommand ( async {
2024-08-21 09:54:59 -04:00
tools ::task ::execute_script ( flags , task_flags ) . await
2023-05-17 17:49:57 -04:00
} ) ,
2021-09-03 19:33:35 -04:00
DenoSubcommand ::Test ( test_flags ) = > {
2023-05-17 17:49:57 -04:00
spawn_subcommand ( async {
2023-06-15 13:09:37 -04:00
if let Some ( ref coverage_dir ) = test_flags . coverage_dir {
2024-05-22 23:04:12 -04:00
if test_flags . clean {
let _ = std ::fs ::remove_dir_all ( coverage_dir ) ;
}
2023-05-17 17:49:57 -04:00
std ::fs ::create_dir_all ( coverage_dir )
. with_context ( | | format! ( " Failed creating: {coverage_dir} " ) ) ? ;
// this is set in order to ensure spawned processes use the same
// coverage directory
env ::set_var (
" DENO_UNSTABLE_COVERAGE_DIR " ,
PathBuf ::from ( coverage_dir ) . canonicalize ( ) ? ,
) ;
}
2022-12-09 09:40:48 -05:00
2023-06-15 13:09:37 -04:00
if test_flags . watch . is_some ( ) {
2023-06-14 18:29:19 -04:00
tools ::test ::run_tests_with_watch ( flags , test_flags ) . await
2023-05-17 17:49:57 -04:00
} else {
2023-06-14 18:29:19 -04:00
tools ::test ::run_tests ( flags , test_flags ) . await
2023-05-17 17:49:57 -04:00
}
} )
2021-09-03 19:33:35 -04:00
}
2021-12-21 09:49:27 -05:00
DenoSubcommand ::Completions ( completions_flags ) = > {
2023-05-17 17:49:57 -04:00
spawn_subcommand ( async move {
display ::write_to_stdout_ignore_sigpipe ( & completions_flags . buf )
} )
2022-12-09 09:40:48 -05:00
}
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Types = > spawn_subcommand ( async move {
2024-01-14 12:29:17 -05:00
let types = tsc ::get_types_declaration_file_text ( ) ;
2023-05-17 17:49:57 -04:00
display ::write_to_stdout_ignore_sigpipe ( types . as_bytes ( ) )
} ) ,
2023-11-29 13:52:25 -05:00
#[ cfg(feature = " upgrade " ) ]
2023-05-17 17:49:57 -04:00
DenoSubcommand ::Upgrade ( upgrade_flags ) = > spawn_subcommand ( async {
tools ::upgrade ::upgrade ( flags , upgrade_flags ) . await
} ) ,
2023-11-29 13:52:25 -05:00
#[ cfg(not(feature = " upgrade " )) ]
DenoSubcommand ::Upgrade ( _ ) = > exit_with_message (
" This deno was built without the \" upgrade \" feature. Please upgrade using the installation method originally used to install Deno. " ,
1 ,
) ,
2024-09-03 03:00:57 -04:00
DenoSubcommand ::Vendor = > exit_with_message ( " ⚠️ `deno vendor` was removed in Deno 2. \n \n See the Deno 1.x to 2.x Migration Guide for migration instructions: https://docs.deno.com/runtime/manual/advanced/migrate_deprecations " , 1 ) ,
2023-11-23 18:38:07 -05:00
DenoSubcommand ::Publish ( publish_flags ) = > spawn_subcommand ( async {
tools ::registry ::publish ( flags , publish_flags ) . await
} ) ,
2024-08-12 11:55:33 -04:00
DenoSubcommand ::Help ( help_flags ) = > spawn_subcommand ( async move {
2024-08-21 09:54:59 -04:00
use std ::io ::Write ;
let mut stream = anstream ::AutoStream ::new ( std ::io ::stdout ( ) , if colors ::use_color ( ) {
anstream ::ColorChoice ::Auto
} else {
anstream ::ColorChoice ::Never
} ) ;
match stream . write_all ( help_flags . help . ansi ( ) . to_string ( ) . as_bytes ( ) ) {
Ok ( ( ) ) = > Ok ( ( ) ) ,
Err ( e ) = > match e . kind ( ) {
std ::io ::ErrorKind ::BrokenPipe = > Ok ( ( ) ) ,
_ = > Err ( e ) ,
} ,
}
2024-08-12 11:55:33 -04:00
} ) ,
2023-05-17 17:49:57 -04:00
} ;
handle . await ?
2020-11-26 09:17:45 -05:00
}
2024-05-08 22:45:06 -04:00
#[ allow(clippy::print_stderr) ]
2021-12-20 08:49:05 -05:00
fn setup_panic_hook ( ) {
// This function does two things inside of the panic hook:
// - Tokio does not exit the process when a task panics, so we define a custom
// panic hook to implement this behaviour.
// - We print a message to stderr to indicate that this is a bug in Deno, and
// should be reported to us.
2021-09-07 19:34:27 -04:00
let orig_hook = std ::panic ::take_hook ( ) ;
std ::panic ::set_hook ( Box ::new ( move | panic_info | {
2021-12-20 08:49:05 -05:00
eprintln! ( " \n ============================================================ " ) ;
eprintln! ( " Deno has panicked. This is a bug in Deno. Please report this " ) ;
eprintln! ( " at https://github.com/denoland/deno/issues/new. " ) ;
eprintln! ( " If you can reliably reproduce this panic, include the " ) ;
eprintln! ( " reproduction steps and re-run with the RUST_BACKTRACE=1 env " ) ;
eprintln! ( " var set and include the backtrace in your report. " ) ;
eprintln! ( ) ;
2022-07-14 17:52:44 -04:00
eprintln! ( " Platform: {} {} " , env ::consts ::OS , env ::consts ::ARCH ) ;
2024-08-15 17:47:16 -04:00
eprintln! ( " Version: {} " , version ::DENO_VERSION_INFO . deno ) ;
2022-07-14 17:52:44 -04:00
eprintln! ( " Args: {:?} " , env ::args ( ) . collect ::< Vec < _ > > ( ) ) ;
2021-12-20 08:49:05 -05:00
eprintln! ( ) ;
2021-09-07 19:34:27 -04:00
orig_hook ( panic_info ) ;
std ::process ::exit ( 1 ) ;
} ) ) ;
}
2024-05-08 22:45:06 -04:00
#[ allow(clippy::print_stderr) ]
2023-11-29 13:52:25 -05:00
fn exit_with_message ( message : & str , code : i32 ) -> ! {
eprintln! (
" {}: {} " ,
colors ::red_bold ( " error " ) ,
message . trim_start_matches ( " error: " )
) ;
std ::process ::exit ( code ) ;
}
2024-09-09 16:51:55 -04:00
fn get_suggestions_for_terminal_errors ( e : & JsError ) -> Vec < FixSuggestion > {
if let Some ( msg ) = & e . message {
if msg . contains ( " module is not defined " )
| | msg . contains ( " exports is not defined " )
{
return vec! [
FixSuggestion ::info (
" Deno does not support CommonJS modules without `.cjs` extension. " ,
) ,
FixSuggestion ::hint (
" Rewrite this module to ESM or change the file extension to `.cjs`. " ,
) ,
] ;
} else if msg . contains ( " openKv is not a function " ) {
return vec! [
FixSuggestion ::info ( " Deno.openKv() is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-kv` flag to enable this API. " ,
) ,
] ;
} else if msg . contains ( " cron is not a function " ) {
return vec! [
FixSuggestion ::info ( " Deno.cron() is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-cron` flag to enable this API. " ,
) ,
] ;
} else if msg . contains ( " createHttpClient is not a function " ) {
return vec! [
FixSuggestion ::info ( " Deno.createHttpClient() is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-http` flag to enable this API. " ,
) ,
] ;
} else if msg . contains ( " WebSocketStream is not defined " ) {
return vec! [
FixSuggestion ::info ( " new WebSocketStream() is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-net` flag to enable this API. " ,
) ,
] ;
} else if msg . contains ( " Temporal is not defined " ) {
return vec! [
FixSuggestion ::info ( " Temporal is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-temporal` flag to enable this API. " ,
) ,
] ;
} else if msg . contains ( " BroadcastChannel is not defined " ) {
return vec! [
FixSuggestion ::info ( " BroadcastChannel is an unstable API. " ) ,
FixSuggestion ::hint (
" Run again with `--unstable-broadcast-channel` flag to enable this API. " ,
) ,
] ;
2024-09-05 08:49:07 -04:00
}
}
vec! [ ]
}
2024-03-31 10:58:19 -04:00
fn exit_for_error ( error : AnyError ) -> ! {
let mut error_string = format! ( " {error:?} " ) ;
let mut error_code = 1 ;
2022-10-25 12:20:07 -04:00
2024-03-31 10:58:19 -04:00
if let Some ( e ) = error . downcast_ref ::< JsError > ( ) {
2024-09-09 16:51:55 -04:00
let suggestions = get_suggestions_for_terminal_errors ( e ) ;
2024-09-05 08:49:07 -04:00
error_string = format_js_error_with_suggestions ( e , suggestions ) ;
2024-03-31 10:58:19 -04:00
} else if let Some ( SnapshotFromLockfileError ::IntegrityCheckFailed ( e ) ) =
error . downcast_ref ::< SnapshotFromLockfileError > ( )
{
error_string = e . to_string ( ) ;
error_code = 10 ;
2021-01-07 13:06:08 -05:00
}
2024-03-31 10:58:19 -04:00
exit_with_message ( & error_string , error_code ) ;
2021-01-07 13:06:08 -05:00
}
2024-05-08 22:45:06 -04:00
#[ allow(clippy::print_stderr) ]
2024-01-23 09:33:07 -05:00
pub ( crate ) fn unstable_exit_cb ( feature : & str , api_name : & str ) {
eprintln! (
" Unstable API '{api_name}'. The `--unstable-{}` flag must be provided. " ,
feature
) ;
2023-10-12 11:55:50 -04:00
std ::process ::exit ( 70 ) ;
}
2024-01-23 09:33:07 -05:00
// TODO(bartlomieju): remove when `--unstable` flag is removed.
2024-05-08 22:45:06 -04:00
#[ allow(clippy::print_stderr) ]
2024-01-23 09:33:07 -05:00
pub ( crate ) fn unstable_warn_cb ( feature : & str , api_name : & str ) {
2023-10-12 11:55:50 -04:00
eprintln! (
2024-01-23 09:33:07 -05:00
" ⚠️ {} " ,
colors ::yellow ( format! (
" The `{}` API was used with `--unstable` flag. The `--unstable` flag is deprecated and will be removed in Deno 2.0. Use granular `--unstable-{}` instead. \n Learn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags " ,
api_name , feature
) )
2023-10-12 11:55:50 -04:00
) ;
}
2020-11-26 09:17:45 -05:00
pub fn main ( ) {
2021-12-20 08:49:05 -05:00
setup_panic_hook ( ) ;
2021-10-25 11:16:16 -04:00
2022-11-28 17:28:54 -05:00
util ::unix ::raise_fd_limit ( ) ;
util ::windows ::ensure_stdio_open ( ) ;
2020-11-26 09:17:45 -05:00
#[ cfg(windows) ]
colors ::enable_ansi ( ) ; // For Windows 10
2024-06-06 23:37:53 -04:00
deno_runtime ::deno_permissions ::set_prompt_callbacks (
2022-12-19 14:31:19 -05:00
Box ::new ( util ::draw_thread ::DrawThread ::hide ) ,
Box ::new ( util ::draw_thread ::DrawThread ::show ) ,
) ;
2020-11-26 09:17:45 -05:00
2024-03-22 17:03:56 -04:00
let args : Vec < _ > = env ::args_os ( ) . collect ( ) ;
2022-12-09 09:40:48 -05:00
let future = async move {
2024-05-26 00:13:20 -04:00
// NOTE(lucacasonato): due to new PKU feature introduced in V8 11.6 we need to
// initialize the V8 platform on a parent thread of all threads that will spawn
// V8 isolates.
let flags = resolve_flags_and_init ( args ) ? ;
2024-07-23 19:00:48 -04:00
run_subcommand ( Arc ::new ( flags ) ) . await
2024-03-31 10:58:19 -04:00
} ;
2024-01-23 09:33:07 -05:00
2024-03-31 10:58:19 -04:00
match create_and_run_current_thread_with_maybe_metrics ( future ) {
Ok ( exit_code ) = > std ::process ::exit ( exit_code ) ,
Err ( err ) = > exit_for_error ( err ) ,
}
}
2021-05-11 00:54:10 -04:00
2024-03-31 10:58:19 -04:00
fn resolve_flags_and_init (
args : Vec < std ::ffi ::OsString > ,
) -> Result < Flags , AnyError > {
let flags = match flags_from_vec ( args ) {
Ok ( flags ) = > flags ,
Err ( err @ clap ::Error { .. } )
2024-08-18 18:39:53 -04:00
if err . kind ( ) = = clap ::error ::ErrorKind ::DisplayVersion = >
2024-03-31 10:58:19 -04:00
{
2024-07-09 18:57:00 -04:00
// Ignore results to avoid BrokenPipe errors.
let _ = err . print ( ) ;
2024-03-31 10:58:19 -04:00
std ::process ::exit ( 0 ) ;
}
Err ( err ) = > exit_for_error ( AnyError ::from ( err ) ) ,
} ;
2024-09-09 17:44:29 -04:00
// TODO(bartlomieju): remove in Deno v2.5 and hard error then.
2024-03-31 10:58:19 -04:00
if flags . unstable_config . legacy_flag_enabled {
2024-09-09 17:44:29 -04:00
log ::warn! (
" ⚠️ {} " ,
colors ::yellow (
" The `--unstable` flag has been removed in Deno 2.0. Use granular `--unstable-*` flags instead. \n Learn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags "
)
) ;
2024-03-31 10:58:19 -04:00
}
2022-02-15 07:33:46 -05:00
2024-03-31 10:58:19 -04:00
let default_v8_flags = match flags . subcommand {
// Using same default as VSCode:
// https://github.com/microsoft/vscode/blob/48d4ba271686e8072fc6674137415bc80d936bc7/extensions/typescript-language-features/src/configuration/configuration.ts#L213-L214
DenoSubcommand ::Lsp = > vec! [ " --max-old-space-size=3072 " . to_string ( ) ] ,
2024-04-29 16:43:05 -04:00
_ = > {
2024-08-30 17:58:24 -04:00
// TODO(bartlomieju): I think this can be removed as it's handled by `deno_core`
// and its settings.
// deno_ast removes TypeScript `assert` keywords, so this flag only affects JavaScript
// TODO(petamoriken): Need to check TypeScript `assert` keywords in deno_ast
vec! [ " --no-harmony-import-assertions " . to_string ( ) ]
2024-04-29 16:43:05 -04:00
}
2022-02-15 07:33:46 -05:00
} ;
2020-05-11 17:33:36 -04:00
2024-03-31 10:58:19 -04:00
init_v8_flags ( & default_v8_flags , & flags . v8_flags , get_v8_flags_from_env ( ) ) ;
2024-08-19 16:36:35 -04:00
// TODO(bartlomieju): remove last argument in Deno 2.
2024-08-30 17:58:24 -04:00
deno_core ::JsRuntime ::init_platform (
None , /* import assertions enabled */ false ,
) ;
2024-03-31 10:58:19 -04:00
util ::logger ::init ( flags . log_level ) ;
2021-11-27 18:45:38 -05:00
2024-03-31 10:58:19 -04:00
Ok ( flags )
2018-06-15 19:43:23 -04:00
}