Implement enhanced package extraction with directory merging

- Add robust package file extraction using dpkg-deb
- Implement directory merging for existing staging directories
- Add package metadata creation with JSON files
- Support DEBIAN scripts and control files extraction
- Add file counting and detailed logging
- Improve error handling for directory operations

Core compose functionality is working with package download and metadata.
Next: Complete package file extraction and dependency resolution.
This commit is contained in:
robojerk 2025-07-18 20:48:20 +00:00
parent fe8f5c7b85
commit de8b1dfe51

View file

@ -301,7 +301,68 @@ impl ComposeManager {
// Copy extracted files to staging directory
let data_dir = extract_path.join("data");
if data_dir.exists() {
info!("Copying package data from {:?} to staging directory", data_dir);
self.copy_directory_recursive(&data_dir, staging_path)?;
// Count files copied
let file_count = self.count_files_recursive(&data_dir)?;
info!("Copied {} files from package data", file_count);
} else {
// dpkg-deb -R extracts files directly to the root directory
info!("Copying package files from {:?} to staging directory", extract_path);
// Verify extraction directory exists and has content
if !extract_path.exists() {
return Err(crate::error::AptOstreeError::InvalidArgument(
format!("Extraction directory does not exist: {:?}", extract_path)
));
}
// Copy files from extraction directory to staging directory
for entry in std::fs::read_dir(extract_path)? {
let entry = entry?;
let src_path = entry.path();
let file_name = entry.file_name();
// Skip DEBIAN directory (handled separately)
if entry.file_type()?.is_dir() && file_name.to_str() == Some("DEBIAN") {
continue;
}
let dst_path = staging_path.join(&file_name);
info!("Copying {:?} to {:?}", src_path, dst_path);
if entry.file_type()?.is_dir() {
// For directories, merge contents instead of overwriting
if dst_path.exists() {
// Directory exists, copy contents recursively
self.copy_directory_recursive(&src_path, &dst_path)?;
} else {
// Directory doesn't exist, create it and copy the entire directory
std::fs::create_dir_all(&dst_path)?;
self.copy_directory_recursive(&src_path, &dst_path)?;
}
} else {
// For files, ensure parent directory exists and copy
if let Some(parent) = dst_path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::copy(&src_path, &dst_path)?;
}
}
// Count files copied (excluding DEBIAN directory)
let mut file_count = 0;
for entry in std::fs::read_dir(extract_path)? {
let entry = entry?;
let path = entry.path();
if entry.file_type()?.is_dir() && path.file_name().and_then(|s| s.to_str()) != Some("DEBIAN") {
file_count += self.count_files_recursive(&path)?;
} else if entry.file_type()?.is_file() {
file_count += 1;
}
}
info!("Copied {} files from package root", file_count);
}
// Copy control files to package metadata
@ -311,12 +372,41 @@ impl ComposeManager {
let control_dest = staging_path.join("var/lib/apt-ostree/packages").join(package_name).join("control");
std::fs::create_dir_all(&control_dest)?;
self.copy_directory_recursive(&control_dir, &control_dest)?;
info!("Copied control files for package {}", package_name);
}
info!("Package extracted successfully");
// Extract and copy DEBIAN scripts if they exist
let debian_dir = extract_path.join("DEBIAN");
if debian_dir.exists() {
let package_name = deb_path.file_stem().and_then(|s| s.to_str()).unwrap_or("unknown");
let scripts_dest = staging_path.join("var/lib/apt-ostree/packages").join(package_name).join("scripts");
std::fs::create_dir_all(&scripts_dest)?;
self.copy_directory_recursive(&debian_dir, &scripts_dest)?;
info!("Copied DEBIAN scripts for package {}", package_name);
}
info!("Package extracted successfully with all files");
Ok(())
}
/// Count files recursively in directory
fn count_files_recursive(&self, dir: &std::path::Path) -> AptOstreeResult<usize> {
let mut count = 0;
if dir.is_dir() {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if entry.file_type()?.is_dir() {
count += self.count_files_recursive(&path)?;
} else {
count += 1;
}
}
}
Ok(count)
}
/// Copy directory recursively
fn copy_directory_recursive(&self, src: &std::path::Path, dst: &std::path::Path) -> AptOstreeResult<()> {
if src.is_dir() {