mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 20:29:11 +00:00
fix(lockfile): re-fetch packuments if version not found, properly pass patch packages (#28964)
Fixes two issues: - If a cached packument was out of date and missing a version from the lockfile, we would fail. Instead we should try again with a forced re-fetch - We weren't threading through the workspace patch packages correctly
This commit is contained in:
parent
6ce1e9b7f7
commit
dbb5373eab
24 changed files with 311 additions and 135 deletions
|
@ -293,7 +293,7 @@ impl CliLockfile {
|
|||
pub async fn read_from_path(
|
||||
sys: &CliSys,
|
||||
opts: CliLockfileReadFromPathOptions,
|
||||
api: &(dyn NpmPackageInfoProvider + Send + Sync),
|
||||
api: &(dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync),
|
||||
) -> Result<CliLockfile, AnyError> {
|
||||
let lockfile = match std::fs::read_to_string(&opts.file_path) {
|
||||
Ok(text) => {
|
||||
|
|
|
@ -404,10 +404,7 @@ impl CliFactory {
|
|||
let workspace_directory = workspace_factory.workspace_directory()?;
|
||||
let maybe_external_import_map =
|
||||
self.workspace_external_import_map_loader()?.get_or_load()?;
|
||||
let provider = self.npm_registry_info_provider()?.clone();
|
||||
let adapter = crate::npm::NpmPackageInfoApiAdapter(Arc::new(
|
||||
provider.as_npm_registry_api(),
|
||||
));
|
||||
let adapter = self.lockfile_npm_package_info_provider()?;
|
||||
|
||||
let maybe_lock_file = CliLockfile::discover(
|
||||
&self.sys(),
|
||||
|
@ -660,6 +657,7 @@ impl CliFactory {
|
|||
.map(|p| p.to_path_buf()),
|
||||
cli_options.lifecycle_scripts_config(),
|
||||
cli_options.npm_system_info(),
|
||||
self.workspace_npm_patch_packages()?.clone(),
|
||||
)))
|
||||
})
|
||||
.await
|
||||
|
@ -680,6 +678,15 @@ impl CliFactory {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn lockfile_npm_package_info_provider(
|
||||
&self,
|
||||
) -> Result<crate::npm::NpmPackageInfoApiAdapter, AnyError> {
|
||||
Ok(crate::npm::NpmPackageInfoApiAdapter::new(
|
||||
Arc::new(self.npm_registry_info_provider()?.as_npm_registry_api()),
|
||||
self.workspace_npm_patch_packages()?.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn npm_resolution_initializer(
|
||||
&self,
|
||||
) -> Result<&Arc<NpmResolutionInitializer>, AnyError> {
|
||||
|
|
|
@ -42,7 +42,6 @@ use deno_lib::args::has_flag_env_var;
|
|||
use deno_lib::util::hash::FastInsecureHasher;
|
||||
use deno_lint::linter::LintConfig as DenoLintConfig;
|
||||
use deno_npm::npm_rc::ResolvedNpmRc;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_package_json::PackageJsonCache;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_resolver::npmrc::discover_npmrc_from_workspace;
|
||||
|
@ -1270,7 +1269,9 @@ impl ConfigData {
|
|||
deno_json_cache: &(dyn DenoJsonCache + Sync),
|
||||
pkg_json_cache: &(dyn PackageJsonCache + Sync),
|
||||
workspace_cache: &(dyn WorkspaceCache + Sync),
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Self {
|
||||
let scope = scope.clone();
|
||||
let discover_result = match scope.to_file_path() {
|
||||
|
@ -1309,7 +1310,7 @@ impl ConfigData {
|
|||
scope,
|
||||
settings,
|
||||
Some(file_fetcher),
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
@ -1325,7 +1326,7 @@ impl ConfigData {
|
|||
scope.clone(),
|
||||
settings,
|
||||
Some(file_fetcher),
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await;
|
||||
// check if any of these need to be added to the workspace
|
||||
|
@ -1368,7 +1369,9 @@ impl ConfigData {
|
|||
scope: Arc<ModuleSpecifier>,
|
||||
settings: &Settings,
|
||||
file_fetcher: Option<&Arc<CliFileFetcher>>,
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Self {
|
||||
let (settings, workspace_folder) = settings.get_for_specifier(&scope);
|
||||
let mut watched_files = HashMap::with_capacity(10);
|
||||
|
@ -1513,8 +1516,10 @@ impl ConfigData {
|
|||
|
||||
let vendor_dir = member_dir.workspace.vendor_dir_path().cloned();
|
||||
// todo(dsherret): add caching so we don't load this so many times
|
||||
let lockfile =
|
||||
resolve_lockfile_from_workspace(&member_dir, npm_package_info_provider)
|
||||
let lockfile = resolve_lockfile_from_workspace(
|
||||
&member_dir,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await
|
||||
.map(Arc::new);
|
||||
if let Some(lockfile) = &lockfile {
|
||||
|
@ -1928,7 +1933,9 @@ impl ConfigTree {
|
|||
workspace_files: &IndexSet<PathBuf>,
|
||||
file_fetcher: &Arc<CliFileFetcher>,
|
||||
deno_dir: &DenoDir,
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) {
|
||||
lsp_log!("Refreshing configuration tree...");
|
||||
// since we're resolving a workspace multiple times in different
|
||||
|
@ -1961,7 +1968,7 @@ impl ConfigTree {
|
|||
&deno_json_cache,
|
||||
&pkg_json_cache,
|
||||
&workspace_cache,
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await,
|
||||
),
|
||||
|
@ -1995,7 +2002,7 @@ impl ConfigTree {
|
|||
&deno_json_cache,
|
||||
&pkg_json_cache,
|
||||
&workspace_cache,
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
@ -2012,7 +2019,7 @@ impl ConfigTree {
|
|||
&deno_json_cache,
|
||||
&pkg_json_cache,
|
||||
&workspace_cache,
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await;
|
||||
scopes.insert(member_scope.clone(), Arc::new(member_data));
|
||||
|
@ -2030,7 +2037,9 @@ impl ConfigTree {
|
|||
pub async fn inject_config_file(
|
||||
&mut self,
|
||||
config_file: ConfigFile,
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) {
|
||||
use sys_traits::FsCreateDirAll;
|
||||
use sys_traits::FsWrite;
|
||||
|
@ -2061,7 +2070,7 @@ impl ConfigTree {
|
|||
scope.clone(),
|
||||
&Default::default(),
|
||||
None,
|
||||
npm_package_info_provider,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await,
|
||||
);
|
||||
|
@ -2072,7 +2081,9 @@ impl ConfigTree {
|
|||
|
||||
async fn resolve_lockfile_from_workspace(
|
||||
workspace: &WorkspaceDirectory,
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Option<CliLockfile> {
|
||||
let lockfile_path = match workspace.workspace.resolve_lockfile_path() {
|
||||
Ok(Some(value)) => value,
|
||||
|
@ -2087,7 +2098,11 @@ async fn resolve_lockfile_from_workspace(
|
|||
.root_deno_json()
|
||||
.and_then(|c| c.to_lock_config().ok().flatten().map(|c| c.frozen()))
|
||||
.unwrap_or(false);
|
||||
resolve_lockfile_from_path(lockfile_path, frozen, npm_package_info_provider)
|
||||
resolve_lockfile_from_path(
|
||||
lockfile_path,
|
||||
frozen,
|
||||
lockfile_package_info_provider,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
|
@ -2124,7 +2139,9 @@ fn resolve_node_modules_dir(
|
|||
async fn resolve_lockfile_from_path(
|
||||
lockfile_path: PathBuf,
|
||||
frozen: bool,
|
||||
npm_package_info_provider: &Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
lockfile_package_info_provider: &Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Option<CliLockfile> {
|
||||
match CliLockfile::read_from_path(
|
||||
&CliSys::default(),
|
||||
|
@ -2133,7 +2150,7 @@ async fn resolve_lockfile_from_path(
|
|||
frozen,
|
||||
skip_write: false,
|
||||
},
|
||||
&crate::npm::NpmPackageInfoApiAdapter(npm_package_info_provider.clone()),
|
||||
&**lockfile_package_info_provider,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
@ -2198,8 +2215,6 @@ mod tests {
|
|||
use deno_core::resolve_url;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
|
@ -2465,16 +2480,20 @@ mod tests {
|
|||
struct DefaultRegistry;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl deno_npm::registry::NpmRegistryApi for DefaultRegistry {
|
||||
async fn package_info(
|
||||
impl deno_lockfile::NpmPackageInfoProvider for DefaultRegistry {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
_name: &str,
|
||||
) -> Result<Arc<NpmPackageInfo>, NpmRegistryPackageInfoLoadError> {
|
||||
Ok(Arc::new(NpmPackageInfo::default()))
|
||||
values: &[deno_semver::package::PackageNv],
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
Ok(values.iter().map(|_| Default::default()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn default_registry() -> Arc<dyn NpmRegistryApi + Send + Sync> {
|
||||
fn default_registry(
|
||||
) -> Arc<dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync> {
|
||||
Arc::new(DefaultRegistry)
|
||||
}
|
||||
|
||||
|
|
|
@ -1967,9 +1967,7 @@ mod tests {
|
|||
|
||||
use deno_config::deno_json::ConfigFile;
|
||||
use deno_core::resolve_url;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
|
||||
use deno_semver::package::PackageNv;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
|
@ -2011,16 +2009,20 @@ mod tests {
|
|||
struct DefaultRegistry;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl NpmRegistryApi for DefaultRegistry {
|
||||
async fn package_info(
|
||||
impl deno_lockfile::NpmPackageInfoProvider for DefaultRegistry {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
_name: &str,
|
||||
) -> Result<Arc<NpmPackageInfo>, NpmRegistryPackageInfoLoadError> {
|
||||
Ok(Arc::new(NpmPackageInfo::default()))
|
||||
values: &[PackageNv],
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
Ok(values.iter().map(|_| Default::default()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn default_registry() -> Arc<dyn NpmRegistryApi + Send + Sync> {
|
||||
fn default_registry(
|
||||
) -> Arc<dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync> {
|
||||
Arc::new(DefaultRegistry)
|
||||
}
|
||||
|
||||
|
|
|
@ -2054,9 +2054,6 @@ mod tests {
|
|||
use deno_config::deno_json::ConfigFile;
|
||||
use deno_core::serde_json;
|
||||
use deno_core::serde_json::json;
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
|
@ -2066,16 +2063,20 @@ mod tests {
|
|||
struct DefaultRegistry;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl deno_npm::registry::NpmRegistryApi for DefaultRegistry {
|
||||
async fn package_info(
|
||||
impl deno_lockfile::NpmPackageInfoProvider for DefaultRegistry {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
_name: &str,
|
||||
) -> Result<Arc<NpmPackageInfo>, NpmRegistryPackageInfoLoadError> {
|
||||
Ok(Arc::new(NpmPackageInfo::default()))
|
||||
values: &[deno_semver::package::PackageNv],
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
Ok(values.iter().map(|_| Default::default()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn default_registry() -> Arc<dyn NpmRegistryApi + Send + Sync> {
|
||||
fn default_registry(
|
||||
) -> Arc<dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync> {
|
||||
Arc::new(DefaultRegistry)
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ use deno_graph::Resolution;
|
|||
use deno_lib::args::get_root_cert_store;
|
||||
use deno_lib::args::CaData;
|
||||
use deno_lib::version::DENO_VERSION_INFO;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_path_util::url_to_file_path;
|
||||
use deno_runtime::deno_tls::rustls::RootCertStore;
|
||||
use deno_runtime::deno_tls::RootCertStoreProvider;
|
||||
|
@ -260,7 +259,8 @@ pub struct Inner {
|
|||
/// Set to `self.config.settings.enable_settings_hash()` after
|
||||
/// refreshing `self.workspace_files`.
|
||||
workspace_files_hash: u64,
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider:
|
||||
Arc<dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync>,
|
||||
_tracing: Option<super::trace::TracingGuard>,
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,9 @@ impl std::fmt::Debug for Inner {
|
|||
impl LanguageServer {
|
||||
pub fn new(
|
||||
client: Client,
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider: Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Self {
|
||||
let performance = Arc::new(Performance::default());
|
||||
Self {
|
||||
|
@ -533,7 +535,9 @@ impl Inner {
|
|||
fn new(
|
||||
client: Client,
|
||||
performance: Arc<Performance>,
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider: Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Self {
|
||||
let cache = LspCache::default();
|
||||
let http_client_provider = Arc::new(HttpClientProvider::new(None, None));
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use deno_core::error::AnyError;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
pub use repl::ReplCompletionItem;
|
||||
pub use repl::ReplLanguageServer;
|
||||
use tower_lsp::LspService;
|
||||
|
@ -42,7 +41,9 @@ mod tsc;
|
|||
mod urls;
|
||||
|
||||
pub async fn start(
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider: Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Result<(), AnyError> {
|
||||
let stdin = tokio::io::stdin();
|
||||
let stdout = tokio::io::stdout();
|
||||
|
|
|
@ -9,7 +9,6 @@ use deno_ast::SourceTextInfo;
|
|||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::error::AnyError;
|
||||
use deno_core::serde_json;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use lsp_types::Uri;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tower_lsp::lsp_types::ClientCapabilities;
|
||||
|
@ -63,7 +62,9 @@ pub struct ReplLanguageServer {
|
|||
|
||||
impl ReplLanguageServer {
|
||||
pub async fn new_initialized(
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider: Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Result<ReplLanguageServer, AnyError> {
|
||||
// downgrade info and warn lsp logging to debug
|
||||
super::logging::set_lsp_log_level(log::Level::Debug);
|
||||
|
|
|
@ -811,7 +811,7 @@ impl<'a> ResolverFactory<'a> {
|
|||
registry_info_provider.clone(),
|
||||
self.services.npm_resolution.clone(),
|
||||
maybe_lockfile.clone(),
|
||||
patch_packages,
|
||||
patch_packages.clone(),
|
||||
));
|
||||
let npm_installer = Arc::new(NpmInstaller::new(
|
||||
npm_cache.clone(),
|
||||
|
@ -827,6 +827,7 @@ impl<'a> ResolverFactory<'a> {
|
|||
maybe_node_modules_path.clone(),
|
||||
LifecycleScriptsConfig::default(),
|
||||
NpmSystemInfo::default(),
|
||||
patch_packages,
|
||||
));
|
||||
self.set_npm_installer(npm_installer);
|
||||
if let Err(err) = npm_resolution_initializer.ensure_initialized().await {
|
||||
|
|
|
@ -5751,9 +5751,6 @@ impl TscRequest {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use deno_npm::registry::NpmPackageInfo;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_npm::registry::NpmRegistryPackageInfoLoadError;
|
||||
use pretty_assertions::assert_eq;
|
||||
use test_util::TempDir;
|
||||
|
||||
|
@ -5770,16 +5767,20 @@ mod tests {
|
|||
struct DefaultRegistry;
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl deno_npm::registry::NpmRegistryApi for DefaultRegistry {
|
||||
async fn package_info(
|
||||
impl deno_lockfile::NpmPackageInfoProvider for DefaultRegistry {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
_name: &str,
|
||||
) -> Result<Arc<NpmPackageInfo>, NpmRegistryPackageInfoLoadError> {
|
||||
Ok(Arc::new(NpmPackageInfo::default()))
|
||||
values: &[deno_semver::package::PackageNv],
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
Ok(values.iter().map(|_| Default::default()).collect())
|
||||
}
|
||||
}
|
||||
|
||||
fn default_registry() -> Arc<dyn NpmRegistryApi + Send + Sync> {
|
||||
fn default_registry(
|
||||
) -> Arc<dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync> {
|
||||
Arc::new(DefaultRegistry)
|
||||
}
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ async fn run_subcommand(flags: Arc<Flags>) -> Result<i32, AnyError> {
|
|||
", colors::cyan("deno lsp"));
|
||||
}
|
||||
let factory = CliFactory::from_flags(flags.clone());
|
||||
lsp::start(Arc::new(factory.npm_registry_info_provider()?.as_npm_registry_api())).await
|
||||
lsp::start(Arc::new(factory.lockfile_npm_package_info_provider()?)).await
|
||||
}),
|
||||
DenoSubcommand::Lint(lint_flags) => spawn_subcommand(async {
|
||||
if lint_flags.rules {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Copyright 2018-2025 the Deno authors. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -14,6 +13,7 @@ use deno_semver::package::PackageNv;
|
|||
|
||||
use super::PackageCaching;
|
||||
use crate::npm::CliNpmCache;
|
||||
use crate::npm::WorkspaceNpmPatchPackages;
|
||||
|
||||
pub mod bin_entries;
|
||||
pub mod lifecycle_scripts;
|
||||
|
@ -56,6 +56,7 @@ pub struct ExtraInfoProvider {
|
|||
npm_cache: Arc<CliNpmCache>,
|
||||
npm_registry_info_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
cache: RwLock<rustc_hash::FxHashMap<PackageNv, NpmPackageExtraInfo>>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ExtraInfoProvider {
|
||||
|
@ -71,11 +72,13 @@ impl ExtraInfoProvider {
|
|||
pub fn new(
|
||||
npm_cache: Arc<CliNpmCache>,
|
||||
npm_registry_info_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
) -> Self {
|
||||
Self {
|
||||
npm_cache,
|
||||
npm_registry_info_provider,
|
||||
cache: RwLock::new(rustc_hash::FxHashMap::default()),
|
||||
workspace_patch_packages,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -107,9 +110,8 @@ impl ExtraInfoProvider {
|
|||
.package_info(&package_nv.name)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
let patched_packages = HashMap::new();
|
||||
let version_info = package_info
|
||||
.version_info(package_nv, &patched_packages)
|
||||
.version_info(package_nv, &self.workspace_patch_packages.0)
|
||||
.map_err(JsErrorBox::from_err)?;
|
||||
Ok(NpmPackageExtraInfo {
|
||||
deprecated: version_info.deprecated.clone(),
|
||||
|
|
|
@ -49,6 +49,7 @@ use crate::colors;
|
|||
use crate::npm::installer::common::NpmPackageExtraInfoProvider;
|
||||
use crate::npm::CliNpmCache;
|
||||
use crate::npm::CliNpmTarballCache;
|
||||
use crate::npm::WorkspaceNpmPatchPackages;
|
||||
use crate::sys::CliSys;
|
||||
use crate::util::fs::clone_dir_recursive;
|
||||
use crate::util::fs::symlink_dir;
|
||||
|
@ -70,6 +71,7 @@ pub struct LocalNpmPackageInstaller {
|
|||
system_info: NpmSystemInfo,
|
||||
npm_registry_info_provider:
|
||||
Arc<dyn deno_npm::registry::NpmRegistryApi + Send + Sync>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for LocalNpmPackageInstaller {
|
||||
|
@ -103,6 +105,7 @@ impl LocalNpmPackageInstaller {
|
|||
npm_registry_info_provider: Arc<
|
||||
dyn deno_npm::registry::NpmRegistryApi + Send + Sync,
|
||||
>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
) -> Self {
|
||||
Self {
|
||||
cache,
|
||||
|
@ -115,6 +118,7 @@ impl LocalNpmPackageInstaller {
|
|||
root_node_modules_path: node_modules_folder,
|
||||
system_info,
|
||||
npm_registry_info_provider,
|
||||
workspace_patch_packages,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +144,7 @@ impl NpmPackageFsInstaller for LocalNpmPackageInstaller {
|
|||
&self.sys,
|
||||
&self.system_info,
|
||||
&self.lifecycle_scripts,
|
||||
&self.workspace_patch_packages,
|
||||
)
|
||||
.await
|
||||
.map_err(JsErrorBox::from_err)
|
||||
|
@ -246,6 +251,7 @@ async fn sync_resolution_with_fs(
|
|||
sys: &CliSys,
|
||||
system_info: &NpmSystemInfo,
|
||||
lifecycle_scripts_config: &LifecycleScriptsConfig,
|
||||
workspace_patch_packages: &Arc<WorkspaceNpmPatchPackages>,
|
||||
) -> Result<(), SyncResolutionWithFsError> {
|
||||
if snapshot.is_empty() && npm_install_deps_provider.local_pkgs().is_empty() {
|
||||
return Ok(()); // don't create the directory
|
||||
|
@ -318,6 +324,7 @@ async fn sync_resolution_with_fs(
|
|||
let extra_info_provider = Arc::new(super::common::ExtraInfoProvider::new(
|
||||
cache.clone(),
|
||||
npm_registry_info_provider.clone(),
|
||||
workspace_patch_packages.clone(),
|
||||
));
|
||||
for package in &package_partitions.packages {
|
||||
if let Some(current_pkg) =
|
||||
|
|
|
@ -21,6 +21,7 @@ use self::local::LocalNpmPackageInstaller;
|
|||
pub use self::resolution::AddPkgReqsResult;
|
||||
pub use self::resolution::NpmResolutionInstaller;
|
||||
use super::NpmResolutionInitializer;
|
||||
use super::WorkspaceNpmPatchPackages;
|
||||
use crate::args::CliLockfile;
|
||||
use crate::args::LifecycleScriptsConfig;
|
||||
use crate::args::NpmInstallDepsProvider;
|
||||
|
@ -71,6 +72,7 @@ impl NpmInstaller {
|
|||
maybe_node_modules_path: Option<PathBuf>,
|
||||
lifecycle_scripts: LifecycleScriptsConfig,
|
||||
system_info: NpmSystemInfo,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
) -> Self {
|
||||
let fs_installer: Arc<dyn NpmPackageFsInstaller> =
|
||||
match maybe_node_modules_path {
|
||||
|
@ -85,6 +87,7 @@ impl NpmInstaller {
|
|||
lifecycle_scripts,
|
||||
system_info,
|
||||
npm_registry_info_provider,
|
||||
workspace_patch_packages,
|
||||
)),
|
||||
None => Arc::new(GlobalNpmPackageInstaller::new(
|
||||
npm_cache,
|
||||
|
|
|
@ -8,7 +8,6 @@ use std::sync::Arc;
|
|||
|
||||
use dashmap::DashMap;
|
||||
use deno_config::workspace::Workspace;
|
||||
use deno_core::anyhow::anyhow;
|
||||
use deno_core::futures::stream::FuturesOrdered;
|
||||
use deno_core::futures::TryStreamExt;
|
||||
use deno_core::serde_json;
|
||||
|
@ -56,24 +55,35 @@ pub type CliNpmResolverCreateOptions =
|
|||
pub type CliByonmNpmResolverCreateOptions =
|
||||
ByonmNpmResolverCreateOptions<CliSys>;
|
||||
|
||||
pub struct NpmPackageInfoApiAdapter(pub Arc<dyn NpmRegistryApi + Send + Sync>);
|
||||
pub struct NpmPackageInfoApiAdapter {
|
||||
api: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl deno_lockfile::NpmPackageInfoProvider for NpmPackageInfoApiAdapter {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
impl NpmPackageInfoApiAdapter {
|
||||
pub fn new(
|
||||
api: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
workspace_patch_packages: Arc<WorkspaceNpmPatchPackages>,
|
||||
) -> Self {
|
||||
Self {
|
||||
api,
|
||||
workspace_patch_packages,
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn get_infos(
|
||||
info_provider: &(dyn NpmRegistryApi + Send + Sync),
|
||||
workspace_patch_packages: &WorkspaceNpmPatchPackages,
|
||||
values: &[PackageNv],
|
||||
) -> Result<
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
> {
|
||||
let futs = values
|
||||
.iter()
|
||||
.map(|v| async move {
|
||||
let info = self.0.package_info(v.name.as_str()).await?;
|
||||
let version_info = info.versions.get(&v.version).ok_or_else(|| {
|
||||
anyhow!("Version {} not found for package {}", v.version, v.name)
|
||||
})?;
|
||||
let info = info_provider.package_info(v.name.as_str()).await?;
|
||||
let version_info = info.version_info(v, &workspace_patch_packages.0)?;
|
||||
Ok::<_, Box<dyn std::error::Error + Send + Sync>>(
|
||||
deno_lockfile::Lockfile5NpmInfo {
|
||||
tarball_url: version_info.dist.as_ref().and_then(|d| {
|
||||
|
@ -123,6 +133,30 @@ impl deno_lockfile::NpmPackageInfoProvider for NpmPackageInfoApiAdapter {
|
|||
.collect::<FuturesOrdered<_>>();
|
||||
let package_infos = futs.try_collect::<Vec<_>>().await?;
|
||||
Ok(package_infos)
|
||||
}
|
||||
|
||||
#[async_trait::async_trait(?Send)]
|
||||
impl deno_lockfile::NpmPackageInfoProvider for NpmPackageInfoApiAdapter {
|
||||
async fn get_npm_package_info(
|
||||
&self,
|
||||
values: &[PackageNv],
|
||||
) -> Result<
|
||||
Vec<deno_lockfile::Lockfile5NpmInfo>,
|
||||
Box<dyn std::error::Error + Send + Sync>,
|
||||
> {
|
||||
let package_infos =
|
||||
get_infos(&*self.api, &self.workspace_patch_packages, values).await;
|
||||
|
||||
match package_infos {
|
||||
Ok(package_infos) => Ok(package_infos),
|
||||
Err(err) => {
|
||||
if self.api.mark_force_reload() {
|
||||
get_infos(&*self.api, &self.workspace_patch_packages, values).await
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ pub async fn kernel(
|
|||
|
||||
let factory = CliFactory::from_flags(flags);
|
||||
let registry_provider =
|
||||
Arc::new(factory.npm_registry_info_provider()?.as_npm_registry_api());
|
||||
Arc::new(factory.lockfile_npm_package_info_provider()?);
|
||||
let cli_options = factory.cli_options()?;
|
||||
let main_module =
|
||||
resolve_url_or_path("./$deno$jupyter.mts", cli_options.initial_cwd())
|
||||
|
|
|
@ -200,7 +200,7 @@ pub async fn run(
|
|||
worker,
|
||||
main_module.clone(),
|
||||
test_event_receiver,
|
||||
Arc::new(factory.npm_registry_info_provider()?.as_npm_registry_api()),
|
||||
Arc::new(factory.lockfile_npm_package_info_provider()?),
|
||||
)
|
||||
.await?;
|
||||
let rustyline_channel = rustyline_channel();
|
||||
|
|
|
@ -33,7 +33,6 @@ use deno_graph::Position;
|
|||
use deno_graph::PositionRange;
|
||||
use deno_graph::SpecifierWithRange;
|
||||
use deno_lib::util::result::any_and_jserrorbox_downcast_ref;
|
||||
use deno_npm::registry::NpmRegistryApi;
|
||||
use deno_runtime::worker::MainWorker;
|
||||
use deno_semver::npm::NpmPackageReqReference;
|
||||
use node_resolver::NodeResolutionKind;
|
||||
|
@ -210,7 +209,9 @@ impl ReplSession {
|
|||
mut worker: MainWorker,
|
||||
main_module: ModuleSpecifier,
|
||||
test_event_receiver: TestEventReceiver,
|
||||
registry_provider: Arc<dyn NpmRegistryApi + Send + Sync>,
|
||||
registry_provider: Arc<
|
||||
dyn deno_lockfile::NpmPackageInfoProvider + Send + Sync,
|
||||
>,
|
||||
) -> Result<Self, AnyError> {
|
||||
let language_server =
|
||||
ReplLanguageServer::new_initialized(registry_provider).await?;
|
||||
|
|
37
tests/specs/lockfile/out_of_date_npm_info/__test__.jsonc
Normal file
37
tests/specs/lockfile/out_of_date_npm_info/__test__.jsonc
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"tempDir": true,
|
||||
"envs": {
|
||||
"DENO_DIR": "$PWD/deno_dir"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"args": "install",
|
||||
"output": "[WILDCARD]"
|
||||
},
|
||||
{
|
||||
"args": "run -A --no-lock ./rm-version.ts $PWD/deno_dir/npm/localhost_4260/@denotest/add/registry.json 1.0.0",
|
||||
"output": "[WILDCARD]"
|
||||
},
|
||||
{
|
||||
"args": "run -A --no-lock ./mv.ts ./deno.lock.old ./deno.lock",
|
||||
"output": ""
|
||||
},
|
||||
// trigger a lockfile update
|
||||
{
|
||||
"args": "install npm:chalk",
|
||||
"output": "[WILDCARD]"
|
||||
},
|
||||
{
|
||||
"args": "remove npm:chalk",
|
||||
"output": "[WILDCARD]"
|
||||
},
|
||||
{
|
||||
"args": [
|
||||
"eval",
|
||||
"--no-lock",
|
||||
"console.log(Deno.readTextFileSync('./deno.lock').trim())"
|
||||
],
|
||||
"output": "deno.lock.out"
|
||||
}
|
||||
]
|
||||
}
|
5
tests/specs/lockfile/out_of_date_npm_info/deno.json
Normal file
5
tests/specs/lockfile/out_of_date_npm_info/deno.json
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"imports": {
|
||||
"@denotest/add": "npm:@denotest/add@1.0.0"
|
||||
}
|
||||
}
|
16
tests/specs/lockfile/out_of_date_npm_info/deno.lock.old
Normal file
16
tests/specs/lockfile/out_of_date_npm_info/deno.lock.old
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"version": "4",
|
||||
"specifiers": {
|
||||
"npm:@denotest/add@1.0.0": "1.0.0"
|
||||
},
|
||||
"npm": {
|
||||
"@denotest/add@1.0.0": {
|
||||
"integrity": "3b2e675c1ad7fba2a45bc251992e01aff08a3c974ac09079b11e6a5b95d4bfcb"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"npm:@denotest/add@1.0.0"
|
||||
]
|
||||
}
|
||||
}
|
17
tests/specs/lockfile/out_of_date_npm_info/deno.lock.out
Normal file
17
tests/specs/lockfile/out_of_date_npm_info/deno.lock.out
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"version": "5",
|
||||
"specifiers": {
|
||||
"npm:@denotest/add@1.0.0": "1.0.0"
|
||||
},
|
||||
"npm": {
|
||||
"@denotest/add@1.0.0": {
|
||||
"integrity": "sha512-P7KqAn8qFLI/13TfERSPS0NYt7CmA0diT6bhscyT6FzZjFaAVCja3K/dk96eZDsCyI1gtwtHg5Ahh8XDIvAgrw==",
|
||||
"tarball": "http://localhost:4260/@denotest/add/1.0.0.tgz"
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"npm:@denotest/add@1.0.0"
|
||||
]
|
||||
}
|
||||
}
|
3
tests/specs/lockfile/out_of_date_npm_info/mv.ts
Normal file
3
tests/specs/lockfile/out_of_date_npm_info/mv.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
const [from, to] = Deno.args;
|
||||
|
||||
Deno.renameSync(from.trim(), to.trim());
|
14
tests/specs/lockfile/out_of_date_npm_info/rm-version.ts
Normal file
14
tests/specs/lockfile/out_of_date_npm_info/rm-version.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
const registryPath = Deno.args[0].trim();
|
||||
const version = Deno.args[1].trim();
|
||||
|
||||
const registryJson = JSON.parse(Deno.readTextFileSync(registryPath));
|
||||
|
||||
delete registryJson.versions[version];
|
||||
|
||||
if (registryJson["dist-tags"]["latest"] === version) {
|
||||
const latestVersion = Object.keys(registryJson.versions).sort()[0];
|
||||
registryJson["dist-tags"]["latest"] = latestVersion;
|
||||
}
|
||||
const registryJsonString = JSON.stringify(registryJson, null, 2);
|
||||
Deno.writeTextFileSync(registryPath, registryJsonString);
|
||||
console.log(registryJsonString);
|
Loading…
Add table
Add a link
Reference in a new issue