mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2024-11-25 17:05:39 +01:00
meta: add repair functionality
This commit is contained in:
parent
c7628c1474
commit
45c562d723
@ -23,11 +23,12 @@ pub fn handle(service: &WebService, req: Request) -> Future {
|
||||
|
||||
Box::new(req.body().concat2().map(move |b| {
|
||||
let results = form_urlencoded::parse(b.as_ref())
|
||||
.into_owned()
|
||||
.collect::<HashMap<String, String>>();
|
||||
|
||||
.into_owned()
|
||||
.collect::<HashMap<String, String>>();
|
||||
|
||||
let mut to_install = Vec::new();
|
||||
let mut path: Option<String> = None;
|
||||
let mut force_install = false;
|
||||
|
||||
// Transform results into just an array of stuff to install
|
||||
for (key, value) in &results {
|
||||
@ -36,6 +37,11 @@ pub fn handle(service: &WebService, req: Request) -> Future {
|
||||
continue;
|
||||
}
|
||||
|
||||
if key == "mode" && value == "force" {
|
||||
force_install = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if value == "true" {
|
||||
to_install.push(key.to_owned());
|
||||
}
|
||||
@ -55,7 +61,7 @@ pub fn handle(service: &WebService, req: Request) -> Future {
|
||||
framework.set_install_dir(&path);
|
||||
}
|
||||
|
||||
if let Err(v) = framework.install(to_install, &sender, new_install) {
|
||||
if let Err(v) = framework.install(to_install, &sender, new_install, force_install) {
|
||||
error!("Install error occurred: {:?}", v);
|
||||
if let Err(v) = sender.send(InstallMessage::Error(v)) {
|
||||
error!("Failed to send install error: {:?}", v);
|
||||
|
@ -153,11 +153,13 @@ impl InstallerFramework {
|
||||
/// items: Array of named packages to be installed/kept
|
||||
/// messages: Channel used to send progress messages
|
||||
/// fresh_install: If the install directory must be empty
|
||||
/// force_install: If the install directory should be erased first
|
||||
pub fn install(
|
||||
&mut self,
|
||||
items: Vec<String>,
|
||||
messages: &Sender<InstallMessage>,
|
||||
fresh_install: bool,
|
||||
force_install: bool,
|
||||
) -> Result<(), String> {
|
||||
info!(
|
||||
"Framework: Installing {:?} to {:?}",
|
||||
@ -186,6 +188,7 @@ impl InstallerFramework {
|
||||
items,
|
||||
uninstall_items,
|
||||
fresh_install,
|
||||
force_install
|
||||
});
|
||||
|
||||
let mut tree = DependencyTree::build(task);
|
||||
|
@ -6,6 +6,7 @@ use crate::tasks::ensure_only_instance::EnsureOnlyInstanceTask;
|
||||
use crate::tasks::install_dir::VerifyInstallDirTask;
|
||||
use crate::tasks::install_global_shortcut::InstallGlobalShortcutsTask;
|
||||
use crate::tasks::install_pkg::InstallPackageTask;
|
||||
use crate::tasks::remove_target_dir::RemoveTargetDirTask;
|
||||
use crate::tasks::save_executable::SaveExecutableTask;
|
||||
use crate::tasks::uninstall_pkg::UninstallPackageTask;
|
||||
|
||||
@ -19,6 +20,8 @@ pub struct InstallTask {
|
||||
pub items: Vec<String>,
|
||||
pub uninstall_items: Vec<String>,
|
||||
pub fresh_install: bool,
|
||||
// force_install: remove the target directory before installing
|
||||
pub force_install: bool,
|
||||
}
|
||||
|
||||
impl Task for InstallTask {
|
||||
@ -40,6 +43,13 @@ impl Task for InstallTask {
|
||||
Box::new(EnsureOnlyInstanceTask {}),
|
||||
));
|
||||
|
||||
if self.force_install {
|
||||
elements.push(TaskDependency::build(
|
||||
TaskOrdering::Pre,
|
||||
Box::new(RemoveTargetDirTask {}),
|
||||
));
|
||||
}
|
||||
|
||||
elements.push(TaskDependency::build(
|
||||
TaskOrdering::Pre,
|
||||
Box::new(VerifyInstallDirTask {
|
||||
|
@ -23,6 +23,7 @@ pub mod uninstall;
|
||||
pub mod uninstall_global_shortcut;
|
||||
pub mod uninstall_pkg;
|
||||
pub mod uninstall_shortcuts;
|
||||
pub mod remove_target_dir;
|
||||
|
||||
/// An abstraction over the various parameters that can be passed around.
|
||||
pub enum TaskParamType {
|
||||
|
58
src/tasks/remove_target_dir.rs
Normal file
58
src/tasks/remove_target_dir.rs
Normal file
@ -0,0 +1,58 @@
|
||||
//! remove the whole target directory from the existence
|
||||
|
||||
use crate::installer::InstallerFramework;
|
||||
|
||||
use crate::tasks::Task;
|
||||
use crate::tasks::TaskDependency;
|
||||
use crate::tasks::TaskMessage;
|
||||
use crate::tasks::TaskParamType;
|
||||
|
||||
pub struct RemoveTargetDirTask {}
|
||||
|
||||
impl Task for RemoveTargetDirTask {
|
||||
fn execute(
|
||||
&mut self,
|
||||
_: Vec<TaskParamType>,
|
||||
context: &mut InstallerFramework,
|
||||
messenger: &dyn Fn(&TaskMessage),
|
||||
) -> Result<TaskParamType, String> {
|
||||
messenger(&TaskMessage::DisplayMessage(
|
||||
"Removing previous install...",
|
||||
0.1,
|
||||
));
|
||||
// erase the database as well
|
||||
context.database.packages = Vec::new();
|
||||
if let Some(path) = context.install_path.as_ref() {
|
||||
let entries = std::fs::read_dir(path)
|
||||
.map_err(|e| format!("Error reading {}: {}", path.to_string_lossy(), e))?;
|
||||
// remove everything except the maintenancetool
|
||||
for entry in entries {
|
||||
let path = entry
|
||||
.map_err(|e| format!("Error reading file: {}", e))?
|
||||
.path();
|
||||
if let Some(filename) = path.file_name() {
|
||||
if filename.to_string_lossy().starts_with("maintenancetool") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if path.is_dir() {
|
||||
std::fs::remove_dir_all(&path)
|
||||
.map_err(|e| format!("Error removing {}: {}", path.to_string_lossy(), e))?;
|
||||
} else {
|
||||
std::fs::remove_file(&path)
|
||||
.map_err(|e| format!("Error removing {}: {}", path.to_string_lossy(), e))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TaskParamType::None)
|
||||
}
|
||||
|
||||
fn dependencies(&self) -> Vec<TaskDependency> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn name(&self) -> String {
|
||||
"RemoveTargetDirTask".to_string()
|
||||
}
|
||||
}
|
@ -13,10 +13,12 @@
|
||||
},
|
||||
"select_packages":{
|
||||
"title":"Select which packages you want to install:",
|
||||
"title_repair":"Select which packages you want to repair:",
|
||||
"installed":"(installed)",
|
||||
"advanced":"Advanced...",
|
||||
"install":"Install",
|
||||
"modify":"Modify",
|
||||
"repair": "Repair",
|
||||
"location":"Install Location",
|
||||
"location_placeholder":"Enter a install path here",
|
||||
"select":"Select"
|
||||
@ -44,6 +46,7 @@
|
||||
"title":"Choose an option:",
|
||||
"update":"Update",
|
||||
"modify":"Modify",
|
||||
"repair": "Repair",
|
||||
"uninstall":"Uninstall",
|
||||
"prompt":"Are you sure you want to uninstall {name}?"
|
||||
},
|
||||
|
@ -24,6 +24,7 @@ export default {
|
||||
is_uninstall: false,
|
||||
is_updater_update: false,
|
||||
is_update: false,
|
||||
is_repair: false,
|
||||
failed_with_error: false,
|
||||
packages_installed: 0
|
||||
}
|
||||
@ -32,6 +33,7 @@ export default {
|
||||
this.is_uninstall = this.$route.params.kind === 'uninstall'
|
||||
this.is_updater_update = this.$route.params.kind === 'updater'
|
||||
this.is_update = this.$route.params.kind === 'update'
|
||||
this.is_repair = this.$route.params.kind === 'repair'
|
||||
console.log('Installer kind: ' + this.$route.params.kind)
|
||||
this.install()
|
||||
},
|
||||
@ -51,6 +53,10 @@ export default {
|
||||
|
||||
results.path = app.install_location
|
||||
|
||||
if (this.is_repair) {
|
||||
results['mode'] = 'force'
|
||||
}
|
||||
|
||||
var targetUrl = '/api/start-install'
|
||||
if (this.is_uninstall) {
|
||||
targetUrl = '/api/uninstall'
|
||||
|
@ -14,6 +14,12 @@
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<a class="button is-dark is-medium" v-on:click="repair_packages">
|
||||
{{ $t('modify.repair') }}
|
||||
</a>
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<b-button class="is-dark is-medium" v-on:click="prepare_uninstall">
|
||||
{{ $t('modify.uninstall') }}
|
||||
</b-button>
|
||||
@ -48,6 +54,9 @@ export default {
|
||||
modify_packages: function () {
|
||||
this.$router.push('/packages')
|
||||
},
|
||||
repair_packages: function () {
|
||||
this.$router.push({ name: 'packages', params: { repair: true } })
|
||||
},
|
||||
prepare_uninstall: function () {
|
||||
this.show_uninstall = true
|
||||
},
|
||||
@ -56,7 +65,8 @@ export default {
|
||||
},
|
||||
uninstall: function () {
|
||||
this.$router.push('/install/uninstall')
|
||||
}
|
||||
},
|
||||
view_files: function () {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="column has-padding">
|
||||
<h4 class="subtitle">{{ $t('select_packages.title') }}</h4>
|
||||
<h4 class="subtitle" v-if="!repair">{{ $t('select_packages.title') }}</h4>
|
||||
<h4 class="subtitle" v-if="repair">{{ $t('select_packages.title_repair') }}</h4>
|
||||
|
||||
<!-- Build options -->
|
||||
<div class="tile is-ancestor">
|
||||
@ -45,8 +46,8 @@
|
||||
v-on:click="install">{{ $t('select_packages.install') }}</b-button>
|
||||
</p>
|
||||
<p class="control">
|
||||
<b-button class="is-dark is-medium" v-if="$root.$data.metadata.preexisting_install"
|
||||
v-on:click="install">{{ $t('select_packages.modify') }}</b-button>
|
||||
<a class="button is-dark is-medium" v-if="$root.$data.metadata.preexisting_install"
|
||||
v-on:click="install">{{ repair ? $t('select_packages.repair') : $t('select_packages.modify') }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -65,9 +66,13 @@ export default {
|
||||
name: 'SelectPackages',
|
||||
data: function () {
|
||||
return {
|
||||
advanced: false
|
||||
advanced: false,
|
||||
repair: false
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
this.repair = this.$route.params.repair
|
||||
},
|
||||
methods: {
|
||||
select_file: function () {
|
||||
window.external.invoke(JSON.stringify({
|
||||
@ -77,7 +82,7 @@ export default {
|
||||
}))
|
||||
},
|
||||
install: function () {
|
||||
this.$router.push('/install/regular')
|
||||
this.$router.push(this.repair ? '/install/repair' : '/install/regular')
|
||||
},
|
||||
go_back: function () {
|
||||
this.$router.go(-1)
|
||||
|
Loading…
Reference in New Issue
Block a user