From da6c7f16fb60e33ab0325333d6e8cfa0d4ae46f6 Mon Sep 17 00:00:00 2001
From: 2Shirt <2xShirt@gmail.com>
Date: Sat, 9 Nov 2024 20:05:21 -0800
Subject: [PATCH] Add Command and Diskpart actions
---
src/action.rs | 6 ++-
src/app.rs | 98 +++++++++++++++++++++++++++++++++++++-----
src/components/left.rs | 3 --
src/config.rs | 8 +++-
4 files changed, 99 insertions(+), 16 deletions(-)
diff --git a/src/action.rs b/src/action.rs
index 98824fc..bf8ce58 100644
--- a/src/action.rs
+++ b/src/action.rs
@@ -14,6 +14,7 @@
// along with Deja-vu. If not, see .
//
use serde::{Deserialize, Serialize};
+use std::path::PathBuf;
use strum::Display;
use crate::{
@@ -28,14 +29,15 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
pub enum Action {
// App
- Command(String, String, Vec), // (label, command, args)
- Diskpart(String, String), // (label, script_as_string)
+ Command(String, PathBuf, Vec), // (label, command, args)
+ Diskpart(String, String), // (label, script_as_string)
InstallDriver,
Process,
ScanDisks,
Select(Option, Option), // indicies for (source, dest) or (boot, os)
SelectDriver(Driver),
SelectTableType(PartitionTableType),
+ UpdateDestDisk,
UpdateDiskList(Vec),
// Screens
DismissPopup,
diff --git a/src/app.rs b/src/app.rs
index 9b53cb0..7cd42d9 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -15,8 +15,10 @@
//
use std::{
iter::zip,
+ path::PathBuf,
sync::{Arc, Mutex},
- thread::{self, JoinHandle},
+ thread::{self, sleep, JoinHandle},
+ time::Duration,
};
use color_eyre::Result;
@@ -32,17 +34,12 @@ use tracing::{debug, info};
use crate::{
action::Action,
components::{
- footer::Footer,
- fps::FpsCounter,
- left::Left,
- popup::{Popup, Type},
- right::Right,
- title::Title,
- Component,
+ footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component,
},
config::Config,
system::{
disk::{get_disks, Disk, PartitionTableType},
+ diskpart::refresh_disk_info,
drivers::{self, Driver},
},
tui::{Event, Tui},
@@ -101,7 +98,7 @@ impl App {
Box::new(Left::new()),
Box::new(Right::new()),
Box::new(Footer::new()),
- Box::new(Popup::new()),
+ Box::new(popup::Popup::new()),
],
config: Config::new()?,
frame_rate,
@@ -278,6 +275,21 @@ impl App {
Action::Suspend => self.should_suspend = true,
Action::Resume => self.should_suspend = false,
Action::ClearScreen => tui.terminal.clear()?,
+ Action::Command(ref label, ref cmd_path, ref cmd_args) => {
+ self.action_tx.send(Action::DisplayPopup(
+ popup::Type::Info,
+ String::from(&label.to_owned()),
+ ))?;
+ self.task_handles
+ .push(lazy_command(&cmd_path, cmd_args.clone()))
+ }
+ Action::Diskpart(ref label, ref script) => {
+ self.action_tx.send(Action::DisplayPopup(
+ popup::Type::Info,
+ String::from(&label.to_owned()),
+ ))?;
+ self.task_handles.push(lazy_diskpart(&script.to_owned()))
+ }
Action::InstallDriver => {
self.action_tx.send(Action::SetMode(Mode::InstallDrivers))?
}
@@ -297,6 +309,7 @@ impl App {
}
Action::NextScreen => {
if let Some(mode) = self.next_mode() {
+ self.action_tx.send(Action::DismissPopup)?;
self.action_tx.send(Action::SetMode(mode))?;
}
}
@@ -331,15 +344,48 @@ impl App {
self.action_tx
.send(Action::UpdateDiskList(disk_list.clone()))?;
}
+ Mode::PreClone => {
+ // TODO: FIXME
+ self.action_tx.send(Action::Diskpart(
+ String::from("Formatting destination disk"),
+ String::from("TODO: FIXME"),
+ ))?;
+ }
+ Mode::Clone => {
+ self.action_tx.send(Action::UpdateDestDisk)?;
+ self.action_tx.send(Action::Command(
+ String::from("Running Clone Tool"),
+ self.config.clone_app_path.clone(),
+ Vec::new(),
+ ))?;
+ }
+ Mode::PostClone => {
+ // TODO: FIXME
+ self.action_tx.send(Action::Diskpart(
+ String::from("Creating boot files"),
+ String::from("TODO: FIXME"),
+ ))?;
+ }
Mode::Done => {
self.action_tx.send(Action::DisplayPopup(
- Type::Success,
+ popup::Type::Success,
String::from("COMPLETE\n\n\nThank you for using this tool!"),
))?;
}
_ => {}
}
}
+ Action::UpdateDestDisk => {
+ let disk_list_arc = Arc::clone(&self.disk_list);
+ if let Some(dest_id_index) = self.disk_id_dest {
+ self.action_tx.send(Action::DisplayPopup(
+ popup::Type::Info,
+ String::from("Updating info for destination disk"),
+ ))?;
+ self.task_handles
+ .push(lazy_update_dest_disk(disk_list_arc, dest_id_index));
+ }
+ }
_ => {}
}
for component in self.components.iter_mut() {
@@ -432,9 +478,41 @@ fn get_chunks(r: Rect) -> Vec {
chunks
}
+fn lazy_command(cmd_path: &PathBuf, cmd_args: Vec) -> JoinHandle<()> {
+ if cfg!(windows) {
+ // TODO: FIXME
+ thread::spawn(|| sleep(Duration::from_secs(1)))
+ } else {
+ thread::spawn(|| sleep(Duration::from_secs(1)))
+ }
+}
+
+fn lazy_diskpart(script: &str) -> JoinHandle<()> {
+ if cfg!(windows) {
+ // TODO: FIXME
+ thread::spawn(|| sleep(Duration::from_secs(1)))
+ } else {
+ thread::spawn(|| sleep(Duration::from_secs(1)))
+ }
+}
+
fn lazy_get_disks(disk_list_arc: Arc>>) -> JoinHandle<()> {
thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap();
*disks = get_disks();
})
}
+
+fn lazy_update_dest_disk(
+ disk_list_arc: Arc>>,
+ dest_index: usize,
+) -> JoinHandle<()> {
+ if cfg!(windows) {
+ thread::spawn(move || {
+ let mut disks = disk_list_arc.lock().unwrap();
+ refresh_disk_info(&mut disks[dest_index]);
+ })
+ } else {
+ thread::spawn(|| sleep(Duration::from_secs(2)))
+ }
+}
diff --git a/src/components/left.rs b/src/components/left.rs
index c60c5f9..3d2c10e 100644
--- a/src/components/left.rs
+++ b/src/components/left.rs
@@ -202,9 +202,6 @@ impl Component for Left {
self.selections[0] = None;
self.selections[1] = None;
self.title_text = String::from("Select Source and Destination Disks");
- if let Some(command_tx) = self.command_tx.clone() {
- command_tx.send(Action::DismissPopup)?;
- }
}
(_, Mode::SelectTableType) => {
self.list_table_types
diff --git a/src/config.rs b/src/config.rs
index eb62250..4fb882c 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -40,6 +40,8 @@ pub struct AppConfig {
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Config {
+ #[serde(default)]
+ pub clone_app_path: PathBuf,
#[serde(default, flatten)]
pub config: AppConfig,
#[serde(default)]
@@ -67,7 +69,11 @@ impl Config {
let config_dir = get_config_dir();
let mut builder = config::Config::builder()
.set_default("data_dir", data_dir.to_str().unwrap())?
- .set_default("config_dir", config_dir.to_str().unwrap())?;
+ .set_default("config_dir", config_dir.to_str().unwrap())?
+ .set_default(
+ "clone_app_path",
+ String::from("C:\\Program Files\\Some Clone Tool\\app.exe"),
+ )?;
let config_files = [
("config.json5", config::FileFormat::Json5),