mirror of
https://github.com/yuzu-emu/liftinstall.git
synced 2025-01-24 10:31:11 +00:00
Add a global shortcut for the maintenance tool
This commit is contained in:
parent
82b3681a74
commit
19bec5d80c
|
@ -27,6 +27,7 @@ use logging::LoggingErrors;
|
||||||
use dirs::home_dir;
|
use dirs::home_dir;
|
||||||
|
|
||||||
use std::fs::remove_file;
|
use std::fs::remove_file;
|
||||||
|
use tasks::uninstall_global_shortcut::UninstallGlobalShortcutsTask;
|
||||||
|
|
||||||
/// A message thrown during the installation of packages.
|
/// A message thrown during the installation of packages.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
@ -36,12 +37,29 @@ pub enum InstallMessage {
|
||||||
EOF,
|
EOF,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Metadata about the current installation itself.
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
pub struct InstallationDatabase {
|
||||||
|
pub packages: Vec<LocalInstallation>,
|
||||||
|
pub shortcuts: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstallationDatabase {
|
||||||
|
/// Creates a new, empty installation database.
|
||||||
|
pub fn new() -> InstallationDatabase {
|
||||||
|
InstallationDatabase {
|
||||||
|
packages: Vec::new(),
|
||||||
|
shortcuts: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The installer framework contains metadata about packages, what is installable, what isn't,
|
/// The installer framework contains metadata about packages, what is installable, what isn't,
|
||||||
/// etc.
|
/// etc.
|
||||||
pub struct InstallerFramework {
|
pub struct InstallerFramework {
|
||||||
pub base_attributes: BaseAttributes,
|
pub base_attributes: BaseAttributes,
|
||||||
pub config: Option<Config>,
|
pub config: Option<Config>,
|
||||||
pub database: Vec<LocalInstallation>,
|
pub database: InstallationDatabase,
|
||||||
pub install_path: Option<PathBuf>,
|
pub install_path: Option<PathBuf>,
|
||||||
pub preexisting_install: bool,
|
pub preexisting_install: bool,
|
||||||
pub is_launcher: bool,
|
pub is_launcher: bool,
|
||||||
|
@ -51,7 +69,7 @@ pub struct InstallerFramework {
|
||||||
/// Contains basic properties on the status of the session. Subset of InstallationFramework.
|
/// Contains basic properties on the status of the session. Subset of InstallationFramework.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct InstallationStatus {
|
pub struct InstallationStatus {
|
||||||
pub database: Vec<LocalInstallation>,
|
pub database: InstallationDatabase,
|
||||||
pub install_path: Option<String>,
|
pub install_path: Option<String>,
|
||||||
pub preexisting_install: bool,
|
pub preexisting_install: bool,
|
||||||
pub is_launcher: bool,
|
pub is_launcher: bool,
|
||||||
|
@ -110,7 +128,7 @@ impl InstallerFramework {
|
||||||
// Calculate packages to *uninstall*
|
// Calculate packages to *uninstall*
|
||||||
let mut uninstall_items = Vec::new();
|
let mut uninstall_items = Vec::new();
|
||||||
if !fresh_install {
|
if !fresh_install {
|
||||||
for package in &self.database {
|
for package in &self.database.packages {
|
||||||
if !items.contains(&package.name) {
|
if !items.contains(&package.name) {
|
||||||
uninstall_items.push(package.name.clone());
|
uninstall_items.push(package.name.clone());
|
||||||
}
|
}
|
||||||
|
@ -141,7 +159,12 @@ impl InstallerFramework {
|
||||||
|
|
||||||
/// Sends a request for everything to be uninstalled.
|
/// Sends a request for everything to be uninstalled.
|
||||||
pub fn uninstall(&mut self, messages: &Sender<InstallMessage>) -> Result<(), String> {
|
pub fn uninstall(&mut self, messages: &Sender<InstallMessage>) -> Result<(), String> {
|
||||||
let items: Vec<String> = self.database.iter().map(|x| x.name.clone()).collect();
|
let items: Vec<String> = self
|
||||||
|
.database
|
||||||
|
.packages
|
||||||
|
.iter()
|
||||||
|
.map(|x| x.name.clone())
|
||||||
|
.collect();
|
||||||
|
|
||||||
let task = Box::new(UninstallTask { items });
|
let task = Box::new(UninstallTask { items });
|
||||||
|
|
||||||
|
@ -155,6 +178,17 @@ impl InstallerFramework {
|
||||||
}
|
}
|
||||||
}).map(|_x| ())?;
|
}).map(|_x| ())?;
|
||||||
|
|
||||||
|
// Uninstall shortcuts
|
||||||
|
let task = Box::new(UninstallGlobalShortcutsTask {});
|
||||||
|
|
||||||
|
let mut tree = DependencyTree::build(task);
|
||||||
|
|
||||||
|
tree.execute(self, &|msg: &str, progress: f64| {
|
||||||
|
if let Err(v) = messages.send(InstallMessage::Status(msg.to_string(), progress as _)) {
|
||||||
|
error!("Failed to submit queue message: {:?}", v);
|
||||||
|
}
|
||||||
|
}).map(|_x| ())?;
|
||||||
|
|
||||||
// Delete the metadata file
|
// Delete the metadata file
|
||||||
let path = self
|
let path = self
|
||||||
.install_path
|
.install_path
|
||||||
|
@ -216,7 +250,7 @@ impl InstallerFramework {
|
||||||
InstallerFramework {
|
InstallerFramework {
|
||||||
base_attributes: attrs,
|
base_attributes: attrs,
|
||||||
config: None,
|
config: None,
|
||||||
database: Vec::new(),
|
database: InstallationDatabase::new(),
|
||||||
install_path: None,
|
install_path: None,
|
||||||
preexisting_install: false,
|
preexisting_install: false,
|
||||||
is_launcher: false,
|
is_launcher: false,
|
||||||
|
@ -234,7 +268,7 @@ impl InstallerFramework {
|
||||||
Err(v) => return Err(format!("Unable to open file handle: {:?}", v)),
|
Err(v) => return Err(format!("Unable to open file handle: {:?}", v)),
|
||||||
};
|
};
|
||||||
|
|
||||||
let database: Vec<LocalInstallation> = match serde_json::from_reader(metadata_file) {
|
let database: InstallationDatabase = match serde_json::from_reader(metadata_file) {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
Err(v) => return Err(format!("Unable to read metadata file: {:?}", v)),
|
Err(v) => return Err(format!("Unable to read metadata file: {:?}", v)),
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl Task for DownloadPackageTask {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check to see if this is the newest file available already
|
// Check to see if this is the newest file available already
|
||||||
for element in &context.database {
|
for element in &context.database.packages {
|
||||||
if element.name == self.name {
|
if element.name == self.name {
|
||||||
if element.version == version {
|
if element.version == version {
|
||||||
info!("{:?} is already up to date.", self.name);
|
info!("{:?} is already up to date.", self.name);
|
||||||
|
|
|
@ -7,6 +7,7 @@ use tasks::install_pkg::InstallPackageTask;
|
||||||
use tasks::save_executable::SaveExecutableTask;
|
use tasks::save_executable::SaveExecutableTask;
|
||||||
use tasks::uninstall_pkg::UninstallPackageTask;
|
use tasks::uninstall_pkg::UninstallPackageTask;
|
||||||
|
|
||||||
|
use tasks::install_global_shortcut::InstallGlobalShortcutsTask;
|
||||||
use tasks::Task;
|
use tasks::Task;
|
||||||
use tasks::TaskDependency;
|
use tasks::TaskDependency;
|
||||||
use tasks::TaskOrdering;
|
use tasks::TaskOrdering;
|
||||||
|
@ -61,6 +62,11 @@ impl Task for InstallTask {
|
||||||
TaskOrdering::Pre,
|
TaskOrdering::Pre,
|
||||||
Box::new(SaveExecutableTask {}),
|
Box::new(SaveExecutableTask {}),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
elements.push(TaskDependency::build(
|
||||||
|
TaskOrdering::Pre,
|
||||||
|
Box::new(InstallGlobalShortcutsTask {}),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
elements
|
elements
|
||||||
|
|
72
src/tasks/install_global_shortcut.rs
Normal file
72
src/tasks/install_global_shortcut.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
//! Generates the global shortcut for this application.
|
||||||
|
|
||||||
|
use installer::InstallerFramework;
|
||||||
|
|
||||||
|
use tasks::Task;
|
||||||
|
use tasks::TaskDependency;
|
||||||
|
use tasks::TaskParamType;
|
||||||
|
|
||||||
|
use logging::LoggingErrors;
|
||||||
|
|
||||||
|
use native::create_shortcut;
|
||||||
|
use tasks::save_database::SaveDatabaseTask;
|
||||||
|
use tasks::TaskOrdering;
|
||||||
|
|
||||||
|
pub struct InstallGlobalShortcutsTask {}
|
||||||
|
|
||||||
|
impl Task for InstallGlobalShortcutsTask {
|
||||||
|
fn execute(
|
||||||
|
&mut self,
|
||||||
|
_: Vec<TaskParamType>,
|
||||||
|
context: &mut InstallerFramework,
|
||||||
|
messenger: &Fn(&str, f64),
|
||||||
|
) -> Result<TaskParamType, String> {
|
||||||
|
messenger(&format!("Generating global shortcut..."), 0.0);
|
||||||
|
|
||||||
|
let path = context
|
||||||
|
.install_path
|
||||||
|
.as_ref()
|
||||||
|
.log_expect("No install path specified");
|
||||||
|
|
||||||
|
let starting_dir = path
|
||||||
|
.to_str()
|
||||||
|
.log_expect("Unable to build shortcut metadata (startingdir)");
|
||||||
|
|
||||||
|
// Generate installer path
|
||||||
|
let platform_extension = if cfg!(windows) {
|
||||||
|
"maintenancetool.exe"
|
||||||
|
} else {
|
||||||
|
"maintenancetool"
|
||||||
|
};
|
||||||
|
|
||||||
|
let tool_path = path.join(platform_extension);
|
||||||
|
let tool_path = tool_path
|
||||||
|
.to_str()
|
||||||
|
.log_expect("Unable to build shortcut metadata (tool)");
|
||||||
|
|
||||||
|
context.database.shortcuts.push(create_shortcut(
|
||||||
|
&format!("{} maintenance tool", context.base_attributes.name),
|
||||||
|
&format!(
|
||||||
|
"Launch the {} maintenance tool to update, modify and uninstall the application.",
|
||||||
|
context.base_attributes.name
|
||||||
|
),
|
||||||
|
tool_path,
|
||||||
|
// TODO: Send by list
|
||||||
|
"",
|
||||||
|
&starting_dir,
|
||||||
|
)?);
|
||||||
|
|
||||||
|
Ok(TaskParamType::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dependencies(&self) -> Vec<TaskDependency> {
|
||||||
|
vec![TaskDependency::build(
|
||||||
|
TaskOrdering::Post,
|
||||||
|
Box::new(SaveDatabaseTask {}),
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"InstallGlobalShortcutsTask".to_string()
|
||||||
|
}
|
||||||
|
}
|
|
@ -163,7 +163,7 @@ impl Task for InstallPackageTask {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Save metadata about this package
|
// Save metadata about this package
|
||||||
context.database.push(LocalInstallation {
|
context.database.packages.push(LocalInstallation {
|
||||||
name: package.name.to_owned(),
|
name: package.name.to_owned(),
|
||||||
version,
|
version,
|
||||||
shortcuts,
|
shortcuts,
|
||||||
|
|
|
@ -12,12 +12,14 @@ use sources::types::Version;
|
||||||
pub mod download_pkg;
|
pub mod download_pkg;
|
||||||
pub mod install;
|
pub mod install;
|
||||||
pub mod install_dir;
|
pub mod install_dir;
|
||||||
|
pub mod install_global_shortcut;
|
||||||
pub mod install_pkg;
|
pub mod install_pkg;
|
||||||
pub mod install_shortcuts;
|
pub mod install_shortcuts;
|
||||||
pub mod resolver;
|
pub mod resolver;
|
||||||
pub mod save_database;
|
pub mod save_database;
|
||||||
pub mod save_executable;
|
pub mod save_executable;
|
||||||
pub mod uninstall;
|
pub mod uninstall;
|
||||||
|
pub mod uninstall_global_shortcut;
|
||||||
pub mod uninstall_pkg;
|
pub mod uninstall_pkg;
|
||||||
pub mod uninstall_shortcuts;
|
pub mod uninstall_shortcuts;
|
||||||
|
|
||||||
|
|
44
src/tasks/uninstall_global_shortcut.rs
Normal file
44
src/tasks/uninstall_global_shortcut.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
//! Uninstalls a specific package.
|
||||||
|
|
||||||
|
use installer::InstallerFramework;
|
||||||
|
|
||||||
|
use tasks::Task;
|
||||||
|
use tasks::TaskDependency;
|
||||||
|
use tasks::TaskParamType;
|
||||||
|
|
||||||
|
use std::fs::remove_file;
|
||||||
|
use tasks::save_database::SaveDatabaseTask;
|
||||||
|
use tasks::TaskOrdering;
|
||||||
|
|
||||||
|
pub struct UninstallGlobalShortcutsTask {}
|
||||||
|
|
||||||
|
impl Task for UninstallGlobalShortcutsTask {
|
||||||
|
fn execute(
|
||||||
|
&mut self,
|
||||||
|
input: Vec<TaskParamType>,
|
||||||
|
context: &mut InstallerFramework,
|
||||||
|
messenger: &Fn(&str, f64),
|
||||||
|
) -> Result<TaskParamType, String> {
|
||||||
|
assert_eq!(input.len(), 0);
|
||||||
|
|
||||||
|
messenger(&format!("Uninstalling global shortcut..."), 0.0);
|
||||||
|
|
||||||
|
while let Some(file) = context.database.shortcuts.pop() {
|
||||||
|
info!("Deleting shortcut {:?}", file);
|
||||||
|
remove_file(file).map_err(|x| format!("Unable to delete global shortcut: {:?}", x))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(TaskParamType::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dependencies(&self) -> Vec<TaskDependency> {
|
||||||
|
vec![TaskDependency::build(
|
||||||
|
TaskOrdering::Post,
|
||||||
|
Box::new(SaveDatabaseTask {}),
|
||||||
|
)]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
"UninstallGlobalShortcutsTask".to_string()
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,9 +36,9 @@ impl Task for UninstallPackageTask {
|
||||||
.log_expect("No install path specified");
|
.log_expect("No install path specified");
|
||||||
|
|
||||||
let mut metadata: Option<LocalInstallation> = None;
|
let mut metadata: Option<LocalInstallation> = None;
|
||||||
for i in 0..context.database.len() {
|
for i in 0..context.database.packages.len() {
|
||||||
if self.name == context.database[i].name {
|
if self.name == context.database.packages[i].name {
|
||||||
metadata = Some(context.database.remove(i));
|
metadata = Some(context.database.packages.remove(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,9 @@ impl Task for UninstallShortcutsTask {
|
||||||
.log_expect("No install path specified");
|
.log_expect("No install path specified");
|
||||||
|
|
||||||
let mut metadata: Option<LocalInstallation> = None;
|
let mut metadata: Option<LocalInstallation> = None;
|
||||||
for i in 0..context.database.len() {
|
for i in 0..context.database.packages.len() {
|
||||||
if self.name == context.database[i].name {
|
if self.name == context.database.packages[i].name {
|
||||||
metadata = Some(context.database[i].clone());
|
metadata = Some(context.database.packages[i].clone());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,10 +66,10 @@ impl Task for UninstallShortcutsTask {
|
||||||
for (i, file) in package.shortcuts.iter().enumerate() {
|
for (i, file) in package.shortcuts.iter().enumerate() {
|
||||||
let name = file.clone();
|
let name = file.clone();
|
||||||
let file = path.join(file);
|
let file = path.join(file);
|
||||||
info!("Deleting {:?}", file);
|
info!("Deleting shortcut {:?}", file);
|
||||||
|
|
||||||
messenger(
|
messenger(
|
||||||
&format!("Deleting {} ({} of {})", name, i + 1, max),
|
&format!("Deleting shortcut {} ({} of {})", name, i + 1, max),
|
||||||
(i as f64) / (max as f64),
|
(i as f64) / (max as f64),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ impl Task for UninstallShortcutsTask {
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(v) = result {
|
if let Err(v) = result {
|
||||||
error!("Failed to delete file: {:?}", v);
|
error!("Failed to delete shortcut: {:?}", v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,10 +53,10 @@ const DownloadConfig = {
|
||||||
app.config.packages[x].installed = false;
|
app.config.packages[x].installed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < app.metadata.database.length; i++) {
|
for (var i = 0; i < app.metadata.database.packages.length; i++) {
|
||||||
// Find this config package
|
// Find this config package
|
||||||
for (var x = 0; x < app.config.packages.length; x++) {
|
for (var x = 0; x < app.config.packages.length; x++) {
|
||||||
if (app.config.packages[x].name === app.metadata.database[i].name) {
|
if (app.config.packages[x].name === app.metadata.database.packages[i].name) {
|
||||||
app.config.packages[x].default = true;
|
app.config.packages[x].default = true;
|
||||||
app.config.packages[x].installed = true;
|
app.config.packages[x].installed = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue