diff options
| author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-11-01 23:15:08 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-11-01 23:15:08 +0100 |
| commit | 24c3c9695865bb478f5651da4982b7e0a34afc72 (patch) | |
| tree | 5afe78a8c67bb9e9c1cd69d56a9a0c68bca67515 /cli | |
| parent | 42c426e7695a0037032d1ac5237830800eeaaed4 (diff) | |
feat: granular --unstable-* flags (#20968)
This commit adds granular `--unstable-*` flags:
- "--unstable-broadcast-channel"
- "--unstable-ffi"
- "--unstable-fs"
- "--unstable-http"
- "--unstable-kv"
- "--unstable-net"
- "--unstable-worker-options"
- "--unstable-cron"
These flags are meant to replace a "catch-all" flag - "--unstable", that
gives a binary control whether unstable features are enabled or not. The
downside of this flag that allowing eg. Deno KV API also enables the FFI
API (though the latter is still gated with a permission).
These flags can also be specified in `deno.json` file under `unstable`
key.
Currently, "--unstable" flag works the same way - I will open a follow
up PR that will print a warning when using "--unstable" and suggest to use
concrete "--unstable-*" flag instead. We plan to phase out "--unstable"
completely in Deno 2.
Diffstat (limited to 'cli')
| -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 |
7 files changed, 164 insertions, 6 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( |
