diff --git a/libips/src/api.rs b/libips/src/api.rs index 8282b63..90a8307 100644 --- a/libips/src/api.rs +++ b/libips/src/api.rs @@ -635,7 +635,10 @@ impl Resolver { // Helper: extract the package FMRI from a manifest's attributes fn manifest_fmri(manifest: &Manifest) -> Option { for attr in &manifest.attributes { - if attr.key == "pkg.fmri" && let Some(val) = attr.values.first() && let Ok(f) = Fmri::parse(val) { + if attr.key == "pkg.fmri" + && let Some(val) = attr.values.first() + && let Ok(f) = Fmri::parse(val) + { return Some(f); } } diff --git a/libips/src/recv.rs b/libips/src/recv.rs index 8dc94cf..25ac1b8 100644 --- a/libips/src/recv.rs +++ b/libips/src/recv.rs @@ -3,12 +3,15 @@ // MPL was not distributed with this file, You can // obtain one at https://mozilla.org/MPL/2.0/. -use crate::repository::{ReadableRepository, FileBackend, RepositoryError, Result, WritableRepository, ProgressReporter, ProgressInfo, NoopProgressReporter}; -use crate::fmri::Fmri; use crate::actions::Manifest; +use crate::fmri::Fmri; +use crate::repository::{ + FileBackend, NoopProgressReporter, ProgressInfo, ProgressReporter, ReadableRepository, + RepositoryError, Result, WritableRepository, +}; use std::collections::HashSet; use tempfile::tempdir; -use tracing::{info, debug}; +use tracing::{debug, info}; /// PackageReceiver handles downloading packages from a source repository /// and storing them in a destination repository. @@ -21,7 +24,11 @@ pub struct PackageReceiver<'a, S: ReadableRepository> { impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { /// Create a new PackageReceiver pub fn new(source: &'a mut S, dest: FileBackend) -> Self { - Self { source, dest, progress: None } + Self { + source, + dest, + progress: None, + } } /// Set the progress reporter @@ -37,7 +44,12 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { /// * `default_publisher` - The default publisher name if not specified in FMRI /// * `fmris` - List of FMRIs to receive /// * `recursive` - Whether to receive dependencies recursively - pub fn receive(&mut self, default_publisher: Option<&str>, fmris: &[Fmri], recursive: bool) -> Result<()> { + pub fn receive( + &mut self, + default_publisher: Option<&str>, + fmris: &[Fmri], + recursive: bool, + ) -> Result<()> { let mut processed = HashSet::new(); let mut queue: Vec = fmris.to_vec(); let mut updated_publishers = HashSet::new(); @@ -53,36 +65,55 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { while let Some(fmri) = queue.pop() { // If the FMRI doesn't have a version, we need to find the newest one let fmris_to_fetch = if fmri.version.is_none() { - let publisher = fmri.publisher.as_deref().or(default_publisher).ok_or_else(|| { - RepositoryError::Other(format!("No publisher specified for package {}", fmri.name)) - })?; + let publisher = + fmri.publisher + .as_deref() + .or(default_publisher) + .ok_or_else(|| { + RepositoryError::Other(format!( + "No publisher specified for package {}", + fmri.name + )) + })?; - overall_progress = overall_progress.with_context(format!("Looking up newest version for {}", fmri.name)); + overall_progress = overall_progress + .with_context(format!("Looking up newest version for {}", fmri.name)); progress.update(&overall_progress); debug!("No version specified for {}, looking up newest", fmri.name); - let pkgs = self.source.list_packages(Some(publisher), Some(&fmri.name))?; - + let pkgs = self + .source + .list_packages(Some(publisher), Some(&fmri.name))?; + // Group by package name to find the newest version for each - let mut by_name: std::collections::HashMap> = std::collections::HashMap::new(); + let mut by_name: std::collections::HashMap< + String, + Vec, + > = std::collections::HashMap::new(); for pi in pkgs { by_name.entry(pi.fmri.name.clone()).or_default().push(pi); } let mut results = Vec::new(); for (name, versions) in by_name { - let newest = versions.into_iter().max_by(|a, b| { - a.fmri.to_string().cmp(&b.fmri.to_string()) - }); + let newest = versions + .into_iter() + .max_by(|a, b| a.fmri.to_string().cmp(&b.fmri.to_string())); if let Some(pi) = newest { results.push(pi.fmri); } else { - info!("Package {} not found in source for publisher {}", name, publisher); + info!( + "Package {} not found in source for publisher {}", + name, publisher + ); } } - + if results.is_empty() { - info!("Package {} not found in source for publisher {}", fmri.name, publisher); + info!( + "Package {} not found in source for publisher {}", + fmri.name, publisher + ); continue; } // Update total_packages: remove the wildcard FMRI we just popped, and add actual results @@ -93,9 +124,17 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { }; for fmri_to_fetch in fmris_to_fetch { - let publisher_name = fmri_to_fetch.publisher.as_deref().or(default_publisher).ok_or_else(|| { - RepositoryError::Other(format!("No publisher specified for package {}", fmri_to_fetch.name)) - })?.to_string(); + let publisher_name = fmri_to_fetch + .publisher + .as_deref() + .or(default_publisher) + .ok_or_else(|| { + RepositoryError::Other(format!( + "No publisher specified for package {}", + fmri_to_fetch.name + )) + })? + .to_string(); if !processed.insert(fmri_to_fetch.clone()) { // If we already processed it (possibly as a dependency), don't count it again @@ -110,7 +149,10 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { .with_context(format!("Receiving {}", fmri_to_fetch)); progress.update(&overall_progress); - info!("Receiving package {} from publisher {}", fmri_to_fetch, publisher_name); + info!( + "Receiving package {} from publisher {}", + fmri_to_fetch, publisher_name + ); let manifest = self.receive_one(&publisher_name, &fmri_to_fetch)?; updated_publishers.insert(publisher_name.clone()); @@ -121,10 +163,10 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { if dep_fmri.publisher.is_none() { dep_fmri.publisher = Some(publisher_name.clone()); } - + if !processed.contains(&dep_fmri) && queued.insert(dep_fmri.clone()) { - total_packages += 1; - queue.push(dep_fmri); + total_packages += 1; + queue.push(dep_fmri); } } } @@ -134,7 +176,8 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { for pub_name in updated_publishers { info!("Rebuilding metadata for publisher {}", pub_name); - overall_progress = overall_progress.with_context(format!("Rebuilding metadata for {}", pub_name)); + overall_progress = + overall_progress.with_context(format!("Rebuilding metadata for {}", pub_name)); progress.update(&overall_progress); self.dest.rebuild(Some(&pub_name), false, false)?; } @@ -147,10 +190,11 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { /// Receive a single package fn receive_one(&mut self, publisher: &str, fmri: &Fmri) -> Result { let progress = self.progress.unwrap_or(&NoopProgressReporter); - + let manifest_text = self.source.fetch_manifest_text(publisher, fmri)?; - let manifest = Manifest::parse_string(manifest_text.clone()).map_err(RepositoryError::from)?; - + let manifest = + Manifest::parse_string(manifest_text.clone()).map_err(RepositoryError::from)?; + // Ensure publisher exists in destination let dest_info = self.dest.get_info()?; if !dest_info.publishers.iter().any(|p| p.name == publisher) { @@ -163,30 +207,41 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { txn.set_legacy_manifest(manifest_text); let temp_dir = tempdir().map_err(RepositoryError::IoError)?; - - let payload_files: Vec<_> = manifest.files.iter().filter(|f| f.payload.is_some()).collect(); + + let payload_files: Vec<_> = manifest + .files + .iter() + .filter(|f| f.payload.is_some()) + .collect(); let total_files = payload_files.len() as u64; - + for (i, file) in payload_files.into_iter().enumerate() { if let Some(payload) = &file.payload { let files_done = (i + 1) as u64; let digest = &payload.primary_identifier.hash; - - progress.update(&ProgressInfo::new(format!("Receiving payloads for {}", fmri.name)) - .with_total(total_files) - .with_current(files_done) - .with_context(format!("Payload: {}", digest))); + + progress.update( + &ProgressInfo::new(format!("Receiving payloads for {}", fmri.name)) + .with_total(total_files) + .with_current(files_done) + .with_context(format!("Payload: {}", digest)), + ); let temp_file_path = temp_dir.path().join(digest); - debug!("Fetching payload {} to {}", digest, temp_file_path.display()); - self.source.fetch_payload(publisher, digest, &temp_file_path)?; + debug!( + "Fetching payload {} to {}", + digest, + temp_file_path.display() + ); + self.source + .fetch_payload(publisher, digest, &temp_file_path)?; txn.add_file(file.clone(), &temp_file_path)?; } } txn.update_manifest(manifest.clone()); txn.commit()?; - + Ok(manifest) } } @@ -194,8 +249,8 @@ impl<'a, S: ReadableRepository> PackageReceiver<'a, S> { #[cfg(test)] mod tests { use super::*; - use crate::repository::{FileBackend, RepositoryVersion}; use crate::actions::Attr; + use crate::repository::{FileBackend, RepositoryVersion}; use tempfile::tempdir; #[test] @@ -206,7 +261,7 @@ mod tests { // Create source repo with one package let mut source_repo = FileBackend::create(source_dir.path(), RepositoryVersion::V4)?; source_repo.add_publisher("test")?; - + let fmri = Fmri::parse("pkg://test/pkgA@1.0").unwrap(); let mut manifest = Manifest::new(); manifest.attributes.push(Attr { @@ -245,15 +300,18 @@ mod tests { // Create source repo let mut source_repo = FileBackend::create(source_dir.path(), RepositoryVersion::V4)?; source_repo.add_publisher("test")?; - + let _fmri = Fmri::parse("pkg://test/pkgA@1.0").unwrap(); - let manifest_content = "set name=pkg.fmri value=pkg://test/pkgA@1.0\nset name=pkg.summary value=test\n"; - + let manifest_content = + "set name=pkg.fmri value=pkg://test/pkgA@1.0\nset name=pkg.summary value=test\n"; + // Manually write the manifest in IPS format to the source repo - let manifest_path = FileBackend::construct_manifest_path(source_dir.path(), "test", "pkgA", "1.0"); - std::fs::create_dir_all(manifest_path.parent().unwrap()).map_err(RepositoryError::IoError)?; + let manifest_path = + FileBackend::construct_manifest_path(source_dir.path(), "test", "pkgA", "1.0"); + std::fs::create_dir_all(manifest_path.parent().unwrap()) + .map_err(RepositoryError::IoError)?; std::fs::write(&manifest_path, manifest_content).map_err(RepositoryError::IoError)?; - + // Rebuild source repo to recognize the package source_repo.rebuild(Some("test"), false, false)?; @@ -264,9 +322,11 @@ mod tests { receiver.receive(Some("test"), &[Fmri::new("pkgA")], false)?; // Verify dest repo has the package and the manifest is in IPS format - let dest_manifest_path = FileBackend::construct_manifest_path(dest_dir.path(), "test", "pkgA", "1.0"); - let content = std::fs::read_to_string(&dest_manifest_path).map_err(RepositoryError::IoError)?; - + let dest_manifest_path = + FileBackend::construct_manifest_path(dest_dir.path(), "test", "pkgA", "1.0"); + let content = + std::fs::read_to_string(&dest_manifest_path).map_err(RepositoryError::IoError)?; + assert_eq!(content, manifest_content); assert!(!content.starts_with('{'), "Manifest should not be JSON"); @@ -275,9 +335,16 @@ mod tests { let mut filename = json_path.file_name().unwrap().to_os_string(); filename.push(".json"); json_path.set_file_name(filename); - assert!(json_path.exists(), "JSON manifest should exist at {}", json_path.display()); + assert!( + json_path.exists(), + "JSON manifest should exist at {}", + json_path.display() + ); let json_content = std::fs::read_to_string(&json_path).map_err(RepositoryError::IoError)?; - assert!(json_content.starts_with('{'), "JSON manifest should be JSON"); + assert!( + json_content.starts_with('{'), + "JSON manifest should be JSON" + ); Ok(()) } diff --git a/libips/src/repository/file_backend.rs b/libips/src/repository/file_backend.rs index b47da2a..9d451ff 100644 --- a/libips/src/repository/file_backend.rs +++ b/libips/src/repository/file_backend.rs @@ -1593,11 +1593,7 @@ impl ReadableRepository for FileBackend { ))) } - fn fetch_manifest_text( - &mut self, - publisher: &str, - fmri: &Fmri, - ) -> Result { + fn fetch_manifest_text(&mut self, publisher: &str, fmri: &Fmri) -> Result { // Require a concrete version let version = fmri.version(); if version.is_empty() { @@ -1609,10 +1605,7 @@ impl ReadableRepository for FileBackend { let path = Self::construct_manifest_path(&self.path, publisher, fmri.stem(), &version); if path.exists() { return std::fs::read_to_string(&path) - .map_err(|e| RepositoryError::FileReadError { - path, - source: e, - }); + .map_err(|e| RepositoryError::FileReadError { path, source: e }); } // Fallbacks: global pkg layout without publisher let encoded_stem = Self::url_encode(fmri.stem()); diff --git a/libips/src/repository/mod.rs b/libips/src/repository/mod.rs index 98ca713..a14242d 100644 --- a/libips/src/repository/mod.rs +++ b/libips/src/repository/mod.rs @@ -385,11 +385,7 @@ pub trait ReadableRepository { ) -> Result; /// Fetch a package manifest as raw text by FMRI from the repository. - fn fetch_manifest_text( - &mut self, - publisher: &str, - fmri: &crate::fmri::Fmri, - ) -> Result; + fn fetch_manifest_text(&mut self, publisher: &str, fmri: &crate::fmri::Fmri) -> Result; /// Search for packages in the repository /// diff --git a/libips/src/repository/rest_backend.rs b/libips/src/repository/rest_backend.rs index 0edf0c2..1e9bada 100644 --- a/libips/src/repository/rest_backend.rs +++ b/libips/src/repository/rest_backend.rs @@ -64,7 +64,11 @@ impl WritableRepository for RestBackend { // This is a stub implementation // In a real implementation, we would make a REST API call to create the repository - let uri_str = uri.as_ref().to_string_lossy().trim_end_matches('/').to_string(); + let uri_str = uri + .as_ref() + .to_string_lossy() + .trim_end_matches('/') + .to_string(); // Create the repository configuration let config = RepositoryConfig { @@ -323,7 +327,11 @@ impl WritableRepository for RestBackend { impl ReadableRepository for RestBackend { /// Open an existing repository fn open>(uri: P) -> Result { - let uri_str = uri.as_ref().to_string_lossy().trim_end_matches('/').to_string(); + let uri_str = uri + .as_ref() + .to_string_lossy() + .trim_end_matches('/') + .to_string(); // Create an HTTP client let client = Client::new(); @@ -444,14 +452,20 @@ impl ReadableRepository for RestBackend { return Ok(Vec::new()); } Err(e) => { - return Err(RepositoryError::Other(format!("Search API error: {} for {}", e, url))); + return Err(RepositoryError::Other(format!( + "Search API error: {} for {}", + e, url + ))); } }; let reader = BufReader::new(resp); for line in reader.lines() { let line = line.map_err(|e| { - RepositoryError::Other(format!("Failed to read search response line: {}", e)) + RepositoryError::Other(format!( + "Failed to read search response line: {}", + e + )) })?; // Line format: // Example: pkg.fmri pkg:/system/rsyslog@8.2508.0,5.11-151056.0:20251023T180542Z set omnios/system/rsyslog @@ -621,7 +635,7 @@ impl ReadableRepository for RestBackend { // Write atomically let tmp_path = dest.with_extension("tmp"); let mut tmp_file = File::create(&tmp_path)?; - + std::io::copy(&mut resp, &mut tmp_file).map_err(|e| { RepositoryError::Other(format!("Failed to download payload: {}", e)) })?; @@ -681,11 +695,7 @@ impl ReadableRepository for RestBackend { todo!() } - fn fetch_manifest_text( - &mut self, - publisher: &str, - fmri: &crate::fmri::Fmri, - ) -> Result { + fn fetch_manifest_text(&mut self, publisher: &str, fmri: &crate::fmri::Fmri) -> Result { // Require versioned FMRI let version = fmri.version(); if version.is_empty() { diff --git a/pkg6depotd/src/http/handlers/publisher.rs b/pkg6depotd/src/http/handlers/publisher.rs index 2b280d4..94b7396 100644 --- a/pkg6depotd/src/http/handlers/publisher.rs +++ b/pkg6depotd/src/http/handlers/publisher.rs @@ -69,8 +69,8 @@ async fn get_publisher_response( }], version: 1, }; - let json = - serde_json::to_string_pretty(&p5i).map_err(|e| DepotError::Server(e.to_string()))?; + let json = serde_json::to_string_pretty(&p5i) + .map_err(|e| DepotError::Server(e.to_string()))?; Ok(([(header::CONTENT_TYPE, "application/vnd.pkg5.info")], json).into_response()) } else { Err(DepotError::Repo( diff --git a/pkg6depotd/src/http/routes.rs b/pkg6depotd/src/http/routes.rs index 27b46e6..bb2f97f 100644 --- a/pkg6depotd/src/http/routes.rs +++ b/pkg6depotd/src/http/routes.rs @@ -38,9 +38,15 @@ pub fn app_router(state: Arc) -> Router { ) .route("/{publisher}/info/0/{fmri}", get(info::get_info)) .route("/{publisher}/publisher/0", get(publisher::get_publisher_v0)) - .route("/{publisher}/publisher/0/", get(publisher::get_publisher_v0)) + .route( + "/{publisher}/publisher/0/", + get(publisher::get_publisher_v0), + ) .route("/{publisher}/publisher/1", get(publisher::get_publisher_v1)) - .route("/{publisher}/publisher/1/", get(publisher::get_publisher_v1)) + .route( + "/{publisher}/publisher/1/", + get(publisher::get_publisher_v1), + ) .route("/publisher/0", get(publisher::get_default_publisher_v0)) .route("/publisher/0/", get(publisher::get_default_publisher_v0)) .route("/publisher/1", get(publisher::get_default_publisher_v1)) diff --git a/pkg6depotd/tests/integration_tests.rs b/pkg6depotd/tests/integration_tests.rs index 978adfa..6550c94 100644 --- a/pkg6depotd/tests/integration_tests.rs +++ b/pkg6depotd/tests/integration_tests.rs @@ -175,7 +175,7 @@ async fn test_depot_server() { let pub_json: serde_json::Value = resp.json().await.unwrap(); assert_eq!(pub_json["version"], 1); assert_eq!(pub_json["publishers"][0]["name"], "test"); - + // Test Default Publisher Route v1 let def_pub_url = format!("{}/publisher/1", base_url); let resp = client.get(&def_pub_url).send().await.unwrap(); @@ -427,10 +427,10 @@ async fn test_multiple_publishers_default_route() { let temp_dir = TempDir::new().unwrap(); let repo_path = temp_dir.path().join("repo_multi"); let mut backend = FileBackend::create(&repo_path, RepositoryVersion::V4).unwrap(); - + backend.add_publisher("pub1").unwrap(); backend.add_publisher("pub2").unwrap(); - + let config = Config { server: ServerConfig { bind: vec!["127.0.0.1:0".to_string()], @@ -471,12 +471,15 @@ async fn test_multiple_publishers_default_route() { let pub_json: serde_json::Value = resp.json().await.unwrap(); let pubs = pub_json["publishers"].as_array().unwrap(); - + // CURRENT BEHAVIOR: returns 1 // DESIRED BEHAVIOR: returns 2 assert_eq!(pubs.len(), 2, "Should return all publishers"); - - let names: Vec = pubs.iter().map(|p| p["name"].as_str().unwrap().to_string()).collect(); + + let names: Vec = pubs + .iter() + .map(|p| p["name"].as_str().unwrap().to_string()) + .collect(); assert!(names.contains(&"pub1".to_string())); assert!(names.contains(&"pub2".to_string())); } diff --git a/pkg6recv/src/main.rs b/pkg6recv/src/main.rs index a3e7f7e..daa9c02 100644 --- a/pkg6recv/src/main.rs +++ b/pkg6recv/src/main.rs @@ -1,8 +1,10 @@ use clap::Parser; -use miette::{IntoDiagnostic, Result}; -use libips::repository::{FileBackend, RestBackend, ReadableRepository, ProgressReporter, ProgressInfo}; -use libips::recv::PackageReceiver; use libips::fmri::Fmri; +use libips::recv::PackageReceiver; +use libips::repository::{ + FileBackend, ProgressInfo, ProgressReporter, ReadableRepository, RestBackend, +}; +use miette::{IntoDiagnostic, Result}; use std::path::PathBuf; use tracing::info; use tracing_subscriber::{EnvFilter, fmt}; @@ -56,7 +58,9 @@ fn main() -> Result<()> { // Open destination repository // We'll open it inside each branch to avoid borrow checker issues with moves - let fmris: Vec = cli.packages.iter() + let fmris: Vec = cli + .packages + .iter() .map(|s| Fmri::parse(s)) .collect::, _>>() .into_diagnostic()?; @@ -69,13 +73,17 @@ fn main() -> Result<()> { let dest_repo = FileBackend::open(&cli.dest).into_diagnostic()?; let mut receiver = PackageReceiver::new(&mut source_repo, dest_repo); receiver = receiver.with_progress(&progress); - receiver.receive(cli.publisher.as_deref(), &fmris, cli.recursive).into_diagnostic()?; + receiver + .receive(cli.publisher.as_deref(), &fmris, cli.recursive) + .into_diagnostic()?; } else { let mut source_repo = FileBackend::open(&cli.source).into_diagnostic()?; let dest_repo = FileBackend::open(&cli.dest).into_diagnostic()?; let mut receiver = PackageReceiver::new(&mut source_repo, dest_repo); receiver = receiver.with_progress(&progress); - receiver.receive(cli.publisher.as_deref(), &fmris, cli.recursive).into_diagnostic()?; + receiver + .receive(cli.publisher.as_deref(), &fmris, cli.recursive) + .into_diagnostic()?; } info!("Package receive complete."); diff --git a/pkgtree/src/main.rs b/pkgtree/src/main.rs index 75a037d..3e003e9 100644 --- a/pkgtree/src/main.rs +++ b/pkgtree/src/main.rs @@ -131,7 +131,12 @@ fn main() -> Result<()> { tracing_subscriber::fmt().with_env_filter(env_filter).init(); // Load image - let image = Image::load(&cli.image_path).map_err(|e| PkgTreeError(format!("Failed to load image at {:?}: {}", cli.image_path, e)))?; + let image = Image::load(&cli.image_path).map_err(|e| { + PkgTreeError(format!( + "Failed to load image at {:?}: {}", + cli.image_path, e + )) + })?; // Targeted analysis of solver error file has top priority if provided if let Some(err_path) = &cli.solver_error_file { @@ -164,7 +169,9 @@ fn main() -> Result<()> { .query_catalog(Some(needle.as_str())) .map_err(|e| PkgTreeError(format!("Failed to query catalog: {}", e)))? } else { - image.query_catalog(None).map_err(|e| PkgTreeError(format!("Failed to query catalog: {}", e)))? + image + .query_catalog(None) + .map_err(|e| PkgTreeError(format!("Failed to query catalog: {}", e)))? }; // Filter by publisher if specified @@ -765,7 +772,10 @@ fn query_catalog_cached_mut( return Ok(v.clone()); } let mut out = Vec::new(); - for p in image.query_catalog(Some(stem)).map_err(|e| PkgTreeError(format!("Failed to query catalog for {}: {}", stem, e)))? { + for p in image + .query_catalog(Some(stem)) + .map_err(|e| PkgTreeError(format!("Failed to query catalog for {}: {}", stem, e)))? + { out.push((p.publisher, p.fmri)); } ctx.catalog_cache.insert(stem.to_string(), out.clone()); @@ -781,9 +791,13 @@ fn get_manifest_cached( if let Some(m) = ctx.manifest_cache.get(&key) { return Ok(m.clone()); } - let manifest_opt = image - .get_manifest_from_catalog(fmri) - .map_err(|e| PkgTreeError(format!("Failed to load manifest for {}: {}", fmri.to_string(), e)))?; + let manifest_opt = image.get_manifest_from_catalog(fmri).map_err(|e| { + PkgTreeError(format!( + "Failed to load manifest for {}: {}", + fmri.to_string(), + e + )) + })?; let manifest = manifest_opt.unwrap_or_else(|| libips::actions::Manifest::new()); ctx.manifest_cache.insert(key, manifest.clone()); Ok(manifest) @@ -1018,7 +1032,9 @@ fn run_dangling_scan( format: OutputFormat, ) -> Result<()> { // Query full catalog once - let mut pkgs = image.query_catalog(None).map_err(|e| PkgTreeError(format!("Failed to query catalog: {}", e)))?; + let mut pkgs = image + .query_catalog(None) + .map_err(|e| PkgTreeError(format!("Failed to query catalog: {}", e)))?; // Build set of available non-obsolete stems AND an index of available (release, branch) pairs per stem, // honoring publisher filter @@ -1188,7 +1204,12 @@ fn run_dangling_scan( // ---------- Targeted analysis: parse pkg6 solver error text ---------- fn analyze_solver_error(image: &Image, publisher: Option<&str>, err_path: &PathBuf) -> Result<()> { - let text = std::fs::read_to_string(err_path).map_err(|e| PkgTreeError(format!("Failed to read solver error file {:?}: {}", err_path, e)))?; + let text = std::fs::read_to_string(err_path).map_err(|e| { + PkgTreeError(format!( + "Failed to read solver error file {:?}: {}", + err_path, e + )) + })?; // Build a stack based on indentation before the tree bullet "└─". let mut stack: Vec = Vec::new(); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index c933a5d..685f4c5 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -262,11 +262,7 @@ fn fmt() -> Result<()> { /// Run clippy fn clippy() -> Result<()> { Command::new("cargo") - .args([ - "clippy", - "--all-targets", - "--all-features", - ]) + .args(["clippy", "--all-targets", "--all-features"]) .status() .context("Failed to run clippy")?;