Skip to content

Commit 30bd202

Browse files
committed
Merge remote-tracking branch 'origin/main' into agent/fix-bun-open-issues
# Conflicts: # crates/socket-patch-cli/CLI_CONTRACT.md # crates/socket-patch-core/src/vendor/bun_lock_text.rs
2 parents 7661645 + 431b818 commit 30bd202

88 files changed

Lines changed: 7171 additions & 820 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,19 @@ jobs:
800800
- name: Run npm dispatch tests
801801
run: node --test npm/socket-patch/bin/socket-patch.test.mjs
802802

803+
- name: Run npm schema tests
804+
# The `./schema` export's zod tests. `npm install --no-save`, not
805+
# `npm ci`, for the reason publish-npm.yml gives (a version-synced
806+
# lock can name platform packages not yet on the registry); the
807+
# platform binaries are optional and not needed here. The pack
808+
# test runs again once `npm test` has built dist/, so it also
809+
# checks that the compiled schema ships.
810+
working-directory: npm/socket-patch
811+
run: |
812+
npm install --no-save --ignore-scripts --no-audit --no-fund --omit=optional
813+
npm test
814+
node --test --test-name-pattern="npm package contents" bin/socket-patch.test.mjs
815+
803816
# Compiles the CLI and every CLI test target once per OS (--all-features,
804817
# so this is also the feature-gated suites' compile-rot check) and uploads
805818
# the binaries the e2e, e2e-full and cargo-vex legs run. The legs run the

‎crates/socket-patch-bench/src/fixtures/npm.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,17 @@ pub fn yarn_classic_lock(g: &Graph) -> String {
537537

538538
pub fn build_yarn_classic(t: &mut Tree, size: Size) -> std::io::Result<Fixture> {
539539
let g = graph("yarn-classic", size);
540-
t.write("project/package.json", g.package_json())?;
540+
// Pin yarn 1 as a real classic project does: without the pin a hosted
541+
// scan rightly warns `redirect_yarn_classic_berry_migration_risk`
542+
// (#907), which the scenario would count as an unexpected warning.
543+
t.write(
544+
"project/package.json",
545+
g.package_json().replacen(
546+
"\"private\": true",
547+
"\"private\": true,\n \"packageManager\": \"yarn@1.22.22\"",
548+
1,
549+
),
550+
)?;
541551
t.write("project/yarn.lock", yarn_classic_lock(&g))?;
542552
t.write(
543553
"project/node_modules/.yarn-integrity",

‎crates/socket-patch-cli/CLI_CONTRACT.md‎

Lines changed: 16 additions & 12 deletions
Large diffs are not rendered by default.

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

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,7 +1743,11 @@ type LockRefusals = HashMap<String, (&'static str, String)>;
17431743
/// refusal and the ledger's idempotency skip, which take precedence in the
17441744
/// fetch loop. A purl the lockfiles pin hosted is left to the vendor loop:
17451745
/// its takeover restores the upstream lock entry first, and the restore
1746-
/// rewrites the very text the gates read.
1746+
/// rewrites the very text the gates read. The one exception is a hosted
1747+
/// gem the takeover would refuse ([`gem_takeover_refusals_for`]), which
1748+
/// is refused here with the takeover's code instead of after its fetch.
1749+
///
1750+
/// [`gem_takeover_refusals_for`]: crate::commands::vendor::gem_takeover_refusals_for
17471751
///
17481752
/// Only a package the vendor loop would hand to its backend is refused
17491753
/// here (see [`crate::commands::vendor::lock_refusals_reaching_backend`]):
@@ -1760,44 +1764,65 @@ async fn lock_text_refusals_for(
17601764
prior: Option<&crate::ecosystem_dispatch::NpmCrawlSnapshot>,
17611765
) -> LockRefusals {
17621766
let cwd = params.cwd.as_path();
1763-
let claimed: Vec<String> = socket_patch_core::patch::redirect::upstream::HostedPin::all(
1767+
let origins: Vec<String> = params
1768+
.patch_server_url
1769+
.iter()
1770+
.filter(|url| !url.trim().is_empty())
1771+
.cloned()
1772+
.collect();
1773+
let pins = socket_patch_core::patch::redirect::upstream::HostedPin::all(
17641774
&socket_patch_core::vex::discover_patched_refs_with(
17651775
cwd,
17661776
&socket_patch_core::vex::DiscoverOptions {
1767-
patch_server_origins: params
1768-
.patch_server_url
1769-
.iter()
1770-
.filter(|url| !url.trim().is_empty())
1771-
.cloned()
1772-
.collect(),
1777+
patch_server_origins: origins.clone(),
17731778
},
17741779
)
17751780
.await,
1776-
)
1777-
.into_iter()
1778-
.map(|pin| canonical_purl(&pin.purl))
1779-
.collect();
1780-
let candidates: Vec<(&str, &str)> = selected
1781+
);
1782+
let claimed: Vec<String> = pins.iter().map(|pin| canonical_purl(&pin.purl)).collect();
1783+
let fetchable: Vec<&PatchSearchResult> = selected
17811784
.iter()
17821785
.filter(|sr| bun_refusal.filter(|r| r.applies_to(&sr.purl)).is_none())
17831786
.filter(|sr| {
17841787
detached_ledger_record(RecordStore::Ledger(&ledger.entries), &sr.purl, &sr.uuid)
17851788
.is_none()
17861789
})
1790+
.collect();
1791+
let candidates: Vec<(&str, &str)> = fetchable
1792+
.iter()
17871793
.filter(|sr| !claimed.contains(&canonical_purl(&sr.purl)))
17881794
.map(|sr| (sr.purl.as_str(), sr.uuid.as_str()))
17891795
.collect();
17901796
let refused = socket_patch_core::vendor::lock_text_refusals(cwd, &candidates).await;
17911797
let options = params.crawler_options();
1792-
crate::commands::vendor::lock_refusals_reaching_backend(
1793-
cwd,
1794-
refused,
1795-
&ledger.entries,
1796-
|purls| async move {
1797-
crate::commands::vendor::installed_purls(&options, &purls, prior).await
1798-
},
1799-
)
1800-
.await
1798+
let mut refusals =
1799+
crate::commands::vendor::lock_refusals_reaching_backend(
1800+
cwd,
1801+
refused,
1802+
&ledger.entries,
1803+
|purls| async move {
1804+
crate::commands::vendor::installed_purls(&options, &purls, prior).await
1805+
},
1806+
)
1807+
.await;
1808+
// A hosted gem the takeover will refuse (#775) is refused here too, so
1809+
// its view is never fetched for a package the run cannot vendor. The
1810+
// download phase only runs online (`--offline` refuses `get` and `scan`
1811+
// before it), so the dry-run restore may resolve the registry entry.
1812+
refusals.extend(
1813+
crate::commands::vendor::gem_takeover_refusals_for(
1814+
cwd,
1815+
fetchable
1816+
.iter()
1817+
.filter(|sr| claimed.contains(&canonical_purl(&sr.purl)))
1818+
.map(|sr| sr.purl.as_str()),
1819+
&pins,
1820+
false,
1821+
origins,
1822+
)
1823+
.await,
1824+
);
1825+
refusals
18011826
}
18021827

18031828
/// The record a detached ledger entry already carries for `purl` at
@@ -3759,7 +3784,12 @@ async fn run_get_vendored(
37593784
// Dry run: ledger-classification preview only (scan's posture) — no
37603785
// download, no vendor step, no writes.
37613786
if args.common.dry_run {
3762-
let preview = super::scan::preview_vendor_json(&args.common.cwd, selected).await;
3787+
let takeover = super::vendor::gem_takeover_preview_refusals(
3788+
&args.common,
3789+
selected.iter().map(|p| p.purl.as_str()),
3790+
)
3791+
.await;
3792+
let preview = super::scan::preview_vendor_json(&args.common.cwd, selected, &takeover).await;
37633793
if args.common.json {
37643794
let mut result = serde_json::json!({
37653795
"status": "success",

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,7 @@ pub async fn run(args: RemoveArgs) -> i32 {
603603
&manifest,
604604
&vendored_keys,
605605
InnerSelection::Identifier(Some(&args.identifier)),
606+
&super::rollback::superseded_by_hosted(&manifest, &hosted_pins),
606607
Some(&telemetry_client),
607608
)
608609
.await

0 commit comments

Comments
 (0)