Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ jobs:

- name: Run clippy
run: cargo clippy --workspace --all-features -- -D warnings
# Moved-module aliases (patch::vendor → vendor, patch::go_mod_edit →
# vendor::go_mod_edit, patch::go_redirect → patch::redirect::golang_local)
# exist only for external consumers of the published core crate.
# #[deprecated] on a `pub use` re-export emits no warnings
# (rust-lang/rust#30827), so the compiler cannot pressure internal code
# off the old paths — this grep is the guard instead.
- name: Reject internal uses of moved-module alias paths
run: |
if grep -rn --include='*.rs' \
-e 'patch::vendor' -e 'patch::go_mod_edit' \
-e 'patch::go_redirect' -e 'patch::bun_lock_text' \
-e 'utils::telemetry' -e 'utils::cleanup_blobs' \
-e 'utils::date' -e 'utils::fuzzy_match' \
crates; then
echo '::error::use the canonical module paths (crate::vendor, patch::redirect::golang_local, crate::telemetry, manifest::cleanup_blobs, api::date, crawlers::fuzzy_match); the old-path aliases exist only for external consumers'
exit 1
fi

# Lint the out-of-workspace packaging artifacts for the ecosystems whose setup
# / CLI-distribution we added: the RubyGems CLI launcher gem + the Bundler
Expand Down
16 changes: 8 additions & 8 deletions crates/socket-patch-cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use clap::Args;
use socket_patch_core::api::client::ApiClientEnvOverrides;
use socket_patch_core::constants::DEFAULT_PATCH_MANIFEST_PATH;
use socket_patch_core::crawlers::Ecosystem;
use socket_patch_core::patch::vendor::VendorSource;
use socket_patch_core::vendor::VendorSource;

/// clap value-parser for each `--ecosystems` / `SOCKET_ECOSYSTEMS` token.
///
Expand Down Expand Up @@ -317,7 +317,7 @@ impl GlobalArgs {
/// flags are off.
///
/// `offline` matters most: the telemetry kill-switch
/// (`socket_patch_core::utils::telemetry::is_telemetry_disabled`) honors the
/// (`socket_patch_core::telemetry::is_telemetry_disabled`) honors the
/// strict-airgap contract by reading `SOCKET_OFFLINE` from the env, so
/// without this mirror a bare `--offline` flag (or a truthy spelling like
/// `SOCKET_OFFLINE=yes` that core's `"1" | "true"` match doesn't recognize)
Expand Down Expand Up @@ -503,7 +503,7 @@ mod tests {
}

/// `--offline` promises "never contact the network", but the telemetry
/// kill-switch (`socket_patch_core::utils::telemetry::is_telemetry_disabled`)
/// kill-switch (`socket_patch_core::telemetry::is_telemetry_disabled`)
/// reads the `SOCKET_OFFLINE` env var directly — it never sees the parsed
/// flag. `apply_env_toggles` must therefore mirror `--offline` into the
/// env exactly like `--debug` / `--no-telemetry`, or an airgapped
Expand All @@ -520,7 +520,7 @@ mod tests {
apply_env_toggles(&args);
assert_eq!(std::env::var("SOCKET_OFFLINE").as_deref(), Ok("1"));
assert!(
socket_patch_core::utils::telemetry::is_telemetry_disabled(),
socket_patch_core::telemetry::is_telemetry_disabled(),
"--offline must disable telemetry (strict airgap: never contact the network)",
);
});
Expand All @@ -541,7 +541,7 @@ mod tests {
assert!(cli.common.offline, "SOCKET_OFFLINE=yes parses as offline");
apply_env_toggles(&cli.common);
assert!(
socket_patch_core::utils::telemetry::is_telemetry_disabled(),
socket_patch_core::telemetry::is_telemetry_disabled(),
"SOCKET_OFFLINE=yes must disable telemetry like SOCKET_OFFLINE=1",
);
});
Expand Down Expand Up @@ -1082,7 +1082,7 @@ mod tests {
};

// Guard against a vacuous pass: the gate must start open.
assert!(!socket_patch_core::utils::telemetry::is_telemetry_disabled());
assert!(!socket_patch_core::telemetry::is_telemetry_disabled());

let tmp = tempfile::tempdir().unwrap();
rt.block_on(crate::commands::list::run(
Expand All @@ -1091,7 +1091,7 @@ mod tests {
},
));
assert!(
socket_patch_core::utils::telemetry::is_telemetry_disabled(),
socket_patch_core::telemetry::is_telemetry_disabled(),
"`list --offline --no-telemetry` must mirror the toggles into the \
env — its telemetry kill-switch reads only SOCKET_OFFLINE / \
SOCKET_TELEMETRY_DISABLED",
Expand All @@ -1115,7 +1115,7 @@ mod tests {
},
));
assert!(
socket_patch_core::utils::telemetry::is_telemetry_disabled(),
socket_patch_core::telemetry::is_telemetry_disabled(),
"`setup --offline --no-telemetry` must mirror the toggles into the env",
);
});
Expand Down
13 changes: 6 additions & 7 deletions crates/socket-patch-cli/src/commands/apply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ use socket_patch_core::manifest::schema::{PatchFileInfo, PatchManifest, PatchRec
use socket_patch_core::patch::apply::{
apply_package_patch, verify_file_patch, ApplyResult, MismatchPolicy, PatchSources, VerifyStatus,
};
use socket_patch_core::patch::go_redirect::{
use socket_patch_core::patch::redirect::golang_local::{
apply_go_redirect, reconcile_go_redirects, verify_go_redirect_state,
};
use socket_patch_core::telemetry::{track_patch_applied, track_patch_apply_failed};
use socket_patch_core::utils::purl::parse_golang_purl;
use socket_patch_core::utils::purl::{normalize_purl, strip_purl_qualifiers};
use socket_patch_core::utils::telemetry::{track_patch_applied, track_patch_apply_failed};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::time::Duration;
Expand Down Expand Up @@ -268,7 +268,7 @@ async fn try_local_go_apply(
version,
pkg_path,
&common.cwd,
socket_patch_core::patch::go_mod_edit::GO_PATCHES_DIR,
socket_patch_core::vendor::go_mod_edit::GO_PATCHES_DIR,
&patch.files,
sources,
Some(&patch.uuid),
Expand Down Expand Up @@ -339,12 +339,12 @@ async fn run_check(args: &ApplyArgs, manifest_path: &Path) -> i32 {
let mut checked: usize = 0;

{
use socket_patch_core::patch::go_redirect::Drift as GoDrift;
use socket_patch_core::patch::redirect::golang_local::Drift as GoDrift;
if go_in_local_scope(&args.common) {
// Vendored modules are excluded: their replace directives point at
// `.socket/vendor/golang/` (the verify engine skips Vendor-owned
// entries) and their state is audited by `vendor`, not `--check`.
let vendored = socket_patch_core::patch::vendor::load_state(&args.common.cwd)
let vendored = socket_patch_core::vendor::load_state(&args.common.cwd)
.await
.map(|s| {
s.entries
Expand Down Expand Up @@ -1002,8 +1002,7 @@ async fn apply_patches_inner(
// by ledger key, resolved base purl, or qualifier-stripped key so
// release-variant manifest keys (pypi `?artifact_id=`…) hit too;
// unreadable state degrades to "nothing vendored" (fail-open).
let vendored_purls =
socket_patch_core::patch::vendor::vendored_purl_keys(&args.common.cwd).await;
let vendored_purls = socket_patch_core::vendor::vendored_purl_keys(&args.common.cwd).await;
let is_vendored =
|p: &str| vendored_purls.contains(p) || vendored_purls.contains(strip_purl_qualifiers(p));
let (mut results, mut matched_manifest_purls, vendored_bases) =
Expand Down
7 changes: 2 additions & 5 deletions crates/socket-patch-cli/src/commands/fetch_stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,11 +353,8 @@ pub(crate) async fn stage_vendor_sources_in_memory(
// The committed vendor artifact IS the patched content: harvest its
// afterHash blobs into memory so in-sync re-runs and fresh clones of
// already-vendored projects stage with no network and no disk blobs.
mem = socket_patch_core::patch::vendor::harvest_artifact_blobs(
project_root,
&manifest.patches,
)
.await;
mem = socket_patch_core::vendor::harvest_artifact_blobs(project_root, &manifest.patches)
.await;
if !mem.is_empty() {
to_fetch.retain(|(purl, _)| {
manifest.patches.get(*purl).is_none_or(|record| {
Expand Down
18 changes: 8 additions & 10 deletions crates/socket-patch-cli/src/commands/get.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ use socket_patch_core::api::ranking::{cmp_search_results, severity_order};
use socket_patch_core::api::types::{
PatchResponse, PatchSearchResult, SearchResponse, VulnerabilityResponse,
};
use socket_patch_core::crawlers::fuzzy_match::fuzzy_match_packages;
use socket_patch_core::crawlers::{CrawlerOptions, Ecosystem};
use socket_patch_core::manifest::operations::{read_manifest, write_manifest};
use socket_patch_core::manifest::schema::{
PatchFileInfo, PatchManifest, PatchRecord, VulnerabilityInfo,
};
use socket_patch_core::patch::apply::select_installed_variants;
use socket_patch_core::utils::fuzzy_match::fuzzy_match_packages;
use socket_patch_core::telemetry::{track_patch_fetch_failed, track_patch_fetched};
use socket_patch_core::utils::purl::{is_purl, normalize_purl, strip_purl_qualifiers};
use socket_patch_core::utils::telemetry::{track_patch_fetch_failed, track_patch_fetched};
use std::collections::HashMap;
use std::fmt;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -869,7 +869,7 @@ pub(crate) async fn download_patch_records(
let (selected, narrow_warnings) =
filter_to_installed_releases(selected, params, &api_client).await;

let vendor_state = socket_patch_core::patch::vendor::load_state(&params.cwd)
let vendor_state = socket_patch_core::vendor::load_state(&params.cwd)
.await
.unwrap_or_default();

Expand All @@ -882,11 +882,9 @@ pub(crate) async fn download_patch_records(
for search_result in &selected {
// Idempotency: a detached entry already at this uuid carries its
// own record — no view fetch needed.
let existing = socket_patch_core::patch::vendor::lookup_entry(
&vendor_state.entries,
&search_result.purl,
)
.filter(|e| e.detached && e.uuid == search_result.uuid);
let existing =
socket_patch_core::vendor::lookup_entry(&vendor_state.entries, &search_result.purl)
.filter(|e| e.detached && e.uuid == search_result.uuid);
if let Some(record) = existing.and_then(|e| e.record.clone()) {
if !params.json && !params.silent {
eprintln!(" [skip] {} (already vendored)", search_result.purl);
Expand Down Expand Up @@ -993,7 +991,7 @@ async fn warn_on_vendored_uuid_drift(
downloaded_patches: &[serde_json::Value],
warnings: &mut Vec<String>,
) {
let Ok(vendor_state) = socket_patch_core::patch::vendor::load_state(cwd).await else {
let Ok(vendor_state) = socket_patch_core::vendor::load_state(cwd).await else {
return;
};
if vendor_state.entries.is_empty() {
Expand All @@ -1006,7 +1004,7 @@ async fn warn_on_vendored_uuid_drift(
if !matches!(rec["action"].as_str(), Some("added" | "updated")) {
continue;
}
let entry = socket_patch_core::patch::vendor::lookup_entry(&vendor_state.entries, purl);
let entry = socket_patch_core::vendor::lookup_entry(&vendor_state.entries, purl);
if let Some(entry) = entry.filter(|e| e.uuid != uuid) {
let w = format!(
"{purl} is vendored at patch {} but the manifest now records {uuid}; \
Expand Down
2 changes: 1 addition & 1 deletion crates/socket-patch-cli/src/commands/list.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use clap::Args;
use socket_patch_core::manifest::operations::read_manifest;
use socket_patch_core::manifest::schema::PatchManifest;
use socket_patch_core::telemetry::track_patch_listed;
use socket_patch_core::utils::socket_cli_config;
use socket_patch_core::utils::telemetry::track_patch_listed;

use crate::args::{apply_env_toggles, GlobalArgs};
use crate::json_envelope::{
Expand Down
6 changes: 3 additions & 3 deletions crates/socket-patch-cli/src/commands/remove.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use clap::Args;
use socket_patch_core::api::client::get_api_client_with_overrides;
use socket_patch_core::manifest::cleanup_blobs::{cleanup_unused_blobs, format_cleanup_result};
use socket_patch_core::manifest::operations::{read_manifest, write_manifest};
use socket_patch_core::manifest::schema::PatchManifest;
use socket_patch_core::patch::vendor::{load_state, save_state, VendorEntry, VendorState};
use socket_patch_core::utils::cleanup_blobs::{cleanup_unused_blobs, format_cleanup_result};
use socket_patch_core::telemetry::{track_patch_remove_failed, track_patch_removed};
use socket_patch_core::utils::purl::purl_matches_identifier;
use socket_patch_core::utils::telemetry::{track_patch_remove_failed, track_patch_removed};
use socket_patch_core::vendor::{load_state, save_state, VendorEntry, VendorState};
use std::path::Path;
use std::time::Duration;

Expand Down
14 changes: 7 additions & 7 deletions crates/socket-patch-cli/src/commands/repair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use socket_patch_core::api::blob_fetcher::{
DownloadMode,
};
use socket_patch_core::api::client::get_api_client_with_overrides;
use socket_patch_core::manifest::operations::read_manifest;
use socket_patch_core::patch::apply::PatchSources;
use socket_patch_core::utils::cleanup_blobs::{
use socket_patch_core::manifest::cleanup_blobs::{
cleanup_unused_archives, cleanup_unused_blobs, format_cleanup_result,
};
use socket_patch_core::utils::telemetry::{track_patch_repair_failed, track_patch_repaired};
use socket_patch_core::manifest::operations::read_manifest;
use socket_patch_core::patch::apply::PatchSources;
use socket_patch_core::telemetry::{track_patch_repair_failed, track_patch_repaired};
use std::path::Path;
use std::time::Duration;

Expand Down Expand Up @@ -83,7 +83,7 @@ pub async fn run(args: RepairArgs) -> i32 {
let state_file = args
.common
.cwd
.join(socket_patch_core::patch::vendor::VENDOR_STATE_REL);
.join(socket_patch_core::vendor::VENDOR_STATE_REL);
let has_vendor_traces = tokio::fs::metadata(&state_file).await.is_ok()
|| !crate::commands::repair_vendor::scan_vendor_references(&args.common.cwd)
.await
Expand Down Expand Up @@ -272,7 +272,7 @@ async fn repair_inner(
// packages` — repair must not re-litter them (or fail trying). The
// cleanup phase below still uses the FULL manifest, so it never sweeps
// sources an in-place apply may need for rollback.
let vendor_state = socket_patch_core::patch::vendor::load_state(&args.common.cwd)
let vendor_state = socket_patch_core::vendor::load_state(&args.common.cwd)
.await
.unwrap_or_default();
// Lockfile vendor references count as vendored even before the ledger
Expand All @@ -290,7 +290,7 @@ async fn repair_inner(
.iter()
.filter(|(purl, rec)| {
!referenced_uuids.contains(&rec.uuid)
&& socket_patch_core::patch::vendor::lookup_entry(&vendor_state.entries, purl)
&& socket_patch_core::vendor::lookup_entry(&vendor_state.entries, purl)
.is_none_or(|e| e.uuid != rec.uuid)
})
.map(|(k, v)| (k.clone(), v.clone()))
Expand Down
10 changes: 5 additions & 5 deletions crates/socket-patch-cli/src/commands/repair_vendor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ use socket_patch_core::api::client::get_api_client_with_overrides;
use socket_patch_core::crawlers::CrawlerOptions;
use socket_patch_core::manifest::schema::{PatchManifest, PatchRecord};
use socket_patch_core::patch::copy_tree::remove_tree;
use socket_patch_core::patch::vendor::state::VendorArtifact;
use socket_patch_core::patch::vendor::{
self, check_vendored_artifact, file_sha256_hex, load_state, lock_inventory, parse_vendor_path,
registry_fetch, ArtifactHealth, VendorEntry, VendorOutcome,
};
use socket_patch_core::utils::purl::{
normalize_purl, percent_decode_purl_component, strip_purl_qualifiers,
};
use socket_patch_core::vendor::state::VendorArtifact;
use socket_patch_core::vendor::{
self, check_vendored_artifact, file_sha256_hex, load_state, lock_inventory, parse_vendor_path,
registry_fetch, ArtifactHealth, VendorEntry, VendorOutcome,
};
use socket_patch_core::vex::time::now_rfc3339;

use crate::args::GlobalArgs;
Expand Down
17 changes: 8 additions & 9 deletions crates/socket-patch-cli/src/commands/rollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use socket_patch_core::patch::apply::select_installed_variants;
use socket_patch_core::patch::rollback::{
rollback_package_patch, RollbackResult, VerifyRollbackStatus,
};
use socket_patch_core::telemetry::{track_patch_rollback_failed, track_patch_rolled_back};
use socket_patch_core::utils::purl::strip_purl_qualifiers;
use socket_patch_core::utils::telemetry::{track_patch_rollback_failed, track_patch_rolled_back};
use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::time::Duration;
Expand Down Expand Up @@ -97,8 +97,8 @@ async fn try_rollback_local_go(
patch: &PatchRecord,
common: &GlobalArgs,
) -> Option<RollbackResult> {
use socket_patch_core::patch::go_mod_edit::{ReplaceOwner, GO_PATCHES_DIR};
use socket_patch_core::patch::go_redirect::remove_go_redirect;
use socket_patch_core::patch::redirect::golang_local::remove_go_redirect;
use socket_patch_core::vendor::go_mod_edit::{ReplaceOwner, GO_PATCHES_DIR};
if !is_local_go(purl, common) {
return None;
}
Expand Down Expand Up @@ -511,8 +511,7 @@ async fn rollback_patches_inner(
// `vendor --revert` undoes it wholesale. Matching mirrors apply's
// ledger-key / base-purl / qualifier-stripped triple; unreadable state
// degrades to "nothing vendored".
let vendored_keys =
socket_patch_core::patch::vendor::vendored_purl_keys(&args.common.cwd).await;
let vendored_keys = socket_patch_core::vendor::vendored_purl_keys(&args.common.cwd).await;
let is_vendored =
|p: &str| vendored_keys.contains(p) || vendored_keys.contains(strip_purl_qualifiers(p));
let (vendored_targets, patches_to_rollback): (Vec<_>, Vec<_>) = patches_to_rollback
Expand Down Expand Up @@ -1246,7 +1245,7 @@ mod tests {
/// kept using the patched copy.
#[tokio::test]
async fn try_rollback_local_go_drops_redirect_and_copy() {
use socket_patch_core::patch::go_mod_edit::{
use socket_patch_core::vendor::go_mod_edit::{
ensure_replace_entry, read_replace_entries, GO_PATCHES_DIR,
};

Expand Down Expand Up @@ -1331,7 +1330,7 @@ mod tests {
/// that mutated nothing.
#[tokio::test]
async fn try_rollback_local_go_dry_run_reports_no_files_rolled_back() {
use socket_patch_core::patch::go_mod_edit::{
use socket_patch_core::vendor::go_mod_edit::{
ensure_replace_entry, read_replace_entries, GO_PATCHES_DIR,
};

Expand Down Expand Up @@ -1423,7 +1422,7 @@ mod tests {
/// record deleted, i.e. an active patch nothing tracks.
#[tokio::test]
async fn rollback_drops_local_go_redirect_when_module_cache_has_no_copy() {
use socket_patch_core::patch::go_mod_edit::{
use socket_patch_core::vendor::go_mod_edit::{
ensure_replace_entry, read_replace_entries, GO_PATCHES_DIR,
};

Expand Down Expand Up @@ -1520,7 +1519,7 @@ mod tests {
/// filter's back.
#[tokio::test]
async fn undiscovered_local_go_redirect_respects_ecosystem_filter() {
use socket_patch_core::patch::go_mod_edit::{
use socket_patch_core::vendor::go_mod_edit::{
ensure_replace_entry, read_replace_entries, GO_PATCHES_DIR,
};

Expand Down
4 changes: 2 additions & 2 deletions crates/socket-patch-cli/src/commands/scan/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub(super) async fn lockfile_supplement(
common: &GlobalArgs,
crawled: &[socket_patch_core::crawlers::types::CrawledPackage],
) -> LockfileSupplement {
use socket_patch_core::patch::vendor::lock_inventory;
use socket_patch_core::vendor::lock_inventory;

let mut out = LockfileSupplement::default();
if common.global || common.global_prefix.is_some() {
Expand Down Expand Up @@ -99,7 +99,7 @@ pub(super) async fn vendored_ledger_supplement(
if common.global || common.global_prefix.is_some() {
return Vec::new();
}
let Ok(state) = socket_patch_core::patch::vendor::load_state(&common.cwd).await else {
let Ok(state) = socket_patch_core::vendor::load_state(&common.cwd).await else {
return Vec::new();
};
let crawled_norm: HashSet<String> = crawled
Expand Down
Loading
Loading