Check installation path, add error messages to frontend

This commit is contained in:
James 2018-01-30 17:19:54 +11:00
parent c8af1009a2
commit 34e7698d76
3 changed files with 62 additions and 4 deletions

View File

@ -4,6 +4,9 @@
use regex::Regex; use regex::Regex;
use std::fs::create_dir_all;
use std::fs::read_dir;
use std::env::home_dir; use std::env::home_dir;
use std::env::var; use std::env::var;
use std::env::consts::OS; use std::env::consts::OS;
@ -62,10 +65,34 @@ impl InstallerFramework {
pub fn install( pub fn install(
&self, &self,
items: Vec<String>, items: Vec<String>,
path: &str,
messages: &Sender<InstallMessage>, messages: &Sender<InstallMessage>,
) -> Result<(), String> { ) -> Result<(), String> {
// TODO: Error handling // TODO: Error handling
println!("Framework: Installing {:?}", items); println!("Framework: Installing {:?} to {}", items, path);
// Create our install directory
let path = PathBuf::from(path);
if !path.exists() {
match create_dir_all(&path) {
Ok(_) => {},
Err(v) => return Err(format!("Failed to create install directory: {:?}", v)),
}
}
if !path.is_dir() {
return Err(format!("Install destination is not a directory."));
}
// Make sure it is empty
let paths = match read_dir(path) {
Ok(v) => v,
Err(v) => return Err(format!("Failed to read install destination: {:?}", v)),
};
if paths.count() != 0 {
return Err(format!("Install destination is not empty."));
}
// Resolve items in config // Resolve items in config
let mut to_install = Vec::new(); let mut to_install = Vec::new();

View File

@ -158,20 +158,29 @@ impl Service for WebService {
.collect::<HashMap<String, String>>(); .collect::<HashMap<String, String>>();
let mut to_install = Vec::new(); let mut to_install = Vec::new();
let mut path : Option<String> = None;
// Transform results into just an array of stuff to install // Transform results into just an array of stuff to install
for (key, value) in results.iter() { for (key, value) in results.iter() {
if key == "path" {
path = Some(value.to_owned());
continue;
}
if value == "true" { if value == "true" {
to_install.push(key.to_owned()); to_install.push(key.to_owned());
} }
} }
// The frontend always provides this
let path = path.unwrap();
let (sender, receiver) = channel(); let (sender, receiver) = channel();
let (tx, rx) = hyper::Body::pair(); let (tx, rx) = hyper::Body::pair();
// Startup a thread to do this operation for us // Startup a thread to do this operation for us
thread::spawn(move || { thread::spawn(move || {
match cloned_element.install(to_install, &sender) { match cloned_element.install(to_install, &path, &sender) {
Err(v) => sender.send(InstallMessage::Error(v)).unwrap(), Err(v) => sender.send(InstallMessage::Error(v)).unwrap(),
_ => {} _ => {}
} }

View File

@ -33,7 +33,15 @@
</h2> </h2>
</div> </div>
<div class="column" v-if="select_packages"> <div class="column" v-if="has_error">
<h4 class="subtitle">An error occurred:</h4>
<pre><code>{{ error }}</code></pre>
<a class="button is-primary is-pulled-right" v-on:click="back_to_packages">Back</a>
</div>
<div class="column" v-else-if="select_packages">
<h4 class="subtitle">Select your preferred settings:</h4> <h4 class="subtitle">Select your preferred settings:</h4>
<!-- Build options --> <!-- Build options -->
@ -108,7 +116,9 @@
is_installing : false, is_installing : false,
is_finished : false, is_finished : false,
progress : 0, progress : 0,
progress_message : "" progress_message : "",
has_error : false,
error : ""
}, },
methods: { methods: {
"select_file": function() { "select_file": function() {
@ -134,17 +144,29 @@
} }
console.log(results); console.log(results);
results["path"] = this.install_location;
stream_ajax("/api/start-install", function(line) { stream_ajax("/api/start-install", function(line) {
console.log(line); console.log(line);
if (line.hasOwnProperty("Status")) { if (line.hasOwnProperty("Status")) {
app.progress_message = line.Status[0]; app.progress_message = line.Status[0];
app.progress = line.Status[1] * 100; app.progress = line.Status[1] * 100;
} }
if (line.hasOwnProperty("Error")) {
app.is_installing = false;
app.has_error = true;
app.error = line.Error;
}
}, function(e) { }, function(e) {
app.is_installing = false; app.is_installing = false;
app.is_finished = true; app.is_finished = true;
}, undefined, results); }, undefined, results);
}, },
"back_to_packages": function() {
app.select_packages = true;
app.has_error = false;
},
"exit": function() { "exit": function() {
ajax("/api/exit", function() {}); ajax("/api/exit", function() {});
} }