summaryrefslogtreecommitdiff
path: root/src/pkgtoolkit
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkgtoolkit')
-rw-r--r--src/pkgtoolkit/archive.rs28
-rw-r--r--src/pkgtoolkit/build.rs1
-rw-r--r--src/pkgtoolkit/install.rs205
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;
+ }
}
}