diff options
-rw-r--r-- | cli/args/flags.rs | 57 | ||||
-rw-r--r-- | cli/args/mod.rs | 20 | ||||
-rw-r--r-- | cli/factory.rs | 6 | ||||
-rw-r--r-- | cli/main.rs | 51 | ||||
-rw-r--r-- | cli/tests/integration/check_tests.rs | 7 | ||||
-rw-r--r-- | cli/tests/testdata/check/deno_unstable_not_found/deno.json | 3 | ||||
-rw-r--r-- | cli/worker.rs | 26 | ||||
-rw-r--r-- | ext/ffi/README.md | 2 | ||||
-rw-r--r-- | runtime/js/90_deno_ns.js | 58 | ||||
-rw-r--r-- | runtime/js/99_main.js | 52 | ||||
-rw-r--r-- | runtime/ops/worker_host.rs | 2 | ||||
-rw-r--r-- | runtime/worker_bootstrap.rs | 7 | ||||
-rw-r--r-- | test_ffi/tests/integration_tests.rs | 2 |
13 files changed, 266 insertions, 27 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs index dbc868efa..e558fe391 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -419,6 +419,7 @@ pub struct Flags { pub unstable: bool, pub unstable_bare_node_builtlins: bool, pub unstable_byonm: bool, + pub unstable_features: Vec<String>, pub unsafely_ignore_certificate_errors: Option<Vec<String>>, pub v8_flags: Vec<String>, } @@ -814,6 +815,46 @@ pub fn flags_from_vec(args: Vec<String>) -> clap::error::Result<Flags> { if matches.get_flag("unstable") { flags.unstable = true; } + if matches.get_flag("unstable-broadcast-channel") { + flags.unstable_features.push( + deno_runtime::deno_broadcast_channel::UNSTABLE_FEATURE_NAME.to_string(), + ); + } + if matches.get_flag("unstable-ffi") { + flags + .unstable_features + .push(deno_runtime::deno_ffi::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-fs") { + flags + .unstable_features + .push(deno_runtime::deno_fs::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-http") { + flags + .unstable_features + .push(deno_runtime::ops::http::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-kv") { + flags + .unstable_features + .push(deno_runtime::deno_kv::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-net") { + flags + .unstable_features + .push(deno_runtime::deno_net::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-worker-options") { + flags + .unstable_features + .push(deno_runtime::ops::worker_host::UNSTABLE_FEATURE_NAME.to_string()); + } + if matches.get_flag("unstable-cron") { + flags + .unstable_features + .push(deno_runtime::deno_cron::UNSTABLE_FEATURE_NAME.to_string()); + } flags.unstable_bare_node_builtlins = matches.get_flag("unstable-bare-node-builtins"); @@ -901,7 +942,7 @@ fn clap_root() -> Command { crate::version::TYPESCRIPT ); - Command::new("deno") + let mut cmd = Command::new("deno") .bin_name("deno") .color(ColorChoice::Never) .max_term_width(80) @@ -931,7 +972,19 @@ fn clap_root() -> Command { .value_parser(FalseyValueParser::new()) .action(ArgAction::SetTrue) .global(true), - ) + ); + + for (flag_name, help, _) in crate::UNSTABLE_GRANULAR_FLAGS { + cmd = cmd.arg( + Arg::new(format!("unstable-{}", flag_name)) + .long(format!("unstable-{}", flag_name)) + .help(help) + .action(ArgAction::SetTrue) + .global(true), + ); + } + + cmd .arg( Arg::new("log-level") .short('L') diff --git a/cli/args/mod.rs b/cli/args/mod.rs index 0778dee79..1d28df124 100644 --- a/cli/args/mod.rs +++ b/cli/args/mod.rs @@ -723,7 +723,14 @@ impl CliOptions { } pub fn ts_type_lib_window(&self) -> TsTypeLib { - if self.flags.unstable { + if self.flags.unstable + || !self.flags.unstable_features.is_empty() + || self + .maybe_config_file + .as_ref() + .map(|f| !f.json.unstable.is_empty()) + .unwrap_or(false) + { TsTypeLib::UnstableDenoWindow } else { TsTypeLib::DenoWindow @@ -1264,6 +1271,17 @@ impl CliOptions { .unwrap_or(false) } + pub fn unstable_features(&self) -> Vec<String> { + let mut from_config_file = self + .maybe_config_file() + .as_ref() + .map(|c| c.json.unstable.clone()) + .unwrap_or_default(); + + from_config_file.extend_from_slice(&self.flags.unstable_features); + from_config_file + } + pub fn v8_flags(&self) -> &Vec<String> { &self.flags.v8_flags } diff --git a/cli/factory.rs b/cli/factory.rs index 389c4dbe0..06c9472fa 100644 --- a/cli/factory.rs +++ b/cli/factory.rs @@ -595,6 +595,12 @@ impl CliFactory { if self.options.unstable() { checker.enable_legacy_unstable(); } + let unstable_features = self.options.unstable_features(); + for (flag_name, _, _) in crate::UNSTABLE_GRANULAR_FLAGS { + if unstable_features.contains(&flag_name.to_string()) { + checker.enable_feature(flag_name); + } + } Arc::new(checker) }) diff --git a/cli/main.rs b/cli/main.rs index 7a8647a81..24b964169 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -256,6 +256,57 @@ fn unwrap_or_exit<T>(result: Result<T, AnyError>) -> T { } } +// NOTE(bartlomieju): keep IDs in sync with `runtime/90_deno_ns.js`. +pub(crate) static UNSTABLE_GRANULAR_FLAGS: &[( + // flag name + &str, + // help text + &str, + // id to enable it in runtime/99_main.js + i32, +)] = &[ + ( + deno_runtime::deno_broadcast_channel::UNSTABLE_FEATURE_NAME, + "Enable unstable `BroadcastChannel` API", + 1, + ), + ( + deno_runtime::deno_ffi::UNSTABLE_FEATURE_NAME, + "Enable unstable FFI APIs", + 2, + ), + ( + deno_runtime::deno_fs::UNSTABLE_FEATURE_NAME, + "Enable unstable file system APIs", + 3, + ), + ( + deno_runtime::deno_kv::UNSTABLE_FEATURE_NAME, + "Enable unstable Key-Value store APIs", + 4, + ), + ( + deno_runtime::deno_net::UNSTABLE_FEATURE_NAME, + "Enable unstable net APIs", + 5, + ), + ( + deno_runtime::ops::http::UNSTABLE_FEATURE_NAME, + "Enable unstable HTTP APIs", + 6, + ), + ( + deno_runtime::ops::worker_host::UNSTABLE_FEATURE_NAME, + "Enable unstable Web Worker APIs", + 7, + ), + ( + deno_runtime::deno_cron::UNSTABLE_FEATURE_NAME, + "Enable unstable Deno.cron API", + 8, + ), +]; + pub(crate) fn unstable_exit_cb(_feature: &str, api_name: &str) { // TODO(bartlomieju): change to "The `--unstable-{feature}` flag must be provided.". eprintln!("Unstable API '{api_name}'. The --unstable flag must be provided."); diff --git a/cli/tests/integration/check_tests.rs b/cli/tests/integration/check_tests.rs index ca80ffa94..029f89119 100644 --- a/cli/tests/integration/check_tests.rs +++ b/cli/tests/integration/check_tests.rs @@ -123,11 +123,16 @@ itest!(check_deno_not_found { }); itest!(check_deno_unstable_not_found { - args: "check --quiet check/deno_unstable_not_found/main.ts", + args: "check --quiet --no-config check/deno_unstable_not_found/main.ts", output: "check/deno_unstable_not_found/main.out", exit_code: 1, }); +itest!(check_deno_unstable_from_config { + args: "check --quiet --config check/deno_unstable_not_found/deno.json check/deno_unstable_not_found/main.ts", + output_str: Some(""), +}); + #[test] fn cache_switching_config_then_no_config() { let context = TestContext::default(); diff --git a/cli/tests/testdata/check/deno_unstable_not_found/deno.json b/cli/tests/testdata/check/deno_unstable_not_found/deno.json new file mode 100644 index 000000000..d7de05e18 --- /dev/null +++ b/cli/tests/testdata/check/deno_unstable_not_found/deno.json @@ -0,0 +1,3 @@ +{ + "unstable": ["cron", "http", "kv"] +} diff --git a/cli/worker.rs b/cli/worker.rs index 58bd96642..5022b39f1 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -529,6 +529,16 @@ impl CliMainWorkerFactory { let mut extensions = ops::cli_exts(shared.npm_resolver.clone()); extensions.append(&mut custom_extensions); + // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out + // list of enabled features. + let feature_checker = shared.feature_checker.clone(); + let mut unstable_features = Vec::with_capacity(8); + for (feature_name, _, id) in crate::UNSTABLE_GRANULAR_FLAGS { + if feature_checker.check(feature_name) { + unstable_features.push(*id); + } + } + let options = WorkerOptions { bootstrap: BootstrapOptions { args: shared.options.argv.clone(), @@ -544,6 +554,7 @@ impl CliMainWorkerFactory { runtime_version: version::deno().to_string(), ts_version: version::TYPESCRIPT.to_string(), unstable: shared.options.unstable, + unstable_features, user_agent: version::get_user_agent().to_string(), inspect: shared.options.is_inspecting, has_node_modules_dir: shared.options.has_node_modules_dir, @@ -580,7 +591,7 @@ impl CliMainWorkerFactory { shared.compiled_wasm_module_store.clone(), ), stdio, - feature_checker: shared.feature_checker.clone(), + feature_checker, }; let worker = MainWorker::bootstrap_from_options( @@ -704,6 +715,16 @@ fn create_web_worker_callback( .join(checksum::gen(&[key.as_bytes()])) }); + // TODO(bartlomieju): this is cruft, update FeatureChecker to spit out + // list of enabled features. + let feature_checker = shared.feature_checker.clone(); + let mut unstable_features = Vec::with_capacity(8); + for (feature_name, _, id) in crate::UNSTABLE_GRANULAR_FLAGS { + if feature_checker.check(feature_name) { + unstable_features.push(*id); + } + } + let options = WebWorkerOptions { bootstrap: BootstrapOptions { args: shared.options.argv.clone(), @@ -719,6 +740,7 @@ fn create_web_worker_callback( runtime_version: version::deno().to_string(), ts_version: version::TYPESCRIPT.to_string(), unstable: shared.options.unstable, + unstable_features, user_agent: version::get_user_agent().to_string(), inspect: shared.options.is_inspecting, has_node_modules_dir: shared.options.has_node_modules_dir, @@ -752,7 +774,7 @@ fn create_web_worker_callback( ), stdio: stdio.clone(), cache_storage_dir, - feature_checker: shared.feature_checker.clone(), + feature_checker, }; WebWorker::bootstrap_from_options( diff --git a/ext/ffi/README.md b/ext/ffi/README.md index 5f7f1cb9f..a821a3981 100644 --- a/ext/ffi/README.md +++ b/ext/ffi/README.md @@ -21,5 +21,5 @@ MacOS. To run benchmarks: ```bash -target/release/deno bench --allow-ffi --allow-read --unstable ./test_ffi/tests/bench.js +target/release/deno bench --allow-ffi --allow-read --unstable-ffi ./test_ffi/tests/bench.js ``` diff --git a/runtime/js/90_deno_ns.js b/runtime/js/90_deno_ns.js index c44c14bbe..ab2a5c308 100644 --- a/runtime/js/90_deno_ns.js +++ b/runtime/js/90_deno_ns.js @@ -154,6 +154,62 @@ const denoNs = { ChildProcess: process.ChildProcess, }; +// NOTE(bartlomieju): keep IDs in sync with `cli/main.rs` +const denoNsUnstableById = { + // BroadcastChannel is always available? + // 1: {}, + + // FFI + 2: { + dlopen: ffi.dlopen, + UnsafeCallback: ffi.UnsafeCallback, + UnsafePointer: ffi.UnsafePointer, + UnsafePointerView: ffi.UnsafePointerView, + UnsafeFnPointer: ffi.UnsafeFnPointer, + }, + + // FS + 3: { + flock: fs.flock, + flockSync: fs.flockSync, + funlock: fs.funlock, + funlockSync: fs.funlockSync, + umask: fs.umask, + }, + + // KV + 4: { + openKv: kv.openKv, + AtomicOperation: kv.AtomicOperation, + Kv: kv.Kv, + KvU64: kv.KvU64, + KvListIterator: kv.KvListIterator, + }, + + // net + 5: { + listenDatagram: net.createListenDatagram( + ops.op_net_listen_udp, + ops.op_net_listen_unixpacket, + ), + }, + + // HTTP + 6: { + HttpClient: httpClient.HttpClient, + createHttpClient: httpClient.createHttpClient, + // TODO(bartlomieju): why is it needed? + http, + upgradeHttp: http.upgradeHttp, + }, + // Worker options + // 7: {} + + 8: { + cron: cron.cron, + }, +}; + // when editing this list, also update unstableDenoProps in cli/tsc/99_main_compiler.js const denoNsUnstable = { listenDatagram: net.createListenDatagram( @@ -183,4 +239,4 @@ const denoNsUnstable = { cron: cron.cron, }; -export { denoNs, denoNsUnstable }; +export { denoNs, denoNsUnstable, denoNsUnstableById }; diff --git a/runtime/js/99_main.js b/runtime/js/99_main.js index ac1f52e74..b06cef651 100644 --- a/runtime/js/99_main.js +++ b/runtime/js/99_main.js @@ -57,7 +57,11 @@ import * as performance from "ext:deno_web/15_performance.js"; import * as url from "ext:deno_url/00_url.js"; import * as fetch from "ext:deno_fetch/26_fetch.js"; import * as messagePort from "ext:deno_web/13_message_port.js"; -import { denoNs, denoNsUnstable } from "ext:runtime/90_deno_ns.js"; +import { + denoNs, + denoNsUnstable, + denoNsUnstableById, +} from "ext:runtime/90_deno_ns.js"; import { errors } from "ext:runtime/01_errors.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; @@ -467,14 +471,15 @@ function bootstrapMainRuntime(runtimeOptions) { 7: isTty, 8: tsVersion, 9: unstableFlag, - 10: pid, - 11: target, - 12: v8Version, - 13: userAgent, - 14: inspectFlag, - // 15: enableTestingFeaturesFlag - 16: hasNodeModulesDir, - 17: maybeBinaryNpmCommandName, + 10: unstableFeatures, + 11: pid, + 12: target, + 13: v8Version, + 14: userAgent, + 15: inspectFlag, + // 16: enableTestingFeaturesFlag + 17: hasNodeModulesDir, + 18: maybeBinaryNpmCommandName, } = runtimeOptions; performance.setTimeOrigin(DateNow()); @@ -557,6 +562,7 @@ function bootstrapMainRuntime(runtimeOptions) { mainModule: util.getterOnly(opMainModule), }); + // TODO(bartlomieju): deprecate --unstable if (unstableFlag) { ObjectAssign(finalDenoNs, denoNsUnstable); // TODO(bartlomieju): this is not ideal, but because we use `ObjectAssign` @@ -576,6 +582,11 @@ function bootstrapMainRuntime(runtimeOptions) { jupyterNs = val; }, }); + } else { + for (let i = 0; i <= unstableFeatures.length; i++) { + const id = unstableFeatures[i]; + ObjectAssign(finalDenoNs, denoNsUnstableById[id]); + } } // Setup `Deno` global - we're actually overriding already existing global @@ -611,14 +622,15 @@ function bootstrapWorkerRuntime( 7: isTty, 8: tsVersion, 9: unstableFlag, - 10: pid, - 11: target, - 12: v8Version, - 13: userAgent, - // 14: inspectFlag, - 15: enableTestingFeaturesFlag, - 16: hasNodeModulesDir, - 17: maybeBinaryNpmCommandName, + 10: unstableFeatures, + 11: pid, + 12: target, + 13: v8Version, + 14: userAgent, + // 15: inspectFlag, + 16: enableTestingFeaturesFlag, + 17: hasNodeModulesDir, + 18: maybeBinaryNpmCommandName, } = runtimeOptions; performance.setTimeOrigin(DateNow()); @@ -688,8 +700,14 @@ function bootstrapWorkerRuntime( globalThis.pollForMessages = pollForMessages; + // TODO(bartlomieju): deprecate --unstable if (unstableFlag) { ObjectAssign(finalDenoNs, denoNsUnstable); + } else { + for (let i = 0; i <= unstableFeatures.length; i++) { + const id = unstableFeatures[i]; + ObjectAssign(finalDenoNs, denoNsUnstableById[id]); + } } ObjectDefineProperties(finalDenoNs, { pid: util.readOnly(pid), diff --git a/runtime/ops/worker_host.rs b/runtime/ops/worker_host.rs index 960e35b3d..b2ea1affe 100644 --- a/runtime/ops/worker_host.rs +++ b/runtime/ops/worker_host.rs @@ -26,7 +26,7 @@ use std::collections::HashMap; use std::rc::Rc; use std::sync::Arc; -pub const UNSTABLE_FEATURE_NAME: &str = "worker"; +pub const UNSTABLE_FEATURE_NAME: &str = "worker-options"; pub struct CreateWebWorkerArgs { pub name: String, diff --git a/runtime/worker_bootstrap.rs b/runtime/worker_bootstrap.rs index 0f533344f..b21b4aa21 100644 --- a/runtime/worker_bootstrap.rs +++ b/runtime/worker_bootstrap.rs @@ -54,7 +54,10 @@ pub struct BootstrapOptions { pub runtime_version: String, /// Sets `Deno.version.typescript` in JS runtime. pub ts_version: String, + // --unstable flag, deprecated pub unstable: bool, + // --unstable-* flags + pub unstable_features: Vec<i32>, pub user_agent: String, pub inspect: bool, pub has_node_modules_dir: bool, @@ -82,6 +85,7 @@ impl Default for BootstrapOptions { locale: "en".to_string(), location: Default::default(), unstable: Default::default(), + unstable_features: Default::default(), inspect: Default::default(), args: Default::default(), has_node_modules_dir: Default::default(), @@ -121,6 +125,8 @@ struct BootstrapV8<'a>( &'a str, // unstable bool, + // granular unstable flags + &'a [i32], // process_id i32, // env!("TARGET") @@ -159,6 +165,7 @@ impl BootstrapOptions { self.is_tty, &self.ts_version, self.unstable, + self.unstable_features.as_ref(), std::process::id() as _, env!("TARGET"), deno_core::v8_version(), diff --git a/test_ffi/tests/integration_tests.rs b/test_ffi/tests/integration_tests.rs index ad00465e6..99707438e 100644 --- a/test_ffi/tests/integration_tests.rs +++ b/test_ffi/tests/integration_tests.rs @@ -29,7 +29,7 @@ fn basic() { .arg("run") .arg("--allow-ffi") .arg("--allow-read") - .arg("--unstable") + .arg("--unstable-ffi") .arg("--quiet") .arg(r#"--v8-flags=--allow-natives-syntax"#) .arg("tests/test.js") |