summaryrefslogtreecommitdiff
path: root/cli/args
diff options
context:
space:
mode:
Diffstat (limited to 'cli/args')
-rw-r--r--cli/args/lockfile.rs100
-rw-r--r--cli/args/mod.rs11
-rw-r--r--cli/args/package_json.rs37
3 files changed, 91 insertions, 57 deletions
diff --git a/cli/args/lockfile.rs b/cli/args/lockfile.rs
index 1a3233c5a..31519aee3 100644
--- a/cli/args/lockfile.rs
+++ b/cli/args/lockfile.rs
@@ -1,18 +1,30 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
-use deno_core::error::AnyError;
+
+use std::collections::HashMap;
use std::path::PathBuf;
+use std::sync::Arc;
+
+use deno_core::anyhow::bail;
+use deno_core::anyhow::Context;
+use deno_core::error::AnyError;
+use deno_core::futures::stream::FuturesOrdered;
+use deno_core::futures::StreamExt;
+use deno_core::parking_lot::Mutex;
+use deno_npm::registry::NpmRegistryApi;
+use deno_npm::resolution::NpmResolutionSnapshot;
+use deno_npm::resolution::NpmResolutionSnapshotCreateOptions;
+use deno_npm::resolution::NpmResolutionSnapshotCreateOptionsPackage;
+use deno_npm::NpmPackageId;
+use deno_semver::npm::NpmPackageReq;
use crate::args::config_file::LockConfig;
use crate::args::ConfigFile;
-use crate::npm::NpmResolutionPackage;
use crate::Flags;
use super::DenoSubcommand;
pub use deno_lockfile::Lockfile;
pub use deno_lockfile::LockfileError;
-use deno_lockfile::NpmPackageDependencyLockfileInfo;
-use deno_lockfile::NpmPackageLockfileInfo;
pub fn discover(
flags: &Flags,
@@ -61,24 +73,68 @@ pub fn discover(
Ok(Some(lockfile))
}
-// NOTE(bartlomieju): we don't want a reverse mapping to be possible.
-#[allow(clippy::from_over_into)]
-impl Into<NpmPackageLockfileInfo> for NpmResolutionPackage {
- fn into(self) -> NpmPackageLockfileInfo {
- let dependencies = self
- .dependencies
- .into_iter()
- .map(|(name, id)| NpmPackageDependencyLockfileInfo {
- name,
- id: id.as_serialized(),
- })
- .collect();
-
- NpmPackageLockfileInfo {
- display_id: self.pkg_id.nv.to_string(),
- serialized_id: self.pkg_id.as_serialized(),
- integrity: self.dist.integrity().to_string(),
- dependencies,
+pub async fn snapshot_from_lockfile(
+ lockfile: Arc<Mutex<Lockfile>>,
+ api: &dyn NpmRegistryApi,
+) -> Result<NpmResolutionSnapshot, AnyError> {
+ let (root_packages, mut packages) = {
+ let lockfile = lockfile.lock();
+
+ let mut root_packages =
+ HashMap::<NpmPackageReq, NpmPackageId>::with_capacity(
+ lockfile.content.npm.specifiers.len(),
+ );
+ // collect the specifiers to version mappings
+ for (key, value) in &lockfile.content.npm.specifiers {
+ let package_req = NpmPackageReq::from_str(key)
+ .with_context(|| format!("Unable to parse npm specifier: {key}"))?;
+ let package_id = NpmPackageId::from_serialized(value)?;
+ root_packages.insert(package_req, package_id.clone());
+ }
+
+ // now fill the packages except for the dist information
+ let mut packages = Vec::with_capacity(lockfile.content.npm.packages.len());
+ for (key, package) in &lockfile.content.npm.packages {
+ let pkg_id = NpmPackageId::from_serialized(key)?;
+
+ // collect the dependencies
+ let mut dependencies = HashMap::with_capacity(package.dependencies.len());
+ for (name, specifier) in &package.dependencies {
+ let dep_id = NpmPackageId::from_serialized(specifier)?;
+ dependencies.insert(name.clone(), dep_id);
+ }
+
+ packages.push(NpmResolutionSnapshotCreateOptionsPackage {
+ pkg_id,
+ dist: Default::default(), // temporarily empty
+ dependencies,
+ });
}
+ (root_packages, packages)
+ };
+
+ // 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 {
+ match api.package_version_info(&nv).await? {
+ Some(version_info) => Ok(version_info),
+ None => {
+ bail!("could not find '{}' specified in the lockfile. Maybe try again with --reload", nv);
+ }
+ }
+ },
+ ));
+
+ let mut i = 0;
+ while let Some(version_info) = version_infos.next().await {
+ packages[i].dist = version_info?.dist;
+ i += 1;
}
+
+ NpmResolutionSnapshot::from_packages(NpmResolutionSnapshotCreateOptions {
+ packages,
+ root_packages,
+ })
+ .context("The lockfile is corrupt. You can recreate it with --lock-write")
}
diff --git a/cli/args/mod.rs b/cli/args/mod.rs
index bbf3f7efb..20c382622 100644
--- a/cli/args/mod.rs
+++ b/cli/args/mod.rs
@@ -8,14 +8,14 @@ mod lockfile;
pub mod package_json;
pub use self::import_map::resolve_import_map_from_specifier;
+use self::lockfile::snapshot_from_lockfile;
use self::package_json::PackageJsonDeps;
use ::import_map::ImportMap;
use deno_core::resolve_url_or_path;
-use deno_graph::npm::NpmPackageReqReference;
+use deno_npm::resolution::NpmResolutionSnapshot;
+use deno_semver::npm::NpmPackageReqReference;
use indexmap::IndexMap;
-use crate::npm::NpmRegistryApi;
-use crate::npm::NpmResolutionSnapshot;
pub use config_file::BenchConfig;
pub use config_file::CompilerOptions;
pub use config_file::ConfigFile;
@@ -65,6 +65,7 @@ use std::sync::Arc;
use crate::cache::DenoDir;
use crate::file_fetcher::FileFetcher;
use crate::npm::NpmProcessState;
+use crate::npm::NpmRegistry;
use crate::util::fs::canonicalize_path_maybe_not_exists;
use crate::version;
@@ -745,7 +746,7 @@ impl CliOptions {
pub async fn resolve_npm_resolution_snapshot(
&self,
- api: &NpmRegistryApi,
+ api: &NpmRegistry,
) -> Result<Option<NpmResolutionSnapshot>, AnyError> {
if let Some(state) = &*NPM_PROCESS_STATE {
// TODO(bartlomieju): remove this clone
@@ -755,7 +756,7 @@ impl CliOptions {
if let Some(lockfile) = self.maybe_lock_file() {
if !lockfile.lock().overwrite {
return Ok(Some(
- NpmResolutionSnapshot::from_lockfile(lockfile.clone(), api)
+ snapshot_from_lockfile(lockfile.clone(), api)
.await
.with_context(|| {
format!(
diff --git a/cli/args/package_json.rs b/cli/args/package_json.rs
index 5975395bb..c4d4ce956 100644
--- a/cli/args/package_json.rs
+++ b/cli/args/package_json.rs
@@ -7,41 +7,18 @@ use std::path::PathBuf;
use deno_core::anyhow::bail;
use deno_core::error::AnyError;
-use deno_graph::npm::NpmPackageReq;
-use deno_graph::semver::NpmVersionReqSpecifierParseError;
-use deno_graph::semver::VersionReq;
+use deno_npm::registry::parse_dep_entry_name_and_raw_version;
+use deno_npm::registry::PackageDepNpmSchemeValueParseError;
use deno_runtime::deno_node::PackageJson;
+use deno_semver::npm::NpmPackageReq;
+use deno_semver::npm::NpmVersionReqSpecifierParseError;
+use deno_semver::VersionReq;
use thiserror::Error;
-#[derive(Debug, Clone, Error, PartialEq, Eq, Hash)]
-#[error("Could not find @ symbol in npm url '{value}'")]
-pub struct PackageJsonDepNpmSchemeValueParseError {
- pub value: String,
-}
-
-/// Gets the name and raw version constraint taking into account npm
-/// package aliases.
-pub fn parse_dep_entry_name_and_raw_version<'a>(
- key: &'a str,
- value: &'a str,
-) -> Result<(&'a str, &'a str), PackageJsonDepNpmSchemeValueParseError> {
- if let Some(package_and_version) = value.strip_prefix("npm:") {
- if let Some((name, version)) = package_and_version.rsplit_once('@') {
- Ok((name, version))
- } else {
- Err(PackageJsonDepNpmSchemeValueParseError {
- value: value.to_string(),
- })
- }
- } else {
- Ok((key, value))
- }
-}
-
-#[derive(Debug, Error, Clone, Hash)]
+#[derive(Debug, Error, Clone)]
pub enum PackageJsonDepValueParseError {
#[error(transparent)]
- SchemeValue(#[from] PackageJsonDepNpmSchemeValueParseError),
+ SchemeValue(#[from] PackageDepNpmSchemeValueParseError),
#[error(transparent)]
Specifier(#[from] NpmVersionReqSpecifierParseError),
#[error("Not implemented scheme '{scheme}'")]