Skip to content

Commit 924951a

Browse files
committed
fix(vendor): classify vlt package dirs by layout, not a .zip suffix
#300 added .zip to artifact_is_file_shaped for pypi sdists. A vlt package dir path ends in the npm package name, so a package such as lodash.zip stopped being recognized as a vlt dir: its health check took the generic dir branch, which refuses the dependency links under its node_modules, and restore took the file branch and refused for want of an archive SHA-256. is_vlt_dir_entry now also accepts a path in the vendored vlt dir layout (<name>-<version>/node_modules/<name>), whatever its suffix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NEUik3Qo9HQtYGVEAMs1Di
1 parent efbbe31 commit 924951a

1 file changed

Lines changed: 36 additions & 2 deletions

File tree

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,11 +196,16 @@ async fn verify_dir_members(
196196
Ok(())
197197
}
198198

199-
/// A vlt package-dir entry: npm, flavor `vlt`, not a tarball.
199+
/// A vlt package-dir entry: npm, flavor `vlt`, not a tarball. The vendored
200+
/// dir layout decides before the suffix does: the path ends in the package
201+
/// name, which may itself end in one (`lodash.zip`).
200202
pub(crate) fn is_vlt_dir_entry(entry: &VendorEntry) -> bool {
201203
entry.ecosystem == "npm"
202204
&& entry.flavor.as_deref() == Some(super::vlt_lock::FLAVOR)
203-
&& !artifact_is_file_shaped(&entry.artifact.path)
205+
&& (!artifact_is_file_shaped(&entry.artifact.path)
206+
|| parse_vendor_path(&entry.artifact.path)
207+
.and_then(|p| super::vlt_lock_text::parse_vendored_dir_leaf(&p.leaf))
208+
.is_some())
204209
}
205210

206211
/// The largest afterHash blob the vlt manifest exemption reads.
@@ -1760,6 +1765,35 @@ mod tests {
17601765
));
17611766
}
17621767

1768+
/// A vlt package whose name ends in an archive suffix (`lodash.zip`) is
1769+
/// still a vlt dir: its dependency links pass the vlt structure rule
1770+
/// instead of failing the generic whole-tree inventory walk.
1771+
#[cfg(unix)]
1772+
#[tokio::test]
1773+
async fn vlt_dir_named_like_an_archive_is_still_a_vlt_dir() {
1774+
let tmp = tempfile::tempdir().unwrap();
1775+
let root = tmp.path();
1776+
let rel = format!(".socket/vendor/npm/{UUID}/lodash.zip-4.2.0/node_modules/lodash.zip");
1777+
let dir = root.join(&rel);
1778+
tokio::fs::create_dir_all(dir.join("node_modules"))
1779+
.await
1780+
.unwrap();
1781+
tokio::fs::write(dir.join("index.js"), PATCHED)
1782+
.await
1783+
.unwrap();
1784+
std::os::unix::fs::symlink("../../../dep", dir.join("node_modules/dep")).unwrap();
1785+
let rec = record(UUID, "package/index.js");
1786+
let mut ent = entry("npm", UUID, &rel);
1787+
ent.flavor = Some("vlt".into());
1788+
ent.artifact.file_inventory = Some(compute_package_dir_inventory(&dir).await.unwrap());
1789+
assert!(artifact_is_file_shaped(&rel));
1790+
assert!(is_vlt_dir_entry(&ent));
1791+
assert_eq!(
1792+
check_vendored_artifact(root, &ent, &rec).await,
1793+
ArtifactHealth::Healthy
1794+
);
1795+
}
1796+
17631797
#[tokio::test]
17641798
async fn vlt_manifest_blob_pins_the_inventory() {
17651799
use sha2::Digest;

0 commit comments

Comments
 (0)