Skip to content

Commit d3f6c30

Browse files
mikolalysenkoclaude
andcommitted
Merge the parallel #612 attempt into this branch
Another session pushed a co-wiring implementation to this branch while this one was finishing its own. Keep this branch's implementation (which also covers the CLI e2e, the in-sync re-run, the superseding re-vendor and the docs) and carry over that attempt's core test, which also checks that discovery finds both files with nothing contested. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2 parents 4207f59 + c17e5d8 commit d3f6c30

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

  • crates/socket-patch-core/src/vendor

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

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5785,6 +5785,72 @@ wheels = [
57855785
.await
57865786
}
57875787

5788+
/// #612: `pipenv requirements > requirements.txt` beside Pipfile.lock is
5789+
/// a second install source (Docker / plain pip). Vendored mode must wire
5790+
/// both, as hosted mode does, and revert must restore both byte for byte.
5791+
#[tokio::test]
5792+
async fn pipenv_vendor_wires_the_exported_sibling_requirements() {
5793+
const EXPORTED: &str =
5794+
"-i https://pypi.org/simple\nsix==1.16.0 ; python_version >= '2.7'\n";
5795+
let fx = pipenv_e2e_fixture().await;
5796+
touch(&fx.root, "requirements.txt", EXPORTED).await;
5797+
let VendorOutcome::Done {
5798+
entry, warnings, ..
5799+
} = pipenv_vendor(&fx, &fx.record).await
5800+
else {
5801+
panic!("vendor did not complete");
5802+
};
5803+
let requirements = tokio::fs::read_to_string(fx.root.join("requirements.txt"))
5804+
.await
5805+
.unwrap();
5806+
assert!(
5807+
requirements.contains(&format!(".socket/vendor/pypi/{UUID}/")),
5808+
"requirements.txt left unpatched:\n{requirements}"
5809+
);
5810+
let lock = tokio::fs::read_to_string(fx.root.join("Pipfile.lock"))
5811+
.await
5812+
.unwrap();
5813+
assert!(lock.contains(UUID), "Pipfile.lock not wired:\n{lock}");
5814+
assert!(
5815+
warnings.iter().all(|w| w.code != "pypi_multiple_lockfiles"),
5816+
"{warnings:?}"
5817+
);
5818+
// What `vendor --check` and `vex` read: both files wire the same
5819+
// vendored wheel, so neither contests the other.
5820+
let discovery = crate::vex::discover::discover_patched_refs(&fx.root).await;
5821+
assert!(discovery.contested.is_empty(), "{:?}", discovery.contested);
5822+
let wired_in: std::collections::BTreeSet<String> = discovery
5823+
.refs
5824+
.iter()
5825+
.filter(|r| r.uuid == UUID)
5826+
.map(|r| r.source_file.to_string_lossy().replace('\\', "/"))
5827+
.collect();
5828+
assert!(
5829+
wired_in.contains("Pipfile.lock") && wired_in.contains("requirements.txt"),
5830+
"{:?}",
5831+
discovery.refs
5832+
);
5833+
5834+
let outcome = revert_pypi(
5835+
entry.as_ref().expect("a wet vendor records its entry"),
5836+
&fx.root,
5837+
false,
5838+
)
5839+
.await;
5840+
assert!(outcome.success, "{:?}", outcome.error);
5841+
assert!(!outcome.kept_artifact, "{:?}", outcome.warnings);
5842+
assert_eq!(
5843+
tokio::fs::read_to_string(fx.root.join("requirements.txt"))
5844+
.await
5845+
.unwrap(),
5846+
EXPORTED
5847+
);
5848+
assert_eq!(
5849+
read_json(&fx.root, "Pipfile.lock").await,
5850+
serde_json::from_str::<serde_json::Value>(PIPENV_REGISTRY_LOCK).unwrap()
5851+
);
5852+
}
5853+
57885854
async fn read_json(root: &Path, name: &str) -> serde_json::Value {
57895855
serde_json::from_str(&tokio::fs::read_to_string(root.join(name)).await.unwrap()).unwrap()
57905856
}

0 commit comments

Comments
 (0)