summaryrefslogtreecommitdiff
path: root/src/pkgtoolkit/archive.rs
diff options
context:
space:
mode:
authorNamilskyy <alive6863@gmail.com>2025-12-07 14:29:35 +0300
committerNamilskyy <alive6863@gmail.com>2025-12-07 14:29:35 +0300
commit778a979e2e774e1b2e91227fa2db2e56d41927c1 (patch)
treeae1560e203477a90edc089c1832e37af83f43540 /src/pkgtoolkit/archive.rs
parente7c49d685efe768c0c1d9c66da7b93b6e118b305 (diff)
Fixed logical issues
Diffstat (limited to 'src/pkgtoolkit/archive.rs')
-rw-r--r--src/pkgtoolkit/archive.rs136
1 files changed, 111 insertions, 25 deletions
diff --git a/src/pkgtoolkit/archive.rs b/src/pkgtoolkit/archive.rs
index 9d9a7d1..eef0888 100644
--- a/src/pkgtoolkit/archive.rs
+++ b/src/pkgtoolkit/archive.rs
@@ -39,21 +39,105 @@ impl ArchiveOperations for Package {
let cache_dir = &config.paths.cache_dir;
create_dir_all(cache_dir)?;
- for meta_name in ["INSTALL", "SETTS", "BUILD"] {
- let meta_path = Path::new(cache_dir).join(meta_name);
- if meta_path.exists() {
- fs::remove_file(&meta_path)?;
- }
+ // Extract to temporary directory first
+ let temp_dir = Path::new(cache_dir).join("temp_extract");
+ if temp_dir.exists() {
+ fs::remove_dir_all(&temp_dir)?;
}
+ fs::create_dir_all(&temp_dir)?;
+
let file = File::open(path_to_archive)?;
let gz = GzDecoder::new(file);
let mut archive = Archive::new(gz);
- // Unpack directly into the cache directory. Игнорируем AlreadyExists, чтобы не мешать валидации.
- match archive.unpack(cache_dir) {
+
+ // Unpack into temporary directory
+ match archive.unpack(&temp_dir) {
Ok(()) => Ok(()),
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => Ok(()),
Err(e) => Err(e),
+ }?;
+
+ // Read package name from INSTALL file to determine final directory
+ let install_path = temp_dir.join("INSTALL");
+ if !install_path.exists() {
+ // Try to find INSTALL in subdirectories
+ for entry in fs::read_dir(&temp_dir)? {
+ let entry = entry?;
+ let path = entry.path();
+ if path.is_dir() {
+ let install_in_subdir = path.join("INSTALL");
+ if install_in_subdir.exists() {
+ // Move contents to temp_dir
+ for item in fs::read_dir(&path)? {
+ let item = item?;
+ let item_path = item.path();
+ let dest_path = temp_dir.join(item_path.file_name().unwrap());
+ fs::rename(&item_path, &dest_path)?;
+ }
+ fs::remove_dir(&path)?;
+ break;
+ }
+ }
+ }
+ }
+
+ let mut install_path = None;
+ let mut pkg_dir_name = None;
+
+ let root_install = temp_dir.join("INSTALL");
+ if root_install.exists() {
+ install_path = Some(root_install);
+ pkg_dir_name = Some("package".to_string());
+ } else {
+ for entry in fs::read_dir(&temp_dir)? {
+ let entry = entry?;
+ let path = entry.path();
+ if path.is_dir() {
+ 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());
+ break;
+ }
+ }
+ }
+ }
+
+ let install_path = install_path.ok_or_else(|| {
+ 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 = Path::new(cache_dir).join(&final_dir_name);
+
+ if final_dir.exists() {
+ fs::remove_dir_all(&final_dir)?;
}
+ fs::create_dir_all(&final_dir)?;
+
+ if pkg_dir_name.clone().unwrap() == "package" {
+ for entry in fs::read_dir(&temp_dir)? {
+ let entry = entry?;
+ let src_path = entry.path();
+ let dest_path = final_dir.join(src_path.file_name().unwrap());
+ fs::rename(&src_path, &dest_path)?;
+ }
+ fs::remove_dir(&temp_dir)?;
+ } else {
+ let pkg_subdir = temp_dir.join(pkg_dir_name.clone().unwrap());
+ fs::rename(&pkg_subdir, &final_dir)?;
+
+ fs::remove_dir(&temp_dir)?;
+ }
+
+ Ok(())
}
/// Load meta information from the .mesk archive.
@@ -72,7 +156,7 @@ impl ArchiveOperations for Package {
/// is not found, or if the 'INSTALL' file is empty.
#[allow(clippy::type_complexity)]
fn loadmeta(
- minimal_package_meta: &mut Self,
+ minimal_package_meta: &mut Package,
) -> Result<(Install, Option<Setts>, Option<Build>), std::io::Error> {
// Changed return type for more flexibility
/*
@@ -82,34 +166,38 @@ impl ArchiveOperations for Package {
version = "1.0.0"
arch = "X86_64"
descr = "Just example INSTALL script"
+ license = "BSD-2-Clause"
+ url = "/repo/my-package.mesk"
+ git_repo = "https://github.com/example/my-package.git"
[install]
path = "/usr/bin/my-package"
+ dependencies = ["package", "i2pd", "llvm-19-devel", "etc..."] # Leave it empty if there are no dependencies
user = "root"
group = "root"
mode = "755"
- # Also [install] can be
- # path = "/usr/bin/my-package"
- # user = "root"
- # group = "root"
- # mode = "755"
- # custom_script = "./install.sh" OR
- # custom_script = """
- # echo "Installing my-package"
- # sudo apt-get install my-package
- # """
+ Also [install] can be
+ path = "/usr/bin/my-package"
+ user = "root"
+ group = "root"
+ mode = "755"
+ custom_script = "./install.sh" OR
+ custom_script = """
+ echo "Installing my-package"
+ sudo apt-get install my-package
+ """
+ If there is a custom_script field, mesk will not automatically install your package and other fields in [install] will not be required.
*/
-
let config = Config::parse().map_err(|e| std::io::Error::other(e.to_string()))?;
fs::create_dir_all(&config.paths.cache_dir)?;
let cache_dir = &config.paths.cache_dir;
- let install_path =
- Path::new(cache_dir).join(format!("{}/INSTALL", minimal_package_meta.name));
- let setts_path = Path::new(cache_dir).join(format!("{}/SETTS", minimal_package_meta.name));
- let build_path = Path::new(cache_dir).join(format!("{}/BUILD", minimal_package_meta.name));
+ 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));
if !install_path.exists() {
return Err(io::Error::new(
@@ -171,7 +259,6 @@ impl ArchiveOperations for Package {
let config = Config::parse().map_err(|e| std::io::Error::other(e.to_string()))?;
let cache_root = Path::new(&config.paths.cache_dir);
- // Рекурсивно находим все файлы INSTALL под cache_root
fn find_install(root: &Path) -> Result<Vec<std::path::PathBuf>, std::io::Error> {
let mut installs = Vec::new();
for entry in fs::read_dir(root)? {
@@ -208,7 +295,6 @@ impl ArchiveOperations for Package {
)
})?;
- // Проверим, что структура именно <cachedir>/<packagename>/INSTALL
if pkg_dir.parent() != Some(cache_root) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,