mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
feat: add --no-npm flag to disable npm: imports (#15673)
This commit adds "--no-npm" flag, it's similar to "--no-remote" flag. This flag makes Deno error out if "npm:" specifier is encountered.
This commit is contained in:
parent
3b1204eb2d
commit
4a250b2f25
8 changed files with 144 additions and 2 deletions
|
@ -312,6 +312,7 @@ pub struct Flags {
|
||||||
pub lock: Option<PathBuf>,
|
pub lock: Option<PathBuf>,
|
||||||
pub log_level: Option<Level>,
|
pub log_level: Option<Level>,
|
||||||
pub no_remote: bool,
|
pub no_remote: bool,
|
||||||
|
pub no_npm: bool,
|
||||||
pub no_prompt: bool,
|
pub no_prompt: bool,
|
||||||
pub reload: bool,
|
pub reload: bool,
|
||||||
pub seed: Option<u64>,
|
pub seed: Option<u64>,
|
||||||
|
@ -1732,6 +1733,7 @@ fn compile_args(app: Command) -> Command {
|
||||||
app
|
app
|
||||||
.arg(import_map_arg())
|
.arg(import_map_arg())
|
||||||
.arg(no_remote_arg())
|
.arg(no_remote_arg())
|
||||||
|
.arg(no_npm_arg())
|
||||||
.arg(no_config_arg())
|
.arg(no_config_arg())
|
||||||
.arg(config_arg())
|
.arg(config_arg())
|
||||||
.arg(no_check_arg())
|
.arg(no_check_arg())
|
||||||
|
@ -1746,6 +1748,7 @@ fn compile_args_without_check_args(app: Command) -> Command {
|
||||||
app
|
app
|
||||||
.arg(import_map_arg())
|
.arg(import_map_arg())
|
||||||
.arg(no_remote_arg())
|
.arg(no_remote_arg())
|
||||||
|
.arg(no_npm_arg())
|
||||||
.arg(config_arg())
|
.arg(config_arg())
|
||||||
.arg(no_config_arg())
|
.arg(no_config_arg())
|
||||||
.arg(reload_arg())
|
.arg(reload_arg())
|
||||||
|
@ -2140,6 +2143,12 @@ fn no_remote_arg<'a>() -> Arg<'a> {
|
||||||
.help("Do not resolve remote modules")
|
.help("Do not resolve remote modules")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn no_npm_arg<'a>() -> Arg<'a> {
|
||||||
|
Arg::new("no-npm")
|
||||||
|
.long("no-npm")
|
||||||
|
.help("Do not resolve npm modules")
|
||||||
|
}
|
||||||
|
|
||||||
fn unsafely_ignore_certificate_errors_arg<'a>() -> Arg<'a> {
|
fn unsafely_ignore_certificate_errors_arg<'a>() -> Arg<'a> {
|
||||||
Arg::new("unsafely-ignore-certificate-errors")
|
Arg::new("unsafely-ignore-certificate-errors")
|
||||||
.long("unsafely-ignore-certificate-errors")
|
.long("unsafely-ignore-certificate-errors")
|
||||||
|
@ -2785,6 +2794,7 @@ fn vendor_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
fn compile_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
fn compile_args_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
import_map_arg_parse(flags, matches);
|
import_map_arg_parse(flags, matches);
|
||||||
no_remote_arg_parse(flags, matches);
|
no_remote_arg_parse(flags, matches);
|
||||||
|
no_npm_arg_parse(flags, matches);
|
||||||
config_args_parse(flags, matches);
|
config_args_parse(flags, matches);
|
||||||
no_check_arg_parse(flags, matches);
|
no_check_arg_parse(flags, matches);
|
||||||
check_arg_parse(flags, matches);
|
check_arg_parse(flags, matches);
|
||||||
|
@ -2799,6 +2809,7 @@ fn compile_args_without_no_check_parse(
|
||||||
) {
|
) {
|
||||||
import_map_arg_parse(flags, matches);
|
import_map_arg_parse(flags, matches);
|
||||||
no_remote_arg_parse(flags, matches);
|
no_remote_arg_parse(flags, matches);
|
||||||
|
no_npm_arg_parse(flags, matches);
|
||||||
config_args_parse(flags, matches);
|
config_args_parse(flags, matches);
|
||||||
reload_arg_parse(flags, matches);
|
reload_arg_parse(flags, matches);
|
||||||
lock_args_parse(flags, matches);
|
lock_args_parse(flags, matches);
|
||||||
|
@ -3040,6 +3051,12 @@ fn no_remote_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn no_npm_arg_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
|
||||||
|
if matches.is_present("no-npm") {
|
||||||
|
flags.no_npm = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inspect_arg_validate(val: &str) -> Result<(), String> {
|
fn inspect_arg_validate(val: &str) -> Result<(), String> {
|
||||||
match val.parse::<SocketAddr>() {
|
match val.parse::<SocketAddr>() {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
|
@ -4998,6 +5015,21 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_npm() {
|
||||||
|
let r = flags_from_vec(svec!["deno", "run", "--no-npm", "script.ts"]);
|
||||||
|
assert_eq!(
|
||||||
|
r.unwrap(),
|
||||||
|
Flags {
|
||||||
|
subcommand: DenoSubcommand::Run(RunFlags {
|
||||||
|
script: "script.ts".to_string(),
|
||||||
|
}),
|
||||||
|
no_npm: true,
|
||||||
|
..Flags::default()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn cached_only() {
|
fn cached_only() {
|
||||||
let r = flags_from_vec(svec!["deno", "run", "--cached-only", "script.ts"]);
|
let r = flags_from_vec(svec!["deno", "run", "--cached-only", "script.ts"]);
|
||||||
|
|
|
@ -331,6 +331,10 @@ impl CliOptions {
|
||||||
self.flags.no_remote
|
self.flags.no_remote
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn no_npm(&self) -> bool {
|
||||||
|
self.flags.no_npm
|
||||||
|
}
|
||||||
|
|
||||||
pub fn permissions_options(&self) -> PermissionsOptions {
|
pub fn permissions_options(&self) -> PermissionsOptions {
|
||||||
self.flags.permissions_options()
|
self.flags.permissions_options()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ use std::sync::Arc;
|
||||||
use deno_ast::ModuleSpecifier;
|
use deno_ast::ModuleSpecifier;
|
||||||
use deno_core::anyhow::bail;
|
use deno_core::anyhow::bail;
|
||||||
use deno_core::anyhow::Context;
|
use deno_core::anyhow::Context;
|
||||||
|
use deno_core::error::custom_error;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
|
|
||||||
use deno_core::futures;
|
use deno_core::futures;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
use deno_runtime::deno_node::DenoDirNpmResolver;
|
use deno_runtime::deno_node::DenoDirNpmResolver;
|
||||||
|
@ -77,6 +77,7 @@ pub struct GlobalNpmPackageResolver {
|
||||||
resolution: Arc<NpmResolution>,
|
resolution: Arc<NpmResolution>,
|
||||||
registry_url: Url,
|
registry_url: Url,
|
||||||
unstable: bool,
|
unstable: bool,
|
||||||
|
no_npm: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalNpmPackageResolver {
|
impl GlobalNpmPackageResolver {
|
||||||
|
@ -85,12 +86,14 @@ impl GlobalNpmPackageResolver {
|
||||||
reload: bool,
|
reload: bool,
|
||||||
cache_setting: CacheSetting,
|
cache_setting: CacheSetting,
|
||||||
unstable: bool,
|
unstable: bool,
|
||||||
|
no_npm: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::from_cache(
|
Self::from_cache(
|
||||||
NpmCache::from_deno_dir(dir, cache_setting.clone()),
|
NpmCache::from_deno_dir(dir, cache_setting.clone()),
|
||||||
reload,
|
reload,
|
||||||
cache_setting,
|
cache_setting,
|
||||||
unstable,
|
unstable,
|
||||||
|
no_npm,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +102,7 @@ impl GlobalNpmPackageResolver {
|
||||||
reload: bool,
|
reload: bool,
|
||||||
cache_setting: CacheSetting,
|
cache_setting: CacheSetting,
|
||||||
unstable: bool,
|
unstable: bool,
|
||||||
|
no_npm: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let api = NpmRegistryApi::new(cache.clone(), reload, cache_setting);
|
let api = NpmRegistryApi::new(cache.clone(), reload, cache_setting);
|
||||||
let registry_url = api.base_url().to_owned();
|
let registry_url = api.base_url().to_owned();
|
||||||
|
@ -109,6 +113,7 @@ impl GlobalNpmPackageResolver {
|
||||||
resolution,
|
resolution,
|
||||||
registry_url,
|
registry_url,
|
||||||
unstable,
|
unstable,
|
||||||
|
no_npm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +127,28 @@ impl GlobalNpmPackageResolver {
|
||||||
&self,
|
&self,
|
||||||
packages: Vec<NpmPackageReq>,
|
packages: Vec<NpmPackageReq>,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
if !self.unstable && !packages.is_empty() {
|
assert!(!packages.is_empty());
|
||||||
|
|
||||||
|
if !self.unstable {
|
||||||
bail!(
|
bail!(
|
||||||
"Unstable use of npm specifiers. The --unstable flag must be provided."
|
"Unstable use of npm specifiers. The --unstable flag must be provided."
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.no_npm {
|
||||||
|
let fmt_reqs = packages
|
||||||
|
.iter()
|
||||||
|
.map(|p| format!("\"{}\"", p))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", ");
|
||||||
|
return Err(custom_error(
|
||||||
|
"NoNpm",
|
||||||
|
format!(
|
||||||
|
"Following npm specifiers were requested: {}; but --no-npm is specified.",
|
||||||
|
fmt_reqs
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
self.resolution.add_package_reqs(packages).await
|
self.resolution.add_package_reqs(packages).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,6 +223,7 @@ impl ProcState {
|
||||||
cli_options.unstable()
|
cli_options.unstable()
|
||||||
// don't do the unstable error when in the lsp
|
// don't do the unstable error when in the lsp
|
||||||
|| matches!(cli_options.sub_command(), DenoSubcommand::Lsp),
|
|| matches!(cli_options.sub_command(), DenoSubcommand::Lsp),
|
||||||
|
cli_options.no_npm(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(ProcState(Arc::new(Inner {
|
Ok(ProcState(Arc::new(Inner {
|
||||||
|
|
|
@ -231,6 +231,81 @@ fn cached_only_after_first_run() {
|
||||||
assert_contains!(stdout, "createChalk: chalk");
|
assert_contains!(stdout, "createChalk: chalk");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_npm_after_first_run() {
|
||||||
|
let _server = http_server();
|
||||||
|
|
||||||
|
let deno_dir = util::new_deno_dir();
|
||||||
|
|
||||||
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg("--allow-read")
|
||||||
|
.arg("--allow-env")
|
||||||
|
.arg("--no-npm")
|
||||||
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.envs(env_vars())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let output = deno.wait_with_output().unwrap();
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
assert_contains!(
|
||||||
|
stderr,
|
||||||
|
"Following npm specifiers were requested: \"chalk@5\"; but --no-npm is specified."
|
||||||
|
);
|
||||||
|
assert!(stdout.is_empty());
|
||||||
|
assert!(!output.status.success());
|
||||||
|
|
||||||
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg("--allow-read")
|
||||||
|
.arg("--allow-env")
|
||||||
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.envs(env_vars())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let output = deno.wait_with_output().unwrap();
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
assert_contains!(stderr, "Download");
|
||||||
|
assert_contains!(stdout, "createChalk: chalk");
|
||||||
|
assert!(output.status.success());
|
||||||
|
|
||||||
|
let deno = util::deno_cmd_with_deno_dir(&deno_dir)
|
||||||
|
.current_dir(util::testdata_path())
|
||||||
|
.arg("run")
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg("--allow-read")
|
||||||
|
.arg("--allow-env")
|
||||||
|
.arg("--no-npm")
|
||||||
|
.arg("npm/no_npm_after_first_run/main1.ts")
|
||||||
|
.env("NO_COLOR", "1")
|
||||||
|
.envs(env_vars())
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.stderr(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.unwrap();
|
||||||
|
let output = deno.wait_with_output().unwrap();
|
||||||
|
let stderr = String::from_utf8_lossy(&output.stderr);
|
||||||
|
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||||
|
assert_contains!(
|
||||||
|
stderr,
|
||||||
|
"Following npm specifiers were requested: \"chalk@5\"; but --no-npm is specified."
|
||||||
|
);
|
||||||
|
assert!(stdout.is_empty());
|
||||||
|
assert!(!output.status.success());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn deno_run_cjs_module() {
|
fn deno_run_cjs_module() {
|
||||||
let _server = http_server();
|
let _server = http_server();
|
||||||
|
|
3
cli/tests/testdata/npm/no_npm_after_first_run/main1.ts
vendored
Normal file
3
cli/tests/testdata/npm/no_npm_after_first_run/main1.ts
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import chalk from "npm:chalk@5";
|
||||||
|
|
||||||
|
console.log(chalk);
|
|
@ -321,6 +321,10 @@ fn resolve_shim_data(
|
||||||
executable_args.push("--no-remote".to_string());
|
executable_args.push("--no-remote".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if flags.no_npm {
|
||||||
|
executable_args.push("--no-npm".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
if flags.lock_write {
|
if flags.lock_write {
|
||||||
executable_args.push("--lock-write".to_string());
|
executable_args.push("--lock-write".to_string());
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,6 +279,7 @@ pub fn compile_to_runtime_flags(
|
||||||
.unsafely_ignore_certificate_errors
|
.unsafely_ignore_certificate_errors
|
||||||
.clone(),
|
.clone(),
|
||||||
no_remote: false,
|
no_remote: false,
|
||||||
|
no_npm: false,
|
||||||
no_prompt: flags.no_prompt,
|
no_prompt: flags.no_prompt,
|
||||||
reload: false,
|
reload: false,
|
||||||
seed: flags.seed,
|
seed: flags.seed,
|
||||||
|
|
Loading…
Reference in a new issue