mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-24 08:35:19 -04:00
fix(pacquet): accept string libc in PackageMetadata (#11880)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
use crate::LockfileResolution;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Metadata for one resolved package version, as stored in the v9
|
||||
@@ -19,7 +19,11 @@ pub struct PackageMetadata {
|
||||
pub cpu: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub os: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
deserialize_with = "deserialize_string_or_vec"
|
||||
)]
|
||||
pub libc: Option<Vec<String>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub deprecated: Option<String>,
|
||||
@@ -36,7 +40,34 @@ pub struct PackageMetadata {
|
||||
pub peer_dependencies_meta: Option<HashMap<String, PeerDependencyMeta>>,
|
||||
}
|
||||
|
||||
// Some packages declare `libc` as a plain string in `package.json`; pnpm writes
|
||||
// that string as-is into the lockfile. Accepts both string and array forms,
|
||||
// normalizing to `Vec<Value>`.
|
||||
fn deserialize_string_or_vec<'de, Value, Deser>(
|
||||
deserializer: Deser,
|
||||
) -> Result<Option<Vec<Value>>, Deser::Error>
|
||||
where
|
||||
Value: Deserialize<'de>,
|
||||
Deser: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum StringOrVec<Value> {
|
||||
String(Value),
|
||||
Vec(Vec<Value>),
|
||||
}
|
||||
|
||||
let opt = Option::<StringOrVec<Value>>::deserialize(deserializer)?;
|
||||
Ok(opt.map(|value| match value {
|
||||
StringOrVec::String(item) => vec![item],
|
||||
StringOrVec::Vec(items) => items,
|
||||
}))
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct PeerDependencyMeta {
|
||||
pub optional: bool,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
44
pacquet/crates/lockfile/src/package_metadata/tests.rs
Normal file
44
pacquet/crates/lockfile/src/package_metadata/tests.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use super::PackageMetadata;
|
||||
use crate::serialize_yaml;
|
||||
use text_block_macros::text_block;
|
||||
|
||||
fn make_metadata(libc_yaml: &str) -> String {
|
||||
let base = text_block! {
|
||||
"resolution:"
|
||||
" integrity: sha512-abc123"
|
||||
" tarball: https://registry.npmjs.org/foo/-/foo-1.0.0.tgz"
|
||||
"cpu: [arm64]"
|
||||
"os: [linux]"
|
||||
};
|
||||
format!("{base}\n{libc_yaml}")
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn libc_as_string() {
|
||||
let yaml = make_metadata("libc: glibc\n");
|
||||
let metadata: PackageMetadata = serde_saphyr::from_str(&yaml).unwrap();
|
||||
assert_eq!(metadata.libc, Some(vec!["glibc".to_string()]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn libc_as_array() {
|
||||
let yaml = make_metadata("libc: [glibc]\n");
|
||||
let metadata: PackageMetadata = serde_saphyr::from_str(&yaml).unwrap();
|
||||
assert_eq!(metadata.libc, Some(vec!["glibc".to_string()]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn libc_absent() {
|
||||
let yaml = make_metadata("");
|
||||
let metadata: PackageMetadata = serde_saphyr::from_str(&yaml).unwrap();
|
||||
assert_eq!(metadata.libc, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn libc_string_roundtrip() {
|
||||
let yaml = make_metadata("libc: glibc\n");
|
||||
let metadata: PackageMetadata = serde_saphyr::from_str(&yaml).unwrap();
|
||||
let serialized = serialize_yaml::to_string(&metadata).unwrap();
|
||||
let reparsed: PackageMetadata = serde_saphyr::from_str(&serialized).unwrap();
|
||||
assert_eq!(metadata.libc, reparsed.libc);
|
||||
}
|
||||
Reference in New Issue
Block a user