1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

refactor: cleanup main entrypoint (#23145)

This commit is contained in:
David Sherret 2024-03-31 10:58:19 -04:00 committed by GitHub
parent 05598af36e
commit eb6f6ff33d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 98 additions and 87 deletions

View file

@ -45,6 +45,7 @@ use deno_runtime::fmt_errors::format_js_error;
use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics; use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
use deno_terminal::colors; use deno_terminal::colors;
use factory::CliFactory; use factory::CliFactory;
use std::borrow::Cow;
use std::env; use std::env;
use std::env::current_exe; use std::env::current_exe;
use std::future::Future; use std::future::Future;
@ -262,30 +263,25 @@ fn exit_with_message(message: &str, code: i32) -> ! {
std::process::exit(code); std::process::exit(code);
} }
fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T { fn exit_for_error(error: AnyError) -> ! {
match result { let mut error_string = format!("{error:?}");
Ok(value) => value, let mut error_code = 1;
Err(error) => {
let mut error_string = format!("{error:?}");
let mut error_code = 1;
if let Some(e) = error.downcast_ref::<JsError>() { if let Some(e) = error.downcast_ref::<JsError>() {
error_string = format_js_error(e); error_string = format_js_error(e);
} else if let Some(args::LockfileError::IntegrityCheckFailed(e)) = } else if let Some(args::LockfileError::IntegrityCheckFailed(e)) =
error.downcast_ref::<args::LockfileError>() error.downcast_ref::<args::LockfileError>()
{ {
error_string = e.to_string(); error_string = e.to_string();
error_code = 10; error_code = 10;
} else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) = } else if let Some(SnapshotFromLockfileError::IntegrityCheckFailed(e)) =
error.downcast_ref::<SnapshotFromLockfileError>() error.downcast_ref::<SnapshotFromLockfileError>()
{ {
error_string = e.to_string(); error_string = e.to_string();
error_code = 10; error_code = 10;
}
exit_with_message(&error_string, error_code);
}
} }
exit_with_message(&error_string, error_code);
} }
pub(crate) fn unstable_exit_cb(feature: &str, api_name: &str) { pub(crate) fn unstable_exit_cb(feature: &str, api_name: &str) {
@ -320,73 +316,81 @@ pub fn main() {
); );
let args: Vec<_> = env::args_os().collect(); let args: Vec<_> = env::args_os().collect();
// 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 current_exe_path = current_exe().unwrap(); let current_exe_path = current_exe().unwrap();
let standalone = let maybe_standalone = match standalone::extract_standalone(
standalone::extract_standalone(&current_exe_path, args.clone()); &current_exe_path,
Cow::Borrowed(&args),
) {
Ok(standalone) => standalone,
Err(err) => exit_for_error(err),
};
let future = async move { let future = async move {
let standalone_res = match standalone { match maybe_standalone {
Ok(Some(future)) => { Some(future) => {
let (metadata, eszip) = future.await?; let (metadata, eszip) = future.await?;
standalone::run(eszip, metadata).await standalone::run(eszip, metadata).await
} }
Ok(None) => Ok(()), None => {
Err(err) => Err(err), // 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
// TODO(bartlomieju): doesn't handle exit code set by the runtime properly // V8 isolates.
unwrap_or_exit(standalone_res); let flags = resolve_flags_and_init(args)?;
run_subcommand(flags).await
let flags = match flags_from_vec(args) {
Ok(flags) => flags,
Err(err @ clap::Error { .. })
if err.kind() == clap::error::ErrorKind::DisplayHelp
|| err.kind() == clap::error::ErrorKind::DisplayVersion =>
{
err.print().unwrap();
std::process::exit(0);
}
Err(err) => unwrap_or_exit(Err(AnyError::from(err))),
};
// TODO(bartlomieju): remove when `--unstable` flag is removed.
if flags.unstable_config.legacy_flag_enabled {
if matches!(flags.subcommand, DenoSubcommand::Check(_)) {
eprintln!(
"⚠️ {}",
colors::yellow(
"The `--unstable` flag is not needed for `deno check` anymore."
)
);
} else {
eprintln!(
"⚠️ {}",
colors::yellow(
"The `--unstable` flag is deprecated and will be removed in Deno 2.0. Use granular `--unstable-*` flags instead.\nLearn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags"
)
);
} }
} }
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()],
_ => vec![],
};
init_v8_flags(&default_v8_flags, &flags.v8_flags, get_v8_flags_from_env());
deno_core::JsRuntime::init_platform(None);
util::logger::init(flags.log_level);
run_subcommand(flags).await
}; };
let exit_code = match create_and_run_current_thread_with_maybe_metrics(future) {
unwrap_or_exit(create_and_run_current_thread_with_maybe_metrics(future)); Ok(exit_code) => std::process::exit(exit_code),
Err(err) => exit_for_error(err),
std::process::exit(exit_code); }
}
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 { .. })
if err.kind() == clap::error::ErrorKind::DisplayHelp
|| err.kind() == clap::error::ErrorKind::DisplayVersion =>
{
err.print().unwrap();
std::process::exit(0);
}
Err(err) => exit_for_error(AnyError::from(err)),
};
// TODO(bartlomieju): remove when `--unstable` flag is removed.
if flags.unstable_config.legacy_flag_enabled {
if matches!(flags.subcommand, DenoSubcommand::Check(_)) {
eprintln!(
"⚠️ {}",
colors::yellow(
"The `--unstable` flag is not needed for `deno check` anymore."
)
);
} else {
eprintln!(
"⚠️ {}",
colors::yellow(
"The `--unstable` flag is deprecated and will be removed in Deno 2.0. Use granular `--unstable-*` flags instead.\nLearn more at: https://docs.deno.com/runtime/manual/tools/unstable_flags"
)
);
}
}
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()],
_ => vec![],
};
init_v8_flags(&default_v8_flags, &flags.v8_flags, get_v8_flags_from_env());
deno_core::JsRuntime::init_platform(None);
util::logger::init(flags.log_level);
Ok(flags)
} }

View file

@ -30,6 +30,7 @@ use deno_runtime::tokio_util::create_and_run_current_thread_with_maybe_metrics;
pub use deno_runtime::UNSTABLE_GRANULAR_FLAGS; pub use deno_runtime::UNSTABLE_GRANULAR_FLAGS;
use deno_terminal::colors; use deno_terminal::colors;
use std::borrow::Cow;
use std::env; use std::env;
use std::env::current_exe; use std::env::current_exe;
@ -70,12 +71,14 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T {
fn main() { fn main() {
let args: Vec<_> = env::args_os().collect(); let args: Vec<_> = env::args_os().collect();
let current_exe_path = current_exe().unwrap(); let current_exe_path = current_exe().unwrap();
let standalone = standalone::extract_standalone(&current_exe_path, args); let standalone =
standalone::extract_standalone(&current_exe_path, Cow::Owned(args));
let future = async move { let future = async move {
match standalone { match standalone {
Ok(Some(future)) => { Ok(Some(future)) => {
let (metadata, eszip) = future.await?; let (metadata, eszip) = future.await?;
standalone::run(eszip, metadata).await let exit_code = standalone::run(eszip, metadata).await?;
std::process::exit(exit_code);
} }
Ok(None) => Ok(()), Ok(None) => Ok(()),
Err(err) => Err(err), Err(err) => Err(err),

View file

@ -1,5 +1,6 @@
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
use std::borrow::Cow;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::env::current_exe; use std::env::current_exe;
use std::ffi::OsString; use std::ffi::OsString;
@ -240,7 +241,7 @@ pub fn is_standalone_binary(exe_path: &Path) -> bool {
/// the bundle is executed. If not, this function exits with `Ok(None)`. /// the bundle is executed. If not, this function exits with `Ok(None)`.
pub fn extract_standalone( pub fn extract_standalone(
exe_path: &Path, exe_path: &Path,
cli_args: Vec<OsString>, cli_args: Cow<Vec<OsString>>,
) -> Result< ) -> Result<
Option<impl Future<Output = Result<(Metadata, eszip::EszipV2), AnyError>>>, Option<impl Future<Output = Result<(Metadata, eszip::EszipV2), AnyError>>>,
AnyError, AnyError,
@ -257,6 +258,7 @@ pub fn extract_standalone(
file.seek(SeekFrom::Start(trailer.eszip_pos))?; file.seek(SeekFrom::Start(trailer.eszip_pos))?;
let cli_args = cli_args.into_owned();
// If we have an eszip, read it out // If we have an eszip, read it out
Ok(Some(async move { Ok(Some(async move {
let bufreader = let bufreader =

View file

@ -319,7 +319,7 @@ impl RootCertStoreProvider for StandaloneRootCertStoreProvider {
pub async fn run( pub async fn run(
mut eszip: eszip::EszipV2, mut eszip: eszip::EszipV2,
metadata: Metadata, metadata: Metadata,
) -> Result<(), AnyError> { ) -> Result<i32, AnyError> {
let main_module = &metadata.entrypoint; let main_module = &metadata.entrypoint;
let current_exe_path = std::env::current_exe().unwrap(); let current_exe_path = std::env::current_exe().unwrap();
let current_exe_name = let current_exe_name =
@ -574,12 +574,14 @@ pub async fn run(
false, false,
); );
// Initialize v8 once from the main thread.
v8_set_flags(construct_v8_flags(&[], &metadata.v8_flags, vec![])); v8_set_flags(construct_v8_flags(&[], &metadata.v8_flags, vec![]));
deno_core::JsRuntime::init_platform(None);
let mut worker = worker_factory let mut worker = worker_factory
.create_main_worker(main_module.clone(), permissions) .create_main_worker(main_module.clone(), permissions)
.await?; .await?;
let exit_code = worker.run().await?; let exit_code = worker.run().await?;
std::process::exit(exit_code) Ok(exit_code)
} }