Repository navigation
Fix pip rollback refusing all-hosted requirements (#410) - #827
Mikola Lysenko (mikolalysenko) wants to merge 9 commits into
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Hosted rollback, remove and the hosted-to-vendored takeover refused a requirements.txt in which every requirement was a hosted pin (a lone `six==1.16.0`, or one beside `-e .`). They couldn't tell whether the original line used pip's hash-checking mode, so the only way back was version control. The restore now counts an editable line as unhashed evidence (pip refuses editables in hash-checking mode). When no other line settles the mode, it reads the hosted line itself: the rewriter writes `--hash` only into an already hashed file and otherwise pins by the url's `#sha256=` fragment. With nothing else in the file to conflict with, either restored form installs. Fixes #410 Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
|
BugBot review Generated by Claude Code |
|
[agent] CI status on
The head is now green (482 succeeded, 6 skipped), Bugbot found no issues, and there are no open threads. It's waiting on human review. Generated by Claude Code |
|
Ready for review — head
Generated by Claude Code |
Resolve the CLI_CONTRACT.md pypi restore bullet: keep main's uv upload_time spelling note and this branch's hash-checking-mode (#410) description. Co-Authored-By: Claude <noreply@anthropic.com>
|
bugbot run Generated by Claude Code |
Assisted-by: Claude Code:claude-opus-5-5
#605 taught the name-keyed npm resolver to probe bundled store trees, so it now finds aliased copies (node_modules/lp) and a nested host's store peers itself. Two vex_consumed tests from #738 assumed that set never held aliases, so main's CI went red after both merged. The tests now feed the alias-free set explicitly to keep covering alias expansion, and also check the resolver's own set reaches the same copies with no duplicates. No production code changes. Assisted-by: Claude Code:claude-opus-5-5 (cherry picked from commit 40dac07)
|
[agent] CI on This isn't this PR's failure: both tests fail the same way on bare Local results on Generated by Claude Code |
|
BugBot review Generated by Claude Code |
|
[agent] This isn't this PR's failure. The PR changes only the requirements.txt upstream restore, which never handles pdm.lock. The same workflow passed on Generated by Claude Code |
|
Burn-down agent: labeled Ready for review.
Generated by Claude Code |
Assisted-by: Claude Code:claude-opus-5-5
|
BugBot review Generated by Claude Code |
Assisted-by: Claude Code:claude-opus-5-5
main has failed socket-patch-core's lib tests since Gradle support (#646) and the digest helpers (#865) both landed. The guard test production_digests_go_through_the_helpers flags three files #646 added that still hash inline: crawlers/gradle_cache.rs, patch/jvm_jar.rs and patch/sidecars/maven.rs. That breaks test, test-release and coverage on every open PR. Each inline sha1/sha256 call now goes through sha1_hex_of or sha256_hex_of, which compute the same lowercase hex. Behaviour is unchanged. Assisted-by: Claude Code:claude-opus-5-5 (cherry picked from commit 659ac2c)
|
[agent] This isn't this PR's failure. The test fails the same way on bare Local results on Generated by Claude Code |
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 09364ea. Configure here.
|
Burn-down agent: labeled Ready for review at
Generated by Claude Code |
LLM Description written by Claude Code:claude-opus-5-5
Fixes #410
Summary
Hosted
rollback,remove <purl>and the hosted → vendored takeover (vendor/scan --mode vendoredover a hosted pin) no longer refuse arequirements.txtin which every requirement is a hosted pin. Before this fix, the simplest project shape (six==1.16.0, or-e .plus a pin) could be switched to hosted but never switched back. All three commands exited 1 with… is not derivable; restore it from version control instead.Root cause
restore_requirements(crates/socket-patch-core/src/patch/redirect/upstream/pypi.rs) works out pip's hash-checking mode for the restored line from the other requirement lines in the file:(false, false)arm and refused.--prefixed line before counting, so an-e .line, which pip refuses in hash-checking mode, never counted as evidence that the file is unhashed.Fix
-e <path>,-e<path>,--editable <path>,--editable=<path>) now counts as unhashed evidence.pip install -rfor every other unhashed line #376 / Fix requirements.txt writers ignoring pip hash mode (#376) #383, the requirements rewriter writes--hashonly into a file already in hash-checking mode, and otherwise pins by the url's#sha256=fragment. A pre-Fix requirements.txt writers ignoring pip hash mode (#376) #383 hosted line always carried--hashand so restores hashed. With no other requirement in the file to conflict with, either form installs.--require-hashesfile with an-eline (which pip can't install) is now refused through that same "mixes" arm.Test evidence
six==1.16.0only (LF + CRLF, plus comment/option/blank lines)upstream::pypi::tests::requirements_with_only_a_hosted_pin_restores_unhashedsix==1.16.0 --hash=…only lineupstream::pypi::tests::requirements_with_only_a_hashed_hosted_pin_restores_hashed-e .+ pin (5 editable spellings × fragment /--hashhosted line)upstream::pypi::tests::an_editable_line_settles_requirements_as_unhashedupstream::pypi::tests::other_requirement_lines_still_settle_the_mode--require-hashes+-erefusalupstream_restore_golden::requirements_hash_mode_ambiguity_is_refused(updated: it asserted the #410 refusal)scanthenrollback/remove/vendortakeover,six==1.16.0mode_migration_pypi::requirements_sole_hosted_pin_unwinds-e .+six==1.16.0mode_migration_pypi::requirements_editable_beside_hosted_pin_unwindsCommands run locally:
cargo test -p socket-patch-core --all-features --lib --test upstream_restore_golden: 4846 passed. 4 tests failed, all unrelated to this change:copy_tree::relax_loop_must_not_traverse_symlinked_root,vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry,pypi_poetry::wire_write_failure_…andpypi_requirements::wire_failure_rolls_back_…. They inject write failures withchmod 0555, which root ignores, and the sandbox runs as uid 0.cargo test -p socket-patch-core --all-features --test upstream_restore_golden: 42 passed.cargo test -p socket-patch-cli --all-features --test in_process_rollback_hosted --test mode_migration_pypi --test in_process_get_hosted_ecosystems: 22 + 14 + 8 passed.cargo clippy --workspace --all-features -- -D warnings: clean.cargo fmt: the changed hunks are formatted.cargo fmt --all -- --checkalready fails onmain(about 130 files; CI runs no fmt job), so those files are left alone here.cargo test --workspaceran out of the sandbox's disk allowance (30 GB of test binaries), so the full matrix is left to CI.CI
f4033e3: 482 check runs succeeded and 6 were skipped. Bugbot found no issues and there are no review threads.PDM patch compatibility / native (ubuntu-latest, 2.1.5)and(…, 2.10.4)failed once onf4033e3in agent-mode cells (marker agent FAIL appliedExactlyOne). That path doesn't touch the requirements restore, and the same workflow passed on191ff15, whose code is identical except for one test file. One rerun of the failed jobs passed.9eb4381(main merged + Fix vex alias tests broken by store-copy merge #851's tests-only fix ported): all 488 check runs succeeded or were skipped.PDM patch compatibility / native (ubuntu-latest, 2.17.3)and(…, 2.22.4)failed once in a pdm.lock hosted cell this PR doesn't touch; one rerun passed. Bugbot found no issues on this head, and the PR is approved.Note
Medium Risk
Changes hosted unwind behavior for PyPI requirements files (user-visible restore output and hash mode), though scope is narrow and heavily tested; digest helper swap is low-risk plumbing.
Overview
Fixes #410: hosted unwind (
rollback,remove, vendored takeover) no longer refuses arequirements.txtwhere every line is a hosted pin.PyPI upstream restore now derives pip hash-checking mode when sibling lines cannot: it reads the hosted line itself (
--hashvs URL#sha256=fragment, per the post-#376 rewriter), and treats editable requirements (-e/--editable) as evidence the file is unhashed. Genuinely mixed hashed/unhashed files are still refused.CLI_CONTRACT.mddocuments this behavior.Tests cover sole-pin and
-e+ pin unwind via core unit tests, golden round-trips, and CLI migration tests.Minor refactor: Gradle cache, JVM jar patching, and Maven sidecars use shared
utils::digest::{sha1_hex_of, sha256_hex_of}instead of inlinesha1/sha2calls.Reviewed by Cursor Bugbot for commit 09364ea. Configure here.
Generated by Claude Code