From 2bca69a5cab9a5193d47e299d9f9e19e9f9d1b9f Mon Sep 17 00:00:00 2001 From: Mikola Lysenko Date: Fri, 14 Aug 2026 20:47:53 -0400 Subject: [PATCH] chore: convert production unwrap() to expect() with invariant messages Sweep of every .unwrap() in production code paths (both crates): 111 sites across 12 files converted to .expect() whose message states the invariant that justifies the expectation, so a violated invariant panics with its reason instead of a bare unwrap message. Test-scope unwraps (cfg(test) modules, tests/, and the cfg(test)-gated conformance_tests.rs / yarn_layering_tests.rs) are deliberately left alone: a test panic already identifies the failing test, and the churn would drown review. Zero behavior change: no control-flow edits, no unwrap-to-? rewrites. Co-Authored-By: Claude Fable 5 --- crates/socket-patch-cli/src/commands/apply.rs | 18 +- crates/socket-patch-cli/src/commands/get.rs | 28 +- .../socket-patch-cli/src/commands/repair.rs | 4 +- .../socket-patch-cli/src/commands/rollback.rs | 16 +- .../src/commands/scan/hosted.rs | 20 +- .../socket-patch-cli/src/commands/scan/mod.rs | 43 ++- .../src/commands/scan/vendor_flow.rs | 18 +- crates/socket-patch-cli/src/commands/setup.rs | 21 +- crates/socket-patch-cli/src/output.rs | 4 +- crates/socket-patch-core/src/api/client.rs | 16 +- .../src/patch/redirect/mod.rs | 293 ++++++++++++------ .../src/setup/composer/mod.rs | 14 +- .../src/vendor/go_sum_edit.rs | 6 +- 13 files changed, 368 insertions(+), 133 deletions(-) diff --git a/crates/socket-patch-cli/src/commands/apply.rs b/crates/socket-patch-cli/src/commands/apply.rs index 96fc577e..ee3b0a2e 100644 --- a/crates/socket-patch-cli/src/commands/apply.rs +++ b/crates/socket-patch-cli/src/commands/apply.rs @@ -759,7 +759,13 @@ pub async fn run(args: ApplyArgs) -> i32 { match &vex_result { Some(Ok(summary)) => { env.vex = Some(VexSummary { - path: args.vex.vex.as_ref().unwrap().display().to_string(), + path: args + .vex + .vex + .as_ref() + .expect("vex_result is Some only when --vex was given") + .display() + .to_string(), statements: summary.statements, format: "openvex-0.2.0".to_string(), }); @@ -860,7 +866,11 @@ pub async fn run(args: ApplyArgs) -> i32 { println!( "Wrote OpenVEX document with {} statement(s) to {}", summary.statements, - args.vex.vex.as_ref().unwrap().display(), + args.vex + .vex + .as_ref() + .expect("vex_result is Some only when --vex was given") + .display(), ); } } @@ -1001,7 +1011,9 @@ async fn apply_patches_inner( // Resolve patch sources (read `.socket/` directly, or stage an overlay // tempdir + download the gap). Shared with `vendor` via fetch_stage. - let socket_dir = manifest_path.parent().unwrap(); + let socket_dir = manifest_path + .parent() + .expect("manifest path names a file, so it has a parent"); // Partition manifest PURLs by ecosystem up front. The source probes, // the offline guard, and the download planner in `fetch_stage` must only // consider patches this run can actually apply — the `--ecosystems` diff --git a/crates/socket-patch-cli/src/commands/get.rs b/crates/socket-patch-cli/src/commands/get.rs index 60ffec69..d508fe74 100644 --- a/crates/socket-patch-cli/src/commands/get.rs +++ b/crates/socket-patch-cli/src/commands/get.rs @@ -178,7 +178,10 @@ fn merge_metadata(record: &mut serde_json::Value, meta: serde_json::Value) { /// Print a `serde_json::Value` as pretty JSON to stdout. fn print_json(v: &serde_json::Value) { - println!("{}", serde_json::to_string_pretty(v).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(v).expect("serializing an in-memory JSON value cannot fail") + ); } /// Truncate `s` to at most `limit` displayed characters, appending an @@ -496,10 +499,11 @@ impl fmt::Display for IdentifierType { } fn detect_identifier_type(identifier: &str) -> Option { - let uuid_re = - Regex::new(r"(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$").unwrap(); - let cve_re = Regex::new(r"(?i)^CVE-\d{4}-\d+$").unwrap(); - let ghsa_re = Regex::new(r"(?i)^GHSA-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$").unwrap(); + let uuid_re = Regex::new(r"(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") + .expect("hardcoded UUID regex must compile"); + let cve_re = Regex::new(r"(?i)^CVE-\d{4}-\d+$").expect("hardcoded CVE regex must compile"); + let ghsa_re = Regex::new(r"(?i)^GHSA-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}$") + .expect("hardcoded GHSA regex must compile"); if uuid_re.is_match(identifier) { Some(IdentifierType::Uuid) @@ -635,7 +639,7 @@ pub(crate) fn select_patches( "purl": purl, "options": options_json, })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); return Err(1); } @@ -1840,7 +1844,11 @@ pub async fn run(args: GetArgs) -> i32 { let (code, result_json) = download_and_apply_patches(&selected, ¶ms).await; if args.common.json { - println!("{}", serde_json::to_string_pretty(&result_json).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result_json) + .expect("serializing an in-memory JSON value cannot fail") + ); } code @@ -2083,7 +2091,11 @@ async fn save_and_apply_patch(args: &GetArgs, patch: &PatchResponse) -> i32 { if !warnings.is_empty() { result_json["warnings"] = serde_json::json!(warnings); } - println!("{}", serde_json::to_string_pretty(&result_json).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result_json) + .expect("serializing an in-memory JSON value cannot fail") + ); } exit_code diff --git a/crates/socket-patch-cli/src/commands/repair.rs b/crates/socket-patch-cli/src/commands/repair.rs index e5722178..9313fcbb 100644 --- a/crates/socket-patch-cli/src/commands/repair.rs +++ b/crates/socket-patch-cli/src/commands/repair.rs @@ -234,7 +234,9 @@ async fn repair_inner( .await .map_err(|e| e.to_string())?; - let socket_dir = manifest_path.parent().unwrap(); + let socket_dir = manifest_path + .parent() + .expect("manifest path names a file, so it has a parent"); let blobs_path = socket_dir.join("blobs"); let diffs_path = socket_dir.join("diffs"); let packages_path = socket_dir.join("packages"); diff --git a/crates/socket-patch-cli/src/commands/rollback.rs b/crates/socket-patch-cli/src/commands/rollback.rs index e5198229..12acfeb4 100644 --- a/crates/socket-patch-cli/src/commands/rollback.rs +++ b/crates/socket-patch-cli/src/commands/rollback.rs @@ -250,7 +250,7 @@ pub async fn run(args: RollbackArgs) -> i32 { "status": "error", "error": msg, })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); } else { eprintln!("Error: {msg}"); @@ -274,7 +274,7 @@ pub async fn run(args: RollbackArgs) -> i32 { "error": "Manifest not found", "path": manifest_path.display().to_string(), })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); } else { // Errors print even under --silent ("errors only", never @@ -331,7 +331,7 @@ pub async fn run(args: RollbackArgs) -> i32 { "vendored": vendored, "results": results.iter().map(result_to_json).collect::>(), })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); } else if !args.common.silent && !results.is_empty() { let rolled_back: Vec<_> = results @@ -458,7 +458,7 @@ pub async fn run(args: RollbackArgs) -> i32 { "vendored": [], "results": [], })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); } else { // Errors print even under --silent ("errors only", never @@ -479,7 +479,9 @@ async fn rollback_patches_inner( .map_err(|e| e.to_string())? .ok_or_else(|| "Invalid manifest".to_string())?; - let socket_dir = manifest_path.parent().unwrap(); + let socket_dir = manifest_path + .parent() + .expect("manifest path names a file, so it has a parent"); let mut blobs_path = socket_dir.join("blobs"); // `--dry-run` must not mutate `.socket/` ("Preview, no mutations"): // don't create the blobs dir; a throwaway stage replaces it below. @@ -495,7 +497,9 @@ async fn rollback_patches_inner( if args.identifier.is_some() { return Err(format!( "No patch found matching identifier: {}", - args.identifier.as_deref().unwrap() + args.identifier + .as_deref() + .expect("is_some checked by the enclosing if") )); } if !args.common.silent && !args.common.json { diff --git a/crates/socket-patch-cli/src/commands/scan/hosted.rs b/crates/socket-patch-cli/src/commands/scan/hosted.rs index b956486e..a3b24ef8 100644 --- a/crates/socket-patch-cli/src/commands/scan/hosted.rs +++ b/crates/socket-patch-cli/src/commands/scan/hosted.rs @@ -96,7 +96,11 @@ fn emit_json_error(scan_result: Option, message: &str) { if !result.get("redirect").is_some_and(|r| r.is_object()) { result["redirect"] = serde_json::json!({ "mode": "hosted" }); } - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); } /// Build the hosted `--json` success envelope: the classic scan object @@ -931,7 +935,7 @@ pub(super) async fn run_redirect( let mut result = build_redirect_json_envelope(scan_result.take(), redirect); if let Some(statements) = vex_statements { result["vex"] = serde_json::json!({ - "path": args.vex.vex.as_ref().unwrap().display().to_string(), + "path": args.vex.vex.as_ref().expect("vex_statements is Some only when --vex was given").display().to_string(), "statements": statements, "format": "openvex-0.2.0", "verified": false, @@ -940,7 +944,11 @@ pub(super) async fn run_redirect( result["status"] = serde_json::json!("error"); result["error"] = serde_json::json!({ "code": code, "message": message }); } - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); } else { if !args.common.silent { let verb = if args.common.dry_run { @@ -993,7 +1001,11 @@ pub(super) async fn run_redirect( install time; run `socket-patch vex` after installing to verify against \ the installed tree).", statements, - args.vex.vex.as_ref().unwrap().display(), + args.vex + .vex + .as_ref() + .expect("vex_statements is Some only when --vex was given") + .display(), ); } else if args.vex.vex.is_some() && args.common.dry_run { eprintln!("Skipping VEX generation (--dry-run)."); diff --git a/crates/socket-patch-cli/src/commands/scan/mod.rs b/crates/socket-patch-cli/src/commands/scan/mod.rs index 93b76485..d112ced1 100644 --- a/crates/socket-patch-cli/src/commands/scan/mod.rs +++ b/crates/socket-patch-cli/src/commands/scan/mod.rs @@ -297,7 +297,7 @@ async fn embed_vex_into_json( match generate_vex_from_manifest_path(common, ¶ms, manifest_path).await { Ok(summary) => { result["vex"] = serde_json::json!({ - "path": vex_args.vex.as_ref().unwrap().display().to_string(), + "path": vex_args.vex.as_ref().expect("--vex is Some: guarded by the early return above").display().to_string(), "statements": summary.statements, "format": "openvex-0.2.0", }); @@ -341,7 +341,11 @@ async fn embed_vex_human( println!( "Wrote OpenVEX document with {} statement(s) to {}", summary.statements, - vex_args.vex.as_ref().unwrap().display(), + vex_args + .vex + .as_ref() + .expect("--vex is Some: guarded by the early return above") + .display(), ); } 0 @@ -411,7 +415,11 @@ async fn discover_selected( fn emit_discovery_error_json(result: &mut serde_json::Value, message: &str) { result["status"] = serde_json::json!("error"); result["error"] = serde_json::json!(message); - println!("{}", serde_json::to_string_pretty(result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(result) + .expect("serializing an in-memory JSON value cannot fail") + ); } /// The `DownloadParams` every scan-driven download shares. Only the output @@ -988,7 +996,11 @@ pub async fn run(mut args: ScanArgs) -> i32 { "packages": [], "updates": [], }); - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); } else { eprintln!("Error: {err}"); } @@ -1024,7 +1036,10 @@ pub async fn run(mut args: ScanArgs) -> i32 { // `--vex` side-effect reads the manifest at several terminal returns, // including the early "no packages" exit before the GC block. let manifest_path = args.common.resolved_manifest_path(); - let socket_dir = manifest_path.parent().unwrap().to_path_buf(); + let socket_dir = manifest_path + .parent() + .expect("manifest path names a file, so it has a parent") + .to_path_buf(); let overrides = args.common.api_client_overrides(); let (mut api_client, mut use_public_proxy) = @@ -1186,7 +1201,11 @@ pub async fn run(mut args: ScanArgs) -> i32 { } let code = embed_vex_into_json(&args.common, &args.vex, &manifest_path, 0, &mut result).await; - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); return code; } else if args.common.silent { // Errors only: the empty-scan hint is informational. @@ -1347,7 +1366,11 @@ pub async fn run(mut args: ScanArgs) -> i32 { "packages": [], "updates": [], }); - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); } else { eprintln!("Error: all {total_batches} API batch queries failed: {err}"); } @@ -1676,7 +1699,11 @@ pub async fn run(mut args: ScanArgs) -> i32 { &mut result, ) .await; - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); return final_code; } diff --git a/crates/socket-patch-cli/src/commands/scan/vendor_flow.rs b/crates/socket-patch-cli/src/commands/scan/vendor_flow.rs index 5ede5957..2800b156 100644 --- a/crates/socket-patch-cli/src/commands/scan/vendor_flow.rs +++ b/crates/socket-patch-cli/src/commands/scan/vendor_flow.rs @@ -269,7 +269,11 @@ async fn run_vendor_json_path( if args.vex.vex.is_some() { result["vex"] = serde_json::json!({ "skipped": true, "reason": "dry_run" }); } - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); return 0; } @@ -369,7 +373,11 @@ async fn run_vendor_json_path( "code": code, "message": message, }); - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); return 1; } }; @@ -379,7 +387,11 @@ async fn run_vendor_json_path( let final_code = embed_vex_into_json(&args.common, &args.vex, manifest_path, vendor_code, result).await; - println!("{}", serde_json::to_string_pretty(&result).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&result) + .expect("serializing an in-memory JSON value cannot fail") + ); final_code } diff --git a/crates/socket-patch-cli/src/commands/setup.rs b/crates/socket-patch-cli/src/commands/setup.rs index ac5f157a..53b14d52 100644 --- a/crates/socket-patch-cli/src/commands/setup.rs +++ b/crates/socket-patch-cli/src/commands/setup.rs @@ -154,7 +154,8 @@ fn report_no_files(args: &SetupArgs, counts: &[(&str, i64)]) -> i32 { map.insert("files".to_string(), serde_json::json!([])); println!( "{}", - serde_json::to_string_pretty(&serde_json::Value::Object(map)).unwrap() + serde_json::to_string_pretty(&serde_json::Value::Object(map)) + .expect("serializing an in-memory JSON value cannot fail") ); } else if !args.common.silent { println!("No package.json, Python, Bundler, or Composer project found"); @@ -180,7 +181,9 @@ fn confirm_proceed(prompt: &str) -> bool { return true; } print!("{prompt}"); - io::stdout().flush().unwrap(); + io::stdout() + .flush() + .expect("failed to write the confirmation prompt to stdout"); let mut answer = String::new(); if io::stdin().read_line(&mut answer).is_err() { // Terminals can deliver non-UTF-8 bytes (e.g. a Latin-1 paste); @@ -1042,7 +1045,7 @@ async fn run_check(args: &SetupArgs) -> i32 { }) }).collect::>(), })) - .unwrap() + .expect("serializing an in-memory JSON value cannot fail") ); } else if !args.common.silent { println!("\nConfiguration status:\n"); @@ -1493,7 +1496,11 @@ fn print_remove_envelope( if !warnings.is_empty() { obj["warnings"] = serde_json::json!(warnings); } - println!("{}", serde_json::to_string_pretty(&obj).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&obj) + .expect("serializing an in-memory JSON value cannot fail") + ); } // ───────────────────────────────────────────────────────────────────────── @@ -1893,5 +1900,9 @@ fn print_setup_envelope( if !warnings.is_empty() { obj["warnings"] = serde_json::json!(warnings); } - println!("{}", serde_json::to_string_pretty(&obj).unwrap()); + println!( + "{}", + serde_json::to_string_pretty(&obj) + .expect("serializing an in-memory JSON value cannot fail") + ); } diff --git a/crates/socket-patch-cli/src/output.rs b/crates/socket-patch-cli/src/output.rs index d3337dfb..2b332387 100644 --- a/crates/socket-patch-cli/src/output.rs +++ b/crates/socket-patch-cli/src/output.rs @@ -62,7 +62,9 @@ pub(crate) fn confirm(prompt: &str, default_yes: bool, skip_prompt: bool, is_jso } let hint = if default_yes { "[Y/n]" } else { "[y/N]" }; eprint!("{prompt} {hint} "); - io::stderr().flush().unwrap(); + io::stderr() + .flush() + .expect("stderr is unbuffered, so flush cannot fail"); let mut answer = String::new(); if io::stdin().read_line(&mut answer).is_err() { // Terminals can deliver non-UTF-8 bytes (e.g. a Latin-1 paste); diff --git a/crates/socket-patch-core/src/api/client.rs b/crates/socket-patch-core/src/api/client.rs index cef4c8cd..ce756974 100644 --- a/crates/socket-patch-core/src/api/client.rs +++ b/crates/socket-patch-core/src/api/client.rs @@ -541,7 +541,10 @@ impl ApiClient { /// proxy) do we re-derive the proxy base from the environment. fn binary_url(&self, kind: &str, identifier: &str) -> (String, bool) { if self.api_token.is_some() && self.org_slug.is_some() && !self.use_public_proxy { - let slug = self.org_slug.as_deref().unwrap(); + let slug = self + .org_slug + .as_deref() + .expect("org_slug is_some checked in this branch's condition"); let u = format!( "{}/v0/orgs/{}/patches/{}/{}", self.api_url, slug, kind, identifier @@ -776,7 +779,10 @@ impl ApiClient { None => proxy_url_from_env().trim_end_matches('/').to_string(), }; if use_auth { - let slug = self.org_slug.as_deref().unwrap(); + let slug = self + .org_slug + .as_deref() + .expect("use_auth requires org_slug.is_some()"); (format!("{base}/v0/orgs/{slug}/patches/package"), true) } else { (format!("{base}/patch/package"), false) @@ -1358,7 +1364,11 @@ fn select_org_slug(mut orgs: Vec) -> Result 0 => Err(ApiError::Other( "No organizations found for this API token.".into(), )), - 1 => Ok(orgs.into_iter().next().unwrap().slug), + 1 => Ok(orgs + .into_iter() + .next() + .expect("this match arm guarantees exactly one org") + .slug), _ => { let slugs: Vec<_> = orgs.iter().map(|o| o.slug.as_str()).collect(); let first = orgs[0].slug.clone(); diff --git a/crates/socket-patch-core/src/patch/redirect/mod.rs b/crates/socket-patch-core/src/patch/redirect/mod.rs index 7512b422..4ebb1150 100644 --- a/crates/socket-patch-core/src/patch/redirect/mod.rs +++ b/crates/socket-patch-core/src/patch/redirect/mod.rs @@ -443,7 +443,8 @@ fn rewrite_pypi_requirements( if pypi.is_empty() || !files.contains_key("requirements.txt") { return; } - let name_re = Regex::new(r"^([A-Za-z0-9._-]+)\s*(?:[=<>~!]=?|@|;|\s|$)").unwrap(); + let name_re = Regex::new(r"^([A-Za-z0-9._-]+)\s*(?:[=<>~!]=?|@|;|\s|$)") + .expect("static requirements-name regex is valid"); let mut lines: Vec = files["requirements.txt"] .split('\n') .map(|s| s.to_string()) @@ -822,9 +823,14 @@ fn strip_toml_key_quotes(s: &str) -> String { enum CargoTomlSection { /// `[dependencies]` & friends (dev/build/target-specific) plus /// `[workspace.dependencies]` — entries are `key = value` lines. - DepTable { workspace: bool }, + DepTable { + workspace: bool, + }, /// The multi-line table form `[dependencies.]` (all variants). - DepEntry { key: String, workspace: bool }, + DepEntry { + key: String, + workspace: bool, + }, Other, } @@ -851,7 +857,9 @@ fn classify_cargo_section(header_inner: &str) -> CargoTomlSection { key: strip_toml_key_quotes(key), workspace: true, }, - ["target", .., k] if is_cargo_dep_kind(k) => CargoTomlSection::DepTable { workspace: false }, + ["target", .., k] if is_cargo_dep_kind(k) => { + CargoTomlSection::DepTable { workspace: false } + } ["target", mid @ .., key] if mid.len() >= 2 && is_cargo_dep_kind(mid[mid.len() - 1]) => { CargoTomlSection::DepEntry { key: strip_toml_key_quotes(key), @@ -927,13 +935,20 @@ fn plan_cargo_toml( reg: &str, ) -> Result { let lines: Vec<&str> = content.split('\n').collect(); - let header_re = Regex::new(r"^\[([^\]]+)\]\s*(?:#.*)?$").unwrap(); - let package_re = Regex::new(r#"\bpackage\s*=\s*"([^"]*)""#).unwrap(); - let registry_val_re = Regex::new(r#"\bregistry\s*=\s*"([^"]*)""#).unwrap(); - let registry_key_re = Regex::new(r"\bregistry\s*=").unwrap(); - let registry_index_re = Regex::new(r"\bregistry-index\s*=").unwrap(); - let workspace_key_re = Regex::new(r"\bworkspace\s*=").unwrap(); - let path_git_re = Regex::new(r"\b(?:path|git)\s*=").unwrap(); + let header_re = + Regex::new(r"^\[([^\]]+)\]\s*(?:#.*)?$").expect("static section-header regex is valid"); + let package_re = + Regex::new(r#"\bpackage\s*=\s*"([^"]*)""#).expect("static package-key regex is valid"); + let registry_val_re = + Regex::new(r#"\bregistry\s*=\s*"([^"]*)""#).expect("static registry-value regex is valid"); + let registry_key_re = + Regex::new(r"\bregistry\s*=").expect("static registry-key probe regex is valid"); + let registry_index_re = + Regex::new(r"\bregistry-index\s*=").expect("static registry-index probe regex is valid"); + let workspace_key_re = + Regex::new(r"\bworkspace\s*=").expect("static workspace-key probe regex is valid"); + let path_git_re = + Regex::new(r"\b(?:path|git)\s*=").expect("static path/git probe regex is valid"); // A pending occurrence: what was found, resolved to an action in pass 2 // (workspace-inheriting entries need the whole file scanned first). @@ -955,7 +970,11 @@ fn plan_cargo_toml( } if trimmed.starts_with('[') && !trimmed.starts_with("[[") { section = match header_re.captures(trimmed) { - Some(c) => classify_cargo_section(c.get(1).unwrap().as_str()), + Some(c) => classify_cargo_section( + c.get(1) + .expect("header_re always captures group 1 (section name)") + .as_str(), + ), None => CargoTomlSection::Other, }; if let CargoTomlSection::DepEntry { key, workspace } = section.clone() { @@ -1015,9 +1034,7 @@ fn plan_cargo_toml( // Inserting `registry = …` next to `registry-index` makes // cargo reject the manifest as ambiguous — refuse, like // the inline-table branch does. - pending.push(Pending::Refuse( - "pinned to another registry".to_string(), - )); + pending.push(Pending::Refuse("pinned to another registry".to_string())); } else if let Some((line_idx, value)) = find_value("registry") { if value == reg { pending.push(Pending::Action(CargoTomlAction::Already)); @@ -1126,7 +1143,10 @@ fn plan_cargo_toml( let new_text = registry_val_re .replace(raw, format!("registry = \"{reg}\"").as_str()) .into_owned(); - pending.push(Pending::Action(CargoTomlAction::ReplaceLine { idx, new_text })); + pending.push(Pending::Action(CargoTomlAction::ReplaceLine { + idx, + new_text, + })); if workspace { workspace_pinned = true; } @@ -1136,9 +1156,7 @@ fn plan_cargo_toml( ))); } } else if registry_key_re.is_match(inner) || registry_index_re.is_match(inner) { - pending.push(Pending::Refuse( - "pinned to another registry".to_string(), - )); + pending.push(Pending::Refuse("pinned to another registry".to_string())); } else { // Rebuild the line: everything through `{`, the trimmed // inner, the registry pin, then `}` + any trailing bytes @@ -1157,7 +1175,10 @@ fn plan_cargo_toml( &raw[..=brace], &raw[close_raw..] ); - pending.push(Pending::Action(CargoTomlAction::ReplaceLine { idx, new_text })); + pending.push(Pending::Action(CargoTomlAction::ReplaceLine { + idx, + new_text, + })); if workspace { workspace_pinned = true; } @@ -1171,9 +1192,10 @@ fn plan_cargo_toml( // line after the entry is untouched (the old `\s*$` regex // swallowed it). let c = regex::escape(crate_name); - let line_re = - Regex::new(&format!(r#"^(\s*(?:{c}|"{c}")\s*=\s*)"([^"]+)"([ \t]*(?:#.*)?)$"#)) - .unwrap(); + let line_re = Regex::new(&format!( + r#"^(\s*(?:{c}|"{c}")\s*=\s*)"([^"]+)"([ \t]*(?:#.*)?)$"# + )) + .expect("line regex from the escaped crate name is valid"); let Some(m) = line_re.captures(raw) else { pending.push(Pending::Refuse( "unsupported version-entry spelling".to_string(), @@ -1182,11 +1204,20 @@ fn plan_cargo_toml( }; let new_text = format!( "{}{{ version = \"{}\", registry = \"{reg}\" }}{}", - m.get(1).unwrap().as_str(), - m.get(2).unwrap().as_str(), - m.get(3).unwrap().as_str() + m.get(1) + .expect("line_re always captures group 1 (key prefix)") + .as_str(), + m.get(2) + .expect("line_re always captures group 2 (version)") + .as_str(), + m.get(3) + .expect("line_re always captures group 3 (trailing comment)") + .as_str() ); - pending.push(Pending::Action(CargoTomlAction::ReplaceLine { idx, new_text })); + pending.push(Pending::Action(CargoTomlAction::ReplaceLine { + idx, + new_text, + })); if workspace { workspace_pinned = true; } @@ -1305,7 +1336,8 @@ fn plan_cargo_lock( } let original = content[block_start..block_end].to_string(); let mut body = content[body_start..block_end].to_string(); - let source_re = Regex::new(r#"(?m)^source = "[^"]*"$"#).unwrap(); + let source_re = + Regex::new(r#"(?m)^source = "[^"]*"$"#).expect("static lock source-line regex is valid"); if source_re.is_match(&body) { body = source_re .replace(&body, format!("source = \"{index_url}\"").as_str()) @@ -1313,13 +1345,15 @@ fn plan_cargo_lock( } else { body = format!("source = \"{index_url}\"\n{body}"); } - let checksum_re = Regex::new(r#"(?m)^checksum = "[^"]*"$"#).unwrap(); + let checksum_re = Regex::new(r#"(?m)^checksum = "[^"]*"$"#) + .expect("static lock checksum-line regex is valid"); if checksum_re.is_match(&body) { body = checksum_re .replace(&body, format!("checksum = \"{cksum}\"").as_str()) .to_string(); } else { - let after_source = Regex::new(r#"(?m)^(source = "[^"]*"\n)"#).unwrap(); + let after_source = Regex::new(r#"(?m)^(source = "[^"]*"\n)"#) + .expect("static source-line anchor regex is valid"); body = after_source .replace(&body, format!("${{1}}checksum = \"{cksum}\"\n").as_str()) .to_string(); @@ -1348,7 +1382,10 @@ fn plan_cargo_lock( /// over an already-redirected block (no edit, no warning) from a genuinely /// missing package (the caller warns AND skips the dep entirely). enum CargoLockPlan { - Rewritten { content: String, edit: Box }, + Rewritten { + content: String, + edit: Box, + }, AlreadyRedirected, NotFound, } @@ -1506,7 +1543,8 @@ fn rewrite_pnpm_lock( + "/" + ®ex::escape(&dep.version) + r"(?:[_(][^:\n]*)?):"; - let legacy_re = Regex::new(&legacy_pat).unwrap(); + let legacy_re = Regex::new(&legacy_pat) + .expect("legacy-key regex from the escaped name and version is valid"); let mut legacy_keys: Vec = Vec::new(); for (lock_key, content, _) in &contents { for caps in legacy_re.captures_iter(content) { @@ -1532,16 +1570,29 @@ fn rewrite_pnpm_lock( + r"'|/?" + &key + r"):\n(?: {4,}.*\n)*? {4,}resolution: )\{([^}\n]*)\}"; - let re = Regex::new(&pat).unwrap(); + let re = + Regex::new(&pat).expect("resolution regex from the escaped name@version key is valid"); let mut matched_any = false; for (key, content, changed) in &mut contents { let Some(caps) = re.captures(content) else { continue; }; matched_any = true; - let whole = caps.get(0).unwrap().as_str().to_string(); - let prefix = caps.get(1).unwrap().as_str().to_string(); - let inner = caps.get(2).unwrap().as_str().to_string(); + let whole = caps + .get(0) + .expect("group 0 is the whole match") + .as_str() + .to_string(); + let prefix = caps + .get(1) + .expect("resolution regex always captures group 1 (prefix)") + .as_str() + .to_string(); + let inner = caps + .get(2) + .expect("resolution regex always captures group 2 (inner)") + .as_str() + .to_string(); let original = format!("{{{inner}}}"); let mut fields: Vec = vec![ format!("integrity: {sha512}"), @@ -1598,7 +1649,10 @@ fn rewrite_yarn_classic( return; } let raw = &files["yarn.lock"]; - if Regex::new(r"(?m)^__metadata:").unwrap().is_match(raw) { + if Regex::new(r"(?m)^__metadata:") + .expect("static __metadata probe regex is valid") + .is_match(raw) + { return; // yarn-berry — not classic } // CRLF locks (core.autocrlf Windows checkouts — yarn v1 parses them fine) @@ -1626,8 +1680,10 @@ fn rewrite_yarn_classic( raw }; let mut blocks: Vec = content.split("\n\n").map(String::from).collect(); - let resolved_re = Regex::new(r#"\n {2}resolved "[^"]*""#).unwrap(); - let integrity_re = Regex::new(r"\n {2}integrity [^\n]*").unwrap(); + let resolved_re = + Regex::new(r#"\n {2}resolved "[^"]*""#).expect("static resolved-line regex is valid"); + let integrity_re = + Regex::new(r"\n {2}integrity [^\n]*").expect("static integrity-line regex is valid"); let mut changed = false; for dep in &npm { let fname = full_name(dep); @@ -1640,7 +1696,7 @@ fn rewrite_yarn_classic( }; let version_re = Regex::new(&(String::from(r#"\n {2}version ""#) + ®ex::escape(&dep.version) + "\"")) - .unwrap(); + .expect("version regex from the escaped version is valid"); let mut matched_any = false; let mut alias_skipped = false; for block in blocks.iter_mut() { @@ -1829,7 +1885,10 @@ fn rewrite_yarn_berry( } let content = &files["yarn.lock"]; // The classic rewriter handles a v1 lock; berry stays out of its way. - if !Regex::new(r"(?m)^__metadata:").unwrap().is_match(content) { + if !Regex::new(r"(?m)^__metadata:") + .expect("static __metadata probe regex is valid") + .is_match(content) + { return; } @@ -1879,8 +1938,10 @@ fn rewrite_yarn_berry( } let mut blocks: Vec = content.split("\n\n").map(String::from).collect(); - let resolution_re = Regex::new(r#"\n {2}resolution: "[^"]*""#).unwrap(); - let checksum_re = Regex::new(r"\n {2}checksum: [^\n]*").unwrap(); + let resolution_re = + Regex::new(r#"\n {2}resolution: "[^"]*""#).expect("static resolution-line regex is valid"); + let checksum_re = + Regex::new(r"\n {2}checksum: [^\n]*").expect("static checksum-line regex is valid"); let mut changed = false; for dep in &npm { let fname = full_name(dep); @@ -1897,7 +1958,7 @@ fn rewrite_yarn_berry( // Berry versions are UNQUOTED (` version: 1.3.0`, spike B3 ground truth). let version_re = Regex::new(&(String::from(r"\n {2}version: ") + ®ex::escape(&dep.version) + "\n")) - .unwrap(); + .expect("version regex from the escaped version is valid"); let mut matched_any = false; let mut alias_skipped = false; for block in blocks.iter_mut() { @@ -1920,8 +1981,13 @@ fn rewrite_yarn_berry( if parsed.iter().any(Option::is_none) { continue; } - let names: std::collections::BTreeSet<&str> = - parsed.iter().map(|p| p.unwrap().0).collect(); + let names: std::collections::BTreeSet<&str> = parsed + .iter() + .map(|p| { + p.expect("every pattern parsed — None-bearing keys are skipped above") + .0 + }) + .collect(); if !names.contains(fname.as_str()) { // An `alias@npm:@range` descriptor resolves the // patched package under a different ident. The redirect @@ -1930,7 +1996,7 @@ fn rewrite_yarn_berry( // generic not-found warning would point at the wrong cause. if version_re.is_match(block) && parsed.iter().any(|p| { - p.unwrap() + p.expect("every pattern parsed — None-bearing keys are skipped above") .1 .strip_prefix("npm:") .and_then(split_berry_descriptor) @@ -1970,7 +2036,11 @@ fn rewrite_yarn_berry( // under such a key corrupts the key/resolution protocol pairing. // Mirrors the vendor backend's fail-closed gate // (vendor/yarn_berry_lock.rs). - if !parsed.iter().all(|p| p.unwrap().1.starts_with("npm:")) { + if !parsed.iter().all(|p| { + p.expect("every pattern parsed — None-bearing keys are skipped above") + .1 + .starts_with("npm:") + }) { result.warnings.push(RewriteWarning { code: "redirect_yarn_berry_unsupported_protocol".into(), detail: format!( @@ -2146,9 +2216,11 @@ fn rewrite_bun_lock( "{indent}{key}: [{url}, {deps}, {integrity}]{comma}", indent = entry.indent, key = entry.key_raw, - url = serde_json::to_string(&url_spec).unwrap(), + url = serde_json::to_string(&url_spec) + .expect("a String serializes to JSON infallibly"), deps = deps_verbatim, - integrity = serde_json::to_string(&sha512).unwrap(), + integrity = + serde_json::to_string(&sha512).expect("a String serializes to JSON infallibly"), comma = if entry.trailing_comma { "," } else { "" }, ); if rebuilt == original { @@ -2199,7 +2271,10 @@ fn is_prior_hosted_bun_spec(spec: &str, fname: &str, current_url: &str) -> bool if !url.starts_with("https://") && !url.starts_with("http://") { return None; } - let scheme_end = url.find("://").unwrap() + 3; + let scheme_end = url + .find("://") + .expect("url starts with http(s):// — checked above") + + 3; let path_start = url[scheme_end..].find('/')? + scheme_end; let leaf = url[path_start..] .rsplit('/') @@ -2224,8 +2299,9 @@ fn rewrite_uv_lock( return; } let mut content = files["uv.lock"].clone(); - let wheel_re = Regex::new(r#"\{ url = "[^"]*", hash = "sha256:[^"]*"([^}]*) \}"#).unwrap(); - let name_re = Regex::new(r#"name = "([^"]+)""#).unwrap(); + let wheel_re = Regex::new(r#"\{ url = "[^"]*", hash = "sha256:[^"]*"([^}]*) \}"#) + .expect("static uv wheel-entry regex is valid"); + let name_re = Regex::new(r#"name = "([^"]+)""#).expect("static name-field regex is valid"); let mut changed = false; for dep in &pypi { let Some(sha256) = dep.integrity.sha256.clone() else { @@ -2466,9 +2542,10 @@ fn rewrite_composer_lock( } const DIST_KEY: &str = "\"dist\": {"; let mut content = files["composer.lock"].clone(); - let type_re = Regex::new(r#"("type": ")[^"]*(")"#).unwrap(); - let url_re = Regex::new(r#"("url": ")[^"]*(")"#).unwrap(); - let shasum_re = Regex::new(r#"("shasum": ")[^"]*(")"#).unwrap(); + let type_re = Regex::new(r#"("type": ")[^"]*(")"#).expect("static dist type regex is valid"); + let url_re = Regex::new(r#"("url": ")[^"]*(")"#).expect("static dist url regex is valid"); + let shasum_re = + Regex::new(r#"("shasum": ")[^"]*(")"#).expect("static dist shasum regex is valid"); let mut changed = false; for dep in &composer { let composer_name = full_name(dep); @@ -2664,7 +2741,8 @@ fn insert_nuget_source(config: &str, key: &str, url: &str) -> String { // pair holding the new source. Matched before the open-tag check because a // `` literal does not contain the `` open // tag. - let self_closing = Regex::new(r"").unwrap(); + let self_closing = Regex::new(r"") + .expect("static self-closing packageSources regex is valid"); if let Some(m) = self_closing.find(config) { let mut out = String::with_capacity(config.len() + source_line.len() + 40); out.push_str(&config[..m.start()]); @@ -2692,13 +2770,18 @@ fn insert_nuget_source(config: &str, key: &str, url: &str) -> String { /// is no such element). Used to preserve resolution for non-patched packages /// when a `` is introduced. fn nuget_package_source_keys(config: &str) -> Vec { - let region_re = Regex::new(r"(?s)(.*?)").unwrap(); + let region_re = Regex::new(r"(?s)(.*?)") + .expect("static packageSources region regex is valid"); let scope = region_re .captures(config) - .map(|c| c.get(1).unwrap().as_str()) + .map(|c| { + c.get(1) + .expect("region_re always captures group 1") + .as_str() + }) .unwrap_or(""); Regex::new(r#" String { + ®ex::escape(&dep.name) + r#"["'][^\n]*\nend\r?\n?"#), ) - .unwrap(); + .expect("source-block regex from the escaped gem name is valid"); residue = block_re.replace_all(&residue, "").into_owned(); let decl_re = Regex::new( &(String::from(r#"(?m)^[ \t]*gem\b[^\n]*["']"#) + ®ex::escape(&dep.name) + r#"["'][^\n]*\n?"#), ) - .unwrap(); + .expect("gem-declaration regex from the escaped gem name is valid"); residue = decl_re.replace_all(&residue, "").into_owned(); } residue.trim_end().to_string() @@ -2991,7 +3074,8 @@ fn rewrite_gem( // bundler (verified: `bundle check`/frozen install both accept one on // 4.0.15), and without the tolerance the CHECKSUMS header never matched, // misdiagnosing the lock as bundler <2.6. - let checksums_re = Regex::new(r"(?m)^CHECKSUMS(\r?)$").unwrap(); + let checksums_re = + Regex::new(r"(?m)^CHECKSUMS(\r?)$").expect("static CHECKSUMS header regex is valid"); for dep in &gem { let Some(ov) = &dep.registry_override else { @@ -3031,7 +3115,7 @@ fn rewrite_gem( + ®ex::escape(&dep.version) + r"-[^)]+\) sha256="), ) - .unwrap(); + .expect("platform regex from the escaped name/version is valid"); if platform_re.is_match(lk) { result.warnings.push(RewriteWarning { code: "redirect_gem_platform_unsupported".into(), @@ -3067,9 +3151,11 @@ fn rewrite_gem( + ®ex::escape(&dep.name) + r#"["']"#), ) - .unwrap(); + .expect("source-block regex from the escaped index URL is valid"); if let Some(m) = block_re.captures(gf) { - let url = m.get(1).unwrap(); + let url = m + .get(1) + .expect("block_re always captures group 1 (index URL)"); if url.as_str() == ov.index_url { source_placed = true; } else { @@ -3095,7 +3181,7 @@ fn rewrite_gem( + ®ex::escape(&dep.name) + r#"["']([^\n]*)$"#), ) - .unwrap(); + .expect("gem-line regex from the escaped gem name is valid"); // Looser "declared at all?" probe: gates the append branch — // appending next to a declaration the recognizer above cannot // parse would leave the gem declared twice (bundler @@ -3105,12 +3191,20 @@ fn rewrite_gem( + ®ex::escape(&dep.name) + r#"["']"#), ) - .unwrap(); + .expect("declaration probe regex from the escaped gem name is valid"); if let Some(m) = gem_line_re.captures(gf) { - let range = m.get(0).unwrap().range(); - let original = m.get(0).unwrap().as_str().to_string(); + let range = m.get(0).expect("group 0 is the whole match").range(); + let original = m + .get(0) + .expect("group 0 is the whole match") + .as_str() + .to_string(); let paren = m.get(1).is_some(); - let raw_tail = m.get(2).unwrap().as_str().to_string(); + let raw_tail = m + .get(2) + .expect("gem_line_re always captures group 2 (tail)") + .as_str() + .to_string(); // A parenthesized call keeps its closing `)` in the tail: // strip it (dropping any comment with it), or fail closed // when it is absent (the call continues past this line). @@ -3233,13 +3327,13 @@ fn rewrite_gem( + ®ex::escape(&dep.version) + r"\)) sha256=([0-9a-f]+)(\r?)$"), ) - .unwrap(); + .expect("checksum-line regex from the escaped name/version is valid"); let new_val = format!("{} ({}) sha256={sha256}", dep.name, dep.version); // Already redirected (re-run): the CHECKSUMS line is at the // target value; recording an edit would grow the ledger forever. let already_re = Regex::new(&(String::from(r"(?m)^ ") + ®ex::escape(&new_val) + r"\r?$")) - .unwrap(); + .expect("already-redirected regex from the escaped line is valid"); if already_re.is_match(lk) { // no-op } else if let Some(m) = sum_line_re.captures(lk) { @@ -3249,7 +3343,9 @@ fn rewrite_gem( "{} ({}) sha256={}", dep.name, dep.version, - m.get(2).unwrap().as_str() + m.get(2) + .expect("sum_line_re always captures group 2 (sha hex)") + .as_str() ); *lk = sum_line_re .replace(lk, format!("${{1}} sha256={sha256}${{3}}").as_str()) @@ -3402,9 +3498,12 @@ struct MavenDependencyMatch { /// Inner-text byte range of the first `` inside `pom[from, to)`, or /// None. Offsets are into the FULL `pom`. fn maven_tag_inner_range(pom: &str, tag: &str, from: usize, to: usize) -> Option<(usize, usize)> { - let re = Regex::new(&format!("(?s)<{tag}>(.*?)")).unwrap(); + let re = Regex::new(&format!("(?s)<{tag}>(.*?)")) + .expect("tag regex is valid — callers pass literal tag names"); let caps = re.captures(&pom[from..to])?; - let inner = caps.get(1).unwrap(); + let inner = caps + .get(1) + .expect("tag regex always captures group 1 (inner text)"); Some((from + inner.start(), from + inner.end())) } @@ -3426,7 +3525,8 @@ fn find_maven_dependency_matches( group_id: &str, artifact_id: &str, ) -> Vec { - let dep_re = Regex::new(r"(?s)]*>.*?").unwrap(); + let dep_re = Regex::new(r"(?s)]*>.*?") + .expect("static dependency-block regex is valid"); let mut matches = vec![]; for m in dep_re.find_iter(pom) { let (dep_open, dep_close) = (m.start(), m.end()); @@ -3520,7 +3620,9 @@ fn rewrite_maven_pom( // policy `fail`) exactly as before and warn that this is NOT // fail-closed. let Some(suffixed_version) = suffixed_version else { - let pom_text = pom.as_ref().unwrap(); + let pom_text = pom + .as_ref() + .expect("pom is Some — the is_none() guard above continues"); // Verify-only inspection: warn when the redirect can't take effect. // Only the FIRST match matters here (legacy behavior). let matches = find_maven_dependency_matches(pom_text, &group_id, &artifact_id); @@ -3593,7 +3695,12 @@ fn rewrite_maven_pom( // FAIL-CLOSED: pin the suffixed version explicitly. Scan every matching // , tracking depMgmt containment via the version presence // so we can tell a literal pin here from a version managed elsewhere. - let matches = find_maven_dependency_matches(pom.as_ref().unwrap(), &group_id, &artifact_id); + let matches = find_maven_dependency_matches( + pom.as_ref() + .expect("pom is Some — the is_none() guard above continues"), + &group_id, + &artifact_id, + ); // An unsupported on any match: the single-jar repo can't serve // it — skip the whole dep (no version edit, no repo, no checksum). @@ -3647,7 +3754,10 @@ fn rewrite_maven_pom( .collect(); to_rewrite.sort_by(|a, b| b.0.cmp(&a.0)); for (start, end) in &to_rewrite { - let mut rebuilt = pom.as_ref().unwrap().clone(); + let mut rebuilt = pom + .as_ref() + .expect("pom is Some — the is_none() guard above continues") + .clone(); rebuilt.replace_range(*start..*end, &suffixed_version); pom = Some(rebuilt); pom_changed = true; @@ -3684,7 +3794,8 @@ fn rewrite_maven_pom( // skipped (idempotent). if versioned.is_empty() { pom = Some(insert_maven_dependency_management( - pom.as_ref().unwrap(), + pom.as_ref() + .expect("pom is Some — the is_none() guard above continues"), &group_id, &artifact_id, &suffixed_version, @@ -3718,11 +3829,12 @@ fn rewrite_maven_pom( } if !pom .as_ref() - .unwrap() + .expect("pom is Some — the is_none() guard above continues") .contains(&format!("{repo_id}")) { pom = Some(insert_maven_repository( - pom.as_ref().unwrap(), + pom.as_ref() + .expect("pom is Some — the is_none() guard above continues"), &repo_id, &ov.index_url, )); @@ -3840,7 +3952,8 @@ fn insert_maven_dependency_management( let block = format!( " \n {group_id}\n {artifact_id}\n {version}\n " ); - let dm_re = Regex::new(r"(?s)\s*").unwrap(); + let dm_re = Regex::new(r"(?s)\s*") + .expect("static dependencyManagement regex is valid"); if let Some(m) = dm_re.find(pom) { let matched = m.as_str(); return pom.replacen(matched, &format!("{matched}\n{block}"), 1); @@ -3873,7 +3986,7 @@ fn merge_mvn_config(existing: &str, coordinate: &str) -> (String, Vec) { } let mut appended: Vec<&str> = vec![]; for arg in MVN_CONFIG_ARGS { - let key = key_of(arg).unwrap(); + let key = key_of(arg).expect("every MVN_CONFIG_ARGS entry contains '='"); match present.get(&key) { None => { appended.push(arg); @@ -5795,7 +5908,10 @@ mod tests { ); let r = rewrite_registry_redirect(&files, &[cargo_sparse_override()]); let toml = r.files.get("Cargo.toml").expect("Cargo.toml rewritten"); - let pinned = format!("serde = {{ version = \"1.0.190\", registry = \"{}\" }}", cargo_reg()); + let pinned = format!( + "serde = {{ version = \"1.0.190\", registry = \"{}\" }}", + cargo_reg() + ); assert_eq!( toml.matches(&pinned).count(), 2, @@ -5951,7 +6067,10 @@ mod tests { let lock = r.files.get("Cargo.lock").expect("lock re-pinned"); assert!(lock.contains(&cargo_index_url()), "{lock}"); let cfg = r.files.get(".cargo/config.toml").expect("config updated"); - assert!(cfg.contains(&format!("[registries.{}]", cargo_reg())), "{cfg}"); + assert!( + cfg.contains(&format!("[registries.{}]", cargo_reg())), + "{cfg}" + ); assert!( !r.warnings .iter() diff --git a/crates/socket-patch-core/src/setup/composer/mod.rs b/crates/socket-patch-core/src/setup/composer/mod.rs index 991eefae..b02ad218 100644 --- a/crates/socket-patch-core/src/setup/composer/mod.rs +++ b/crates/socket-patch-core/src/setup/composer/mod.rs @@ -142,13 +142,19 @@ fn serialize_like_input(doc: &Value, original: &str) -> String { /// `None` if already present in every event (idempotent no-op). fn composer_add(content: &str) -> Result, String> { let mut doc = parse_checked(content)?; - let root = doc.as_object_mut().unwrap(); + let root = doc + .as_object_mut() + .expect("parse_checked guarantees an object root"); // Get-or-create the `scripts` object (replacing a `null`). if !root.get("scripts").map(Value::is_object).unwrap_or(false) { root.insert("scripts".to_string(), Value::Object(Map::new())); } - let scripts = root.get_mut("scripts").unwrap().as_object_mut().unwrap(); + let scripts = root + .get_mut("scripts") + .expect("the guard above inserts `scripts` when absent") + .as_object_mut() + .expect("the guard above replaces a non-object `scripts`"); let mut changed = false; for event in HOOK_EVENTS { @@ -173,7 +179,9 @@ fn composer_add(content: &str) -> Result, String> { /// emptied `scripts` object. `None` if our command is absent everywhere. fn composer_remove(content: &str) -> Result, String> { let mut doc = parse_checked(content)?; - let root = doc.as_object_mut().unwrap(); + let root = doc + .as_object_mut() + .expect("parse_checked guarantees an object root"); // An absent (or `null`) `scripts` is a legitimate no-op: nothing of ours. let scripts = match root.get_mut("scripts").and_then(Value::as_object_mut) { Some(s) => s, diff --git a/crates/socket-patch-core/src/vendor/go_sum_edit.rs b/crates/socket-patch-core/src/vendor/go_sum_edit.rs index f0a6638f..01670c53 100644 --- a/crates/socket-patch-core/src/vendor/go_sum_edit.rs +++ b/crates/socket-patch-core/src/vendor/go_sum_edit.rs @@ -69,7 +69,11 @@ pub fn upsert_module_lines( let mut pending = want.iter().map(String::as_str).peekable(); for line in lines { while pending.peek().is_some_and(|w| *w < line) { - out.push(pending.next().unwrap()); + out.push( + pending + .next() + .expect("peek() just confirmed a pending element"), + ); } out.push(line); }