summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml3
-rw-r--r--Cargo.lock1
-rw-r--r--cli/Cargo.toml7
-rw-r--r--cli/bench/main.rs6
-rw-r--r--cli/colors.rs3
-rw-r--r--cli/file_fetcher.rs2
-rw-r--r--cli/flags.rs67
-rw-r--r--cli/http_util.rs14
-rw-r--r--cli/info.rs4
-rw-r--r--cli/lsp/sources.rs2
-rw-r--r--cli/main.rs24
-rw-r--r--cli/main_runtime.rs32
-rw-r--r--cli/module_graph.rs2
-rw-r--r--cli/program_state.rs4
-rw-r--r--cli/standalone.rs224
-rw-r--r--cli/tests/integration_tests.rs11
-rw-r--r--cli/tools/mod.rs1
-rw-r--r--cli/tools/standalone.rs146
-rw-r--r--cli/tools/upgrade.rs2
-rw-r--r--cli/version.rs6
-rw-r--r--runtime/permissions.rs3
-rw-r--r--test_util/src/lib.rs9
22 files changed, 315 insertions, 258 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f57513d3e..7df48aca8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -175,6 +175,7 @@ jobs:
run: |
cd target/release
zip -r deno-x86_64-unknown-linux-gnu.zip deno
+ zip -r denort-x86_64-unknown-linux-gnu.zip denort
./deno types > lib.deno.d.ts
- name: Pre-release (mac)
@@ -184,6 +185,7 @@ jobs:
run: |
cd target/release
zip -r deno-x86_64-apple-darwin.zip deno
+ zip -r denort-x86_64-apple-darwin.zip denort
- name: Pre-release (windows)
if: |
@@ -191,6 +193,7 @@ jobs:
matrix.kind == 'test_release'
run: |
Compress-Archive -CompressionLevel Optimal -Force -Path target/release/deno.exe -DestinationPath target/release/deno-x86_64-pc-windows-msvc.zip
+ Compress-Archive -CompressionLevel Optimal -Force -Path target/release/denort.exe -DestinationPath target/release/denort-x86_64-pc-windows-msvc.zip
- name: Upload canary (unix)
if: |
diff --git a/Cargo.lock b/Cargo.lock
index f22d9a6fd..ab546e2d6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1314,6 +1314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if 0.1.10",
+ "serde",
]
[[package]]
diff --git a/cli/Cargo.toml b/cli/Cargo.toml
index 99760023a..bea5e87a5 100644
--- a/cli/Cargo.toml
+++ b/cli/Cargo.toml
@@ -14,6 +14,11 @@ default-run = "deno"
name = "deno"
path = "main.rs"
+[[bin]]
+name = "denort"
+path = "main_runtime.rs"
+
+
[[bench]]
name = "deno_bench"
harness = false
@@ -51,7 +56,7 @@ indexmap = "1.6.0"
jsonc-parser = "0.14.0"
lazy_static = "1.4.0"
libc = "0.2.77"
-log = "0.4.11"
+log = { version = "0.4.11", features = ["serde"] }
lspower = "0.1.0"
notify = "5.0.0-pre.3"
percent-encoding = "2.1.0"
diff --git a/cli/bench/main.rs b/cli/bench/main.rs
index ea693fb3a..d796237d1 100644
--- a/cli/bench/main.rs
+++ b/cli/bench/main.rs
@@ -202,6 +202,12 @@ fn get_binary_sizes(target_dir: &PathBuf) -> Result<Value> {
Value::Number(Number::from(test_util::deno_exe_path().metadata()?.len())),
);
+ // add up size for denort
+ sizes.insert(
+ "denort".to_string(),
+ Value::Number(Number::from(test_util::denort_exe_path().metadata()?.len())),
+ );
+
// add up size for everything in target/release/deps/libswc*
let swc_size = rlib_size(&target_dir, "libswc");
println!("swc {} bytes", swc_size);
diff --git a/cli/colors.rs b/cli/colors.rs
index 93f252716..97813a72c 100644
--- a/cli/colors.rs
+++ b/cli/colors.rs
@@ -1,5 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+// allow(dead_code) because denort does not use this.
+#![allow(dead_code)]
+
use regex::Regex;
use std::env;
use std::fmt;
diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs
index 5a31ee6cc..632b713a0 100644
--- a/cli/file_fetcher.rs
+++ b/cli/file_fetcher.rs
@@ -4,10 +4,10 @@ use crate::colors;
use crate::http_cache::HttpCache;
use crate::http_util::create_http_client;
use crate::http_util::fetch_once;
-use crate::http_util::get_user_agent;
use crate::http_util::FetchOnceResult;
use crate::media_type::MediaType;
use crate::text_encoding;
+use crate::version::get_user_agent;
use deno_runtime::permissions::Permissions;
use deno_core::error::custom_error;
diff --git a/cli/flags.rs b/cli/flags.rs
index 6b4e5aa5f..7e48c8428 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -6,15 +6,11 @@ use clap::Arg;
use clap::ArgMatches;
use clap::ArgSettings;
use clap::SubCommand;
-use deno_core::serde::de;
use deno_core::serde::Deserialize;
-use deno_core::serde::Deserializer;
use deno_core::serde::Serialize;
-use deno_core::serde::Serializer;
use deno_core::url::Url;
use deno_runtime::permissions::PermissionsOptions;
use log::Level;
-use std::fmt;
use std::net::SocketAddr;
use std::path::PathBuf;
use std::str::FromStr;
@@ -100,66 +96,7 @@ impl Default for DenoSubcommand {
}
}
-fn deserialize_maybe_log_level<'de, D>(d: D) -> Result<Option<Level>, D::Error>
-where
- D: Deserializer<'de>,
-{
- struct OptionalLogLevelVisitor;
- impl<'de> de::Visitor<'de> for OptionalLogLevelVisitor {
- type Value = Option<Level>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "null or a valid log level string")
- }
-
- fn visit_none<E>(self) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Ok(None)
- }
-
- fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
- where
- D: de::Deserializer<'de>,
- {
- struct LogLevelVisitor;
- impl<'de> de::Visitor<'de> for LogLevelVisitor {
- type Value = Level;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "a valid log level string")
- }
-
- fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
- where
- E: de::Error,
- {
- Level::from_str(s).map_err(|_| {
- de::Error::invalid_value(de::Unexpected::Str(s), &self)
- })
- }
- }
- Ok(Some(d.deserialize_str(LogLevelVisitor)?))
- }
- }
- d.deserialize_option(OptionalLogLevelVisitor)
-}
-
-fn serialize_maybe_log_level<S>(
- maybe_level: &Option<Level>,
- s: S,
-) -> Result<S::Ok, S::Error>
-where
- S: Serializer,
-{
- match maybe_level {
- None => s.serialize_none(),
- Some(level) => s.serialize_str(&level.to_string()),
- }
-}
-
-#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize)]
+#[derive(Clone, Debug, PartialEq, Default)]
pub struct Flags {
/// Vector of CLI arguments - these are user script arguments, all Deno
/// specific flags are removed.
@@ -185,8 +122,6 @@ pub struct Flags {
pub inspect_brk: Option<SocketAddr>,
pub lock: Option<PathBuf>,
pub lock_write: bool,
- #[serde(deserialize_with = "deserialize_maybe_log_level")]
- #[serde(serialize_with = "serialize_maybe_log_level")]
pub log_level: Option<Level>,
pub no_check: bool,
pub no_prompts: bool,
diff --git a/cli/http_util.rs b/cli/http_util.rs
index df2a7d3a2..a27928055 100644
--- a/cli/http_util.rs
+++ b/cli/http_util.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::version;
use deno_core::error::generic_error;
use deno_core::error::AnyError;
use deno_core::url::Url;
@@ -15,10 +14,6 @@ use deno_runtime::deno_fetch::reqwest::Client;
use deno_runtime::deno_fetch::reqwest::StatusCode;
use std::collections::HashMap;
-pub fn get_user_agent() -> String {
- format!("Deno/{}", version::deno())
-}
-
/// Create new instance of async reqwest::Client. This client supports
/// proxies and doesn't follow redirects.
pub fn create_http_client(
@@ -155,6 +150,7 @@ pub async fn fetch_once(
#[cfg(test)]
mod tests {
use super::*;
+ use crate::version;
use std::fs::read;
fn create_test_client(ca_data: Option<Vec<u8>>) -> Client {
@@ -313,7 +309,7 @@ mod tests {
Url::parse("https://localhost:5545/cli/tests/fixture.json").unwrap();
let client = create_http_client(
- get_user_agent(),
+ version::get_user_agent(),
Some(
read(
test_util::root_path()
@@ -345,7 +341,7 @@ mod tests {
)
.unwrap();
let client = create_http_client(
- get_user_agent(),
+ version::get_user_agent(),
Some(
read(
test_util::root_path()
@@ -376,7 +372,7 @@ mod tests {
let _http_server_guard = test_util::http_server();
let url = Url::parse("https://localhost:5545/etag_script.ts").unwrap();
let client = create_http_client(
- get_user_agent(),
+ version::get_user_agent(),
Some(
read(
test_util::root_path()
@@ -416,7 +412,7 @@ mod tests {
)
.unwrap();
let client = create_http_client(
- get_user_agent(),
+ version::get_user_agent(),
Some(
read(
test_util::root_path()
diff --git a/cli/info.rs b/cli/info.rs
index d2ea4e7e6..ededcc024 100644
--- a/cli/info.rs
+++ b/cli/info.rs
@@ -2,8 +2,8 @@
use crate::colors;
use crate::media_type::serialize_media_type;
-use crate::MediaType;
-use crate::ModuleSpecifier;
+use crate::media_type::MediaType;
+use deno_core::ModuleSpecifier;
use serde::Serialize;
use serde::Serializer;
diff --git a/cli/lsp/sources.rs b/cli/lsp/sources.rs
index 5ef16a876..7d1fd56f3 100644
--- a/cli/lsp/sources.rs
+++ b/cli/lsp/sources.rs
@@ -14,7 +14,7 @@ use crate::module_graph::GraphBuilder;
use crate::program_state::ProgramState;
use crate::specifier_handler::FetchHandler;
use crate::text_encoding;
-use crate::Permissions;
+use deno_runtime::permissions::Permissions;
use deno_core::error::AnyError;
use deno_core::serde_json;
diff --git a/cli/main.rs b/cli/main.rs
index 066991624..a3b8f3a6d 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -55,7 +55,6 @@ use crate::program_state::exit_unstable;
use crate::program_state::ProgramState;
use crate::source_maps::apply_source_map;
use crate::specifier_handler::FetchHandler;
-use crate::standalone::create_standalone_binary;
use crate::tools::installer::infer_name_from_url;
use deno_core::error::generic_error;
use deno_core::error::AnyError;
@@ -116,7 +115,7 @@ fn create_web_worker_callback(
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_data: program_state.ca_data.clone(),
- user_agent: http_util::get_user_agent(),
+ user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
module_loader,
create_web_worker_cb,
@@ -192,7 +191,7 @@ pub fn create_main_worker(
.map_or(false, |l| l == log::Level::Debug),
unstable: program_state.flags.unstable,
ca_data: program_state.ca_data.clone(),
- user_agent: http_util::get_user_agent(),
+ user_agent: version::get_user_agent(),
seed: program_state.flags.seed,
js_error_create_fn: Some(js_error_create_fn),
create_web_worker_cb,
@@ -307,7 +306,8 @@ async fn compile_command(
let debug = flags.log_level == Some(log::Level::Debug);
- let run_flags = standalone::compile_to_runtime_flags(flags.clone(), args)?;
+ let run_flags =
+ tools::standalone::compile_to_runtime_flags(flags.clone(), args)?;
let module_specifier = ModuleSpecifier::resolve_url_or_path(&source_file)?;
let program_state = ProgramState::new(flags.clone())?;
@@ -337,7 +337,12 @@ async fn compile_command(
colors::green("Compile"),
module_specifier.to_string()
);
- create_standalone_binary(bundle_str, run_flags, output.clone()).await?;
+ tools::standalone::create_standalone_binary(
+ bundle_str,
+ run_flags,
+ output.clone(),
+ )
+ .await?;
info!("{} {}", colors::green("Emit"), output.display());
@@ -1244,7 +1249,14 @@ pub fn main() {
colors::enable_ansi(); // For Windows 10
let args: Vec<String> = env::args().collect();
- if let Err(err) = standalone::try_run_standalone_binary(args.clone()) {
+ let standalone_res = match standalone::extract_standalone(args.clone()) {
+ Ok(Some((metadata, bundle))) => {
+ tokio_util::run_basic(standalone::run(bundle, metadata))
+ }
+ Ok(None) => Ok(()),
+ Err(err) => Err(err),
+ };
+ if let Err(err) = standalone_res {
eprintln!("{}: {}", colors::red_bold("error"), err.to_string());
std::process::exit(1);
}
diff --git a/cli/main_runtime.rs b/cli/main_runtime.rs
new file mode 100644
index 000000000..12cb4329d
--- /dev/null
+++ b/cli/main_runtime.rs
@@ -0,0 +1,32 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+#![deny(warnings)]
+
+#[macro_use]
+extern crate lazy_static;
+
+mod colors;
+mod standalone;
+mod tokio_util;
+mod version;
+
+use deno_core::error::anyhow;
+use deno_core::error::AnyError;
+use std::env;
+
+pub fn main() {
+ #[cfg(windows)]
+ colors::enable_ansi(); // For Windows 10
+
+ let args: Vec<String> = env::args().collect();
+ if let Err(err) = run(args) {
+ eprintln!("{}: {}", colors::red_bold("error"), err.to_string());
+ std::process::exit(1);
+ }
+}
+
+fn run(args: Vec<String>) -> Result<(), AnyError> {
+ let (metadata, bundle) = standalone::extract_standalone(args)?
+ .ok_or_else(|| anyhow!("This executable is used internally by 'deno compile', it is not meant to be invoked directly."))?;
+ tokio_util::run_basic(standalone::run(bundle, metadata))
+}
diff --git a/cli/module_graph.rs b/cli/module_graph.rs
index 686c1bd0e..f2e693724 100644
--- a/cli/module_graph.rs
+++ b/cli/module_graph.rs
@@ -25,7 +25,7 @@ use crate::tsc;
use crate::tsc_config::IgnoredCompilerOptions;
use crate::tsc_config::TsConfig;
use crate::version;
-use crate::AnyError;
+use deno_core::error::AnyError;
use deno_core::error::anyhow;
use deno_core::error::custom_error;
diff --git a/cli/program_state.rs b/cli/program_state.rs
index 896f4d7b4..ad44d8e9b 100644
--- a/cli/program_state.rs
+++ b/cli/program_state.rs
@@ -5,7 +5,6 @@ use crate::file_fetcher::CacheSetting;
use crate::file_fetcher::FileFetcher;
use crate::flags;
use crate::http_cache;
-use crate::http_util;
use crate::import_map::ImportMap;
use crate::lockfile::Lockfile;
use crate::module_graph::CheckOptions;
@@ -14,6 +13,7 @@ use crate::module_graph::TranspileOptions;
use crate::module_graph::TypeLib;
use crate::source_maps::SourceMapGetter;
use crate::specifier_handler::FetchHandler;
+use crate::version;
use deno_runtime::inspector::InspectorServer;
use deno_runtime::permissions::Permissions;
@@ -106,7 +106,7 @@ impl ProgramState {
let maybe_inspector_server = match maybe_inspect_host {
Some(host) => Some(Arc::new(InspectorServer::new(
host,
- http_util::get_user_agent(),
+ version::get_user_agent(),
))),
None => None,
};
diff --git a/cli/standalone.rs b/cli/standalone.rs
index 8d95d30f2..a4b55f081 100644
--- a/cli/standalone.rs
+++ b/cli/standalone.rs
@@ -1,9 +1,7 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
use crate::colors;
-use crate::flags::DenoSubcommand;
-use crate::flags::Flags;
-use crate::tokio_util;
use crate::version;
-use deno_core::error::bail;
use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::error::Context;
@@ -11,35 +9,41 @@ use deno_core::futures::FutureExt;
use deno_core::serde::Deserialize;
use deno_core::serde::Serialize;
use deno_core::serde_json;
+use deno_core::url::Url;
use deno_core::v8_set_flags;
use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
use deno_core::OpState;
use deno_runtime::permissions::Permissions;
+use deno_runtime::permissions::PermissionsOptions;
use deno_runtime::worker::MainWorker;
use deno_runtime::worker::WorkerOptions;
+use log::Level;
use std::cell::RefCell;
use std::convert::TryInto;
use std::env::current_exe;
-use std::fs::read;
use std::fs::File;
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
-use std::io::Write;
use std::iter::once;
-use std::path::PathBuf;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
#[derive(Deserialize, Serialize)]
-struct Metadata {
- flags: Flags,
- ca_data: Option<Vec<u8>>,
+pub struct Metadata {
+ pub argv: Vec<String>,
+ pub unstable: bool,
+ pub seed: Option<u64>,
+ pub permissions: PermissionsOptions,
+ pub location: Option<Url>,
+ pub v8_flags: Vec<String>,
+ pub log_level: Option<Level>,
+ pub ca_data: Option<Vec<u8>>,
}
-const MAGIC_TRAILER: &[u8; 8] = b"d3n0l4nd";
+pub const MAGIC_TRAILER: &[u8; 8] = b"d3n0l4nd";
/// This function will try to run this binary as a standalone binary
/// produced by `deno compile`. It determines if this is a stanalone
@@ -50,7 +54,9 @@ const MAGIC_TRAILER: &[u8; 8] = b"d3n0l4nd";
/// These are dereferenced, and the bundle is executed under the configuration
/// specified by the metadata. If no magic trailer is present, this function
/// exits with `Ok(())`.
-pub fn try_run_standalone_binary(args: Vec<String>) -> Result<(), AnyError> {
+pub fn extract_standalone(
+ args: Vec<String>,
+) -> Result<Option<(Metadata, String)>, AnyError> {
let current_exe_path = current_exe()?;
let mut current_exe = File::open(current_exe_path)?;
@@ -58,31 +64,27 @@ pub fn try_run_standalone_binary(args: Vec<String>) -> Result<(), AnyError> {
let mut trailer = [0; 24];
current_exe.read_exact(&mut trailer)?;
let (magic_trailer, rest) = trailer.split_at(8);
- if magic_trailer == MAGIC_TRAILER {
- let (bundle_pos, rest) = rest.split_at(8);
- let metadata_pos = rest;
- let bundle_pos = u64_from_bytes(bundle_pos)?;
- let metadata_pos = u64_from_bytes(metadata_pos)?;
- let bundle_len = metadata_pos - bundle_pos;
- let metadata_len = trailer_pos - metadata_pos;
- current_exe.seek(SeekFrom::Start(bundle_pos))?;
-
- let bundle = read_string_slice(&mut current_exe, bundle_pos, bundle_len)
- .context("Failed to read source bundle from the current executable")?;
- let metadata =
- read_string_slice(&mut current_exe, metadata_pos, metadata_len)
- .context("Failed to read metadata from the current executable")?;
-
- let mut metadata: Metadata = serde_json::from_str(&metadata).unwrap();
- metadata.flags.argv.append(&mut args[1..].to_vec());
- if let Err(err) = tokio_util::run_basic(run(bundle, metadata)) {
- eprintln!("{}: {}", colors::red_bold("error"), err.to_string());
- std::process::exit(1);
- }
- std::process::exit(0);
- } else {
- Ok(())
+ if magic_trailer != MAGIC_TRAILER {
+ return Ok(None);
}
+
+ let (bundle_pos, rest) = rest.split_at(8);
+ let metadata_pos = rest;
+ let bundle_pos = u64_from_bytes(bundle_pos)?;
+ let metadata_pos = u64_from_bytes(metadata_pos)?;
+ let bundle_len = metadata_pos - bundle_pos;
+ let metadata_len = trailer_pos - metadata_pos;
+ current_exe.seek(SeekFrom::Start(bundle_pos))?;
+
+ let bundle = read_string_slice(&mut current_exe, bundle_pos, bundle_len)
+ .context("Failed to read source bundle from the current executable")?;
+ let metadata =
+ read_string_slice(&mut current_exe, metadata_pos, metadata_len)
+ .context("Failed to read metadata from the current executable")?;
+
+ let mut metadata: Metadata = serde_json::from_str(&metadata).unwrap();
+ metadata.argv.append(&mut args[1..].to_vec());
+ Ok(Some((metadata, bundle)))
}
fn u64_from_bytes(arr: &[u8]) -> Result<u64, AnyError> {
@@ -149,10 +151,12 @@ impl ModuleLoader for EmbeddedModuleLoader {
}
}
-async fn run(source_code: String, metadata: Metadata) -> Result<(), AnyError> {
- let Metadata { flags, ca_data } = metadata;
+pub async fn run(
+ source_code: String,
+ metadata: Metadata,
+) -> Result<(), AnyError> {
let main_module = ModuleSpecifier::resolve_url(SPECIFIER)?;
- let permissions = Permissions::from_options(&flags.clone().into());
+ let permissions = Permissions::from_options(&metadata.permissions);
let module_loader = Rc::new(EmbeddedModuleLoader(source_code));
let create_web_worker_cb = Arc::new(|_| {
todo!("Worker are currently not supported in standalone binaries");
@@ -161,18 +165,18 @@ async fn run(source_code: String, metadata: Metadata) -> Result<(), AnyError> {
// Keep in sync with `main.rs`.
v8_set_flags(
once("UNUSED_BUT_NECESSARY_ARG0".to_owned())
- .chain(flags.v8_flags.iter().cloned())
+ .chain(metadata.v8_flags.iter().cloned())
.collect::<Vec<_>>(),
);
- // TODO(nayeemrmn): Unify this Flags -> WorkerOptions mapping with `deno run`.
+
let options = WorkerOptions {
apply_source_maps: false,
- args: flags.argv,
- debug_flag: flags.log_level.map_or(false, |l| l == log::Level::Debug),
- user_agent: crate::http_util::get_user_agent(),
- unstable: flags.unstable,
- ca_data,
- seed: flags.seed,
+ args: metadata.argv,
+ debug_flag: metadata.log_level.map_or(false, |l| l == log::Level::Debug),
+ user_agent: version::get_user_agent(),
+ unstable: metadata.unstable,
+ ca_data: metadata.ca_data,
+ seed: metadata.seed,
js_error_create_fn: None,
create_web_worker_cb,
attach_inspector: false,
@@ -182,8 +186,8 @@ async fn run(source_code: String, metadata: Metadata) -> Result<(), AnyError> {
runtime_version: version::deno(),
ts_version: version::TYPESCRIPT.to_string(),
no_color: !colors::use_color(),
- get_error_class_fn: Some(&crate::errors::get_error_class_name),
- location: flags.location,
+ get_error_class_fn: Some(&get_error_class_name),
+ location: metadata.location,
};
let mut worker =
MainWorker::from_options(main_module.clone(), permissions, &options);
@@ -192,125 +196,11 @@ async fn run(source_code: String, metadata: Metadata) -> Result<(), AnyError> {
worker.execute("window.dispatchEvent(new Event('load'))")?;
worker.run_event_loop().await?;
worker.execute("window.dispatchEvent(new Event('unload'))")?;
- Ok(())
-}
-
-/// This functions creates a standalone deno binary by appending a bundle
-/// and magic trailer to the currently executing binary.
-pub async fn create_standalone_binary(
- source_code: String,
- flags: Flags,
- output: PathBuf,
-) -> Result<(), AnyError> {
- let mut source_code = source_code.as_bytes().to_vec();
- let ca_data = match &flags.ca_file {
- Some(ca_file) => Some(read(ca_file)?),
- None => None,
- };
- let metadata = Metadata { flags, ca_data };
- let mut metadata = serde_json::to_string(&metadata)?.as_bytes().to_vec();
- let original_binary_path = std::env::current_exe()?;
- let mut original_bin = tokio::fs::read(original_binary_path).await?;
-
- let bundle_pos = original_bin.len();
- let metadata_pos = bundle_pos + source_code.len();
- let mut trailer = MAGIC_TRAILER.to_vec();
- trailer.write_all(&bundle_pos.to_be_bytes())?;
- trailer.write_all(&metadata_pos.to_be_bytes())?;
-
- let mut final_bin =
- Vec::with_capacity(original_bin.len() + source_code.len() + trailer.len());
- final_bin.append(&mut original_bin);
- final_bin.append(&mut source_code);
- final_bin.append(&mut metadata);
- final_bin.append(&mut trailer);
-
- let output =
- if cfg!(windows) && output.extension().unwrap_or_default() != "exe" {
- PathBuf::from(output.display().to_string() + ".exe")
- } else {
- output
- };
-
- if output.exists() {
- // If the output is a directory, throw error
- if output.is_dir() {
- bail!("Could not compile: {:?} is a directory.", &output);
- }
-
- // Make sure we don't overwrite any file not created by Deno compiler.
- // Check for magic trailer in last 24 bytes.
- let mut has_trailer = false;
- let mut output_file = File::open(&output)?;
- // This seek may fail because the file is too small to possibly be
- // `deno compile` output.
- if output_file.seek(SeekFrom::End(-24)).is_ok() {
- let mut trailer = [0; 24];
- output_file.read_exact(&mut trailer)?;
- let (magic_trailer, _) = trailer.split_at(8);
- has_trailer = magic_trailer == MAGIC_TRAILER;
- }
- if !has_trailer {
- bail!("Could not compile: cannot overwrite {:?}.", &output);
- }
- }
- tokio::fs::write(&output, final_bin).await?;
- #[cfg(unix)]
- {
- use std::os::unix::fs::PermissionsExt;
- let perms = std::fs::Permissions::from_mode(0o777);
- tokio::fs::set_permissions(output, perms).await?;
- }
-
- Ok(())
+ std::process::exit(0);
}
-/// Transform the flags passed to `deno compile` to flags that would be used at
-/// runtime, as if `deno run` were used.
-/// - Flags that affect module resolution, loading, type checking, etc. aren't
-/// applicable at runtime so are set to their defaults like `false`.
-/// - Other flags are inherited.
-pub fn compile_to_runtime_flags(
- flags: Flags,
- baked_args: Vec<String>,
-) -> Result<Flags, AnyError> {
- // IMPORTANT: Don't abbreviate any of this to `..flags` or
- // `..Default::default()`. That forces us to explicitly consider how any
- // change to `Flags` should be reflected here.
- Ok(Flags {
- argv: baked_args,
- subcommand: DenoSubcommand::Run {
- script: "placeholder".to_string(),
- },
- allow_env: flags.allow_env,
- allow_hrtime: flags.allow_hrtime,
- allow_net: flags.allow_net,
- allow_plugin: flags.allow_plugin,
- allow_read: flags.allow_read,
- allow_run: flags.allow_run,
- allow_write: flags.allow_write,
- cache_blocklist: vec![],
- ca_file: flags.ca_file,
- cached_only: false,
- config_path: None,
- coverage_dir: flags.coverage_dir,
- ignore: vec![],
- import_map_path: None,
- inspect: None,
- inspect_brk: None,
- location: flags.location,
- lock: None,
- lock_write: false,
- log_level: flags.log_level,
- no_check: false,
- no_prompts: flags.no_prompts,
- no_remote: false,
- reload: false,
- repl: false,
- seed: flags.seed,
- unstable: flags.unstable,
- v8_flags: flags.v8_flags,
- version: false,
- watch: false,
+fn get_error_class_name(e: &AnyError) -> &'static str {
+ deno_runtime::errors::get_error_class_name(e).unwrap_or_else(|| {
+ panic!("Error '{}' contains boxed error of unknown type", e);
})
}
diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs
index aabeb1f77..20e391171 100644
--- a/cli/tests/integration_tests.rs
+++ b/cli/tests/integration_tests.rs
@@ -5036,6 +5036,17 @@ fn standalone_runtime_flags() {
.contains("PermissionDenied: write access"));
}
+#[test]
+fn denort_direct_use_error() {
+ let status = Command::new(util::denort_exe_path())
+ .current_dir(util::root_path())
+ .spawn()
+ .unwrap()
+ .wait()
+ .unwrap();
+ assert!(!status.success());
+}
+
fn concat_bundle(
files: Vec<(PathBuf, String)>,
bundle_path: &Path,
diff --git a/cli/tools/mod.rs b/cli/tools/mod.rs
index be76968fb..4489b7479 100644
--- a/cli/tools/mod.rs
+++ b/cli/tools/mod.rs
@@ -5,5 +5,6 @@ pub mod fmt;
pub mod installer;
pub mod lint;
pub mod repl;
+pub mod standalone;
pub mod test_runner;
pub mod upgrade;
diff --git a/cli/tools/standalone.rs b/cli/tools/standalone.rs
new file mode 100644
index 000000000..112169756
--- /dev/null
+++ b/cli/tools/standalone.rs
@@ -0,0 +1,146 @@
+// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+
+use crate::flags::DenoSubcommand;
+use crate::flags::Flags;
+use deno_core::error::bail;
+use deno_core::error::AnyError;
+use deno_core::serde_json;
+use std::fs::read;
+use std::fs::File;
+use std::io::Read;
+use std::io::Seek;
+use std::io::SeekFrom;
+use std::io::Write;
+use std::path::PathBuf;
+
+use crate::standalone::Metadata;
+use crate::standalone::MAGIC_TRAILER;
+
+/// This functions creates a standalone deno binary by appending a bundle
+/// and magic trailer to the currently executing binary.
+pub async fn create_standalone_binary(
+ source_code: String,
+ flags: Flags,
+ output: PathBuf,
+) -> Result<(), AnyError> {
+ let mut source_code = source_code.as_bytes().to_vec();
+ let ca_data = match &flags.ca_file {
+ Some(ca_file) => Some(read(ca_file)?),
+ None => None,
+ };
+ let metadata = Metadata {
+ argv: flags.argv.clone(),
+ unstable: flags.unstable,
+ seed: flags.seed,
+ location: flags.location.clone(),
+ permissions: flags.clone().into(),
+ v8_flags: flags.v8_flags.clone(),
+ log_level: flags.log_level,
+ ca_data,
+ };
+ let mut metadata = serde_json::to_string(&metadata)?.as_bytes().to_vec();
+ let original_binary_path = std::env::current_exe()?;
+ let mut original_bin = tokio::fs::read(original_binary_path).await?;
+
+ let bundle_pos = original_bin.len();
+ let metadata_pos = bundle_pos + source_code.len();
+ let mut trailer = MAGIC_TRAILER.to_vec();
+ trailer.write_all(&bundle_pos.to_be_bytes())?;
+ trailer.write_all(&metadata_pos.to_be_bytes())?;
+
+ let mut final_bin =
+ Vec::with_capacity(original_bin.len() + source_code.len() + trailer.len());
+ final_bin.append(&mut original_bin);
+ final_bin.append(&mut source_code);
+ final_bin.append(&mut metadata);
+ final_bin.append(&mut trailer);
+
+ let output =
+ if cfg!(windows) && output.extension().unwrap_or_default() != "exe" {
+ PathBuf::from(output.display().to_string() + ".exe")
+ } else {
+ output
+ };
+
+ if output.exists() {
+ // If the output is a directory, throw error
+ if output.is_dir() {
+ bail!("Could not compile: {:?} is a directory.", &output);
+ }
+
+ // Make sure we don't overwrite any file not created by Deno compiler.
+ // Check for magic trailer in last 24 bytes.
+ let mut has_trailer = false;
+ let mut output_file = File::open(&output)?;
+ // This seek may fail because the file is too small to possibly be
+ // `deno compile` output.
+ if output_file.seek(SeekFrom::End(-24)).is_ok() {
+ let mut trailer = [0; 24];
+ output_file.read_exact(&mut trailer)?;
+ let (magic_trailer, _) = trailer.split_at(8);
+ has_trailer = magic_trailer == MAGIC_TRAILER;
+ }
+ if !has_trailer {
+ bail!("Could not compile: cannot overwrite {:?}.", &output);
+ }
+ }
+ tokio::fs::write(&output, final_bin).await?;
+ #[cfg(unix)]
+ {
+ use std::os::unix::fs::PermissionsExt;
+ let perms = std::fs::Permissions::from_mode(0o777);
+ tokio::fs::set_permissions(output, perms).await?;
+ }
+
+ Ok(())
+}
+
+/// Transform the flags passed to `deno compile` to flags that would be used at
+/// runtime, as if `deno run` were used.
+/// - Flags that affect module resolution, loading, type checking, etc. aren't
+/// applicable at runtime so are set to their defaults like `false`.
+/// - Other flags are inherited.
+pub fn compile_to_runtime_flags(
+ flags: Flags,
+ baked_args: Vec<String>,
+) -> Result<Flags, AnyError> {
+ // IMPORTANT: Don't abbreviate any of this to `..flags` or
+ // `..Default::default()`. That forces us to explicitly consider how any
+ // change to `Flags` should be reflected here.
+ Ok(Flags {
+ argv: baked_args,
+ subcommand: DenoSubcommand::Run {
+ script: "placeholder".to_string(),
+ },
+ allow_env: flags.allow_env,
+ allow_hrtime: flags.allow_hrtime,
+ allow_net: flags.allow_net,
+ allow_plugin: flags.allow_plugin,
+ allow_read: flags.allow_read,
+ allow_run: flags.allow_run,
+ allow_write: flags.allow_write,
+ cache_blocklist: vec![],
+ ca_file: flags.ca_file,
+ cached_only: false,
+ config_path: None,
+ coverage_dir: flags.coverage_dir,
+ ignore: vec![],
+ import_map_path: None,
+ inspect: None,
+ inspect_brk: None,
+ location: flags.location,
+ lock: None,
+ lock_write: false,
+ log_level: flags.log_level,
+ no_check: false,
+ no_prompts: flags.no_prompts,
+ no_remote: false,
+ reload: false,
+ repl: false,
+ seed: flags.seed,
+ unstable: flags.unstable,
+ v8_flags: flags.v8_flags,
+ version: false,
+ watch: false,
+ })
+}
diff --git a/cli/tools/upgrade.rs b/cli/tools/upgrade.rs
index da26b3159..a404f75f5 100644
--- a/cli/tools/upgrade.rs
+++ b/cli/tools/upgrade.rs
@@ -2,7 +2,7 @@
//! This module provides feature to upgrade deno executable
-use crate::AnyError;
+use deno_core::error::AnyError;
use deno_runtime::deno_fetch::reqwest;
use deno_runtime::deno_fetch::reqwest::Client;
use semver_parser::version::parse as semver_parse;
diff --git a/cli/version.rs b/cli/version.rs
index 49cb34f1d..3c2f6a995 100644
--- a/cli/version.rs
+++ b/cli/version.rs
@@ -10,6 +10,12 @@ pub fn deno() -> String {
})
}
+// allow(dead_code) because denort does not use this.
+#[allow(dead_code)]
pub fn is_canary() -> bool {
option_env!("DENO_CANARY").is_some()
}
+
+pub fn get_user_agent() -> String {
+ format!("Deno/{}", deno())
+}
diff --git a/runtime/permissions.rs b/runtime/permissions.rs
index 16a611690..66087f2e6 100644
--- a/runtime/permissions.rs
+++ b/runtime/permissions.rs
@@ -8,6 +8,7 @@ use deno_core::error::AnyError;
use deno_core::url;
use deno_core::ModuleSpecifier;
use serde::Deserialize;
+use serde::Serialize;
use std::collections::HashSet;
use std::env::current_dir;
use std::fmt;
@@ -88,7 +89,7 @@ pub fn resolve_fs_allowlist(allow: &Option<Vec<PathBuf>>) -> HashSet<PathBuf> {
}
}
-#[derive(Clone, Debug, PartialEq, Default)]
+#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct PermissionsOptions {
pub allow_env: bool,
pub allow_hrtime: bool,
diff --git a/test_util/src/lib.rs b/test_util/src/lib.rs
index 262084af7..3d5c60175 100644
--- a/test_util/src/lib.rs
+++ b/test_util/src/lib.rs
@@ -106,6 +106,15 @@ pub fn deno_exe_path() -> PathBuf {
p
}
+pub fn denort_exe_path() -> PathBuf {
+ // Something like /Users/rld/src/deno/target/debug/deps/denort
+ let mut p = target_dir().join("denort");
+ if cfg!(windows) {
+ p.set_extension("exe");
+ }
+ p
+}
+
pub fn prebuilt_tool_path(tool: &str) -> PathBuf {
let mut exe = tool.to_string();
exe.push_str(if cfg!(windows) { ".exe" } else { "" });