summaryrefslogtreecommitdiff
path: root/src/pkgtoolkit/install.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkgtoolkit/install.rs')
-rw-r--r--src/pkgtoolkit/install.rs205
1 files changed, 163 insertions, 42 deletions
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;
+ }
}
}