mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -05:00
fix(npm): eagerly reload package information when version from lockfile not found locally (#18673)
Closes #18624
This commit is contained in:
parent
a3c5193a2e
commit
17e4782140
5 changed files with 76 additions and 18 deletions
|
@ -19,6 +19,7 @@ use deno_semver::npm::NpmPackageReq;
|
|||
|
||||
use crate::args::config_file::LockConfig;
|
||||
use crate::args::ConfigFile;
|
||||
use crate::npm::CliNpmRegistryApi;
|
||||
use crate::Flags;
|
||||
|
||||
use super::DenoSubcommand;
|
||||
|
@ -75,7 +76,7 @@ pub fn discover(
|
|||
|
||||
pub async fn snapshot_from_lockfile(
|
||||
lockfile: Arc<Mutex<Lockfile>>,
|
||||
api: &dyn NpmRegistryApi,
|
||||
api: &CliNpmRegistryApi,
|
||||
) -> Result<NpmResolutionSnapshot, AnyError> {
|
||||
let (root_packages, mut packages) = {
|
||||
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
|
||||
let mut version_infos =
|
||||
FuturesOrdered::from_iter(packages.iter().map(|p| p.pkg_id.nv.clone()).map(
|
||||
|nv| async move {
|
||||
let package_info = api.package_info(&nv.name).await?;
|
||||
match package_info.version_info(&nv) {
|
||||
Ok(version_info) => Ok(version_info),
|
||||
Err(err) => {
|
||||
bail!("Could not find '{}' specified in the lockfile. Maybe try again with --reload", err.0);
|
||||
}
|
||||
}
|
||||
},
|
||||
));
|
||||
let pkg_nvs = packages
|
||||
.iter()
|
||||
.map(|p| p.pkg_id.nv.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let get_version_infos = || {
|
||||
FuturesOrdered::from_iter(pkg_nvs.iter().map(|nv| async move {
|
||||
let package_info = api.package_info(&nv.name).await?;
|
||||
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;
|
||||
while let Some(version_info) = version_infos.next().await {
|
||||
packages[i].dist = version_info?.dist;
|
||||
while let Some(result) = version_infos.next().await {
|
||||
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;
|
||||
}
|
||||
|
||||
// clear the memory cache to reduce memory usage
|
||||
api.clear_memory_cache();
|
||||
|
||||
NpmResolutionSnapshot::from_packages(NpmResolutionSnapshotCreateOptions {
|
||||
packages,
|
||||
root_packages,
|
||||
|
|
|
@ -104,7 +104,6 @@ impl PackageJsonDepsInstaller {
|
|||
if inner.npm_registry_api.mark_force_reload() {
|
||||
log::debug!("Failed to resolve package. Retrying. Error: {err:#}");
|
||||
// re-initialize
|
||||
inner.npm_registry_api.clear_memory_cache();
|
||||
reqs_with_info_futures = inner.reqs_with_info_futures();
|
||||
} else {
|
||||
return Err(err.into());
|
||||
|
|
|
@ -112,7 +112,12 @@ impl CliNpmRegistryApi {
|
|||
) {
|
||||
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> {
|
||||
|
|
|
@ -248,7 +248,6 @@ impl NpmResolver for CliGraphResolver {
|
|||
Err(err) => {
|
||||
if self.npm_registry_api.mark_force_reload() {
|
||||
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())
|
||||
} else {
|
||||
NpmPackageReqResolution::Err(err.into())
|
||||
|
|
|
@ -1761,4 +1761,38 @@ fn reload_info_not_found_cache_but_exists_remote() {
|
|||
));
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue