mirror of
https://github.com/denoland/deno.git
synced 2025-01-21 04:52:26 -05:00
Merge remote-tracking branch 'upstream/main' into check-workspace-member-compiler-options
This commit is contained in:
commit
f8be309def
54 changed files with 639 additions and 129 deletions
|
@ -245,7 +245,7 @@ pub struct InstallFlagsGlobal {
|
|||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum InstallKind {
|
||||
pub enum InstallFlags {
|
||||
Local(InstallFlagsLocal),
|
||||
Global(InstallFlagsGlobal),
|
||||
}
|
||||
|
@ -257,11 +257,6 @@ pub enum InstallFlagsLocal {
|
|||
Entrypoints(Vec<String>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct InstallFlags {
|
||||
pub kind: InstallKind,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct JSONReferenceFlags {
|
||||
pub json: deno_core::serde_json::Value,
|
||||
|
@ -600,6 +595,7 @@ pub struct UnstableConfig {
|
|||
pub bare_node_builtins: bool,
|
||||
pub detect_cjs: bool,
|
||||
pub sloppy_imports: bool,
|
||||
pub npm_lazy_caching: bool,
|
||||
pub features: Vec<String>, // --unstabe-kv --unstable-cron
|
||||
}
|
||||
|
||||
|
@ -2912,6 +2908,7 @@ To ignore linting on an entire file, you can add an ignore comment at the top of
|
|||
.arg(watch_arg(false))
|
||||
.arg(watch_exclude_arg())
|
||||
.arg(no_clear_screen_arg())
|
||||
.arg(allow_import_arg())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -4414,6 +4411,16 @@ impl CommandExt for Command {
|
|||
})
|
||||
.help_heading(UNSTABLE_HEADING)
|
||||
.display_order(next_display_order())
|
||||
).arg(
|
||||
Arg::new("unstable-npm-lazy-caching")
|
||||
.long("unstable-npm-lazy-caching")
|
||||
.help("Enable unstable lazy caching of npm dependencies, downloading them only as needed (disabled: all npm packages in package.json are installed on startup; enabled: only npm packages that are actually referenced in an import are installed")
|
||||
.env("DENO_UNSTABLE_NPM_LAZY_CACHING")
|
||||
.value_parser(FalseyValueParser::new())
|
||||
.action(ArgAction::SetTrue)
|
||||
.hide(true)
|
||||
.help_heading(UNSTABLE_HEADING)
|
||||
.display_order(next_display_order()),
|
||||
);
|
||||
|
||||
for granular_flag in crate::UNSTABLE_GRANULAR_FLAGS.iter() {
|
||||
|
@ -4927,15 +4934,14 @@ fn install_parse(
|
|||
let module_url = cmd_values.next().unwrap();
|
||||
let args = cmd_values.collect();
|
||||
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(InstallFlagsGlobal {
|
||||
flags.subcommand =
|
||||
DenoSubcommand::Install(InstallFlags::Global(InstallFlagsGlobal {
|
||||
name,
|
||||
module_url,
|
||||
args,
|
||||
root,
|
||||
force,
|
||||
}),
|
||||
});
|
||||
}));
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
@ -4944,22 +4950,19 @@ fn install_parse(
|
|||
allow_scripts_arg_parse(flags, matches)?;
|
||||
if matches.get_flag("entrypoint") {
|
||||
let entrypoints = matches.remove_many::<String>("cmd").unwrap_or_default();
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Entrypoints(
|
||||
entrypoints.collect(),
|
||||
)),
|
||||
});
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags::Local(
|
||||
InstallFlagsLocal::Entrypoints(entrypoints.collect()),
|
||||
));
|
||||
} else if let Some(add_files) = matches
|
||||
.remove_many("cmd")
|
||||
.map(|packages| add_parse_inner(matches, Some(packages)))
|
||||
{
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Add(add_files)),
|
||||
})
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags::Local(
|
||||
InstallFlagsLocal::Add(add_files),
|
||||
))
|
||||
} else {
|
||||
flags.subcommand = DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(InstallFlagsLocal::TopLevel),
|
||||
});
|
||||
flags.subcommand =
|
||||
DenoSubcommand::Install(InstallFlags::Local(InstallFlagsLocal::TopLevel));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -5091,6 +5094,7 @@ fn lint_parse(
|
|||
unstable_args_parse(flags, matches, UnstableArgsConfig::ResolutionOnly);
|
||||
ext_arg_parse(flags, matches);
|
||||
config_args_parse(flags, matches);
|
||||
allow_import_parse(flags, matches);
|
||||
|
||||
let files = match matches.remove_many::<String>("files") {
|
||||
Some(f) => f.collect(),
|
||||
|
@ -6004,6 +6008,8 @@ fn unstable_args_parse(
|
|||
flags.unstable_config.detect_cjs = matches.get_flag("unstable-detect-cjs");
|
||||
flags.unstable_config.sloppy_imports =
|
||||
matches.get_flag("unstable-sloppy-imports");
|
||||
flags.unstable_config.npm_lazy_caching =
|
||||
matches.get_flag("unstable-npm-lazy-caching");
|
||||
|
||||
if matches!(cfg, UnstableArgsConfig::ResolutionAndRuntime) {
|
||||
for granular_flag in crate::UNSTABLE_GRANULAR_FLAGS {
|
||||
|
@ -7149,6 +7155,7 @@ mod tests {
|
|||
let r = flags_from_vec(svec![
|
||||
"deno",
|
||||
"lint",
|
||||
"--allow-import",
|
||||
"--watch",
|
||||
"script_1.ts",
|
||||
"script_2.ts"
|
||||
|
@ -7170,6 +7177,10 @@ mod tests {
|
|||
compact: false,
|
||||
watch: Some(Default::default()),
|
||||
}),
|
||||
permissions: PermissionFlags {
|
||||
allow_import: Some(vec![]),
|
||||
..Default::default()
|
||||
},
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
|
@ -8607,15 +8618,15 @@ mod tests {
|
|||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(InstallFlagsGlobal {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags::Global(
|
||||
InstallFlagsGlobal {
|
||||
name: None,
|
||||
module_url: "jsr:@std/http/file-server".to_string(),
|
||||
args: vec![],
|
||||
root: None,
|
||||
force: false,
|
||||
}),
|
||||
}),
|
||||
}
|
||||
),),
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
|
@ -8629,15 +8640,15 @@ mod tests {
|
|||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(InstallFlagsGlobal {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags::Global(
|
||||
InstallFlagsGlobal {
|
||||
name: None,
|
||||
module_url: "jsr:@std/http/file-server".to_string(),
|
||||
args: vec![],
|
||||
root: None,
|
||||
force: false,
|
||||
}),
|
||||
}),
|
||||
}
|
||||
),),
|
||||
..Flags::default()
|
||||
}
|
||||
);
|
||||
|
@ -8650,15 +8661,15 @@ mod tests {
|
|||
assert_eq!(
|
||||
r.unwrap(),
|
||||
Flags {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(InstallFlagsGlobal {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags::Global(
|
||||
InstallFlagsGlobal {
|
||||
name: Some("file_server".to_string()),
|
||||
module_url: "jsr:@std/http/file-server".to_string(),
|
||||
args: svec!["foo", "bar"],
|
||||
root: Some("/foo".to_string()),
|
||||
force: true,
|
||||
}),
|
||||
}),
|
||||
}
|
||||
),),
|
||||
import_map_path: Some("import_map.json".to_string()),
|
||||
no_remote: true,
|
||||
config_flag: ConfigFlag::Path("tsconfig.json".to_owned()),
|
||||
|
@ -11212,9 +11223,9 @@ mod tests {
|
|||
..Flags::default()
|
||||
},
|
||||
"install" => Flags {
|
||||
subcommand: DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(InstallFlagsLocal::Add(flags)),
|
||||
}),
|
||||
subcommand: DenoSubcommand::Install(InstallFlags::Local(
|
||||
InstallFlagsLocal::Add(flags),
|
||||
)),
|
||||
..Flags::default()
|
||||
},
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -20,7 +20,6 @@ use crate::Flags;
|
|||
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::InstallFlags;
|
||||
use crate::args::InstallKind;
|
||||
|
||||
use deno_lockfile::Lockfile;
|
||||
|
||||
|
@ -136,10 +135,8 @@ impl CliLockfile {
|
|||
if flags.no_lock
|
||||
|| matches!(
|
||||
flags.subcommand,
|
||||
DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(..),
|
||||
..
|
||||
}) | DenoSubcommand::Uninstall(_)
|
||||
DenoSubcommand::Install(InstallFlags::Global(..))
|
||||
| DenoSubcommand::Uninstall(_)
|
||||
)
|
||||
{
|
||||
return Ok(None);
|
||||
|
|
|
@ -984,9 +984,7 @@ impl CliOptions {
|
|||
match self.sub_command() {
|
||||
DenoSubcommand::Cache(_) => GraphKind::All,
|
||||
DenoSubcommand::Check(_) => GraphKind::TypesOnly,
|
||||
DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Local(_),
|
||||
}) => GraphKind::All,
|
||||
DenoSubcommand::Install(InstallFlags::Local(_)) => GraphKind::All,
|
||||
_ => self.type_check_mode().as_graph_kind(),
|
||||
}
|
||||
}
|
||||
|
@ -1578,11 +1576,11 @@ impl CliOptions {
|
|||
DenoSubcommand::Check(check_flags) => {
|
||||
Some(files_to_urls(&check_flags.files))
|
||||
}
|
||||
DenoSubcommand::Install(InstallFlags {
|
||||
kind: InstallKind::Global(flags),
|
||||
}) => Url::parse(&flags.module_url)
|
||||
.ok()
|
||||
.map(|url| vec![Cow::Owned(url)]),
|
||||
DenoSubcommand::Install(InstallFlags::Global(flags)) => {
|
||||
Url::parse(&flags.module_url)
|
||||
.ok()
|
||||
.map(|url| vec![Cow::Owned(url)])
|
||||
}
|
||||
DenoSubcommand::Doc(DocFlags {
|
||||
source_files: DocSourceFileFlag::Paths(paths),
|
||||
..
|
||||
|
@ -1718,6 +1716,7 @@ impl CliOptions {
|
|||
"detect-cjs",
|
||||
"fmt-component",
|
||||
"fmt-sql",
|
||||
"lazy-npm-caching",
|
||||
])
|
||||
.collect();
|
||||
|
||||
|
@ -1796,6 +1795,19 @@ impl CliOptions {
|
|||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unstable_npm_lazy_caching(&self) -> bool {
|
||||
self.flags.unstable_config.npm_lazy_caching
|
||||
|| self.workspace().has_unstable("npm-lazy-caching")
|
||||
}
|
||||
|
||||
pub fn default_npm_caching_strategy(&self) -> NpmCachingStrategy {
|
||||
if self.flags.unstable_config.npm_lazy_caching {
|
||||
NpmCachingStrategy::Lazy
|
||||
} else {
|
||||
NpmCachingStrategy::Eager
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves the path to use for a local node_modules folder.
|
||||
|
@ -2010,6 +2022,13 @@ fn load_env_variables_from_env_file(filename: Option<&Vec<String>>) {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum NpmCachingStrategy {
|
||||
Eager,
|
||||
Lazy,
|
||||
Manual,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
|
|
@ -998,6 +998,7 @@ impl CliFactory {
|
|||
cli_options.sub_command().clone(),
|
||||
self.create_cli_main_worker_options()?,
|
||||
self.cli_options()?.otel_config(),
|
||||
self.cli_options()?.default_npm_caching_strategy(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -1258,7 +1259,11 @@ impl WorkspaceFileContainer {
|
|||
let module_graph_creator = entry.factory.module_graph_creator().await?;
|
||||
let specifiers = entry.checked_specifiers().cloned().collect::<Vec<_>>();
|
||||
let graph = module_graph_creator
|
||||
.create_graph(graph_kind, specifiers.clone())
|
||||
.create_graph(
|
||||
graph_kind,
|
||||
specifiers.clone(),
|
||||
crate::graph_util::NpmCachingStrategy::Eager,
|
||||
)
|
||||
.await?;
|
||||
module_graph_creator.graph_valid(&graph)?;
|
||||
let dependent_specifiers = specifiers
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::args::config_to_deno_graph_workspace_member;
|
|||
use crate::args::jsr_url;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::CliOptions;
|
||||
pub use crate::args::NpmCachingStrategy;
|
||||
use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS;
|
||||
use crate::cache;
|
||||
use crate::cache::FetchCacher;
|
||||
|
@ -215,6 +216,7 @@ pub struct CreateGraphOptions<'a> {
|
|||
pub is_dynamic: bool,
|
||||
/// Specify `None` to use the default CLI loader.
|
||||
pub loader: Option<&'a mut dyn Loader>,
|
||||
pub npm_caching: NpmCachingStrategy,
|
||||
}
|
||||
|
||||
pub struct ModuleGraphCreator {
|
||||
|
@ -243,10 +245,11 @@ impl ModuleGraphCreator {
|
|||
&self,
|
||||
graph_kind: GraphKind,
|
||||
roots: Vec<ModuleSpecifier>,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> Result<deno_graph::ModuleGraph, AnyError> {
|
||||
let mut cache = self.module_graph_builder.create_graph_loader();
|
||||
self
|
||||
.create_graph_with_loader(graph_kind, roots, &mut cache)
|
||||
.create_graph_with_loader(graph_kind, roots, &mut cache, npm_caching)
|
||||
.await
|
||||
}
|
||||
|
||||
|
@ -255,6 +258,7 @@ impl ModuleGraphCreator {
|
|||
graph_kind: GraphKind,
|
||||
roots: Vec<ModuleSpecifier>,
|
||||
loader: &mut dyn Loader,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> Result<ModuleGraph, AnyError> {
|
||||
self
|
||||
.create_graph_with_options(CreateGraphOptions {
|
||||
|
@ -262,6 +266,7 @@ impl ModuleGraphCreator {
|
|||
graph_kind,
|
||||
roots,
|
||||
loader: Some(loader),
|
||||
npm_caching,
|
||||
})
|
||||
.await
|
||||
}
|
||||
|
@ -314,6 +319,7 @@ impl ModuleGraphCreator {
|
|||
graph_kind: deno_graph::GraphKind::All,
|
||||
roots,
|
||||
loader: Some(&mut publish_loader),
|
||||
npm_caching: self.options.default_npm_caching_strategy(),
|
||||
})
|
||||
.await?;
|
||||
self.graph_valid(&graph)?;
|
||||
|
@ -373,6 +379,7 @@ impl ModuleGraphCreator {
|
|||
graph_kind,
|
||||
roots,
|
||||
loader: None,
|
||||
npm_caching: self.options.default_npm_caching_strategy(),
|
||||
})
|
||||
.await?;
|
||||
|
||||
|
@ -563,7 +570,8 @@ impl ModuleGraphBuilder {
|
|||
};
|
||||
let cli_resolver = &self.resolver;
|
||||
let graph_resolver = self.create_graph_resolver()?;
|
||||
let graph_npm_resolver = cli_resolver.create_graph_npm_resolver();
|
||||
let graph_npm_resolver =
|
||||
cli_resolver.create_graph_npm_resolver(options.npm_caching);
|
||||
let maybe_file_watcher_reporter = self
|
||||
.maybe_file_watcher_reporter
|
||||
.as_ref()
|
||||
|
@ -590,6 +598,7 @@ impl ModuleGraphBuilder {
|
|||
resolver: Some(&graph_resolver),
|
||||
locker: locker.as_mut().map(|l| l as _),
|
||||
},
|
||||
options.npm_caching,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
@ -600,6 +609,7 @@ impl ModuleGraphBuilder {
|
|||
roots: Vec<ModuleSpecifier>,
|
||||
loader: &'a mut dyn deno_graph::source::Loader,
|
||||
options: deno_graph::BuildOptions<'a>,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> Result<(), AnyError> {
|
||||
// ensure an "npm install" is done if the user has explicitly
|
||||
// opted into using a node_modules directory
|
||||
|
@ -610,7 +620,13 @@ impl ModuleGraphBuilder {
|
|||
.unwrap_or(false)
|
||||
{
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
let already_done =
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
if !already_done && matches!(npm_caching, NpmCachingStrategy::Eager) {
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -699,7 +715,9 @@ impl ModuleGraphBuilder {
|
|||
let parser = self.parsed_source_cache.as_capturing_parser();
|
||||
let cli_resolver = &self.resolver;
|
||||
let graph_resolver = self.create_graph_resolver()?;
|
||||
let graph_npm_resolver = cli_resolver.create_graph_npm_resolver();
|
||||
let graph_npm_resolver = cli_resolver.create_graph_npm_resolver(
|
||||
self.cli_options.default_npm_caching_strategy(),
|
||||
);
|
||||
|
||||
graph.build_fast_check_type_graph(
|
||||
deno_graph::BuildFastCheckTypeGraphOptions {
|
||||
|
|
|
@ -270,7 +270,12 @@ impl LanguageServer {
|
|||
open_docs: &open_docs,
|
||||
};
|
||||
let graph = module_graph_creator
|
||||
.create_graph_with_loader(GraphKind::All, roots.clone(), &mut loader)
|
||||
.create_graph_with_loader(
|
||||
GraphKind::All,
|
||||
roots.clone(),
|
||||
&mut loader,
|
||||
graph_util::NpmCachingStrategy::Eager,
|
||||
)
|
||||
.await?;
|
||||
graph_util::graph_valid(
|
||||
&graph,
|
||||
|
|
|
@ -133,7 +133,8 @@ impl LspScopeResolver {
|
|||
cache.for_specifier(config_data.map(|d| d.scope.as_ref())),
|
||||
config_data.and_then(|d| d.lockfile.clone()),
|
||||
)));
|
||||
let npm_graph_resolver = cli_resolver.create_graph_npm_resolver();
|
||||
let npm_graph_resolver = cli_resolver
|
||||
.create_graph_npm_resolver(crate::graph_util::NpmCachingStrategy::Eager);
|
||||
let maybe_jsx_import_source_config =
|
||||
config_data.and_then(|d| d.maybe_jsx_import_source_config());
|
||||
let graph_imports = config_data
|
||||
|
@ -343,7 +344,9 @@ impl LspResolver {
|
|||
file_referrer: Option<&ModuleSpecifier>,
|
||||
) -> WorkerCliNpmGraphResolver {
|
||||
let resolver = self.get_scope_resolver(file_referrer);
|
||||
resolver.resolver.create_graph_npm_resolver()
|
||||
resolver
|
||||
.resolver
|
||||
.create_graph_npm_resolver(crate::graph_util::NpmCachingStrategy::Eager)
|
||||
}
|
||||
|
||||
pub fn as_is_cjs_resolver(
|
||||
|
|
|
@ -157,6 +157,7 @@ impl ModuleLoadPreparer {
|
|||
graph_kind: graph.graph_kind(),
|
||||
roots: roots.to_vec(),
|
||||
loader: Some(&mut cache),
|
||||
npm_caching: self.options.default_npm_caching_strategy(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
|
|
@ -296,6 +296,12 @@ pub fn create_managed_in_npm_pkg_checker(
|
|||
Arc::new(ManagedInNpmPackageChecker { root_dir })
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum PackageCaching<'a> {
|
||||
Only(Cow<'a, [PackageReq]>),
|
||||
All,
|
||||
}
|
||||
|
||||
/// An npm resolver where the resolution is managed by Deno rather than
|
||||
/// the user bringing their own node_modules (BYONM) on the file system.
|
||||
pub struct ManagedCliNpmResolver {
|
||||
|
@ -420,19 +426,44 @@ impl ManagedCliNpmResolver {
|
|||
|
||||
/// Adds package requirements to the resolver and ensures everything is setup.
|
||||
/// This includes setting up the `node_modules` directory, if applicable.
|
||||
pub async fn add_package_reqs(
|
||||
pub async fn add_and_cache_package_reqs(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
) -> Result<(), AnyError> {
|
||||
self
|
||||
.add_package_reqs_raw(packages)
|
||||
.add_package_reqs_raw(
|
||||
packages,
|
||||
Some(PackageCaching::Only(packages.into())),
|
||||
)
|
||||
.await
|
||||
.dependencies_result
|
||||
}
|
||||
|
||||
pub async fn add_package_reqs_raw(
|
||||
pub async fn add_package_reqs_no_cache(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
) -> Result<(), AnyError> {
|
||||
self
|
||||
.add_package_reqs_raw(packages, None)
|
||||
.await
|
||||
.dependencies_result
|
||||
}
|
||||
|
||||
pub async fn add_package_reqs(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
caching: PackageCaching<'_>,
|
||||
) -> Result<(), AnyError> {
|
||||
self
|
||||
.add_package_reqs_raw(packages, Some(caching))
|
||||
.await
|
||||
.dependencies_result
|
||||
}
|
||||
|
||||
pub async fn add_package_reqs_raw<'a>(
|
||||
&self,
|
||||
packages: &[PackageReq],
|
||||
caching: Option<PackageCaching<'a>>,
|
||||
) -> AddPkgReqsResult {
|
||||
if packages.is_empty() {
|
||||
return AddPkgReqsResult {
|
||||
|
@ -449,7 +480,9 @@ impl ManagedCliNpmResolver {
|
|||
}
|
||||
}
|
||||
if result.dependencies_result.is_ok() {
|
||||
result.dependencies_result = self.cache_packages().await;
|
||||
if let Some(caching) = caching {
|
||||
result.dependencies_result = self.cache_packages(caching).await;
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
|
@ -491,16 +524,20 @@ impl ManagedCliNpmResolver {
|
|||
pub async fn inject_synthetic_types_node_package(
|
||||
&self,
|
||||
) -> Result<(), AnyError> {
|
||||
let reqs = &[PackageReq::from_str("@types/node").unwrap()];
|
||||
// add and ensure this isn't added to the lockfile
|
||||
self
|
||||
.add_package_reqs(&[PackageReq::from_str("@types/node").unwrap()])
|
||||
.add_package_reqs(reqs, PackageCaching::Only(reqs.into()))
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cache_packages(&self) -> Result<(), AnyError> {
|
||||
self.fs_resolver.cache_packages().await
|
||||
pub async fn cache_packages(
|
||||
&self,
|
||||
caching: PackageCaching<'_>,
|
||||
) -> Result<(), AnyError> {
|
||||
self.fs_resolver.cache_packages(caching).await
|
||||
}
|
||||
|
||||
pub fn resolve_pkg_folder_from_deno_module(
|
||||
|
@ -545,18 +582,18 @@ impl ManagedCliNpmResolver {
|
|||
/// Ensures that the top level `package.json` dependencies are installed.
|
||||
/// This may set up the `node_modules` directory.
|
||||
///
|
||||
/// Returns `true` if any changes (such as caching packages) were made.
|
||||
/// If this returns `false`, `node_modules` has _not_ been set up.
|
||||
/// Returns `true` if the top level packages are already installed. A
|
||||
/// return value of `false` means that new packages were added to the NPM resolution.
|
||||
pub async fn ensure_top_level_package_json_install(
|
||||
&self,
|
||||
) -> Result<bool, AnyError> {
|
||||
if !self.top_level_install_flag.raise() {
|
||||
return Ok(false); // already did this
|
||||
return Ok(true); // already did this
|
||||
}
|
||||
|
||||
let pkg_json_remote_pkgs = self.npm_install_deps_provider.remote_pkgs();
|
||||
if pkg_json_remote_pkgs.is_empty() {
|
||||
return Ok(false);
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// check if something needs resolving before bothering to load all
|
||||
|
@ -570,14 +607,16 @@ impl ManagedCliNpmResolver {
|
|||
log::debug!(
|
||||
"All package.json deps resolvable. Skipping top level install."
|
||||
);
|
||||
return Ok(false); // everything is already resolvable
|
||||
return Ok(true); // everything is already resolvable
|
||||
}
|
||||
|
||||
let pkg_reqs = pkg_json_remote_pkgs
|
||||
.iter()
|
||||
.map(|pkg| pkg.req.clone())
|
||||
.collect::<Vec<_>>();
|
||||
self.add_package_reqs(&pkg_reqs).await.map(|_| true)
|
||||
self.add_package_reqs_no_cache(&pkg_reqs).await?;
|
||||
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub async fn cache_package_info(
|
||||
|
|
|
@ -255,6 +255,10 @@ impl NpmResolution {
|
|||
.read()
|
||||
.as_valid_serialized_for_system(system_info)
|
||||
}
|
||||
|
||||
pub fn subset(&self, package_reqs: &[PackageReq]) -> NpmResolutionSnapshot {
|
||||
self.snapshot.read().subset(package_reqs)
|
||||
}
|
||||
}
|
||||
|
||||
async fn add_package_reqs_to_snapshot(
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use super::super::PackageCaching;
|
||||
use async_trait::async_trait;
|
||||
use deno_ast::ModuleSpecifier;
|
||||
use deno_core::anyhow::Context;
|
||||
|
@ -57,7 +58,10 @@ pub trait NpmPackageFsResolver: Send + Sync {
|
|||
specifier: &ModuleSpecifier,
|
||||
) -> Result<Option<NpmPackageCacheFolderId>, AnyError>;
|
||||
|
||||
async fn cache_packages(&self) -> Result<(), AnyError>;
|
||||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError>;
|
||||
|
||||
#[must_use = "the resolved return value to mitigate time-of-check to time-of-use issues"]
|
||||
fn ensure_read_permission<'a>(
|
||||
|
|
|
@ -8,6 +8,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::colors;
|
||||
use crate::npm::managed::PackageCaching;
|
||||
use crate::npm::CliNpmCache;
|
||||
use crate::npm::CliNpmTarballCache;
|
||||
use async_trait::async_trait;
|
||||
|
@ -150,10 +151,19 @@ impl NpmPackageFsResolver for GlobalNpmPackageResolver {
|
|||
)
|
||||
}
|
||||
|
||||
async fn cache_packages(&self) -> Result<(), AnyError> {
|
||||
let package_partitions = self
|
||||
.resolution
|
||||
.all_system_packages_partitioned(&self.system_info);
|
||||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
let package_partitions = match caching {
|
||||
PackageCaching::All => self
|
||||
.resolution
|
||||
.all_system_packages_partitioned(&self.system_info),
|
||||
PackageCaching::Only(reqs) => self
|
||||
.resolution
|
||||
.subset(&reqs)
|
||||
.all_system_packages_partitioned(&self.system_info),
|
||||
};
|
||||
cache_packages(&package_partitions.packages, &self.tarball_cache).await?;
|
||||
|
||||
// create the copy package folders
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::sync::Arc;
|
|||
|
||||
use crate::args::LifecycleScriptsConfig;
|
||||
use crate::colors;
|
||||
use crate::npm::managed::PackageCaching;
|
||||
use crate::npm::CliNpmCache;
|
||||
use crate::npm::CliNpmTarballCache;
|
||||
use async_trait::async_trait;
|
||||
|
@ -253,9 +254,16 @@ impl NpmPackageFsResolver for LocalNpmPackageResolver {
|
|||
))
|
||||
}
|
||||
|
||||
async fn cache_packages(&self) -> Result<(), AnyError> {
|
||||
async fn cache_packages<'a>(
|
||||
&self,
|
||||
caching: PackageCaching<'a>,
|
||||
) -> Result<(), AnyError> {
|
||||
let snapshot = match caching {
|
||||
PackageCaching::All => self.resolution.snapshot(),
|
||||
PackageCaching::Only(reqs) => self.resolution.subset(&reqs),
|
||||
};
|
||||
sync_resolution_with_fs(
|
||||
&self.resolution.snapshot(),
|
||||
&snapshot,
|
||||
&self.cache,
|
||||
&self.npm_install_deps_provider,
|
||||
&self.progress_bar,
|
||||
|
|
|
@ -41,6 +41,7 @@ pub use self::managed::CliManagedInNpmPkgCheckerCreateOptions;
|
|||
pub use self::managed::CliManagedNpmResolverCreateOptions;
|
||||
pub use self::managed::CliNpmResolverManagedSnapshotOption;
|
||||
pub use self::managed::ManagedCliNpmResolver;
|
||||
pub use self::managed::PackageCaching;
|
||||
|
||||
pub type CliNpmTarballCache = deno_npm_cache::TarballCache<CliNpmCacheEnv>;
|
||||
pub type CliNpmCache = deno_npm_cache::NpmCache<CliNpmCacheEnv>;
|
||||
|
|
|
@ -32,6 +32,7 @@ use std::path::PathBuf;
|
|||
use std::sync::Arc;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::args::NpmCachingStrategy;
|
||||
use crate::args::DENO_DISABLE_PEDANTIC_NODE_WARNINGS;
|
||||
use crate::node::CliNodeCodeTranslator;
|
||||
use crate::npm::CliNpmResolver;
|
||||
|
@ -240,11 +241,15 @@ impl CliResolver {
|
|||
|
||||
// todo(dsherret): move this off CliResolver as CliResolver is acting
|
||||
// like a factory by doing this (it's beyond its responsibility)
|
||||
pub fn create_graph_npm_resolver(&self) -> WorkerCliNpmGraphResolver {
|
||||
pub fn create_graph_npm_resolver(
|
||||
&self,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
) -> WorkerCliNpmGraphResolver {
|
||||
WorkerCliNpmGraphResolver {
|
||||
npm_resolver: self.npm_resolver.as_ref(),
|
||||
found_package_json_dep_flag: &self.found_package_json_dep_flag,
|
||||
bare_node_builtins_enabled: self.bare_node_builtins_enabled,
|
||||
npm_caching,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,6 +309,7 @@ pub struct WorkerCliNpmGraphResolver<'a> {
|
|||
npm_resolver: Option<&'a Arc<dyn CliNpmResolver>>,
|
||||
found_package_json_dep_flag: &'a AtomicFlag,
|
||||
bare_node_builtins_enabled: bool,
|
||||
npm_caching: NpmCachingStrategy,
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
|
@ -373,7 +379,20 @@ impl<'a> deno_graph::source::NpmResolver for WorkerCliNpmGraphResolver<'a> {
|
|||
Ok(())
|
||||
};
|
||||
|
||||
let result = npm_resolver.add_package_reqs_raw(package_reqs).await;
|
||||
let result = npm_resolver
|
||||
.add_package_reqs_raw(
|
||||
package_reqs,
|
||||
match self.npm_caching {
|
||||
NpmCachingStrategy::Eager => {
|
||||
Some(crate::npm::PackageCaching::All)
|
||||
}
|
||||
NpmCachingStrategy::Lazy => {
|
||||
Some(crate::npm::PackageCaching::Only(package_reqs.into()))
|
||||
}
|
||||
NpmCachingStrategy::Manual => None,
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
NpmResolvePkgReqsResult {
|
||||
results: result
|
||||
|
|
|
@ -291,7 +291,7 @@
|
|||
"type": "array",
|
||||
"description": "List of tag names that will be run. Empty list disables all tags and will only use rules from `include`.",
|
||||
"items": {
|
||||
"$ref": "https://raw.githubusercontent.com/denoland/deno_lint/main/schemas/tags.v1.json"
|
||||
"$ref": "lint-tags.v1.json"
|
||||
},
|
||||
"minItems": 0,
|
||||
"uniqueItems": true
|
||||
|
@ -300,7 +300,7 @@
|
|||
"type": "array",
|
||||
"description": "List of rule names that will be excluded from configured tag sets. If the same rule is in `include` it will be run.",
|
||||
"items": {
|
||||
"$ref": "https://raw.githubusercontent.com/denoland/deno_lint/main/schemas/rules.v1.json"
|
||||
"$ref": "lint-rules.v1.json"
|
||||
},
|
||||
"minItems": 0,
|
||||
"uniqueItems": true
|
||||
|
@ -309,7 +309,7 @@
|
|||
"type": "array",
|
||||
"description": "List of rule names that will be run. Even if the same rule is in `exclude` it will be run.",
|
||||
"items": {
|
||||
"$ref": "https://raw.githubusercontent.com/denoland/deno_lint/main/schemas/rules.v1.json"
|
||||
"$ref": "lint-rules.v1.json"
|
||||
},
|
||||
"minItems": 0,
|
||||
"uniqueItems": true
|
||||
|
|
112
cli/schemas/lint-rules.v1.json
Normal file
112
cli/schemas/lint-rules.v1.json
Normal file
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"enum": [
|
||||
"adjacent-overload-signatures",
|
||||
"ban-ts-comment",
|
||||
"ban-types",
|
||||
"ban-unknown-rule-code",
|
||||
"ban-untagged-ignore",
|
||||
"ban-untagged-todo",
|
||||
"ban-unused-ignore",
|
||||
"camelcase",
|
||||
"constructor-super",
|
||||
"default-param-last",
|
||||
"eqeqeq",
|
||||
"explicit-function-return-type",
|
||||
"explicit-module-boundary-types",
|
||||
"for-direction",
|
||||
"fresh-handler-export",
|
||||
"fresh-server-event-handlers",
|
||||
"getter-return",
|
||||
"guard-for-in",
|
||||
"no-array-constructor",
|
||||
"no-async-promise-executor",
|
||||
"no-await-in-loop",
|
||||
"no-await-in-sync-fn",
|
||||
"no-boolean-literal-for-arguments",
|
||||
"no-case-declarations",
|
||||
"no-class-assign",
|
||||
"no-compare-neg-zero",
|
||||
"no-cond-assign",
|
||||
"no-console",
|
||||
"no-const-assign",
|
||||
"no-constant-condition",
|
||||
"no-control-regex",
|
||||
"no-debugger",
|
||||
"no-delete-var",
|
||||
"no-deprecated-deno-api",
|
||||
"no-dupe-args",
|
||||
"no-dupe-class-members",
|
||||
"no-dupe-else-if",
|
||||
"no-dupe-keys",
|
||||
"no-duplicate-case",
|
||||
"no-empty",
|
||||
"no-empty-character-class",
|
||||
"no-empty-enum",
|
||||
"no-empty-interface",
|
||||
"no-empty-pattern",
|
||||
"no-eval",
|
||||
"no-ex-assign",
|
||||
"no-explicit-any",
|
||||
"no-external-import",
|
||||
"no-extra-boolean-cast",
|
||||
"no-extra-non-null-assertion",
|
||||
"no-fallthrough",
|
||||
"no-func-assign",
|
||||
"no-global-assign",
|
||||
"no-implicit-declare-namespace-export",
|
||||
"no-import-assertions",
|
||||
"no-import-assign",
|
||||
"no-inferrable-types",
|
||||
"no-inner-declarations",
|
||||
"no-invalid-regexp",
|
||||
"no-invalid-triple-slash-reference",
|
||||
"no-irregular-whitespace",
|
||||
"no-misused-new",
|
||||
"no-namespace",
|
||||
"no-new-symbol",
|
||||
"no-node-globals",
|
||||
"no-non-null-asserted-optional-chain",
|
||||
"no-non-null-assertion",
|
||||
"no-obj-calls",
|
||||
"no-octal",
|
||||
"no-process-globals",
|
||||
"no-prototype-builtins",
|
||||
"no-redeclare",
|
||||
"no-regex-spaces",
|
||||
"no-self-assign",
|
||||
"no-self-compare",
|
||||
"no-setter-return",
|
||||
"no-shadow-restricted-names",
|
||||
"no-sloppy-imports",
|
||||
"no-slow-types",
|
||||
"no-sparse-arrays",
|
||||
"no-sync-fn-in-async-fn",
|
||||
"no-this-alias",
|
||||
"no-this-before-super",
|
||||
"no-throw-literal",
|
||||
"no-top-level-await",
|
||||
"no-undef",
|
||||
"no-unreachable",
|
||||
"no-unsafe-finally",
|
||||
"no-unsafe-negation",
|
||||
"no-unused-labels",
|
||||
"no-unused-vars",
|
||||
"no-var",
|
||||
"no-window",
|
||||
"no-window-prefix",
|
||||
"no-with",
|
||||
"prefer-as-const",
|
||||
"prefer-ascii",
|
||||
"prefer-const",
|
||||
"prefer-namespace-keyword",
|
||||
"prefer-primordials",
|
||||
"require-await",
|
||||
"require-yield",
|
||||
"single-var-declarator",
|
||||
"triple-slash-reference",
|
||||
"use-isnan",
|
||||
"valid-typeof",
|
||||
"verbatim-module-syntax"
|
||||
]
|
||||
}
|
4
cli/schemas/lint-tags.v1.json
Normal file
4
cli/schemas/lint-tags.v1.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"enum": ["fresh", "jsr", "jsx", "react", "recommended"]
|
||||
}
|
|
@ -779,6 +779,7 @@ impl<'a> DenoCompileBinaryWriter<'a> {
|
|||
detect_cjs: self.cli_options.unstable_detect_cjs(),
|
||||
sloppy_imports: self.cli_options.unstable_sloppy_imports(),
|
||||
features: self.cli_options.unstable_features(),
|
||||
npm_lazy_caching: self.cli_options.unstable_npm_lazy_caching(),
|
||||
},
|
||||
otel_config: self.cli_options.otel_config(),
|
||||
};
|
||||
|
|
|
@ -924,6 +924,7 @@ pub async fn run(data: StandaloneData) -> Result<i32, AnyError> {
|
|||
serve_host: None,
|
||||
},
|
||||
metadata.otel_config,
|
||||
crate::args::NpmCachingStrategy::Lazy,
|
||||
);
|
||||
|
||||
// Initialize v8 once from the main thread.
|
||||
|
|
|
@ -69,7 +69,11 @@ pub async fn compile(
|
|||
// 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)
|
||||
.create_graph(
|
||||
GraphKind::CodeOnly,
|
||||
module_roots,
|
||||
crate::graph_util::NpmCachingStrategy::Eager,
|
||||
)
|
||||
.await?
|
||||
} else {
|
||||
graph
|
||||
|
|
|
@ -131,7 +131,11 @@ pub async fn doc(
|
|||
|_| true,
|
||||
)?;
|
||||
let graph = module_graph_creator
|
||||
.create_graph(GraphKind::TypesOnly, module_specifiers.clone())
|
||||
.create_graph(
|
||||
GraphKind::TypesOnly,
|
||||
module_specifiers.clone(),
|
||||
crate::graph_util::NpmCachingStrategy::Eager,
|
||||
)
|
||||
.await?;
|
||||
|
||||
graph_exit_integrity_errors(&graph);
|
||||
|
|
|
@ -123,7 +123,12 @@ pub async fn info(
|
|||
let mut loader = module_graph_builder.create_graph_loader();
|
||||
loader.enable_loading_cache_info(); // for displaying the cache information
|
||||
let graph = module_graph_creator
|
||||
.create_graph_with_loader(GraphKind::All, vec![specifier], &mut loader)
|
||||
.create_graph_with_loader(
|
||||
GraphKind::All,
|
||||
vec![specifier],
|
||||
&mut loader,
|
||||
crate::graph_util::NpmCachingStrategy::Eager,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// write out the lockfile if there is one
|
||||
|
|
|
@ -9,7 +9,6 @@ use crate::args::Flags;
|
|||
use crate::args::InstallFlags;
|
||||
use crate::args::InstallFlagsGlobal;
|
||||
use crate::args::InstallFlagsLocal;
|
||||
use crate::args::InstallKind;
|
||||
use crate::args::TypeCheckMode;
|
||||
use crate::args::UninstallFlags;
|
||||
use crate::args::UninstallKind;
|
||||
|
@ -339,11 +338,11 @@ pub async fn install_command(
|
|||
flags: Arc<Flags>,
|
||||
install_flags: InstallFlags,
|
||||
) -> Result<(), AnyError> {
|
||||
match install_flags.kind {
|
||||
InstallKind::Global(global_flags) => {
|
||||
match install_flags {
|
||||
InstallFlags::Global(global_flags) => {
|
||||
install_global(flags, global_flags).await
|
||||
}
|
||||
InstallKind::Local(local_flags) => {
|
||||
InstallFlags::Local(local_flags) => {
|
||||
if let InstallFlagsLocal::Add(add_flags) = &local_flags {
|
||||
check_if_installs_a_single_package_globally(Some(add_flags))?;
|
||||
}
|
||||
|
|
|
@ -556,3 +556,68 @@ struct LintError {
|
|||
file_path: String,
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
use serde::Deserialize;
|
||||
use test_util as util;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct RulesSchema {
|
||||
#[serde(rename = "$schema")]
|
||||
schema: String,
|
||||
|
||||
#[serde(rename = "enum")]
|
||||
rules: Vec<String>,
|
||||
}
|
||||
|
||||
fn get_all_rules() -> Vec<String> {
|
||||
let rule_provider = LintRuleProvider::new(None, None);
|
||||
let configured_rules =
|
||||
rule_provider.resolve_lint_rules(Default::default(), None);
|
||||
let mut all_rules = configured_rules
|
||||
.all_rule_codes
|
||||
.into_iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
all_rules.sort();
|
||||
|
||||
all_rules
|
||||
}
|
||||
|
||||
// TODO(bartlomieju): do the same for tags, once https://github.com/denoland/deno/pull/27162 lands
|
||||
#[test]
|
||||
fn all_lint_rules_are_listed_in_schema_file() {
|
||||
let all_rules = get_all_rules();
|
||||
|
||||
let rules_schema_path =
|
||||
util::root_path().join("cli/schemas/lint-rules.v1.json");
|
||||
let rules_schema_file =
|
||||
std::fs::read_to_string(&rules_schema_path).unwrap();
|
||||
|
||||
let schema: RulesSchema = serde_json::from_str(&rules_schema_file).unwrap();
|
||||
|
||||
const UPDATE_ENV_VAR_NAME: &str = "UPDATE_EXPECTED";
|
||||
|
||||
if std::env::var(UPDATE_ENV_VAR_NAME).ok().is_none() {
|
||||
assert_eq!(
|
||||
schema.rules, all_rules,
|
||||
"Lint rules schema file not up to date. Run again with {}=1 to update the expected output",
|
||||
UPDATE_ENV_VAR_NAME
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
std::fs::write(
|
||||
&rules_schema_path,
|
||||
serde_json::to_string_pretty(&RulesSchema {
|
||||
schema: schema.schema,
|
||||
rules: all_rules,
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::sync::Arc;
|
|||
use crate::factory::CliFactory;
|
||||
use crate::graph_container::ModuleGraphContainer;
|
||||
use crate::graph_container::ModuleGraphUpdatePermit;
|
||||
use crate::graph_util::CreateGraphOptions;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::futures::stream::FuturesUnordered;
|
||||
use deno_core::futures::StreamExt;
|
||||
|
@ -18,18 +19,16 @@ pub async fn cache_top_level_deps(
|
|||
) -> Result<(), AnyError> {
|
||||
let npm_resolver = factory.npm_resolver().await?;
|
||||
let cli_options = factory.cli_options()?;
|
||||
let root_permissions = factory.root_permissions_container()?;
|
||||
if let Some(npm_resolver) = npm_resolver.as_managed() {
|
||||
if !npm_resolver.ensure_top_level_package_json_install().await? {
|
||||
if let Some(lockfile) = cli_options.maybe_lockfile() {
|
||||
lockfile.error_if_changed()?;
|
||||
}
|
||||
|
||||
npm_resolver.cache_packages().await?;
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
if let Some(lockfile) = cli_options.maybe_lockfile() {
|
||||
lockfile.error_if_changed()?;
|
||||
}
|
||||
}
|
||||
// cache as many entries in the import map as we can
|
||||
let resolver = factory.workspace_resolver().await?;
|
||||
|
||||
let mut maybe_graph_error = Ok(());
|
||||
if let Some(import_map) = resolver.maybe_import_map() {
|
||||
let jsr_resolver = if let Some(resolver) = jsr_resolver {
|
||||
resolver
|
||||
|
@ -122,19 +121,29 @@ pub async fn cache_top_level_deps(
|
|||
}
|
||||
drop(info_futures);
|
||||
|
||||
factory
|
||||
.module_load_preparer()
|
||||
.await?
|
||||
.prepare_module_load(
|
||||
let graph_builder = factory.module_graph_builder().await?;
|
||||
graph_builder
|
||||
.build_graph_with_npm_resolution(
|
||||
graph,
|
||||
&roots,
|
||||
false,
|
||||
deno_config::deno_json::TsTypeLib::DenoWorker,
|
||||
root_permissions.clone(),
|
||||
None,
|
||||
CreateGraphOptions {
|
||||
loader: None,
|
||||
graph_kind: graph.graph_kind(),
|
||||
is_dynamic: false,
|
||||
roots: roots.clone(),
|
||||
npm_caching: crate::graph_util::NpmCachingStrategy::Manual,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
maybe_graph_error = graph_builder.graph_roots_valid(graph, &roots);
|
||||
}
|
||||
|
||||
if let Some(npm_resolver) = npm_resolver.as_managed() {
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
}
|
||||
|
||||
maybe_graph_error?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
use deno_core::anyhow::bail;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_semver::package::PackageNv;
|
||||
use deno_semver::package::PackageReq;
|
||||
|
@ -100,15 +101,14 @@ fn print_outdated_table(packages: &[OutdatedPackage]) {
|
|||
println!("└{package_fill}┴{current_fill}┴{update_fill}┴{latest_fill}┘",);
|
||||
}
|
||||
|
||||
#[allow(clippy::print_stdout)]
|
||||
fn print_suggestion(compatible: bool) {
|
||||
println!();
|
||||
log::info!("");
|
||||
let (cmd, txt) = if compatible {
|
||||
("", "compatible")
|
||||
} else {
|
||||
(" --latest", "available")
|
||||
};
|
||||
println!(
|
||||
log::info!(
|
||||
"{}",
|
||||
color_print::cformat!(
|
||||
"<p(245)>Run</> <u>deno outdated --update{}</> <p(245)>to update to the latest {} versions,</>\n<p(245)>or</> <u>deno outdated --help</> <p(245)>for more information.</>",
|
||||
|
@ -198,6 +198,15 @@ pub async fn outdated(
|
|||
let jsr_fetch_resolver =
|
||||
Arc::new(JsrFetchResolver::new(file_fetcher.clone()));
|
||||
|
||||
if !cli_options.start_dir.has_deno_json()
|
||||
&& !cli_options.start_dir.has_pkg_json()
|
||||
{
|
||||
bail!(
|
||||
"No deno.json or package.json in \"{}\".",
|
||||
cli_options.initial_cwd().display(),
|
||||
);
|
||||
}
|
||||
|
||||
let args = dep_manager_args(
|
||||
&factory,
|
||||
cli_options,
|
||||
|
|
|
@ -727,7 +727,9 @@ impl ReplSession {
|
|||
let has_node_specifier =
|
||||
resolved_imports.iter().any(|url| url.scheme() == "node");
|
||||
if !npm_imports.is_empty() || has_node_specifier {
|
||||
npm_resolver.add_package_reqs(&npm_imports).await?;
|
||||
npm_resolver
|
||||
.add_and_cache_package_reqs(&npm_imports)
|
||||
.await?;
|
||||
|
||||
// prevent messages in the repl about @types/node not being cached
|
||||
if has_node_specifier {
|
||||
|
|
|
@ -198,13 +198,23 @@ pub async fn eval_command(
|
|||
}
|
||||
|
||||
pub async fn maybe_npm_install(factory: &CliFactory) -> Result<(), AnyError> {
|
||||
let cli_options = factory.cli_options()?;
|
||||
// ensure an "npm install" is done if the user has explicitly
|
||||
// opted into using a managed node_modules directory
|
||||
if factory.cli_options()?.node_modules_dir()?
|
||||
== Some(NodeModulesDirMode::Auto)
|
||||
{
|
||||
if cli_options.node_modules_dir()? == Some(NodeModulesDirMode::Auto) {
|
||||
if let Some(npm_resolver) = factory.npm_resolver().await?.as_managed() {
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
let already_done =
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
if !already_done
|
||||
&& matches!(
|
||||
cli_options.default_npm_caching_strategy(),
|
||||
crate::graph_util::NpmCachingStrategy::Eager
|
||||
)
|
||||
{
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -440,6 +440,13 @@ impl<'a> TaskRunner<'a> {
|
|||
kill_signal: KillSignal,
|
||||
argv: &'a [String],
|
||||
) -> Result<i32, deno_core::anyhow::Error> {
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let cwd = match &self.task_flags.cwd {
|
||||
Some(path) => canonicalize_path(&PathBuf::from(path))
|
||||
.context("failed canonicalizing --cwd")?,
|
||||
|
@ -450,6 +457,7 @@ impl<'a> TaskRunner<'a> {
|
|||
self.npm_resolver,
|
||||
self.node_resolver,
|
||||
)?;
|
||||
|
||||
self
|
||||
.run_single(RunSingleOptions {
|
||||
task_name,
|
||||
|
@ -473,6 +481,9 @@ impl<'a> TaskRunner<'a> {
|
|||
// ensure the npm packages are installed if using a managed resolver
|
||||
if let Some(npm_resolver) = self.npm_resolver.as_managed() {
|
||||
npm_resolver.ensure_top_level_package_json_install().await?;
|
||||
npm_resolver
|
||||
.cache_packages(crate::npm::PackageCaching::All)
|
||||
.await?;
|
||||
}
|
||||
|
||||
let cwd = match &self.task_flags.cwd {
|
||||
|
@ -492,6 +503,7 @@ impl<'a> TaskRunner<'a> {
|
|||
self.npm_resolver,
|
||||
self.node_resolver,
|
||||
)?;
|
||||
|
||||
for task_name in &task_names {
|
||||
if let Some(script) = scripts.get(task_name) {
|
||||
let exit_code = self
|
||||
|
|
|
@ -50,6 +50,7 @@ use tokio::select;
|
|||
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::DenoSubcommand;
|
||||
use crate::args::NpmCachingStrategy;
|
||||
use crate::args::StorageKeyResolver;
|
||||
use crate::errors;
|
||||
use crate::npm::CliNpmResolver;
|
||||
|
@ -154,6 +155,7 @@ struct SharedWorkerState {
|
|||
options: CliMainWorkerOptions,
|
||||
subcommand: DenoSubcommand,
|
||||
otel_config: Option<OtelConfig>, // `None` means OpenTelemetry is disabled.
|
||||
default_npm_caching_strategy: NpmCachingStrategy,
|
||||
}
|
||||
|
||||
impl SharedWorkerState {
|
||||
|
@ -425,6 +427,7 @@ impl CliMainWorkerFactory {
|
|||
subcommand: DenoSubcommand,
|
||||
options: CliMainWorkerOptions,
|
||||
otel_config: Option<OtelConfig>,
|
||||
default_npm_caching_strategy: NpmCachingStrategy,
|
||||
) -> Self {
|
||||
Self {
|
||||
shared: Arc::new(SharedWorkerState {
|
||||
|
@ -448,6 +451,7 @@ impl CliMainWorkerFactory {
|
|||
options,
|
||||
subcommand,
|
||||
otel_config,
|
||||
default_npm_caching_strategy,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
@ -487,8 +491,19 @@ impl CliMainWorkerFactory {
|
|||
NpmPackageReqReference::from_specifier(&main_module)
|
||||
{
|
||||
if let Some(npm_resolver) = shared.npm_resolver.as_managed() {
|
||||
let reqs = &[package_ref.req().clone()];
|
||||
npm_resolver
|
||||
.add_package_reqs(&[package_ref.req().clone()])
|
||||
.add_package_reqs(
|
||||
reqs,
|
||||
if matches!(
|
||||
shared.default_npm_caching_strategy,
|
||||
NpmCachingStrategy::Lazy
|
||||
) {
|
||||
crate::npm::PackageCaching::Only(reqs.into())
|
||||
} else {
|
||||
crate::npm::PackageCaching::All
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,23 +3,9 @@
|
|||
use deno_lockfile::NewLockfileOptions;
|
||||
use deno_semver::jsr::JsrDepPackageReq;
|
||||
use test_util as util;
|
||||
use test_util::itest;
|
||||
use util::TestContext;
|
||||
use util::TestContextBuilder;
|
||||
|
||||
itest!(check_all {
|
||||
args: "check --allow-import --quiet --all check/all/check_all.ts",
|
||||
output: "check/all/check_all.out",
|
||||
http_server: true,
|
||||
exit_code: 1,
|
||||
});
|
||||
|
||||
itest!(check_all_local {
|
||||
args: "check --allow-import --quiet check/all/check_all.ts",
|
||||
output_str: Some(""),
|
||||
http_server: true,
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn cache_switching_config_then_no_config() {
|
||||
let context = TestContext::default();
|
||||
|
|
5
tests/specs/check/check_all/__test__.jsonc
Normal file
5
tests/specs/check/check_all/__test__.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"args": "check --allow-import --quiet --all check_all.ts",
|
||||
"output": "check_all.out",
|
||||
"exitCode": 1
|
||||
}
|
5
tests/specs/check/check_all_local/__test__.jsonc
Normal file
5
tests/specs/check/check_all_local/__test__.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"args": "check --allow-import --quiet check_all_local.ts",
|
||||
"output": "",
|
||||
"exitCode": 0
|
||||
}
|
3
tests/specs/check/check_all_local/check_all_local.ts
Normal file
3
tests/specs/check/check_all_local/check_all_local.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import * as a from "http://localhost:4545/subdir/type_error.ts";
|
||||
|
||||
console.log(a.a);
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [
|
||||
{
|
||||
"args": "install --unstable-npm-lazy-caching --entrypoint main.ts",
|
||||
"output": "install-entrypoint.out"
|
||||
},
|
||||
{
|
||||
"args": "install",
|
||||
"output": "install.out"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
[UNORDERED_START]
|
||||
Download http://localhost:4260/@denotest%2fadd
|
||||
Download http://localhost:4260/@denotest%2fsay-hello
|
||||
Download http://localhost:4260/@denotest/add/1.0.0.tgz
|
||||
[UNORDERED_END]
|
||||
Initialize @denotest/add@1.0.0
|
|
@ -0,0 +1,2 @@
|
|||
Download http://localhost:4260/@denotest/say-hello/1.0.0.tgz
|
||||
Initialize @denotest/say-hello@1.0.0
|
|
@ -0,0 +1,3 @@
|
|||
import { add } from "@denotest/add";
|
||||
|
||||
console.log(add(1, 2));
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@denotest/add": "1.0.0",
|
||||
"@denotest/say-hello": "1.0.0"
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"tests": {
|
||||
"jsx_import_source_error": {
|
||||
"args": "run --config jsx/deno-jsx-error.jsonc --check jsx_import_source_no_pragma.tsx",
|
||||
|
|
9
tests/specs/run/lazy_npm/__test__.jsonc
Normal file
9
tests/specs/run/lazy_npm/__test__.jsonc
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"steps": [
|
||||
{
|
||||
"args": "run --unstable-npm-lazy-caching -A main.ts",
|
||||
"output": "main.out"
|
||||
}
|
||||
]
|
||||
}
|
3
tests/specs/run/lazy_npm/deno.json
Normal file
3
tests/specs/run/lazy_npm/deno.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"nodeModulesDir": "auto"
|
||||
}
|
7
tests/specs/run/lazy_npm/main.out
Normal file
7
tests/specs/run/lazy_npm/main.out
Normal file
|
@ -0,0 +1,7 @@
|
|||
[UNORDERED_START]
|
||||
Download http://localhost:4260/@denotest%2fadd
|
||||
Download http://localhost:4260/@denotest%2fsay-hello
|
||||
Download http://localhost:4260/@denotest/add/1.0.0.tgz
|
||||
[UNORDERED_END]
|
||||
Initialize @denotest/add@1.0.0
|
||||
3
|
3
tests/specs/run/lazy_npm/main.ts
Normal file
3
tests/specs/run/lazy_npm/main.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
import { add } from "@denotest/add";
|
||||
|
||||
console.log(add(1, 2));
|
6
tests/specs/run/lazy_npm/package.json
Normal file
6
tests/specs/run/lazy_npm/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"@denotest/add": "1.0.0",
|
||||
"@denotest/say-hello": "1.0.0"
|
||||
}
|
||||
}
|
|
@ -26,6 +26,16 @@
|
|||
{
|
||||
"args": "outdated",
|
||||
"output": "outdated.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated foobar",
|
||||
"output": ""
|
||||
},
|
||||
{
|
||||
// Respect `--quiet flag and don't print hint how to update
|
||||
"args": "outdated --quiet",
|
||||
"output": "outdated_quiet.out"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -38,6 +48,11 @@
|
|||
{
|
||||
"args": "outdated --compatible",
|
||||
"output": "outdated_compatible.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated --compatible foobar",
|
||||
"output": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
15
tests/specs/update/deno_json/outdated_quiet.out
Normal file
15
tests/specs/update/deno_json/outdated_quiet.out
Normal file
|
@ -0,0 +1,15 @@
|
|||
┌────────────────────────────────────────────────┬─────────┬────────┬────────┐
|
||||
│ Package │ Current │ Update │ Latest │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ jsr:@denotest/multiple-exports │ 0.2.0 │ 0.2.0 │ 1.0.0 │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ jsr:@denotest/subtract │ 0.2.0 │ 0.2.0 │ 1.0.0 │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ jsr:@denotest/add │ 0.2.0 │ 0.2.1 │ 1.0.0 │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ npm:@denotest/has-patch-versions │ 0.1.0 │ 0.1.1 │ 0.2.0 │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ npm:@denotest/bin │ 0.6.0 │ 0.6.0 │ 1.0.0 │
|
||||
├────────────────────────────────────────────────┼─────────┼────────┼────────┤
|
||||
│ npm:@denotest/breaking-change-between-versions │ 1.0.0 │ 1.0.0 │ 2.0.0 │
|
||||
└────────────────────────────────────────────────┴─────────┴────────┴────────┘
|
|
@ -26,6 +26,11 @@
|
|||
{
|
||||
"args": "outdated",
|
||||
"output": "print_outdated/root.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated foobar",
|
||||
"output": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -38,6 +43,11 @@
|
|||
{
|
||||
"args": "outdated --recursive",
|
||||
"output": "print_outdated/recursive.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated foobar",
|
||||
"output": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
6
tests/specs/update/no_config_file/__test__.jsonc
Normal file
6
tests/specs/update/no_config_file/__test__.jsonc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"args": "outdated",
|
||||
"exitCode": 1,
|
||||
"output": "error: No deno.json or package.json in \"[WILDLINE]\".\n"
|
||||
}
|
|
@ -25,6 +25,11 @@
|
|||
{
|
||||
"args": "outdated",
|
||||
"output": "outdated.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated foobar",
|
||||
"output": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -37,6 +42,11 @@
|
|||
{
|
||||
"args": "outdated --compatible",
|
||||
"output": "outdated_compatible.out"
|
||||
},
|
||||
{
|
||||
// Filtering that matches nothing, should exit cleanly
|
||||
"args": "outdated --compatible foobar",
|
||||
"output": ""
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -211,7 +211,7 @@ async function ensureNoNewITests() {
|
|||
"bench_tests.rs": 0,
|
||||
"cache_tests.rs": 0,
|
||||
"cert_tests.rs": 0,
|
||||
"check_tests.rs": 2,
|
||||
"check_tests.rs": 0,
|
||||
"compile_tests.rs": 0,
|
||||
"coverage_tests.rs": 0,
|
||||
"eval_tests.rs": 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue