feat: add progressbar for extraction and initramfs creation
This commit is contained in:
+24
-9
@@ -1,6 +1,7 @@
|
||||
use crate::veprintln;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use cpio::{newc, NewcBuilder};
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use std::io::Write;
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
use std::path::{Path, PathBuf};
|
||||
@@ -147,13 +148,20 @@ fn get_arch_package_suffix(arch: &str) -> &str {
|
||||
|
||||
/// Create a gzipped cpio initramfs from a directory
|
||||
fn create_initramfs(rootfs: &PathBuf) -> Result<PathBuf> {
|
||||
veprintln!("Creating initramfs from rootfs...");
|
||||
|
||||
// Create a temporary file for the initramfs
|
||||
let initramfs_path = rootfs.parent().unwrap().join("initramfs.cpio.gz");
|
||||
|
||||
// Create the cpio archive
|
||||
let cpio_data = create_cpio_archive(rootfs)?;
|
||||
// Create progress bar
|
||||
let pb = ProgressBar::new_spinner();
|
||||
pb.set_style(ProgressStyle::default_spinner()
|
||||
.template("{spinner:.green} {msg} ({pos} files)")
|
||||
.unwrap());
|
||||
pb.set_message("Scanning rootfs...");
|
||||
|
||||
// Create the cpio archive with progress
|
||||
let cpio_data = create_cpio_archive(rootfs, &pb)?;
|
||||
|
||||
pb.set_message("Compressing initramfs...");
|
||||
|
||||
// Compress with gzip
|
||||
let mut output_file = std::fs::File::create(&initramfs_path)
|
||||
@@ -165,21 +173,25 @@ fn create_initramfs(rootfs: &PathBuf) -> Result<PathBuf> {
|
||||
encoder.finish()
|
||||
.context("Failed to finalize gzip compression")?;
|
||||
|
||||
veprintln!("Initramfs created: {} bytes (uncompressed)", cpio_data.len());
|
||||
// Clear progress bar and print message only in verbose mode
|
||||
pb.finish_and_clear();
|
||||
veprintln!("Initramfs created: {} bytes, {} files", cpio_data.len(), pb.position());
|
||||
|
||||
Ok(initramfs_path)
|
||||
}
|
||||
|
||||
/// Create a newc-format cpio archive from a directory using the cpio crate
|
||||
fn create_cpio_archive(rootfs: &Path) -> Result<Vec<u8>> {
|
||||
fn create_cpio_archive(rootfs: &Path, pb: &ProgressBar) -> Result<Vec<u8>> {
|
||||
let mut archive = Vec::new();
|
||||
|
||||
// Collect all entries with their data
|
||||
let entries = collect_entries(rootfs, rootfs)?;
|
||||
let entries = collect_entries(rootfs, rootfs, pb)?;
|
||||
|
||||
// Collect entry names for checking existence later
|
||||
let entry_names: Vec<&str> = entries.iter().map(|(n, _, _, _, _)| n.as_str()).collect();
|
||||
|
||||
pb.set_message("Writing initramfs...");
|
||||
|
||||
// Write each entry using the cpio crate
|
||||
for (name, mode, mtime, nlink, data) in &entries {
|
||||
let file_size = data.len() as u32;
|
||||
@@ -243,7 +255,7 @@ fn create_cpio_archive(rootfs: &Path) -> Result<Vec<u8>> {
|
||||
}
|
||||
|
||||
/// Collect all filesystem entries recursively
|
||||
fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32, u32, Vec<u8>)>> {
|
||||
fn collect_entries(base: &Path, current: &Path, pb: &ProgressBar) -> Result<Vec<(String, u32, u32, u32, Vec<u8>)>> {
|
||||
let mut entries = Vec::new();
|
||||
|
||||
// Read directory entries
|
||||
@@ -267,6 +279,9 @@ fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32,
|
||||
}
|
||||
};
|
||||
|
||||
// Increment progress counter
|
||||
pb.inc(1);
|
||||
|
||||
let file_type = metadata.file_type();
|
||||
|
||||
// Determine mode (file type + permissions from filesystem)
|
||||
@@ -314,7 +329,7 @@ fn collect_entries(base: &Path, current: &Path) -> Result<Vec<(String, u32, u32,
|
||||
|
||||
// Recurse into directories
|
||||
if file_type.is_dir() {
|
||||
let mut sub_entries = collect_entries(base, &path)?;
|
||||
let mut sub_entries = collect_entries(base, &path, pb)?;
|
||||
entries.append(&mut sub_entries);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user