mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -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::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,
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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())
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue