forked from akanyan/STARTLINER
feat: less bad installations
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use anyhow::{Result, anyhow};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tauri::{AppHandle, Emitter};
|
||||
@ -118,7 +119,7 @@ impl PackageStore {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn install_package(&mut self, key: &PkgKey, force: bool) -> Result<InstallResult> {
|
||||
pub async fn install_package(&mut self, key: &PkgKey, force: bool, install_deps: bool) -> Result<InstallResult> {
|
||||
log::debug!("Installing {}", key);
|
||||
|
||||
let pkg = self.store.get(key)
|
||||
@ -128,14 +129,18 @@ impl PackageStore {
|
||||
if pkg.loc.is_some() && !force {
|
||||
return Ok(InstallResult::Ready);
|
||||
}
|
||||
|
||||
self.app.emit("install-start", Payload {
|
||||
pkg: key.to_owned()
|
||||
})?;
|
||||
|
||||
let rmt = pkg.rmt.as_ref() //clone()
|
||||
.ok_or_else(|| anyhow!("Attempted to install a pkg without remote data"))?;
|
||||
|
||||
for dep in &rmt.dependencies {
|
||||
self.app.emit("install-start", Payload {
|
||||
pkg: dep.to_owned()
|
||||
})?;
|
||||
Box::pin(self.install_package(&dep, false)).await?;
|
||||
if install_deps {
|
||||
for dep in &rmt.dependencies {
|
||||
Box::pin(self.install_package(&dep, false, true)).await?;
|
||||
}
|
||||
}
|
||||
|
||||
let zip_path = util::cache_dir().join(format!(
|
||||
@ -145,6 +150,7 @@ impl PackageStore {
|
||||
|
||||
if !zip_path.exists() {
|
||||
self.dlh.download_zip(&zip_path, &pkg)?;
|
||||
log::debug!("Deferring {}", key);
|
||||
return Ok(InstallResult::Deferred);
|
||||
}
|
||||
|
||||
@ -168,16 +174,16 @@ impl PackageStore {
|
||||
}
|
||||
|
||||
pub async fn delete_package(&mut self, key: &PkgKey, force: bool) -> Result<()> {
|
||||
log::debug!("Will delete {} {}", key, force);
|
||||
|
||||
let pkg = self.store.get_mut(key)
|
||||
.ok_or_else(|| anyhow!("Attempted to delete a nonexistent pkg"))?;
|
||||
let path = pkg.path();
|
||||
|
||||
if path.exists() && path.join("manifest.json").exists() {
|
||||
// TODO don't rm -r - use a file whitelist
|
||||
log::debug!("rm -r'ing {}", path.to_string_lossy());
|
||||
pkg.loc = None;
|
||||
let rv = tokio::fs::remove_dir_all(&path).await
|
||||
.map_err(|e| anyhow!("Could not delete a package: {}", e));
|
||||
|
||||
let rv = Self::clean_up_package(&path).await;
|
||||
|
||||
if rv.is_ok() {
|
||||
self.app.emit("install-end", Payload {
|
||||
@ -201,4 +207,41 @@ impl PackageStore {
|
||||
}
|
||||
self.store.insert(key, new);
|
||||
}
|
||||
|
||||
async fn clean_up_dir(path: impl AsRef<Path>, name: &str) -> Result<()> {
|
||||
let path = path.as_ref().join(name);
|
||||
if path.exists() {
|
||||
tokio::fs::remove_dir_all(path)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Could not delete /{}: {}", name, e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn clean_up_file(path: impl AsRef<Path>, name: &str, force: bool) -> Result<()> {
|
||||
let path = path.as_ref().join(name);
|
||||
if force || path.exists() {
|
||||
tokio::fs::remove_file(path)
|
||||
.await
|
||||
.map_err(|e| anyhow!("Could not delete /{}: {}", name, e))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn clean_up_package(path: impl AsRef<Path>) -> Result<()> {
|
||||
// todo case sensitivity for linux
|
||||
Self::clean_up_dir(&path, "app").await?;
|
||||
Self::clean_up_dir(&path, "option").await?;
|
||||
Self::clean_up_file(&path, "icon.png", true).await?;
|
||||
Self::clean_up_file(&path, "manifest.json", true).await?;
|
||||
Self::clean_up_file(&path, "README.md", true).await?;
|
||||
|
||||
tokio::fs::remove_dir(path.as_ref())
|
||||
.await
|
||||
.map_err(|e| anyhow!("Could not delete {}: {}", path.as_ref().to_string_lossy(), e))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user