Skip to content

Commit c8c77bf

Browse files
committed
Tighten vendor --check artifact remedies
Follow-up from review of the new vendor --check wording: - Only call the root artifact intact for a Bun member-copy failure when the ledger records its sha256; without one it was never checked. - An entry that can't be verified no longer always blames state.json: an unreadable bun.lockb says so, and other cases point at the ledger, the manifest or a re-vendor, and say repair won't rebuild. - A pending re-vendor says the ledger and manifest disagree. - A JVM entry also counts as missing when only its tree marker is gone, so the message names both. - vendor --check and repair now share one check for a Bun member copy failure. Assisted-by: Claude Code:claude-opus-5-5
1 parent e4cffb4 commit c8c77bf

3 files changed

Lines changed: 53 additions & 21 deletions

File tree

‎crates/socket-patch-cli/src/commands/vendored_backend/repair.rs‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,7 @@ impl VendoredBackend<'_> {
760760
}
761761

762762
fn workspace_copy_issue(health: &ArtifactHealth) -> bool {
763-
matches!(health, ArtifactHealth::Corrupt { reason }
764-
if reason == "vendor_workspace_artifact_missing" || reason == "vendor_workspace_artifact_corrupt")
763+
health.is_workspace_copy_issue()
765764
}
766765

767766
/// Preserve package originals while adopting/rebuilding every member-relative

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4783,8 +4783,8 @@ async fn vendor_check_fails_when_lock_no_longer_wires_artifact() {
47834783
/// REGRESSION (#1467): a missing or changed committed artifact failed
47844784
/// `vendor --check` with the Rust Debug text of the health state
47854785
/// (`Missing`, `Corrupt { reason: "vendor_sha256_mismatch" }`): no path,
4786-
/// no remedy. The reason must name the artifact and point at `repair`,
4787-
/// which then turns the check green again.
4786+
/// no remedy. The reason must name the artifact and point at `repair`;
4787+
/// restoring the committed bytes turns the check green again.
47884788
#[tokio::test]
47894789
async fn vendor_check_names_damaged_artifact_and_repair_remedy() {
47904790
let fx = npm_fixture();

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

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,16 @@ pub enum ArtifactHealth {
692692
UnknownFlavor { flavor: String },
693693
}
694694

695+
impl ArtifactHealth {
696+
/// Only a Bun member-relative copy of the canonical tarball is off;
697+
/// `repair` rewrites it from the committed tarball.
698+
pub fn is_workspace_copy_issue(&self) -> bool {
699+
matches!(self, ArtifactHealth::Corrupt { reason }
700+
if reason == "vendor_workspace_artifact_missing"
701+
|| reason == "vendor_workspace_artifact_corrupt")
702+
}
703+
}
704+
695705
/// Health-check one vendored artifact against its patch record: the
696706
/// per-file afterHash verification of [`verify_vendored_patch_record`]
697707
/// (which for dir-shaped artifacts includes the whole-tree fileInventory
@@ -782,10 +792,15 @@ pub async fn describe_artifact_failure(
782792
let path = &entry.artifact.path;
783793
Some(match health {
784794
ArtifactHealth::Healthy => return None,
795+
// A JVM tree also counts as missing when only its marker is gone.
796+
ArtifactHealth::Missing if super::jvm::apply::is_jvm_entry(entry) => format!(
797+
"committed artifact {path} or its tree marker is missing (vendor_artifact_missing); \
798+
{REPAIR}"
799+
),
785800
ArtifactHealth::Missing => {
786801
format!("committed artifact {path} is missing (vendor_artifact_missing); {REPAIR}")
787802
}
788-
ArtifactHealth::Corrupt { reason } if reason.starts_with("vendor_workspace_artifact_") => {
803+
ArtifactHealth::Corrupt { reason } if health.is_workspace_copy_issue() => {
789804
let mirror = super::bun_workspace::failing_mirror(project_root, entry)
790805
.await
791806
.unwrap_or_else(|| format!("of {path}"));
@@ -794,10 +809,14 @@ pub async fn describe_artifact_failure(
794809
} else {
795810
"has different bytes"
796811
};
797-
format!(
798-
"Bun workspace copy {mirror} {cause} ({reason}); the committed artifact {path} \
799-
it mirrors is intact; {REPAIR}"
800-
)
812+
// The canonical tarball was checked against the ledger only
813+
// when the ledger records its sha256.
814+
let canonical = if entry.artifact.sha256.is_empty() {
815+
String::new()
816+
} else {
817+
format!("; the committed artifact {path} it mirrors is intact")
818+
};
819+
format!("Bun workspace copy {mirror} {cause} ({reason}){canonical}; {REPAIR}")
801820
}
802821
ArtifactHealth::Corrupt { reason } => {
803822
let cause = match reason.as_str() {
@@ -811,12 +830,22 @@ pub async fn describe_artifact_failure(
811830
format!("committed artifact {path} {cause} ({reason}); {REPAIR}")
812831
}
813832
ArtifactHealth::StaleUuid => format!(
814-
"committed artifact {path} is for a different patch than the vendor ledger records \
833+
"the vendor ledger and the patch manifest name different patches for {path} \
815834
(vendor_uuid_mismatch); a re-vendor is pending: run `socket-patch vendor`"
816835
),
836+
ArtifactHealth::Unverifiable { reason }
837+
if reason == "vendor_workspace_artifact_invalid" =>
838+
{
839+
format!(
840+
"the Bun workspace copies of {path} cannot be checked because bun.lockb cannot be \
841+
read or names an unsafe path ({reason}); restore bun.lockb from version control \
842+
or re-run `socket-patch vendor`"
843+
)
844+
}
817845
ArtifactHealth::Unverifiable { reason } => format!(
818-
"the vendor ledger entry for {path} cannot be verified ({reason}); fix \
819-
.socket/vendor/state.json, for example by restoring it from version control"
846+
"committed artifact {path} cannot be verified ({reason}), so `socket-patch repair` \
847+
will not rebuild it; restore .socket/vendor/state.json and .socket/manifest.json \
848+
from version control, or re-run `socket-patch vendor`"
820849
),
821850
ArtifactHealth::UnknownFlavor { flavor } => format!(
822851
"{path} was vendored for the npm flavor `{flavor}`, which this socket-patch release \
@@ -1104,19 +1133,19 @@ mod tests {
11041133
(
11051134
ArtifactHealth::StaleUuid,
11061135
format!(
1107-
"committed artifact {rel} is for a different patch than the vendor ledger \
1108-
records (vendor_uuid_mismatch); a re-vendor is pending: run \
1109-
`socket-patch vendor`"
1136+
"the vendor ledger and the patch manifest name different patches for {rel} \
1137+
(vendor_uuid_mismatch); a re-vendor is pending: run `socket-patch vendor`"
11101138
),
11111139
),
11121140
(
11131141
ArtifactHealth::Unverifiable {
11141142
reason: "vendor_artifact_path_invalid".into(),
11151143
},
11161144
format!(
1117-
"the vendor ledger entry for {rel} cannot be verified \
1118-
(vendor_artifact_path_invalid); fix .socket/vendor/state.json, for example \
1119-
by restoring it from version control"
1145+
"committed artifact {rel} cannot be verified (vendor_artifact_path_invalid), \
1146+
so `socket-patch repair` will not rebuild it; restore \
1147+
.socket/vendor/state.json and .socket/manifest.json from version control, \
1148+
or re-run `socket-patch vendor`"
11201149
),
11211150
),
11221151
(
@@ -1139,9 +1168,13 @@ mod tests {
11391168
})
11401169
.await
11411170
.unwrap();
1142-
assert!(
1143-
text.starts_with(&format!("Bun workspace copy of {rel} is missing")),
1144-
"{text}"
1171+
assert_eq!(
1172+
text,
1173+
format!(
1174+
"Bun workspace copy of {rel} is missing (vendor_workspace_artifact_missing); run \
1175+
`socket-patch repair` to restore it, then commit it"
1176+
),
1177+
"no recorded sha256: the canonical tarball is not claimed intact"
11451178
);
11461179
assert!(!text.contains('{') && !text.contains('"'), "{text}");
11471180
}

0 commit comments

Comments
 (0)