Skip to content

Commit fd7e333

Browse files
committed
Address review: merge pruned entries, quiet warnings
The vendored berry revert also merges a restored pruned entry into a sibling with its resolution. The hosted restore drops its node-gyp advisory for an entry merged into yarn's own, and skips the catalog lookup when nothing is folded. Assisted-by: Claude Code:claude-opus-5-5
1 parent f83518a commit fd7e333

4 files changed

Lines changed: 56 additions & 15 deletions

File tree

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

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,13 @@ pub(crate) fn stanza_lines(stanza: &str) -> Vec<String> {
9090
/// keyed by every descriptor, sorted, and `--immutable` rejects a lock
9191
/// that keeps them apart (YN0028). The entry yarn wrote keeps its body;
9292
/// the restored one only adds its keys. The merged key goes to `moved`,
93-
/// for [`BerryStanzas::render`] to sort.
93+
/// for [`BerryStanzas::render`] to sort. Returns the indices (before the
94+
/// call) of the restored stanzas merged away.
9495
pub(crate) fn merge_same_resolution(
9596
stanzas: &mut Vec<String>,
9697
restored: &[usize],
9798
moved: &mut Vec<String>,
98-
) -> bool {
99+
) -> Vec<usize> {
99100
use super::blocks::berry_field;
100101
use super::patterns::split_berry_key_patterns;
101102

@@ -120,20 +121,23 @@ pub(crate) fn merge_same_resolution(
120121
.collect();
121122
patterns.sort();
122123
patterns.dedup();
123-
let old_key = stanza_key(&stanzas[idx]).unwrap_or("").to_string();
124-
moved.retain(|k| *k != old_key);
124+
for old in [idx, sibling] {
125+
let old_key = stanza_key(&stanzas[old]).unwrap_or("").to_string();
126+
moved.retain(|k| *k != old_key);
127+
}
125128
let key = format!("\"{}\"", patterns.join(", "));
126129
let mut lines = stanza_lines(&stanzas[sibling]);
127130
lines[0] = format!("{key}:");
128131
stanzas[sibling] = lines.join("\n");
129132
moved.push(key);
130133
dropped.push(idx);
131134
}
132-
dropped.sort_unstable_by(|a, b| b.cmp(a));
133-
for idx in &dropped {
134-
stanzas.remove(*idx);
135+
let mut descending = dropped.clone();
136+
descending.sort_unstable_by(|a, b| b.cmp(a));
137+
for idx in descending {
138+
stanzas.remove(idx);
135139
}
136-
!dropped.is_empty()
140+
dropped
137141
}
138142

139143
/// A stanza's sort key: its unquoted key, or `None` for header comment
@@ -199,6 +203,28 @@ mod tests {
199203
}
200204
}
201205

206+
/// #1082: a restored entry joins the entry yarn wrote for the same
207+
/// resolution (sorted union of keys, yarn's body); one with no such
208+
/// sibling, and an entry of another resolution, are left alone.
209+
#[test]
210+
fn restored_entries_merge_into_a_sibling_with_their_resolution() {
211+
let raw = "__metadata:\n version: 8\n\n\
212+
\"a@npm:^1.0.0\":\n version: 1.0.0\n resolution: \"a@npm:1.0.0\"\n restored: x\n\n\
213+
\"b@npm:^2\":\n version: 2.0.0\n resolution: \"b@npm:2.0.0\"\n\n\
214+
\"c@npm:a@1.0.0\":\n version: 1.0.0\n resolution: \"a@npm:1.0.0\"\n yarn: y\n";
215+
let mut doc = BerryStanzas::parse(raw);
216+
let mut moved = vec!["\"a@npm:^1.0.0\"".to_string()];
217+
let merged = merge_same_resolution(&mut doc.stanzas, &[1, 2], &mut moved);
218+
assert_eq!(merged, vec![1]);
219+
assert_eq!(moved, vec!["\"a@npm:^1.0.0, c@npm:a@1.0.0\"".to_string()]);
220+
assert_eq!(
221+
doc.render(&moved),
222+
"__metadata:\n version: 8\n\n\
223+
\"a@npm:^1.0.0, c@npm:a@1.0.0\":\n version: 1.0.0\n resolution: \"a@npm:1.0.0\"\n yarn: y\n\n\
224+
\"b@npm:^2\":\n version: 2.0.0\n resolution: \"b@npm:2.0.0\"\n"
225+
);
226+
}
227+
202228
#[test]
203229
fn a_moved_entry_goes_to_its_sorted_place_only_in_a_sorted_lock() {
204230
let raw = "__metadata:\n version: 8\n\n\"a@npm:^1\":\n v: 1\n\n\"b@npm:^1\":\n v: 1\n";

‎crates/socket-patch-core/src/patch/redirect/mod.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4806,7 +4806,9 @@ fn rewrite_yarn_berry_with_manifests(
48064806
.iter()
48074807
.flat_map(|(_, ranges)| ranges.iter().map(String::as_str))
48084808
.collect();
4809-
pin.add_ranges(yarnrc, &fname, &folded_ranges);
4809+
if !folded_ranges.is_empty() {
4810+
pin.add_ranges(yarnrc, &fname, &folded_ranges);
4811+
}
48104812
pin
48114813
}
48124814
Err(warning) => {

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

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,9 @@ async fn restore_berry(
887887
let mut changed = false;
888888
let mut moved: Vec<String> = Vec::new();
889889
let mut restored: Vec<usize> = Vec::new();
890+
// `(block index, warning)`: kept only for an entry that is not merged
891+
// into a sibling below, whose own body yarn wrote.
892+
let mut node_gyp_unresolved: Vec<(usize, String)> = Vec::new();
890893
for Hit {
891894
idx,
892895
uuid,
@@ -978,8 +981,8 @@ async fn restore_berry(
978981
if resolvable {
979982
lines = crate::formats::yarn::berry_entry::with_implicit_node_gyp(&lines);
980983
} else {
981-
result.warnings.push((
982-
"yarn_berry_node_gyp_unresolved",
984+
node_gyp_unresolved.push((
985+
idx,
983986
format!(
984987
"{name}@{version}: yarn gives the restored registry entry an \
985988
implicit `node-gyp` dependency that {rel} no longer resolves; run \
@@ -1010,7 +1013,15 @@ async fn restore_berry(
10101013
if !changed {
10111014
return;
10121015
}
1013-
crate::formats::yarn::stanzas::merge_same_resolution(&mut blocks, &restored, &mut moved);
1016+
let merged =
1017+
crate::formats::yarn::stanzas::merge_same_resolution(&mut blocks, &restored, &mut moved);
1018+
for (idx, warning) in node_gyp_unresolved {
1019+
if !merged.contains(&idx) {
1020+
result
1021+
.warnings
1022+
.push(("yarn_berry_node_gyp_unresolved", warning));
1023+
}
1024+
}
10141025
if pkg_changed {
10151026
if let (Some(text), Some(value)) = (pkg_text.as_deref(), pkg.as_mut()) {
10161027
if let Some(obj) = value.as_object_mut() {

‎crates/socket-patch-core/src/vendor/yarn_berry_lock.rs‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ pub async fn revert_yarn_berry_opts(
764764
let mut changed = false;
765765
let restored_entries: Vec<String> = lock_recs
766766
.iter()
767-
.filter(|rec| rec.kind == KIND_LOCK_ENTRY)
767+
.filter(|rec| rec.kind == KIND_LOCK_ENTRY || rec.kind == KIND_LOCK_ENTRY_PRUNED)
768768
.filter_map(|rec| rec.original.as_ref())
769769
.filter_map(super::yarn_classic_lock::json_to_lines)
770770
.map(|lines| lines.join("\n"))
@@ -792,11 +792,13 @@ pub async fn revert_yarn_berry_opts(
792792
.filter(|&i| restored_entries.contains(&doc.stanzas[i]))
793793
.collect();
794794
let mut moved = Vec::new();
795-
if crate::formats::yarn::stanzas::merge_same_resolution(
795+
if !crate::formats::yarn::stanzas::merge_same_resolution(
796796
&mut doc.stanzas,
797797
&restored,
798798
&mut moved,
799-
) {
799+
)
800+
.is_empty()
801+
{
800802
text = doc.render(&moved);
801803
}
802804
forget_block_scans();

0 commit comments

Comments
 (0)