Skip to content

Commit 025b4ca

Browse files
committed
Match yarn 4's real patch-commit output in tests
yarn patch-commit -s rewrites the dependency itself, not resolutions; the remedies now say to put the registry range back in its place. Assisted-by: Claude Code:claude-opus-5-5
1 parent 3d30d58 commit 025b4ca

4 files changed

Lines changed: 29 additions & 22 deletions

File tree

‎crates/socket-patch-cli/CLI_CONTRACT.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ A missing referenced diff does not remove that protection.
194194
`rollback`, `remove` and `vendor --revert` refuse that package before
195195
writing (hosted: a refused pin, exit 1; vendored:
196196
`vendor_lock_still_wired_revert_blocked`, dry runs included) and ask for the
197-
`patch:` resolution to be dropped first.
197+
`patch:` descriptor to be replaced by the registry range first.
198198

199199
Detection covers root and declared npm workspace manifests, ancestor workspace
200200
settings, and the following evidence:

‎crates/socket-patch-cli/tests/in_process_redirect.rs‎

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,33 +1172,39 @@ async fn yarn_berry_rollback_refuses_a_pin_wrapped_by_a_user_yarn_patch() {
11721172
);
11731173
assert_eq!(vlt_hosted_common::redirected(&env), 1, "{env:#}");
11741174

1175-
// What `yarn patch-commit -s` writes over the hosted pin: a
1176-
// `resolutions` entry routing the tarball descriptor to a `patch:`
1177-
// descriptor (the inner one with yarn's `%3A` escapes), the lock
1178-
// entry it resolves to, and the workspace dependency through it.
1175+
// What yarn 4.18 `yarn patch-commit -s` writes over the hosted pin:
1176+
// the dependency becomes a `patch:` descriptor wrapping the tarball
1177+
// URL (with yarn's `%3A` escapes), locked by a `patch:` entry next to
1178+
// the hosted one, which stays (the `resolutions` selector is kept).
11791179
let wrapped = format!(
1180-
"patch:{NAME}@{}#~/.yarn/patches/{NAME}-http-7f4bf328bd.patch",
1180+
"patch:{NAME}@{}#~/.yarn/patches/{NAME}-http-735c2bb24a.patch",
11811181
hosted_url.replace(':', "%3A")
11821182
);
11831183
let pkg_path = tmp.path().join("package.json");
11841184
let mut pkg: serde_json::Value =
11851185
serde_json::from_str(&std::fs::read_to_string(&pkg_path).unwrap()).unwrap();
1186-
pkg["resolutions"][format!("{NAME}@{hosted_url}")] = serde_json::json!(wrapped);
1186+
pkg["dependencies"][NAME] = serde_json::json!(wrapped);
11871187
std::fs::write(
11881188
&pkg_path,
11891189
serde_json::to_string_pretty(&pkg).unwrap() + "\n",
11901190
)
11911191
.unwrap();
11921192
let lock_path = tmp.path().join("yarn.lock");
1193-
let lock = std::fs::read_to_string(&lock_path).unwrap().replace(
1194-
&format!(" {NAME}: \"npm:^{VERSION}\"\n"),
1195-
&format!(" {NAME}: \"{wrapped}\"\n"),
1196-
) + &format!(
1197-
"\n\"{NAME}@{wrapped}\":\n version: {VERSION}\n \
1198-
resolution: \"{NAME}@{wrapped}::version={VERSION}&hash=0d6d28\"\n \
1199-
checksum: 10c0/{}\n languageName: node\n linkType: hard\n",
1193+
let pinned = std::fs::read_to_string(&lock_path).unwrap();
1194+
let patched_entry = format!(
1195+
"\"{NAME}@{wrapped}\":\n version: {VERSION}\n \
1196+
resolution: \"{NAME}@{wrapped}::version={VERSION}&hash=e516cc\"\n \
1197+
checksum: 10c0/{}\n languageName: node\n linkType: hard\n\n",
12001198
"4".repeat(128)
12011199
);
1200+
let workspace = "\"consumer@workspace:.\":";
1201+
assert!(pinned.contains(workspace), "{pinned}");
1202+
let lock = pinned
1203+
.replace(
1204+
&format!(" {NAME}: \"npm:^{VERSION}\"\n"),
1205+
&format!(" {NAME}: \"{wrapped}\"\n"),
1206+
)
1207+
.replace(workspace, &format!("{patched_entry}{workspace}"));
12021208
std::fs::write(&lock_path, &lock).unwrap();
12031209
let pkg_before = std::fs::read_to_string(&pkg_path).unwrap();
12041210

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -780,9 +780,9 @@ async fn restore_berry(
780780
format!(
781781
"{name}@{version}: a `patch:` entry from `yarn patch` still wraps the \
782782
hosted tarball in {rel}, and restoring the registry entry under it would \
783-
leave a lock `yarn install --immutable` rejects — remove the `patch:` \
784-
resolution from {pkg_rel}, run `yarn install`, roll back, then re-run \
785-
`yarn patch` on the registry version"
783+
leave a lock `yarn install --immutable` rejects — put the registry range \
784+
back in place of the `patch:` descriptor in {pkg_rel}, run `yarn install`, \
785+
roll back, then re-run `yarn patch` on the registry version"
786786
),
787787
);
788788
continue;

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -849,9 +849,9 @@ pub async fn revert_yarn_berry_opts(
849849
let detail = format!(
850850
"refusing to revert {uuid_dir_rel}: a `patch:` entry from `yarn patch` in {wired} \
851851
still wraps the vendored tarball, and restoring the registry entry under it would \
852-
leave a lock `yarn install --immutable` rejects — remove the `patch:` resolution \
853-
from {PACKAGE_JSON}, run `yarn install`, re-run `vendor --revert`, then re-run \
854-
`yarn patch` on the registry version"
852+
leave a lock `yarn install --immutable` rejects — put the registry range back in \
853+
place of the `patch:` descriptor in {PACKAGE_JSON}, run `yarn install`, re-run \
854+
`vendor --revert`, then re-run `yarn patch` on the registry version"
855855
);
856856
return RevertOutcome {
857857
success: false,
@@ -3987,7 +3987,7 @@ __metadata:
39873987
}
39883988

39893989
/// #962: the user ran `yarn patch` / `yarn patch-commit -s` over the
3990-
/// vendored package, so a `patch:` lock entry and `resolutions` value
3990+
/// vendored package, so a `patch:` lock entry and dependency descriptor
39913991
/// wrap the vendored tarball. Restoring the recorded entry would leave
39923992
/// that wrapper naming a descriptor no entry resolves: every
39933993
/// `yarn install --immutable` rejects the lock (YN0028). The revert must
@@ -4017,7 +4017,8 @@ __metadata:
40174017
tokio::fs::write(fx.lock_path(), &lock).await.unwrap();
40184018
let pkg_text = tokio::fs::read_to_string(fx.pkg_path()).await.unwrap();
40194019
let mut pkg: Value = serde_json::from_str(&pkg_text).unwrap();
4020-
pkg["resolutions"][format!("left-pad@{resolution}")] = Value::String(wrapped);
4020+
// yarn 4.18 `patch-commit -s` rewrites the dependency itself.
4021+
pkg["dependencies"]["left-pad"] = Value::String(wrapped);
40214022
let pkg_text = serde_json::to_string_pretty(&pkg).unwrap() + "\n";
40224023
tokio::fs::write(fx.pkg_path(), &pkg_text).await.unwrap();
40234024

0 commit comments

Comments
 (0)