Huakun Shen ed87fc6c12
App Setup (#2)
* chore: add vendor submodules

* feat: add packages for db,ci,schema,api,jarvis cmds

* feat: add tauri-jarvis-plugin

* feat: implement extension commands list

* fix(desktop): import path errors after packages refactor

* chore: add self signed cert

* fix: prevent prerender for desktop

* fix(desktop): desktop sveltekit static build, use csr for dynamic route

* feat: add error handling page and components

* refactor: component lib

* refactor: move more types, functions and components out of desktop

* refactor(ui): more refactor

* refactor(ui): move store components to @kksh/ui

* ci: add CI for build & test

* refactor: rename @kksh/extensions to @kksh/extension

* ci: add 2 more ci

* ci: fix

* fix: CI env var

* chore: add changeset

* feat: implement extension store item detail view

* feat: implement extension store install, uninstall, upgrade

* format

* revert: upgradable logic, the new one doesn't work yet

* refactor: make @kksh/ui dependent only on @kksh/api

Reason: @kksh/ui may be published later for building website, all its dependency packages must be also published. To avoid trouble it should be standalone, depend only on packages already published

* refactor: cleanup

* fixed: some typescript error

* chore: got typedoc working on @kksh/api

* ci: disable manifest schema upload CI on push
2024-11-03 13:54:44 -05:00

120 lines
3.5 KiB
Rust

use std::fs::File;
use std::path::{Path, PathBuf};
use zip::ZipArchive;
/// Decompress a tarball into a destination_folder
/// destination_folder should be a empty folder to avoid being removed
/// The resulting folder is expected to have "package" as its name
/// All .tgz generated with `npm pack` should be decompressed into `package`
pub fn decompress_tarball(
path: &Path,
destination_folder: &Path,
overwrite: bool,
) -> anyhow::Result<PathBuf> {
if !path.exists() {
return Err(anyhow::format_err!("Tarball does not exist: {:?}", path));
}
// if destination exists, remove it
if destination_folder.exists() && overwrite {
std::fs::remove_dir_all(&destination_folder)?;
}
std::fs::create_dir_all(&destination_folder)?;
let tgz = std::fs::File::open(&path)?;
let tar = flate2::read::GzDecoder::new(tgz);
let mut archive = tar::Archive::new(tar);
let dest = destination_folder.join("package");
if dest.exists() && !overwrite {
return Err(anyhow::format_err!(
"Destination folder already exists: {:?}",
dest
));
}
archive.unpack(&destination_folder)?;
if !dest.exists() {
return Err(anyhow::format_err!(
"Failed to unpack tarball to {:?}",
dest
));
}
Ok(dest)
}
pub fn compress_tarball(
src_dir: &Path,
dest_file: &Path,
overwrite: bool,
) -> anyhow::Result<PathBuf> {
if !src_dir.exists() {
return Err(anyhow::format_err!(
"Source directory does not exist: {:?}",
src_dir
));
}
if !src_dir.is_dir() {
return Err(anyhow::format_err!(
"Source path is not a directory: {:?}",
src_dir
));
}
let dest_file = std::fs::canonicalize(dest_file)?;
if dest_file.exists() && !overwrite {
return Err(anyhow::format_err!(
"Destination file already exists: {:?}",
dest_file
));
}
let tar_gz = std::fs::File::create(&dest_file)?;
let enc = flate2::write::GzEncoder::new(tar_gz, flate2::Compression::default());
let mut tar = tar::Builder::new(enc);
tar.append_dir_all(src_dir.file_name().unwrap().to_str().unwrap(), &src_dir)?;
Ok(dest_file)
}
pub fn unzip(path: &Path, destination_folder: &Path, overwrite: bool) -> anyhow::Result<()> {
if destination_folder.exists() && overwrite {
std::fs::remove_dir_all(&destination_folder)?;
}
let file = File::open(path)?;
let mut archive = ZipArchive::new(file)?;
archive.extract(destination_folder)?;
Ok(())
}
#[cfg(test)]
mod tests {
// use super::*;
// use std::fs::File;
// use zip::ZipArchive;
// #[test]
// fn test_decompress_tarball() {
// // this test relies on submodule
// decompress_tarball(
// "/Users/hacker/Desktop/huakunshen-jarvis-ext-qrcode-0.0.0.tgz".into(),
// "/Users/hacker/Desktop/randomfolder".into(),
// true,
// )
// .unwrap();
// }
// #[test]
// fn test_unzip() {
// unzip(
// "/Users/hacker/Downloads/bun-darwin-aarch64.zip".into(),
// "/Users/hacker/Downloads/runtime".into(),
// true,
// )
// .unwrap();
// }
// #[test]
// fn test_unzip() -> Result<(), Box<dyn std::error::Error>> {
// unzip(
// &PathBuf::from("/Users/hacker/Downloads/bun-darwin-aarch64.zip"),
// &PathBuf::from("/Users/hacker/Downloads/runtime"),
// true,
// )?;
// Ok(())
// }
}