diff --git a/src/bootupd.rs b/src/bootupd.rs index a8df07b..5084dea 100755 --- a/src/bootupd.rs +++ b/src/bootupd.rs @@ -57,13 +57,13 @@ pub(crate) fn install( if dest_root.is_empty() { anyhow::bail!("dest_root cannot be empty"); } - + // TODO: Change this to an Option<&str>; though this probably balloons into having // DeviceComponent and FileBasedComponent let device = device.unwrap_or(""); let source_root = openat::Dir::open(source_root) .with_context(|| format!("Opening source root: {}", source_root))?; - + SavedState::ensure_not_present(dest_root) .context("failed to install, invalid re-install attempted")?; @@ -72,14 +72,14 @@ pub(crate) fn install( println!("No components available for this platform."); return Ok(()); } - + let target_components = if let Some(target_components) = target_components { // Checked by CLI parser assert!(!auto_components); if target_components.is_empty() { anyhow::bail!("No target components specified"); } - + target_components .iter() .map(|name| { @@ -99,7 +99,11 @@ pub(crate) fn install( anyhow::bail!("No components specified"); } - log::info!("Installing {} components to {}", target_components.len(), dest_root); + log::info!( + "Installing {} components to {}", + target_components.len(), + dest_root + ); let mut state = SavedState::default(); let mut installed_efi_vendor = None; diff --git a/src/cli/bootupctl.rs b/src/cli/bootupctl.rs index 4032c0d..0dd4739 100755 --- a/src/cli/bootupctl.rs +++ b/src/cli/bootupctl.rs @@ -179,7 +179,7 @@ fn ensure_running_in_systemd() -> Result<()> { let running_in_systemd = running_in_systemd(); if !running_in_systemd { log::info!("Not running in systemd, re-executing via systemd-run"); - + // Clear any failure status that may have happened previously let _r = Command::new("systemctl") .arg("reset-failed") @@ -189,7 +189,7 @@ fn ensure_running_in_systemd() -> Result<()> { .spawn() .and_then(|mut child| child.wait()) .map_err(|e| log::warn!("Failed to reset failed status: {}", e)); - + let r = Command::new("systemd-run") .args(SYSTEMD_ARGS_BOOTUPD) .args( @@ -200,7 +200,10 @@ fn ensure_running_in_systemd() -> Result<()> { .args(std::env::args()) .exec(); // If we got here, it's always an error - return Err(anyhow::anyhow!("Failed to re-execute via systemd-run: {}", r)); + return Err(anyhow::anyhow!( + "Failed to re-execute via systemd-run: {}", + r + )); } Ok(()) } diff --git a/src/packagesystem.rs b/src/packagesystem.rs index 840a822..58bd2cd 100755 --- a/src/packagesystem.rs +++ b/src/packagesystem.rs @@ -8,9 +8,9 @@ use crate::model::*; /// Parse the output of `dpkg -S` to extract package names fn parse_dpkg_s_output(output: &[u8]) -> Result { - let output_str = std::str::from_utf8(output) - .with_context(|| "dpkg output is not valid UTF-8")?; - + let output_str = + std::str::from_utf8(output).with_context(|| "dpkg output is not valid UTF-8")?; + // dpkg -S outputs "package: /path" format // Package names can contain colons (e.g., "grub-efi-amd64:amd64") // We need to find the colon that is followed by a space (start of file path) @@ -26,7 +26,7 @@ fn parse_dpkg_s_output(output: &[u8]) -> Result { } } } - + if let Some(pos) = colon_pos { let package_name = output_str[..pos].trim(); if package_name.is_empty() { @@ -34,7 +34,10 @@ fn parse_dpkg_s_output(output: &[u8]) -> Result { } Ok(package_name.to_string()) } else { - bail!("Invalid dpkg -S output format (no package:path separator): {}", output_str) + bail!( + "Invalid dpkg -S output format (no package:path separator): {}", + output_str + ) } } @@ -43,10 +46,14 @@ fn get_package_install_time(package: &str) -> Result> { if package.is_empty() { bail!("Package name cannot be empty"); } - + let list_path = format!("/var/lib/dpkg/info/{}.list", package); - let metadata = std::fs::metadata(&list_path) - .with_context(|| format!("Failed to get metadata for package '{}' at path '{}'", package, list_path))?; + let metadata = std::fs::metadata(&list_path).with_context(|| { + format!( + "Failed to get metadata for package '{}' at path '{}'", + package, list_path + ) + })?; // Use modification time as installation time let modified = metadata @@ -102,15 +109,19 @@ where if sysroot_path.is_empty() { bail!("sysroot_path cannot be empty"); } - + let mut packages = BTreeSet::new(); let paths: Vec<_> = paths.into_iter().collect(); - + if paths.is_empty() { bail!("No paths provided to query"); } - log::debug!("Querying dpkg database for {} paths in sysroot: {}", paths.len(), sysroot_path); + log::debug!( + "Querying dpkg database for {} paths in sysroot: {}", + paths.len(), + sysroot_path + ); for path in &paths { let path_ref = path.as_ref(); @@ -118,19 +129,23 @@ where log::warn!("Skipping empty path"); continue; } - + // Use dpkg -S to find which package owns the file let mut cmd = std::process::Command::new("dpkg"); cmd.args(["-S", "--root", sysroot_path]); cmd.arg(path_ref); - let dpkgout = cmd.output() + let dpkgout = cmd + .output() .with_context(|| format!("Failed to execute dpkg command for path: {:?}", path_ref))?; - + if !dpkgout.status.success() { // Skip files that don't belong to any package - log::debug!("File {:?} does not belong to any package (dpkg exit code: {})", - path_ref, dpkgout.status); + log::debug!( + "File {:?} does not belong to any package (dpkg exit code: {})", + path_ref, + dpkgout.status + ); continue; } @@ -148,18 +163,27 @@ where cmd.args(["-S"]); cmd.arg(path_ref); - let dpkgout = cmd.output() - .with_context(|| format!("Failed to execute local dpkg command for path: {:?}", path_ref))?; - + let dpkgout = cmd.output().with_context(|| { + format!( + "Failed to execute local dpkg command for path: {:?}", + path_ref + ) + })?; + if dpkgout.status.success() { - let package = parse_dpkg_s_output(&dpkgout.stdout) - .with_context(|| format!("Failed to parse local dpkg output for path: {:?}", path_ref))?; + let package = parse_dpkg_s_output(&dpkgout.stdout).with_context(|| { + format!("Failed to parse local dpkg output for path: {:?}", path_ref) + })?; packages.insert(package); } } } - log::debug!("Found {} packages for {} paths", packages.len(), paths.len()); + log::debug!( + "Found {} packages for {} paths", + packages.len(), + paths.len() + ); dpkg_parse_metadata(&packages) } @@ -184,15 +208,15 @@ fn test_parse_dpkg_s_output_errors() { // Test invalid UTF-8 let invalid_utf8 = b"package\xff: /path"; assert!(parse_dpkg_s_output(invalid_utf8).is_err()); - + // Test empty package name let empty_package = ": /path"; assert!(parse_dpkg_s_output(empty_package.as_bytes()).is_err()); - + // Test no separator let no_separator = "package /path"; assert!(parse_dpkg_s_output(no_separator.as_bytes()).is_err()); - + // Test only colon let only_colon = ":"; assert!(parse_dpkg_s_output(only_colon.as_bytes()).is_err());