From 58530ef352a3435370bbed808514f4b1778bdab6 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 4 Aug 2018 23:35:56 +1000 Subject: [PATCH] Add launcher functionality --- Cargo.lock | 83 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/http.rs | 1 + src/installer.rs | 10 ++++++ src/main.rs | 41 ++++++++++++++++++++-- src/rest.rs | 12 +++++++ static/index.html | 65 ++++++++++++++++++++++++++++++---- static/js/helpers.js | 2 -- 8 files changed, 205 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c923f4a..b04885a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,6 +11,24 @@ dependencies = [ "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "base64" version = "0.9.0" @@ -87,6 +105,20 @@ dependencies = [ "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "clap" +version = "2.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "core-foundation" version = "0.2.3" @@ -320,6 +352,7 @@ name = "liftinstall" version = "0.1.0" dependencies = [ "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "fern 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -637,6 +670,14 @@ name = "redox_syscall" version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "redox_termios" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "0.2.5" @@ -805,6 +846,11 @@ name = "smallvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "strsim" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "syn" version = "0.11.11" @@ -836,6 +882,24 @@ dependencies = [ "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "termion" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "thread_local" version = "0.3.5" @@ -958,6 +1022,11 @@ name = "unicode-normalization" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "unicode-width" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "unicode-xid" version = "0.0.4" @@ -1005,6 +1074,11 @@ name = "vcpkg" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "version_check" version = "0.1.3" @@ -1106,6 +1180,8 @@ dependencies = [ [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" +"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" @@ -1117,6 +1193,7 @@ dependencies = [ "checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0" +"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" @@ -1180,6 +1257,7 @@ dependencies = [ "checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" "checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" +"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" @@ -1200,10 +1278,13 @@ dependencies = [ "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" +"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" +"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" @@ -1217,6 +1298,7 @@ dependencies = [ "checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f" +"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" "checksum url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa35e768d4daf1d85733418a49fb42e10d7f633e394fccab4ab7aba897053fe2" @@ -1224,6 +1306,7 @@ dependencies = [ "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" "checksum uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum want 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a05d9d966753fa4b5c8db73fcab5eed4549cfe0e1e4e66911e5564a0085c35d1" diff --git a/Cargo.toml b/Cargo.toml index e5d797c..d588f67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,8 @@ log = "0.4" fern = "0.5" chrono = "0.4.5" +clap = "2.32.0" + [target.'cfg(windows)'.dependencies] # NFD is needed on Windows, as web-view doesn't work correctly here nfd = "0.0.4" diff --git a/src/http.rs b/src/http.rs index 0f1283d..7ffc4a2 100644 --- a/src/http.rs +++ b/src/http.rs @@ -13,6 +13,7 @@ pub fn stream_file(url: &str, mut callback: F) -> Result<(), String> where F: FnMut(Vec, u64) -> (), { + // TODO: Decrease check time let mut client = match reqwest::get(url) { Ok(v) => v, Err(v) => return Err(format!("Failed to GET resource: {:?}", v)), diff --git a/src/installer.rs b/src/installer.rs index a334a1d..219f5f0 100644 --- a/src/installer.rs +++ b/src/installer.rs @@ -40,6 +40,8 @@ pub struct InstallerFramework { pub database: Vec, pub install_path: Option, pub preexisting_install: bool, + pub is_launcher: bool, + pub launcher_path: Option, } /// Contains basic properties on the status of the session. Subset of InstallationFramework. @@ -48,6 +50,8 @@ pub struct InstallationStatus { pub database: Vec, pub install_path: Option, pub preexisting_install: bool, + pub is_launcher: bool, + pub launcher_path: Option, } /// Tracks the state of a local installation @@ -184,6 +188,8 @@ impl InstallerFramework { None => None, }, preexisting_install: self.preexisting_install, + is_launcher: self.is_launcher, + launcher_path: self.launcher_path.clone(), } } @@ -194,6 +200,8 @@ impl InstallerFramework { database: Vec::new(), install_path: None, preexisting_install: false, + is_launcher: false, + launcher_path: None, } } @@ -217,6 +225,8 @@ impl InstallerFramework { database, install_path: Some(path), preexisting_install: true, + is_launcher: false, + launcher_path: None, }) } } diff --git a/src/main.rs b/src/main.rs index 19e81a6..6cb4954 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,6 +37,8 @@ extern crate log; extern crate chrono; +extern crate clap; + mod assets; mod config; mod http; @@ -65,12 +67,17 @@ use std::sync::RwLock; use logging::LoggingErrors; +use clap::App; +use clap::Arg; +use log::Level; + // TODO: Fetch this over a HTTP request? static RAW_CONFIG: &'static str = include_str!("../config.toml"); #[derive(Deserialize, Debug)] enum CallbackType { SelectInstallDir { callback_name: String }, + Log { msg: String, kind: String }, } fn main() { @@ -80,6 +87,17 @@ fn main() { let app_name = config.general.name.clone(); + let matches = App::new(format!("{} installer", app_name)) + .version(env!("CARGO_PKG_VERSION")) + .about(format!("An interactive installer for {}", app_name).as_ref()) + .arg( + Arg::with_name("launcher") + .long("launcher") + .value_name("TARGET") + .help("Launches the specified executable after checking for updates") + .takes_value(true), + ).get_matches(); + info!("{} installer", app_name); let current_exe = std::env::current_exe().log_expect("Current executable could not be found"); @@ -87,7 +105,7 @@ fn main() { .parent() .log_expect("Parent directory of executable could not be found"); let metadata_file = current_path.join("metadata.json"); - let framework = if metadata_file.exists() { + let mut framework = if metadata_file.exists() { info!("Using pre-existing metadata file: {:?}", metadata_file); InstallerFramework::new_with_db(config, current_path).log_expect("Unable to parse metadata") } else { @@ -95,6 +113,14 @@ fn main() { InstallerFramework::new(config) }; + let is_launcher = if let Some(string) = matches.value_of("launcher") { + framework.is_launcher = true; + framework.launcher_path = Some(string.to_string()); + true + } else { + false + }; + // Firstly, allocate us an epidermal port let target_port = { let listener = TcpListener::bind("127.0.0.1:0") @@ -134,7 +160,8 @@ fn main() { let http_address = format!("http://localhost:{}", http_address.port()); // Init the web view - let size = (1024, 500); + let size = if is_launcher { (600, 300) } else { (1024, 500) }; + let resizable = false; let debug = true; @@ -173,6 +200,16 @@ fn main() { wv.eval(&command); } } + CallbackType::Log { msg, kind } => { + let kind = match kind.as_ref() { + "info" | "log" => Level::Info, + "warn" => Level::Warn, + "error" => Level::Error, + _ => Level::Error, + }; + + log!(target: "liftinstall::frontend-js", kind, "{}", msg); + } } }, (), diff --git a/src/rest.rs b/src/rest.rs index 2672f42..7f6fdcd 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -30,6 +30,7 @@ use installer::InstallMessage; use installer::InstallerFramework; use logging::LoggingErrors; +use std::process::Command; #[derive(Serialize)] struct FileSelection { @@ -135,6 +136,17 @@ impl Service for WebService { } // Immediately exits the application (&Get, "/api/exit") => { + let framework = self + .framework + .read() + .log_expect("InstallerFramework has been dirtied"); + + if let Some(ref v) = framework.launcher_path { + Command::new(v) + .spawn() + .log_expect("Unable to start child process"); + } + exit(0); } // Gets properties such as if the application is in maintenance mode diff --git a/static/index.html b/static/index.html index a4a92c8..0a1a29b 100644 --- a/static/index.html +++ b/static/index.html @@ -19,7 +19,7 @@
-
+

Welcome to the {{ config.general.name }} installer!

@@ -97,7 +97,8 @@
-

Installing...

+

Checking for updates...

+

Installing...


@@ -136,10 +137,37 @@
-