Skip to content

Commit 95f8bed

Browse files
committed
Fix peer ranges dropped from restored yarn lock key
berry_declared_descriptors now reads both dependencies and peerDependencies when determining which descriptors to keep in a restored lock key. This fixes YN0028 failures when a peer range differs from the direct dependency range, since yarn keys entries by the union of all descriptors including peer requests. The fix adds dependency_and_peer_descriptors() to read both maps, leaving dependency_descriptors() unchanged for the prune logic which only tracks actual dependency edges.
1 parent 3977e12 commit 95f8bed

2 files changed

Lines changed: 44 additions & 6 deletions

File tree

‎crates/socket-patch-core/src/formats/yarn/berry_prune.rs‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,44 @@ pub(crate) fn dependency_descriptors(stanza: &str) -> Vec<String> {
6060
out
6161
}
6262

63+
/// The descriptors (`name@range`) an entry's `dependencies:` and
64+
/// `peerDependencies:` maps name. Yarn keys a lock entry by the union of
65+
/// every descriptor that resolved to it, including peer requests.
66+
pub(crate) fn dependency_and_peer_descriptors(stanza: &str) -> Vec<String> {
67+
let mut out = Vec::new();
68+
let mut in_deps = false;
69+
for line in stanza.lines().skip(1) {
70+
if let Some(field) = line.strip_prefix(" ").filter(|r| !r.starts_with(' ')) {
71+
in_deps =
72+
field.trim_end() == "dependencies:" || field.trim_end() == "peerDependencies:";
73+
continue;
74+
}
75+
if !in_deps {
76+
continue;
77+
}
78+
let Some(rest) = line.strip_prefix(" ").filter(|r| !r.starts_with(' ')) else {
79+
continue;
80+
};
81+
let (name, range) = match rest.strip_prefix('"') {
82+
Some(quoted) => match quoted.split_once("\": ") {
83+
Some((name, range)) => (name, range),
84+
None => continue,
85+
},
86+
None => match rest.split_once(": ") {
87+
Some((name, range)) => (name, range),
88+
None => continue,
89+
},
90+
};
91+
let range = range.trim_end();
92+
let range = range
93+
.strip_prefix('"')
94+
.and_then(|r| r.strip_suffix('"'))
95+
.unwrap_or(range);
96+
out.push(format!("{name}@{range}"));
97+
}
98+
out
99+
}
100+
63101
/// The descriptors `before` depends on that `after` (the same entry,
64102
/// rewritten) no longer does: the edges a rewrite cut.
65103
pub(crate) fn cut_descriptors(before: &str, after: &str) -> Vec<String> {

‎crates/socket-patch-core/src/patch/redirect/upstream/npm.rs‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,13 +1068,13 @@ async fn restore_berry(
10681068
}
10691069

10701070
/// The descriptors a berry lock's `stanzas` still declare: every
1071-
/// entry's `dependencies:` map, plus the descriptor a `patch:` descriptor
1072-
/// wraps (`name@patch:name@npm%3A1.3.0#…` wraps `name@npm:1.3.0`), in
1073-
/// either a dependency map or a key. Yarn 4 spells a registry range
1074-
/// `npm:range`, yarn 2 and 3 a bare `range`; see
1071+
/// entry's `dependencies:` and `peerDependencies:` map, plus the
1072+
/// descriptor a `patch:` descriptor wraps (`name@patch:name@npm%3A1.3.0#…`
1073+
/// wraps `name@npm:1.3.0`), in either a dependency map or a key. Yarn 4
1074+
/// spells a registry range `npm:range`, yarn 2 and 3 a bare `range`; see
10751075
/// [`berry_descriptor_declared`].
10761076
fn berry_declared_descriptors(stanzas: &[String]) -> BTreeSet<String> {
1077-
use crate::formats::yarn::berry_prune::dependency_descriptors;
1077+
use crate::formats::yarn::berry_prune::dependency_and_peer_descriptors;
10781078
use crate::formats::yarn::patterns::split_berry_key_patterns;
10791079
use crate::formats::yarn::stanzas::stanza_key;
10801080

@@ -1083,7 +1083,7 @@ fn berry_declared_descriptors(stanzas: &[String]) -> BTreeSet<String> {
10831083
let keys = stanza_key(stanza)
10841084
.map(split_berry_key_patterns)
10851085
.unwrap_or_default();
1086-
for descriptor in dependency_descriptors(stanza) {
1086+
for descriptor in dependency_and_peer_descriptors(stanza) {
10871087
if let Some(inner) = berry_patch_inner(&descriptor) {
10881088
out.insert(inner);
10891089
}

0 commit comments

Comments
 (0)