prefetch-npm-deps: add support for link dependencies in v2 lockfiles

This commit is contained in:
Winter 2022-11-09 22:36:54 -05:00
parent c30da46cc5
commit cc5756b171
2 changed files with 41 additions and 13 deletions

View File

@ -81,6 +81,17 @@
hash = "sha256-oIM05TGHstX1D4k2K4TJ+SHB7H/tNKzxzssqf0GJwvY="; hash = "sha256-oIM05TGHstX1D4k2K4TJ+SHB7H/tNKzxzssqf0GJwvY=";
}; };
linkDependencies = makeTest {
name = "link-dependencies";
src = fetchurl {
url = "https://raw.githubusercontent.com/evcc-io/evcc/0.106.3/package-lock.json";
hash = "sha256-6ZTBMyuyPP/63gpQugggHhKVup6OB4hZ2rmSvPJ0yEs=";
};
hash = "sha256-uQx8F5OXKm+fqx6hP6obVYTlQIYcJwtO52j6VQNo7Sk=";
};
}; };
meta = with lib; { meta = with lib; {

View File

@ -6,7 +6,7 @@ use rayon::prelude::*;
use serde::Deserialize; use serde::Deserialize;
use std::{ use std::{
collections::HashMap, collections::HashMap,
env, fs, env, fmt, fs,
path::Path, path::Path,
process::{self, Command}, process::{self, Command},
}; };
@ -25,18 +25,34 @@ struct PackageLock {
#[derive(Deserialize)] #[derive(Deserialize)]
struct OldPackage { struct OldPackage {
version: String, version: UrlOrString,
resolved: Option<String>, resolved: Option<UrlOrString>,
integrity: Option<String>, integrity: Option<String>,
dependencies: Option<HashMap<String, OldPackage>>, dependencies: Option<HashMap<String, OldPackage>>,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
struct Package { struct Package {
resolved: Option<Url>, resolved: Option<UrlOrString>,
integrity: Option<String>, integrity: Option<String>,
} }
#[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
enum UrlOrString {
Url(Url),
String(String),
}
impl fmt::Display for UrlOrString {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
UrlOrString::Url(url) => url.fmt(f),
UrlOrString::String(string) => string.fmt(f),
}
}
}
fn to_new_packages( fn to_new_packages(
old_packages: HashMap<String, OldPackage>, old_packages: HashMap<String, OldPackage>,
) -> anyhow::Result<HashMap<String, Package>> { ) -> anyhow::Result<HashMap<String, Package>> {
@ -46,10 +62,10 @@ fn to_new_packages(
new.insert( new.insert(
format!("{name}-{}", package.version), format!("{name}-{}", package.version),
Package { Package {
resolved: if let Ok(url) = Url::parse(&package.version) { resolved: if matches!(package.version, UrlOrString::Url(_)) {
Some(url) Some(package.version)
} else { } else {
package.resolved.as_deref().map(Url::parse).transpose()? package.resolved
}, },
integrity: package.integrity, integrity: package.integrity,
}, },
@ -230,14 +246,15 @@ fn main() -> anyhow::Result<()> {
packages packages
.unwrap() .unwrap()
.into_par_iter() .into_par_iter()
.filter(|(dep, _)| !dep.is_empty())
.filter(|(_, package)| matches!(package.resolved, Some(UrlOrString::Url(_))))
.try_for_each(|(dep, package)| { .try_for_each(|(dep, package)| {
if dep.is_empty() || package.resolved.is_none() {
return Ok::<_, anyhow::Error>(());
}
eprintln!("{dep}"); eprintln!("{dep}");
let mut resolved = package.resolved.unwrap(); let mut resolved = match package.resolved {
Some(UrlOrString::Url(url)) => url,
_ => unreachable!(),
};
if let Some(hosted_git_url) = get_hosted_git_url(&resolved) { if let Some(hosted_git_url) = get_hosted_git_url(&resolved) {
resolved = hosted_git_url; resolved = hosted_git_url;
@ -263,7 +280,7 @@ fn main() -> anyhow::Result<()> {
) )
.map_err(|e| anyhow!("couldn't insert cache entry for {dep}: {e:?}"))?; .map_err(|e| anyhow!("couldn't insert cache entry for {dep}: {e:?}"))?;
Ok(()) Ok::<_, anyhow::Error>(())
})?; })?;
fs::write(out.join("package-lock.json"), lock_content)?; fs::write(out.join("package-lock.json"), lock_content)?;