Merge pull request #3 from j-selby/master

Quality of life improvements to messenging
This commit is contained in:
Flame Sage 2018-10-03 22:44:36 -04:00 committed by GitHub
commit fa1c1564c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 185 additions and 90 deletions

View File

@ -30,6 +30,7 @@ use tasks::install::InstallTask;
use tasks::uninstall::UninstallTask; use tasks::uninstall::UninstallTask;
use tasks::uninstall_global_shortcut::UninstallGlobalShortcutsTask; use tasks::uninstall_global_shortcut::UninstallGlobalShortcutsTask;
use tasks::DependencyTree; use tasks::DependencyTree;
use tasks::TaskMessage;
use logging::LoggingErrors; use logging::LoggingErrors;
@ -45,6 +46,7 @@ use number_prefix::{decimal_prefix, Prefixed, Standalone};
#[derive(Serialize)] #[derive(Serialize)]
pub enum InstallMessage { pub enum InstallMessage {
Status(String, f64), Status(String, f64),
PackageInstalled,
Error(String), Error(String),
EOF, EOF,
} }
@ -101,6 +103,24 @@ pub struct LocalInstallation {
pub shortcuts: Vec<String>, pub shortcuts: Vec<String>,
} }
macro_rules! declare_messenger_callback {
($target:expr) => {
&|msg: &TaskMessage| match msg {
&TaskMessage::DisplayMessage(msg, progress) => {
if let Err(v) = $target.send(InstallMessage::Status(msg.to_string(), progress as _))
{
error!("Failed to submit queue message: {:?}", v);
}
}
&TaskMessage::PackageInstalled => {
if let Err(v) = $target.send(InstallMessage::PackageInstalled) {
error!("Failed to submit queue message: {:?}", v);
}
}
}
};
}
impl InstallerFramework { impl InstallerFramework {
/// Returns a copy of the configuration. /// Returns a copy of the configuration.
pub fn get_config(&self) -> Option<Config> { pub fn get_config(&self) -> Option<Config> {
@ -170,11 +190,8 @@ impl InstallerFramework {
info!("Dependency tree:\n{}", tree); info!("Dependency tree:\n{}", tree);
tree.execute(self, &|msg: &str, progress: f64| { tree.execute(self, declare_messenger_callback!(messages))
if let Err(v) = messages.send(InstallMessage::Status(msg.to_string(), progress as _)) { .map(|_x| ())
error!("Failed to submit queue message: {:?}", v);
}
}).map(|_x| ())
} }
/// Sends a request for everything to be uninstalled. /// Sends a request for everything to be uninstalled.
@ -192,22 +209,16 @@ impl InstallerFramework {
info!("Dependency tree:\n{}", tree); info!("Dependency tree:\n{}", tree);
tree.execute(self, &|msg: &str, progress: f64| { tree.execute(self, declare_messenger_callback!(messages))
if let Err(v) = messages.send(InstallMessage::Status(msg.to_string(), progress as _)) { .map(|_x| ())?;
error!("Failed to submit queue message: {:?}", v);
}
}).map(|_x| ())?;
// Uninstall shortcuts // Uninstall shortcuts
let task = Box::new(UninstallGlobalShortcutsTask {}); let task = Box::new(UninstallGlobalShortcutsTask {});
let mut tree = DependencyTree::build(task); let mut tree = DependencyTree::build(task);
tree.execute(self, &|msg: &str, progress: f64| { tree.execute(self, declare_messenger_callback!(messages))
if let Err(v) = messages.send(InstallMessage::Status(msg.to_string(), progress as _)) { .map(|_x| ())?;
error!("Failed to submit queue message: {:?}", v);
}
}).map(|_x| ())?;
// Delete the metadata file // Delete the metadata file
let path = self let path = self

View File

@ -7,7 +7,7 @@ use log;
use std::fmt::Debug; use std::fmt::Debug;
use std::io; use std::io;
pub fn setup_logger(file_name : String) -> Result<(), fern::InitError> { pub fn setup_logger(file_name: String) -> Result<(), fern::InitError> {
fern::Dispatch::new() fern::Dispatch::new()
.format(|out, message, record| { .format(|out, message, record| {
out.finish(format_args!( out.finish(format_args!(

View File

@ -93,10 +93,10 @@ enum CallbackType {
} }
fn main() { fn main() {
let config = let config = BaseAttributes::from_toml_str(RAW_CONFIG).expect("Config file could not be read");
BaseAttributes::from_toml_str(RAW_CONFIG).expect("Config file could not be read");
logging::setup_logger(format!("{}_installer.log", config.name)).expect("Unable to setup logging!"); logging::setup_logger(format!("{}_installer.log", config.name))
.expect("Unable to setup logging!");
let app_name = config.name.clone(); let app_name = config.name.clone();

View File

@ -70,7 +70,7 @@ mod natives {
} }
/// Cleans up the installer /// Cleans up the installer
pub fn burn_on_exit(app_name : &str) { pub fn burn_on_exit(app_name: &str) {
let current_exe = env::current_exe().log_expect("Current executable could not be found"); let current_exe = env::current_exe().log_expect("Current executable could not be found");
let path = current_exe let path = current_exe
.parent() .parent()
@ -123,7 +123,7 @@ mod natives {
} }
/// Cleans up the installer /// Cleans up the installer
pub fn burn_on_exit(app_name : &str) { pub fn burn_on_exit(app_name: &str) {
let current_exe = env::current_exe().log_expect("Current executable could not be found"); let current_exe = env::current_exe().log_expect("Current executable could not be found");
// Thank god for *nix platforms // Thank god for *nix platforms

View File

@ -45,8 +45,17 @@ impl ReleaseSource for GithubReleases {
.send() .send()
.map_err(|x| format!("Error while sending HTTP request: {:?}", x))?; .map_err(|x| format!("Error while sending HTTP request: {:?}", x))?;
if response.status() != StatusCode::OK { match response.status() {
return Err(format!("Bad status code: {:?}", response.status())); StatusCode::OK => {}
StatusCode::FORBIDDEN => {
return Err(format!(
"GitHub is rate limiting you. Try moving to a internet connection \
that isn't shared, and/or disabling VPNs."
));
}
_ => {
return Err(format!("Bad status code: {:?}.", response.status()));
}
} }
let body = response let body = response

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskOrdering; use tasks::TaskOrdering;
use tasks::TaskParamType; use tasks::TaskParamType;
@ -24,7 +25,7 @@ impl Task for DownloadPackageTask {
&mut self, &mut self,
mut input: Vec<TaskParamType>, mut input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 1); assert_eq!(input.len(), 1);
@ -45,7 +46,10 @@ impl Task for DownloadPackageTask {
} }
} }
messenger(&format!("Downloading package {:?}...", self.name), 0.0); messenger(&TaskMessage::DisplayMessage(
&format!("Downloading package {:?}...", self.name),
0.0,
));
let mut downloaded = 0; let mut downloaded = 0;
let mut data_storage: Vec<u8> = Vec::new(); let mut data_storage: Vec<u8> = Vec::new();
@ -73,13 +77,13 @@ impl Task for DownloadPackageTask {
Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix), Prefixed(prefix, n) => format!("{:.0} {}B", n, prefix),
}; };
messenger( messenger(&TaskMessage::DisplayMessage(
&format!( &format!(
"Downloading {} ({} of {})...", "Downloading {} ({} of {})...",
self.name, pretty_current, pretty_total self.name, pretty_current, pretty_total
), ),
percentage, percentage,
); ));
})?; })?;
Ok(TaskParamType::FileContents(version, file, data_storage)) Ok(TaskParamType::FileContents(version, file, data_storage))

View File

@ -10,6 +10,7 @@ use tasks::uninstall_pkg::UninstallPackageTask;
use tasks::install_global_shortcut::InstallGlobalShortcutsTask; use tasks::install_global_shortcut::InstallGlobalShortcutsTask;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskOrdering; use tasks::TaskOrdering;
use tasks::TaskParamType; use tasks::TaskParamType;
@ -24,9 +25,9 @@ impl Task for InstallTask {
&mut self, &mut self,
_: Vec<TaskParamType>, _: Vec<TaskParamType>,
_: &mut InstallerFramework, _: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
messenger("Wrapping up...", 0.0); messenger(&TaskMessage::DisplayMessage("Wrapping up...", 0.0));
Ok(TaskParamType::None) Ok(TaskParamType::None)
} }

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use std::fs::create_dir_all; use std::fs::create_dir_all;
@ -20,10 +21,13 @@ impl Task for VerifyInstallDirTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
messenger("Polling installation directory...", 0.0); messenger(&TaskMessage::DisplayMessage(
"Polling installation directory...",
0.0,
));
let path = context let path = context
.install_path .install_path

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use logging::LoggingErrors; use logging::LoggingErrors;
@ -19,9 +20,12 @@ impl Task for InstallGlobalShortcutsTask {
&mut self, &mut self,
_: Vec<TaskParamType>, _: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
messenger("Generating global shortcut...", 0.0); messenger(&TaskMessage::DisplayMessage(
"Generating global shortcut...",
0.0,
));
let path = context let path = context
.install_path .install_path
@ -45,7 +49,7 @@ impl Task for InstallGlobalShortcutsTask {
.log_expect("Unable to build shortcut metadata (tool)"); .log_expect("Unable to build shortcut metadata (tool)");
let shortcut_file = create_shortcut( let shortcut_file = create_shortcut(
&format!("{} maintenance tool", context.base_attributes.name), &format!("{} Maintenance Tool", context.base_attributes.name),
&format!( &format!(
"Launch the {} Maintenance Tool to update, modify and uninstall the application.", "Launch the {} Maintenance Tool to update, modify and uninstall the application.",
context.base_attributes.name context.base_attributes.name

View File

@ -8,6 +8,7 @@ use tasks::save_database::SaveDatabaseTask;
use tasks::uninstall_pkg::UninstallPackageTask; use tasks::uninstall_pkg::UninstallPackageTask;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskOrdering; use tasks::TaskOrdering;
use tasks::TaskParamType; use tasks::TaskParamType;
@ -33,9 +34,12 @@ impl Task for InstallPackageTask {
&mut self, &mut self,
mut input: Vec<TaskParamType>, mut input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
messenger(&format!("Installing package {:?}...", self.name), 0.0); messenger(&TaskMessage::DisplayMessage(
&format!("Installing package {:?}...", self.name),
0.0,
));
let path = context let path = context
.install_path .install_path
@ -91,16 +95,16 @@ impl Task for InstallPackageTask {
match &archive_size { match &archive_size {
Some(size) => { Some(size) => {
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Extracting {} ({} of {})", string_name, i + 1, size), &format!("Extracting {} ({} of {})", string_name, i + 1, size),
(i as f64) / (*size as f64), (i as f64) / (*size as f64),
); ));
} }
_ => { _ => {
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Extracting {} ({} of ??)", string_name, i + 1), &format!("Extracting {} ({} of ??)", string_name, i + 1),
0.0, 0.0,
); ));
} }
} }
@ -170,6 +174,8 @@ impl Task for InstallPackageTask {
files: installed_files, files: installed_files,
}); });
messenger(&TaskMessage::PackageInstalled);
Ok(TaskParamType::None) Ok(TaskParamType::None)
} }

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use config::PackageDescription; use config::PackageDescription;
@ -21,12 +22,12 @@ impl Task for InstallShortcutsTask {
&mut self, &mut self,
_: Vec<TaskParamType>, _: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Generating shortcuts for package {:?}...", self.name), &format!("Generating shortcuts for package {:?}...", self.name),
0.0, 0.0,
); ));
let path = context let path = context
.install_path .install_path

View File

@ -58,6 +58,12 @@ impl TaskDependency {
} }
} }
/// A message from a task.
pub enum TaskMessage<'a> {
DisplayMessage(&'a str, f64),
PackageInstalled,
}
/// A Task is a small, async task conforming to a fixed set of inputs/outputs. /// A Task is a small, async task conforming to a fixed set of inputs/outputs.
pub trait Task { pub trait Task {
/// Executes this individual task, evaluating to the given Output result. /// Executes this individual task, evaluating to the given Output result.
@ -67,7 +73,7 @@ pub trait Task {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String>; ) -> Result<TaskParamType, String>;
/// Returns a vector containing all dependencies that need to be executed /// Returns a vector containing all dependencies that need to be executed
@ -113,7 +119,7 @@ impl DependencyTree {
pub fn execute( pub fn execute(
&mut self, &mut self,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
let total_tasks = (self.dependencies.len() + 1) as f64; let total_tasks = (self.dependencies.len() + 1) as f64;
@ -126,11 +132,14 @@ impl DependencyTree {
continue; continue;
} }
let result = i.execute(context, &|msg: &str, progress: f64| { let result = i.execute(context, &|msg: &TaskMessage| match msg {
messenger( &TaskMessage::DisplayMessage(msg, progress) => {
msg, messenger(&TaskMessage::DisplayMessage(
progress / total_tasks + (1.0 / total_tasks) * f64::from(count), msg,
) progress / total_tasks + (1.0 / total_tasks) * f64::from(count),
))
}
_ => messenger(msg),
})?; })?;
// Check to see if we skip matching other dependencies // Check to see if we skip matching other dependencies
@ -149,11 +158,14 @@ impl DependencyTree {
let task_result = self let task_result = self
.task .task
.execute(inputs, context, &|msg: &str, progress: f64| { .execute(inputs, context, &|msg: &TaskMessage| match msg {
messenger( &TaskMessage::DisplayMessage(msg, progress) => {
msg, messenger(&TaskMessage::DisplayMessage(
progress / total_tasks + (1.0 / total_tasks) * f64::from(count), msg,
) progress / total_tasks + (1.0 / total_tasks) * f64::from(count),
))
}
_ => messenger(msg),
})?; })?;
if let TaskParamType::Break = task_result { if let TaskParamType::Break = task_result {
@ -166,11 +178,14 @@ impl DependencyTree {
continue; continue;
} }
let result = i.execute(context, &|msg: &str, progress: f64| { let result = i.execute(context, &|msg: &TaskMessage| match msg {
messenger( &TaskMessage::DisplayMessage(msg, progress) => {
msg, messenger(&TaskMessage::DisplayMessage(
progress / total_tasks + (1.0 / total_tasks) * f64::from(count), msg,
) progress / total_tasks + (1.0 / total_tasks) * f64::from(count),
))
}
_ => messenger(msg),
})?; })?;
// Check to see if we skip matching other dependencies // Check to see if we skip matching other dependencies

View File

@ -6,6 +6,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use config::PackageDescription; use config::PackageDescription;
@ -23,7 +24,7 @@ impl Task for ResolvePackageTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
let mut metadata: Option<PackageDescription> = None; let mut metadata: Option<PackageDescription> = None;
@ -44,20 +45,20 @@ impl Task for ResolvePackageTask {
None => return Err(format!("Package {:?} could not be found.", self.name)), None => return Err(format!("Package {:?} could not be found.", self.name)),
}; };
messenger( messenger(&TaskMessage::DisplayMessage(
&format!( &format!(
"Polling {} for latest version of {:?}...", "Polling {} for latest version of {:?}...",
package.source.name, package.name package.source.name, package.name
), ),
0.0, 0.0,
); ));
let results = package.source.get_current_releases()?; let results = package.source.get_current_releases()?;
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Resolving dependency for {:?}...", package.name), &format!("Resolving dependency for {:?}...", package.name),
0.5, 0.5,
); ));
let filtered_regex = package.source.match_regex.replace("#PLATFORM#", OS); let filtered_regex = package.source.match_regex.replace("#PLATFORM#", OS);
let regex = match Regex::new(&filtered_regex) { let regex = match Regex::new(&filtered_regex) {

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
pub struct SaveDatabaseTask {} pub struct SaveDatabaseTask {}
@ -13,10 +14,13 @@ impl Task for SaveDatabaseTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
messenger("Saving application database...", 0.0); messenger(&TaskMessage::DisplayMessage(
"Saving application database...",
0.0,
));
context.save_database()?; context.save_database()?;

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use std::fs::File; use std::fs::File;
@ -22,10 +23,13 @@ impl Task for SaveExecutableTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
messenger("Copying installer binary...", 0.0); messenger(&TaskMessage::DisplayMessage(
"Copying installer binary...",
0.0,
));
let path = context let path = context
.install_path .install_path

View File

@ -7,6 +7,7 @@ use tasks::TaskParamType;
use tasks::uninstall_pkg::UninstallPackageTask; use tasks::uninstall_pkg::UninstallPackageTask;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskOrdering; use tasks::TaskOrdering;
pub struct UninstallTask { pub struct UninstallTask {
@ -18,9 +19,9 @@ impl Task for UninstallTask {
&mut self, &mut self,
_: Vec<TaskParamType>, _: Vec<TaskParamType>,
_: &mut InstallerFramework, _: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
messenger("Wrapping up...", 0.0); messenger(&TaskMessage::DisplayMessage("Wrapping up...", 0.0));
Ok(TaskParamType::None) Ok(TaskParamType::None)
} }

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use std::fs::remove_file; use std::fs::remove_file;
@ -17,11 +18,14 @@ impl Task for UninstallGlobalShortcutsTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
messenger("Uninstalling global shortcut...", 0.0); messenger(&TaskMessage::DisplayMessage(
"Uninstalling global shortcut...",
0.0,
));
while let Some(file) = context.database.shortcuts.pop() { while let Some(file) = context.database.shortcuts.pop() {
info!("Deleting shortcut {:?}", file); info!("Deleting shortcut {:?}", file);

View File

@ -5,6 +5,7 @@ use installer::InstallerFramework;
use tasks::save_database::SaveDatabaseTask; use tasks::save_database::SaveDatabaseTask;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskOrdering; use tasks::TaskOrdering;
use tasks::TaskParamType; use tasks::TaskParamType;
@ -26,7 +27,7 @@ impl Task for UninstallPackageTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 1); assert_eq!(input.len(), 1);
@ -57,7 +58,10 @@ impl Task for UninstallPackageTask {
} }
}; };
messenger(&format!("Uninstalling package {:?}...", self.name), 0.0); messenger(&TaskMessage::DisplayMessage(
&format!("Uninstalling package {:?}...", self.name),
0.0,
));
// Reverse, as to delete directories last // Reverse, as to delete directories last
package.files.reverse(); package.files.reverse();
@ -68,10 +72,10 @@ impl Task for UninstallPackageTask {
let file = path.join(file); let file = path.join(file);
info!("Deleting {:?}", file); info!("Deleting {:?}", file);
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Deleting {} ({} of {})", name, i + 1, max), &format!("Deleting {} ({} of {})", name, i + 1, max),
(i as f64) / (max as f64), (i as f64) / (max as f64),
); ));
let result = if file.is_dir() { let result = if file.is_dir() {
remove_dir(file) remove_dir(file)

View File

@ -4,6 +4,7 @@ use installer::InstallerFramework;
use tasks::Task; use tasks::Task;
use tasks::TaskDependency; use tasks::TaskDependency;
use tasks::TaskMessage;
use tasks::TaskParamType; use tasks::TaskParamType;
use installer::LocalInstallation; use installer::LocalInstallation;
@ -23,7 +24,7 @@ impl Task for UninstallShortcutsTask {
&mut self, &mut self,
input: Vec<TaskParamType>, input: Vec<TaskParamType>,
context: &mut InstallerFramework, context: &mut InstallerFramework,
messenger: &Fn(&str, f64), messenger: &Fn(&TaskMessage),
) -> Result<TaskParamType, String> { ) -> Result<TaskParamType, String> {
assert_eq!(input.len(), 0); assert_eq!(input.len(), 0);
@ -54,10 +55,10 @@ impl Task for UninstallShortcutsTask {
} }
}; };
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Uninstalling shortcuts for package {:?}...", self.name), &format!("Uninstalling shortcuts for package {:?}...", self.name),
0.0, 0.0,
); ));
// Reverse, as to delete directories last // Reverse, as to delete directories last
package.files.reverse(); package.files.reverse();
@ -68,10 +69,10 @@ impl Task for UninstallShortcutsTask {
let file = path.join(file); let file = path.join(file);
info!("Deleting shortcut {:?}", file); info!("Deleting shortcut {:?}", file);
messenger( messenger(&TaskMessage::DisplayMessage(
&format!("Deleting shortcut {} ({} 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),
); ));
let result = if file.is_dir() { let result = if file.is_dir() {
remove_dir(file) remove_dir(file)

View File

@ -199,7 +199,8 @@ const InstallPackages = {
is_uninstall: false, is_uninstall: false,
is_updater_update: false, is_updater_update: false,
is_update: false, is_update: false,
failed_with_error: false failed_with_error: false,
packages_installed: 0
} }
}, },
created: function() { created: function() {
@ -238,6 +239,10 @@ const InstallPackages = {
that.progress = line.Status[1] * 100; that.progress = line.Status[1] * 100;
} }
if (line.hasOwnProperty("PackageInstalled")) {
that.packages_installed += 1;
}
if (line.hasOwnProperty("Error")) { if (line.hasOwnProperty("Error")) {
if (app.metadata.is_launcher) { if (app.metadata.is_launcher) {
app.exit(); app.exit();
@ -263,9 +268,17 @@ const InstallPackages = {
app.exit(); app.exit();
} else if (!that.failed_with_error) { } else if (!that.failed_with_error) {
if (that.is_uninstall) { if (that.is_uninstall) {
router.replace({name: 'complete', params: {uninstall: true, update: that.is_update}}); router.replace({name: 'complete', params: {
uninstall: true,
update: that.is_update,
installed: that.packages_installed
}});
} else { } else {
router.replace({name: 'complete', params: {uninstall: false, update: that.is_update}}); router.replace({name: 'complete', params: {
uninstall: false,
update: that.is_update,
installed: that.packages_installed
}});
} }
} }
} }
@ -305,9 +318,16 @@ const CompleteView = {
template: ` template: `
<div class="column has-padding"> <div class="column has-padding">
<div v-if="was_update"> <div v-if="was_update">
<h4 class="subtitle">{{ $root.$data.attrs.name }} has been updated.</h4> <div v-if="has_installed">
<h4 class="subtitle">{{ $root.$data.attrs.name }} has been updated.</h4>
<p>You can find your installed applications in your start menu.</p>
<p>You can find your installed applications in your start menu.</p>
</div>
<div v-else>
<h4 class="subtitle">{{ $root.$data.attrs.name }} is already up to date!</h4>
<p>You can find your installed applications in your start menu.</p>
</div>
</div> </div>
<div v-else-if="was_install"> <div v-else-if="was_install">
<h4 class="subtitle">Thanks for installing {{ $root.$data.attrs.name }}!</h4> <h4 class="subtitle">Thanks for installing {{ $root.$data.attrs.name }}!</h4>
@ -330,7 +350,8 @@ const CompleteView = {
data: function() { data: function() {
return { return {
was_install: !this.$route.params.uninstall, was_install: !this.$route.params.uninstall,
was_update: this.$route.params.update was_update: this.$route.params.update,
has_installed: this.$route.params.packages_installed > 0
} }
}, },
methods: { methods: {
@ -422,7 +443,7 @@ const router = new VueRouter({
component: ErrorView component: ErrorView
}, },
{ {
path: '/complete/:uninstall/:update', path: '/complete/:uninstall/:update/:packages_installed',
name: 'complete', name: 'complete',
component: CompleteView component: CompleteView
}, },