Skip to content

Commit 8eb0406

Browse files
committed
fix(vendor): let the backend rewrite a missing Bun workspace mirror
#300 sent every same-uuid ledger entry that was not healthy to exact redownload before the backend ran. That includes a bun.lockb workspace whose member-relative mirror tarball is missing or stale while the canonical tarball still matches its ledger SHA-256. Offline, the redownload failed with vendor_redownload_failed and skipped the backend, which would have rewritten the mirror from the committed tarball; online it downloaded an artifact the project already held. A workspace mirror issue over a canonical tarball with a recorded SHA-256 now goes straight to the backend, as repair also handles it locally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
1 parent b389a0f commit 8eb0406

2 files changed

Lines changed: 51 additions & 6 deletions

File tree

‎crates/socket-patch-cli/src/commands/vendor.rs‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2454,12 +2454,25 @@ pub(crate) async fn vendor_records_reusing(
24542454
&& (entry.artifact.file_inventory.is_some()
24552455
|| vendor::artifact_is_file_shaped(&entry.artifact.path))
24562456
}) {
2457-
if vendor::check_vendored_artifact(&common.cwd, entry, record).await
2458-
!= vendor::ArtifactHealth::Healthy
2459-
|| (entry.artifact.sha256.is_empty()
2460-
&& entry.artifact.file_inventory.is_none()
2461-
&& vendor::artifact_is_file_shaped(&entry.artifact.path))
2462-
{
2457+
let redownload =
2458+
match vendor::check_vendored_artifact(&common.cwd, entry, record).await {
2459+
vendor::ArtifactHealth::Healthy => {
2460+
entry.artifact.sha256.is_empty()
2461+
&& entry.artifact.file_inventory.is_none()
2462+
&& vendor::artifact_is_file_shaped(&entry.artifact.path)
2463+
}
2464+
// Only a Bun member-relative mirror of the verified
2465+
// canonical tarball is off: the backend rewrites it from
2466+
// the committed tarball, offline too.
2467+
vendor::ArtifactHealth::Corrupt { reason }
2468+
if reason.starts_with("vendor_workspace_artifact_")
2469+
&& !entry.artifact.sha256.is_empty() =>
2470+
{
2471+
false
2472+
}
2473+
_ => true,
2474+
};
2475+
if redownload {
24632476
if common.dry_run {
24642477
env.record(PatchEvent::new(PatchAction::Verified, candidate.clone()).with_details(serde_json::json!({"wouldRedownload": true, "path": entry.artifact.path})));
24652478
continue;

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,3 +398,35 @@ async fn rollback_and_offline_vendor_refuse_with_the_checkout_remedy() {
398398
);
399399
assert_eq!(p.lock(), hosted, "a refused rollback writes nothing");
400400
}
401+
402+
/// A Bun workspace's member-relative mirror of the vendored tarball goes
403+
/// missing while the canonical tarball still matches its ledger SHA-256:
404+
/// an offline re-vendor rewrites the mirror from the committed tarball
405+
/// rather than refusing to redownload an artifact it already holds.
406+
#[tokio::test]
407+
async fn offline_vendor_rewrites_a_missing_workspace_mirror() {
408+
let p = hosted_project("1.1.45-extensions").await;
409+
// The pre-hosted lock (`git checkout -- bun.lockb`): a plain vendor.
410+
std::fs::write(p.root().join("bun.lockb"), &p.pristine).unwrap();
411+
stage_record(p.root());
412+
let (code, env) = p.run_json(&["vendor"]);
413+
assert_eq!(code, 0, "{env:#}");
414+
let canonical = p
415+
.root()
416+
.join(format!(".socket/vendor/npm/{UUID}/minimist-1.2.2.tgz"));
417+
let mirror = p.root().join(format!(
418+
"packages/helper/.socket/vendor/npm/{UUID}/minimist-1.2.2.tgz"
419+
));
420+
let tarball = std::fs::read(&canonical).unwrap();
421+
assert_eq!(std::fs::read(&mirror).unwrap(), tarball, "{env:#}");
422+
std::fs::remove_file(&mirror).unwrap();
423+
424+
let (code, env) = p.run_json(&["vendor", "--offline"]);
425+
assert_eq!(code, 0, "{env:#}");
426+
assert!(
427+
!codes(&env).iter().any(|c| c == "vendor_redownload_failed"),
428+
"{env:#}"
429+
);
430+
assert_eq!(std::fs::read(&mirror).unwrap(), tarball);
431+
assert_eq!(std::fs::read(&canonical).unwrap(), tarball);
432+
}

0 commit comments

Comments
 (0)