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
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ jobs:
-e 'patch::go_redirect' -e 'patch::bun_lock_text' \
-e 'utils::telemetry' -e 'utils::cleanup_blobs' \
-e 'utils::date' -e 'utils::fuzzy_match' \
-e 'gem_setup::' -e 'composer_setup::' -e 'pth_hook::' \
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
Expand Down
40 changes: 20 additions & 20 deletions crates/socket-patch-cli/src/commands/setup.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use clap::Args;
use socket_patch_core::composer_setup::{self, ComposerSetupStatus};
use socket_patch_core::crawlers::python_crawler::is_python_project;
use socket_patch_core::gem_setup::{self, GemSetupStatus};
use socket_patch_core::manifest::operations::{read_manifest, write_manifest};
use socket_patch_core::manifest::schema::{PatchManifest, SetupConfig};
use socket_patch_core::package_json::detect::{is_setup_configured_str, PackageManager};
Expand All @@ -12,10 +10,12 @@ use socket_patch_core::package_json::update::{
remove_package_json, update_package_json, RemoveResult, RemoveStatus, UpdateResult,
UpdateStatus,
};
use socket_patch_core::pth_hook::detect::{
use socket_patch_core::setup::composer::{self, ComposerSetupStatus};
use socket_patch_core::setup::gem::{self, GemSetupStatus};
use socket_patch_core::setup::pypi::detect::{
deps_contain_hook, detect_python_pm, PythonPackageManager,
};
use socket_patch_core::pth_hook::edit::{
use socket_patch_core::setup::pypi::edit::{
add_hook_dependency, pyproject_contains_hook, remove_hook_dependency, ManifestKind,
PthEditResult, PthStatus,
};
Expand Down Expand Up @@ -356,17 +356,17 @@ pub(crate) async fn configured_ecosystems(
}

// gem: the managed plugin directive is present in the Gemfile.
if let Some(project) = gem_setup::discover_bundler_project(&common.cwd).await {
if let Some(project) = gem::discover_bundler_project(&common.cwd).await {
if let Ok(content) = tokio::fs::read_to_string(&project.gemfile).await {
if gem_setup::is_plugin_directive_present(&content) {
if gem::is_plugin_directive_present(&content) {
set.insert(Ecosystem::Gem);
}
}
}

if let Some(composer_json) = composer_setup::discover_composer_project(&common.cwd).await {
if let Some(composer_json) = composer::discover_composer_project(&common.cwd).await {
if let Ok(content) = tokio::fs::read_to_string(&composer_json).await {
if composer_setup::is_hook_present(&content) {
if composer::is_hook_present(&content) {
set.insert(Ecosystem::Composer);
}
}
Expand Down Expand Up @@ -576,7 +576,7 @@ async fn build_gem_outcome(common: &GlobalArgs, remove: bool, dry_run: bool) ->
if !eco_in_scope(common, ECO_GEM) {
return SetupOutcome::default();
}
let project = match gem_setup::discover_bundler_project(&common.cwd).await {
let project = match gem::discover_bundler_project(&common.cwd).await {
Some(p) => p,
None => return SetupOutcome::default(),
};
Expand All @@ -587,9 +587,9 @@ async fn build_gem_outcome(common: &GlobalArgs, remove: bool, dry_run: bool) ->
};

let results = if remove {
gem_setup::remove_plugin_directive(&project, dry_run).await
gem::remove_plugin_directive(&project, dry_run).await
} else {
gem_setup::add_plugin_directive(&project, dry_run).await
gem::add_plugin_directive(&project, dry_run).await
};

let mut added_paths: Vec<String> = Vec::new();
Expand Down Expand Up @@ -647,7 +647,7 @@ async fn build_composer_outcome(common: &GlobalArgs, remove: bool, dry_run: bool
if !eco_in_scope(common, ECO_COMPOSER) {
return SetupOutcome::default();
}
let composer_json = match composer_setup::discover_composer_project(&common.cwd).await {
let composer_json = match composer::discover_composer_project(&common.cwd).await {
Some(p) => p,
None => return SetupOutcome::default(),
};
Expand All @@ -658,9 +658,9 @@ async fn build_composer_outcome(common: &GlobalArgs, remove: bool, dry_run: bool
};

let r = if remove {
composer_setup::remove_hook(&composer_json, dry_run).await
composer::remove_hook(&composer_json, dry_run).await
} else {
composer_setup::add_hook(&composer_json, dry_run).await
composer::add_hook(&composer_json, dry_run).await
};

let mut added_paths: Vec<String> = Vec::new();
Expand Down Expand Up @@ -716,13 +716,13 @@ async fn append_composer_check_entries(
if !eco_in_scope(common, ECO_COMPOSER) {
return false;
}
let composer_json = match composer_setup::discover_composer_project(&common.cwd).await {
let composer_json = match composer::discover_composer_project(&common.cwd).await {
Some(p) => p,
None => return false,
};
let (state, err) = match tokio::fs::read_to_string(&composer_json).await {
Ok(content) => {
if composer_setup::is_hook_present(&content) {
if composer::is_hook_present(&content) {
(CheckState::Configured, None)
} else {
(CheckState::NeedsConfiguration, None)
Expand Down Expand Up @@ -798,13 +798,13 @@ async fn append_gem_check_entries(
if !eco_in_scope(common, ECO_GEM) {
return false;
}
let project = match gem_setup::discover_bundler_project(&common.cwd).await {
let project = match gem::discover_bundler_project(&common.cwd).await {
Some(p) => p,
None => return false,
};
let (state, err) = match tokio::fs::read_to_string(&project.gemfile).await {
Ok(content) => {
if gem_setup::is_plugin_directive_present(&content) {
if gem::is_plugin_directive_present(&content) {
(CheckState::Configured, None)
} else {
(CheckState::NeedsConfiguration, None)
Expand All @@ -813,14 +813,14 @@ async fn append_gem_check_entries(
Err(e) => (CheckState::Error, Some(e.to_string())),
};
entries.push(("gemfile", project.gemfile.display().to_string(), state, err));
let dir_state = if gem_setup::plugin_files_present(&project.root).await {
let dir_state = if gem::plugin_files_present(&project.root).await {
CheckState::Configured
} else {
CheckState::NeedsConfiguration
};
entries.push((
"gem_plugin",
gem_setup::plugin_dir(&project.root).display().to_string(),
gem::plugin_dir(&project.root).display().to_string(),
dir_state,
None,
));
Expand Down
2 changes: 1 addition & 1 deletion crates/socket-patch-core/src/crawlers/ruby_crawler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ impl RubyCrawler {
/// `Gemfile`/`Gemfile.lock` and the alternate `gems.rb`/`gems.locked`
/// (`Bundler::SharedHelpers.default_gemfile`). Both count: the project
/// gate must recognize every project `setup` can wire, and
/// `gem_setup::discover_bundler_project` already walks up for `gems.rb`.
/// `setup::gem::discover_bundler_project` already walks up for `gems.rb`.
/// Gating on `Gemfile` alone left a `gems.rb` project with a
/// non-deployment `bundle install` undiscoverable — the bundler plugin
/// `setup` installs would run `apply` on every `bundle install` and
Expand Down
12 changes: 9 additions & 3 deletions crates/socket-patch-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
pub mod api;
pub mod composer_setup;
pub mod constants;
pub mod crawlers;
pub mod gem_setup;
pub mod hash;
pub mod manifest;
pub mod package_json;
pub mod patch;
pub mod pth_hook;
pub mod setup;
pub mod telemetry;
pub mod update;
pub mod utils;
pub mod vendor;
pub mod vex;

// Moved modules — these aliases keep the old top-level paths compiling for
// external consumers of the published crate. Internal code must import the
// canonical `setup::*` paths; CI greps reject new uses of the old ones.
// Drop these aliases at 4.0.
pub use setup::composer as composer_setup;
pub use setup::gem as gem_setup;
pub use setup::pypi as pth_hook;
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const HOOK_EVENTS: &[&str] = &["post-install-cmd", "post-update-cmd"];
/// a slightly different flag set still reads as configured.
const HOOK_MARKER: &str = "socket-patch apply";

/// Outcome of one setup edit. Mirrors `gem_setup::GemSetupStatus`.
/// Outcome of one setup edit. Mirrors `setup::gem::GemSetupStatus`.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ComposerSetupStatus {
Updated,
Expand Down
22 changes: 22 additions & 0 deletions crates/socket-patch-core/src/setup/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Per-ecosystem `setup` backends: the code that wires (and unwires) each
//! ecosystem's auto-re-apply hook into a user's project, consumed by the
//! CLI's `setup` command.
//!
//! One concept, one home — these previously lived as four top-level modules
//! under four naming schemes (`gem_setup`, `composer_setup`, `pth_hook`,
//! plus `package_json`'s setup surface):
//!
//! * [`gem`] — Bundler plugin directive in the Gemfile + generated plugin
//! gem, re-applying gem patches on `bundle install`.
//! * [`composer`] — post-install hook in `composer.json`.
//! * [`pypi`] — the `socket-patch[hook]` dependency whose `.pth` wheel
//! re-applies pypi patches at interpreter startup.
//! * [`npm`] — a thin alias: the npm backend's real home is
//! [`crate::package_json`], which stays top-level because it doubles as
//! the crate-wide shared npm-manifest library (crawlers and vendor read
//! package.json through it too).

pub mod composer;
pub mod gem;
pub mod npm;
pub mod pypi;
10 changes: 10 additions & 0 deletions crates/socket-patch-core/src/setup/npm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! The npm setup backend, by alias.
//!
//! npm's hook wiring lives in [`crate::package_json`] — that module stays
//! top-level because it is also the crate-wide shared npm-manifest library
//! (crawlers and vendor parse package.json through it). This alias exists so
//! `setup::*` enumerates every ecosystem backend in one place.

pub use crate::package_json::detect::{is_setup_configured_str, PackageManager};
pub use crate::package_json::find::{detect_package_manager, find_package_json_files};
pub use crate::package_json::update::{remove_package_json, update_package_json};
4 changes: 2 additions & 2 deletions crates/socket-patch-core/src/utils/toml_edit_ext.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Small structured-TOML helpers shared by every module that edits or sniffs
//! TOML (`pth_hook`, `vendor::cargo_config`, `vendor::pypi`,
//! `vendor::pypi_uv`). Extracted from `pth_hook` so the pypi setup backend no
//! TOML (`setup::pypi`, `vendor::cargo_config`, `vendor::pypi`,
//! `vendor::pypi_uv`). Extracted from the pypi setup backend (now `setup::pypi`) so it no
//! longer owns the crate's generic TOML seam.

use toml_edit::{Item, Table};
Expand Down
2 changes: 1 addition & 1 deletion crates/socket-patch-core/src/vendor/cargo_config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Read / write `<project_root>/.cargo/config.toml` for the cargo vendor
//! backend's `[patch.crates-io]` wiring.
//!
//! Mirrors the contract style of [`crate::pth_hook::edit`]: pure
//! Mirrors the contract style of [`crate::setup::pypi::edit`]: pure
//! `fn(&str) -> Result<Option<String>, String>` transforms (`Some(new)` =
//! changed, `None` = already in the desired state) wrapped by async
//! read-or-create / write helpers that honour `dry_run` and preserve the
Expand Down
2 changes: 1 addition & 1 deletion crates/socket-patch-core/tests/crawler_ruby_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ async fn get_gem_paths_with_gemfile_lock_only_returns_gemdir() {

/// Bundler accepts `gems.rb` as the alternate spelling of `Gemfile`
/// (`Bundler::SharedHelpers.default_gemfile`), and
/// `gem_setup::discover_bundler_project` already walks up for it — so
/// `setup::gem::discover_bundler_project` already walks up for it — so
/// `setup` will wire a `gems.rb` project with the bundler plugin that runs
/// `apply` on every `bundle install`. The crawler's project gate must
/// recognize the same spelling; otherwise that project's non-deployment
Expand Down
Loading