diff options
Diffstat (limited to 'src/pkgtoolkit')
| -rw-r--r-- | src/pkgtoolkit/archive.rs | 28 | ||||
| -rw-r--r-- | src/pkgtoolkit/build.rs | 1 | ||||
| -rw-r--r-- | src/pkgtoolkit/install.rs | 205 |
3 files changed, 179 insertions, 55 deletions
diff --git a/src/pkgtoolkit/archive.rs b/src/pkgtoolkit/archive.rs index eef0888..db10f01 100644 --- a/src/pkgtoolkit/archive.rs +++ b/src/pkgtoolkit/archive.rs @@ -49,7 +49,7 @@ impl ArchiveOperations for Package { let file = File::open(path_to_archive)?; let gz = GzDecoder::new(file); let mut archive = Archive::new(gz); - + // Unpack into temporary directory match archive.unpack(&temp_dir) { Ok(()) => Ok(()), @@ -87,7 +87,7 @@ impl ArchiveOperations for Package { let root_install = temp_dir.join("INSTALL"); if root_install.exists() { install_path = Some(root_install); - pkg_dir_name = Some("package".to_string()); + pkg_dir_name = Some("package".to_string()); } else { for entry in fs::read_dir(&temp_dir)? { let entry = entry?; @@ -96,7 +96,8 @@ impl ArchiveOperations for Package { let install_in_subdir = path.join("INSTALL"); if install_in_subdir.exists() { install_path = Some(install_in_subdir); - pkg_dir_name = Some(path.file_name().unwrap().to_string_lossy().to_string()); + pkg_dir_name = + Some(path.file_name().unwrap().to_string_lossy().to_string()); break; } } @@ -104,19 +105,19 @@ impl ArchiveOperations for Package { } let install_path = install_path.ok_or_else(|| { - io::Error::new( - io::ErrorKind::NotFound, - "INSTALL file not found in archive", - ) + io::Error::new(io::ErrorKind::NotFound, "INSTALL file not found in archive") })?; let install_content = fs::read_to_string(&install_path)?; let install_meta: Install = toml::from_str(&install_content) .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))?; - let final_dir_name = format!("{}-{}", install_meta.package.name, install_meta.package.version); + let final_dir_name = format!( + "{}-{}", + install_meta.package.name, install_meta.package.version + ); let final_dir = Path::new(cache_dir).join(&final_dir_name); - + if final_dir.exists() { fs::remove_dir_all(&final_dir)?; } @@ -177,12 +178,12 @@ impl ArchiveOperations for Package { group = "root" mode = "755" - Also [install] can be + Also [install] can be path = "/usr/bin/my-package" user = "root" group = "root" mode = "755" - custom_script = "./install.sh" OR + custom_script = "./install.sh" OR custom_script = """ echo "Installing my-package" sudo apt-get install my-package @@ -194,7 +195,10 @@ impl ArchiveOperations for Package { fs::create_dir_all(&config.paths.cache_dir)?; let cache_dir = &config.paths.cache_dir; - let pkg_dir_name = format!("{}-{}", minimal_package_meta.name, minimal_package_meta.version); + let pkg_dir_name = format!( + "{}-{}", + minimal_package_meta.name, minimal_package_meta.version + ); let install_path = Path::new(cache_dir).join(format!("{}/INSTALL", pkg_dir_name)); let setts_path = Path::new(cache_dir).join(format!("{}/SETTS", pkg_dir_name)); let build_path = Path::new(cache_dir).join(format!("{}/BUILD", pkg_dir_name)); diff --git a/src/pkgtoolkit/build.rs b/src/pkgtoolkit/build.rs index 6264b58..326be1e 100644 --- a/src/pkgtoolkit/build.rs +++ b/src/pkgtoolkit/build.rs @@ -116,7 +116,6 @@ impl BuildOperations for Package { } } BuildSystems::CMake => { - let cmake_file = build_dir.join("CMakeLists.txt"); if !cmake_file.exists() { return Err(std::io::Error::other(format!( diff --git a/src/pkgtoolkit/install.rs b/src/pkgtoolkit/install.rs index 65476d9..37155c2 100644 --- a/src/pkgtoolkit/install.rs +++ b/src/pkgtoolkit/install.rs @@ -157,58 +157,179 @@ impl InstallOperations for Package { "No custom script. Running default install hook for {}", install_meta.package.name ); - let source_file_name = &self.name; + log::info!("Starting default install process"); let build_dir = Path::new(&config.paths.cache_dir) .join(format!("{}-{}", self.name, self.version)); - let src_path = build_dir.join(source_file_name); let dest_path = Path::new(&install_meta.install.path); - // Check if source file exists - if !src_path.exists() { - return Err(std::io::Error::other(format!( - "Source binary file not found: {}", - src_path.display() - ))); - } + log::info!( + "Install path: {:?}, is_dir: {}, ends_with_slash: {}", + dest_path, + dest_path.is_dir(), + dest_path.to_string_lossy().ends_with('/') + ); - if let Some(parent) = dest_path.parent() { - create_dir_all(parent).map_err(|e| { - std::io::Error::other(format!("Failed to create parent dir: {}", e)) + // Check if dest_path is a directory, if so, copy all executables from target/release + if dest_path.is_dir() || dest_path.to_string_lossy().ends_with('/') { + log::info!("Taking multi-binary package path"); + // Multi-binary package - copy all executables from target/release + let target_release = build_dir.join("target/release"); + if !target_release.exists() { + return Err(std::io::Error::other(format!( + "target/release directory not found: {}", + target_release.display() + ))); + } + + // Create destination directory if it doesn't exist + create_dir_all(dest_path).map_err(|e| { + std::io::Error::other(format!("Failed to create dest dir: {}", e)) })?; - } - fs::copy(&src_path, dest_path) - .map_err(|e| std::io::Error::other(format!("Failed to copy file: {}", e)))?; + let mut copied_files = Vec::new(); + for entry in fs::read_dir(&target_release)? { + let entry = entry?; + let path = entry.path(); + + // Check if it's an executable file + if path.is_file() + && let Ok(metadata) = fs::metadata(&path) { + let mode = metadata.permissions().mode(); + log::debug!( + "Checking file: {:?}, mode: {:o}", + path.file_name(), + mode + ); + if mode & 0o111 != 0 { + let file_name = path.file_name().unwrap().to_string_lossy(); + let dest_file = dest_path.join(&*file_name); + + log::info!( + "Copying executable: {} to {}", + file_name, + dest_file.display() + ); + fs::copy(&path, &dest_file).map_err(|e| { + std::io::Error::other(format!( + "Failed to copy {}: {}", + file_name, e + )) + })?; + + copied_files.push(dest_file); + } else { + log::debug!( + "File {:?} is not executable (mode: {:o})", + path.file_name(), + mode + ); + } + } + + } - let mode = u32::from_str_radix(&install_meta.install.mode, 8).map_err(|_| { - std::io::Error::new( - std::io::ErrorKind::InvalidData, - "Invalid mode string in INSTALL", - ) - })?; - let perms = Permissions::from_mode(mode); - set_permissions(dest_path, perms).map_err(|e| { - std::io::Error::other(format!("Failed to set permissions: {}", e)) - })?; + if copied_files.is_empty() { + return Err(std::io::Error::other( + "No executable files found in target/release", + )); + } - let output = Command::new("chown") - .arg(format!( - "{}:{}", - install_meta.install.user, install_meta.install.group - )) - .arg(dest_path) - .output() - .map_err(|e| std::io::Error::other(format!("'chown' command failed: {}", e)))?; - - if !output.status.success() { - let stderr = String::from_utf8_lossy(&output.stderr); - log::warn!( - "Warning: 'chown' command failed (requires root?):\n{}", - stderr - ); - } + // Set permissions and ownership for all copied files + let mode = + u32::from_str_radix(&install_meta.install.mode, 8).map_err(|_| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Invalid mode string in INSTALL", + ) + })?; + let perms = Permissions::from_mode(mode); + + for file_path in &copied_files { + set_permissions(file_path, perms.clone()).map_err(|e| { + std::io::Error::other(format!( + "Failed to set permissions for {}: {}", + file_path.display(), + e + )) + })?; + + let output = Command::new("chown") + .arg(format!( + "{}:{}", + install_meta.install.user, install_meta.install.group + )) + .arg(file_path) + .output() + .map_err(|e| { + std::io::Error::other(format!("'chown' command failed: {}", e)) + })?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + log::warn!( + "Warning: 'chown' command failed for {} (requires root?):\n{}", + file_path.display(), + stderr + ); + } + } + } else { + log::info!("Taking single binary package path"); + // Single binary package - copy specific file + let source_file_name = &self.name; + let src_path = build_dir.join(source_file_name); + + // Check if source file exists + if !src_path.exists() { + return Err(std::io::Error::other(format!( + "Source binary file not found: {}", + src_path.display() + ))); + } + + if let Some(parent) = dest_path.parent() { + create_dir_all(parent).map_err(|e| { + std::io::Error::other(format!("Failed to create parent dir: {}", e)) + })?; + } + + fs::copy(&src_path, dest_path).map_err(|e| { + std::io::Error::other(format!("Failed to copy file: {}", e)) + })?; + + let mode = + u32::from_str_radix(&install_meta.install.mode, 8).map_err(|_| { + std::io::Error::new( + std::io::ErrorKind::InvalidData, + "Invalid mode string in INSTALL", + ) + })?; + let perms = Permissions::from_mode(mode); + set_permissions(dest_path, perms).map_err(|e| { + std::io::Error::other(format!("Failed to set permissions: {}", e)) + })?; - all_files = install_meta.files; + let output = Command::new("chown") + .arg(format!( + "{}:{}", + install_meta.install.user, install_meta.install.group + )) + .arg(dest_path) + .output() + .map_err(|e| { + std::io::Error::other(format!("'chown' command failed: {}", e)) + })?; + + if !output.status.success() { + let stderr = String::from_utf8_lossy(&output.stderr); + log::warn!( + "Warning: 'chown' command failed (requires root?):\n{}", + stderr + ); + } + + all_files = install_meta.files; + } } } |
