1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

fix(npm): eagerly reload package information when version from lockfile not found locally (#18673)

Closes #18624
This commit is contained in:
David Sherret 2023-04-12 18:04:45 -04:00 committed by GitHub
parent a3c5193a2e
commit 17e4782140
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 76 additions and 18 deletions

View file

@ -19,6 +19,7 @@ use deno_semver::npm::NpmPackageReq;
use crate::args::config_file::LockConfig; use crate::args::config_file::LockConfig;
use crate::args::ConfigFile; use crate::args::ConfigFile;
use crate::npm::CliNpmRegistryApi;
use crate::Flags; use crate::Flags;
use super::DenoSubcommand; use super::DenoSubcommand;
@ -75,7 +76,7 @@ pub fn discover(
pub async fn snapshot_from_lockfile( pub async fn snapshot_from_lockfile(
lockfile: Arc<Mutex<Lockfile>>, lockfile: Arc<Mutex<Lockfile>>,
api: &dyn NpmRegistryApi, api: &CliNpmRegistryApi,
) -> Result<NpmResolutionSnapshot, AnyError> { ) -> Result<NpmResolutionSnapshot, AnyError> {
let (root_packages, mut packages) = { let (root_packages, mut packages) = {
let lockfile = lockfile.lock(); let lockfile = lockfile.lock();
@ -114,25 +115,45 @@ pub async fn snapshot_from_lockfile(
}; };
// now that the lockfile is dropped, fetch the package version information // now that the lockfile is dropped, fetch the package version information
let mut version_infos = let pkg_nvs = packages
FuturesOrdered::from_iter(packages.iter().map(|p| p.pkg_id.nv.clone()).map( .iter()
|nv| async move { .map(|p| p.pkg_id.nv.clone())
let package_info = api.package_info(&nv.name).await?; .collect::<Vec<_>>();
match package_info.version_info(&nv) { let get_version_infos = || {
Ok(version_info) => Ok(version_info), FuturesOrdered::from_iter(pkg_nvs.iter().map(|nv| async move {
Err(err) => { let package_info = api.package_info(&nv.name).await?;
bail!("Could not find '{}' specified in the lockfile. Maybe try again with --reload", err.0); match package_info.version_info(nv) {
} Ok(version_info) => Ok(version_info),
} Err(err) => {
}, bail!("Could not find '{}' specified in the lockfile.", err.0);
)); }
}
}))
};
let mut version_infos = get_version_infos();
let mut i = 0; let mut i = 0;
while let Some(version_info) = version_infos.next().await { while let Some(result) = version_infos.next().await {
packages[i].dist = version_info?.dist; packages[i].dist = match result {
Ok(version_info) => version_info.dist,
Err(err) => {
if api.mark_force_reload() {
// reset and try again
version_infos = get_version_infos();
i = 0;
continue;
} else {
return Err(err);
}
}
};
i += 1; i += 1;
} }
// clear the memory cache to reduce memory usage
api.clear_memory_cache();
NpmResolutionSnapshot::from_packages(NpmResolutionSnapshotCreateOptions { NpmResolutionSnapshot::from_packages(NpmResolutionSnapshotCreateOptions {
packages, packages,
root_packages, root_packages,

View file

@ -104,7 +104,6 @@ impl PackageJsonDepsInstaller {
if inner.npm_registry_api.mark_force_reload() { if inner.npm_registry_api.mark_force_reload() {
log::debug!("Failed to resolve package. Retrying. Error: {err:#}"); log::debug!("Failed to resolve package. Retrying. Error: {err:#}");
// re-initialize // re-initialize
inner.npm_registry_api.clear_memory_cache();
reqs_with_info_futures = inner.reqs_with_info_futures(); reqs_with_info_futures = inner.reqs_with_info_futures();
} else { } else {
return Err(err.into()); return Err(err.into());

View file

@ -112,7 +112,12 @@ impl CliNpmRegistryApi {
) { ) {
return false; return false;
} }
self.inner().force_reload_flag.raise() if self.inner().force_reload_flag.raise() {
self.clear_memory_cache(); // clear the memory cache to force reloading
true
} else {
false
}
} }
fn inner(&self) -> &Arc<CliNpmRegistryApiInner> { fn inner(&self) -> &Arc<CliNpmRegistryApiInner> {

View file

@ -248,7 +248,6 @@ impl NpmResolver for CliGraphResolver {
Err(err) => { Err(err) => {
if self.npm_registry_api.mark_force_reload() { if self.npm_registry_api.mark_force_reload() {
log::debug!("Restarting npm specifier resolution to check for new registry information. Error: {:#}", err); log::debug!("Restarting npm specifier resolution to check for new registry information. Error: {:#}", err);
self.npm_registry_api.clear_memory_cache();
NpmPackageReqResolution::ReloadRegistryInfo(err.into()) NpmPackageReqResolution::ReloadRegistryInfo(err.into())
} else { } else {
NpmPackageReqResolution::Err(err.into()) NpmPackageReqResolution::Err(err.into())

View file

@ -1761,4 +1761,38 @@ fn reload_info_not_found_cache_but_exists_remote() {
)); ));
output.assert_exit_code(0); output.assert_exit_code(0);
} }
// now try using a lockfile
{
// create it
temp_dir.write("deno.json", r#"{}"#);
test_context.new_command().args("cache main.ts").run();
assert!(temp_dir.path().join("deno.lock").exists());
// remove a version found in the lockfile
remove_version_for_package(deno_dir, "@denotest/esm-basic", "1.0.0");
// should error for --cached-only
let output = test_context
.new_command()
.args("run --cached-only main.ts")
.run();
output.assert_matches_text(concat!(
"error: failed reading lockfile '[WILDCARD]deno.lock'\n",
"\n",
"Caused by:\n",
" Could not find '@denotest/esm-basic@1.0.0' specified in the lockfile.\n"
));
output.assert_exit_code(1);
// now try running, it should work and only initialize the new package
let output = test_context.new_command().args("run main.ts").run();
output.assert_matches_text(concat!(
"Download http://localhost:4545/npm/registry/@denotest/cjs-default-export\n",
"Download http://localhost:4545/npm/registry/@denotest/esm-basic\n",
"Download http://localhost:4545/npm/registry/@denotest/esm-import-cjs-default\n",
"Node esm importing node cjs\n[WILDCARD]",
));
output.assert_exit_code(0);
}
} }