Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Reland eszip changes #28294

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 38 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ denokv_remote = "0.9.0"
# denokv_sqlite brings in bundled sqlite if we don't disable the default features
denokv_sqlite = { default-features = false, version = "0.9.0" }

eszip = "0.81.0"

# exts
deno_broadcast_channel = { version = "0.186.0", path = "./ext/broadcast_channel" }
deno_cache = { version = "0.124.0", path = "./ext/cache" }
Expand Down Expand Up @@ -129,7 +131,7 @@ dashmap = "5.5.3"
data-encoding = "2.3.3"
data-url = "=0.3.1"
deno_cache_dir = "=0.18.0"
deno_error = "=0.5.5"
deno_error = "=0.5.6"
deno_package_json = { version = "=0.5.0", default-features = false }
deno_unsync = "0.4.2"
dlopen2 = "0.6.1"
Expand Down Expand Up @@ -356,3 +358,6 @@ opt-level = 3
opt-level = 3
[profile.release.package.zstd-sys]
opt-level = 3

[patch.crates-io]
eszip = { git = "https://github.com/bartlomieju/eszip.git", branch = "upgrade_deno_graph" }
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ deno_snapshots = { workspace = true }
deno_task_shell = "=0.20.2"
deno_telemetry.workspace = true
deno_terminal.workspace = true
eszip.workspace = true
libsui.workspace = true
node_resolver.workspace = true

Expand Down
25 changes: 23 additions & 2 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub struct CompileFlags {
pub no_terminal: bool,
pub icon: Option<String>,
pub include: Vec<String>,
pub eszip: bool,
}

impl CompileFlags {
Expand Down Expand Up @@ -676,6 +677,7 @@ pub struct Flags {
pub code_cache_enabled: bool,
pub permissions: PermissionFlags,
pub allow_scripts: PackagesAllowedScripts,
pub eszip: bool,
}

#[derive(Clone, Debug, Eq, PartialEq, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -3833,6 +3835,14 @@ fn runtime_misc_args(app: Command) -> Command {
.arg(seed_arg())
.arg(enable_testing_features_arg())
.arg(strace_ops_arg())
.arg(eszip_arg())
}

fn eszip_arg() -> Arg {
Arg::new("eszip-internal-do-not-use")
.hide(true)
.long("eszip-internal-do-not-use")
.action(ArgAction::SetTrue)
}

fn allow_import_arg() -> Arg {
Expand Down Expand Up @@ -4603,6 +4613,7 @@ fn compile_parse(
let target = matches.remove_one::<String>("target");
let icon = matches.remove_one::<String>("icon");
let no_terminal = matches.get_flag("no-terminal");
let eszip = matches.get_flag("eszip-internal-do-not-use");
let include = match matches.remove_many::<String>("include") {
Some(f) => f.collect(),
None => vec![],
Expand All @@ -4619,6 +4630,7 @@ fn compile_parse(
no_terminal,
icon,
include,
eszip,
});

Ok(())
Expand Down Expand Up @@ -5716,9 +5728,16 @@ fn runtime_args_parse(
enable_testing_features_arg_parse(flags, matches);
env_file_arg_parse(flags, matches);
strace_ops_parse(flags, matches);
eszip_arg_parse(flags, matches);
Ok(())
}

fn eszip_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
if matches.get_flag("eszip-internal-do-not-use") {
flags.eszip = true;
}
}

fn inspect_arg_parse(flags: &mut Flags, matches: &mut ArgMatches) {
flags.inspect = matches.remove_one::<SocketAddr>("inspect");
flags.inspect_brk = matches.remove_one::<SocketAddr>("inspect-brk");
Expand Down Expand Up @@ -10303,7 +10322,8 @@ mod tests {
target: None,
no_terminal: false,
icon: None,
include: vec![]
include: vec![],
eszip: false,
}),
type_check_mode: TypeCheckMode::Local,
code_cache_enabled: true,
Expand All @@ -10327,7 +10347,8 @@ mod tests {
target: None,
no_terminal: true,
icon: Some(String::from("favicon.ico")),
include: vec![]
include: vec![],
eszip: true
}),
import_map_path: Some("import_map.json".to_string()),
no_remote: true,
Expand Down
138 changes: 138 additions & 0 deletions cli/tools/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::collections::HashSet;
use std::collections::VecDeque;
use std::io::Write as _;
use std::path::Path;
use std::path::PathBuf;
use std::sync::Arc;
Expand Down Expand Up @@ -146,6 +147,141 @@ pub async fn compile(
Ok(())
}

pub async fn compile_eszip(
flags: Arc<Flags>,
compile_flags: CompileFlags,
) -> Result<(), AnyError> {
let factory = CliFactory::from_flags(flags);
let cli_options = factory.cli_options()?;
let module_graph_creator = factory.module_graph_creator().await?;
let parsed_source_cache = factory.parsed_source_cache();
let binary_writer = factory.create_compile_binary_writer().await?;
let tsconfig_resolver = factory.tsconfig_resolver()?;
let http_client = factory.http_client_provider();
let entrypoint = cli_options.resolve_main_module()?;
let output_path = resolve_compile_executable_output_path(
http_client,
&compile_flags,
cli_options.initial_cwd(),
)
.await?;
let (module_roots, include_files) = get_module_roots_and_include_files(
entrypoint,
&url_from_file_path(&cli_options.initial_cwd().join(&output_path))?,
&compile_flags,
cli_options.initial_cwd(),
)?;

let graph = Arc::try_unwrap(
module_graph_creator
.create_graph_and_maybe_check(module_roots.clone())
.await?,
)
.unwrap();
let graph = if cli_options.type_check_mode().is_true() {
// In this case, the previous graph creation did type checking, which will
// create a module graph with types information in it. We don't want to
// store that in the binary so create a code only module graph from scratch.
module_graph_creator
.create_graph(
GraphKind::CodeOnly,
module_roots,
crate::graph_util::NpmCachingStrategy::Eager,
)
.await?
} else {
graph
};

let transpile_and_emit_options = tsconfig_resolver
.transpile_and_emit_options(cli_options.workspace().root_dir())?;
let transpile_options = transpile_and_emit_options.transpile;
let emit_options = transpile_and_emit_options.emit;

let parser = parsed_source_cache.as_capturing_parser();
let root_dir_url = resolve_root_dir_from_specifiers(
cli_options.workspace().root_dir(),
graph.specifiers().map(|(s, _)| s).chain(
cli_options
.node_modules_dir_path()
.and_then(|p| ModuleSpecifier::from_directory_path(p).ok())
.iter(),
),
);
log::debug!("Binary root dir: {}", root_dir_url);
let root_dir_url = eszip::EszipRelativeFileBaseUrl::new(&root_dir_url);
let eszip = eszip::EszipV2::from_graph(eszip::FromGraphOptions {
graph,
parser,
transpile_options,
emit_options,
// make all the modules relative to the root folder
relative_file_base: Some(root_dir_url),
npm_packages: None,
module_kind_resolver: Default::default(),
})?;

log::info!(
"{} {} to {}",
colors::green("Compile"),
entrypoint,
output_path.display(),
);
validate_output_path(&output_path)?;

let mut temp_filename = output_path.file_name().unwrap().to_owned();
temp_filename.push(format!(
".tmp-{}",
faster_hex::hex_encode(
&rand::thread_rng().gen::<[u8; 8]>(),
&mut [0u8; 16]
)
.unwrap()
));
let temp_path = output_path.with_file_name(temp_filename);

let file = std::fs::File::create(&temp_path).with_context(|| {
format!("Opening temporary file '{}'", temp_path.display())
})?;

let write_result = {
let r = file.write_all(&eszip.into_bytes());
drop(file);
r
};

// set it as executable
#[cfg(unix)]
let write_result = write_result.and_then(|_| {
use std::os::unix::fs::PermissionsExt;
let perms = std::fs::Permissions::from_mode(0o755);
std::fs::set_permissions(&temp_path, perms).with_context(|| {
format!(
"Setting permissions on temporary file '{}'",
temp_path.display()
)
})
});

let write_result = write_result.and_then(|_| {
std::fs::rename(&temp_path, &output_path).with_context(|| {
format!(
"Renaming temporary file '{}' to '{}'",
temp_path.display(),
output_path.display()
)
})
});

if let Err(err) = write_result {
// errored, so attempt to remove the temporary file
let _ = std::fs::remove_file(temp_path);
return Err(err);
}

Ok(())
}

/// This function writes out a final binary to specified path. If output path
/// is not already standalone binary it will return error instead.
fn validate_output_path(output_path: &Path) -> Result<(), AnyError> {
Expand Down Expand Up @@ -357,6 +493,7 @@ mod test {
no_terminal: false,
icon: None,
include: vec![],
eszip: true,
},
&std::env::current_dir().unwrap(),
)
Expand All @@ -382,6 +519,7 @@ mod test {
include: vec![],
icon: None,
no_terminal: false,
eszip: true,
},
&std::env::current_dir().unwrap(),
)
Expand Down
Loading