Compare commits
No commits in common. "59b9ddbee64325c73ffccfe4dcbfc41e7eaa4af7" and "8be96d21b9509fd1e1ae338ca3d47dee1b7527f5" have entirely different histories.
59b9ddbee6
...
8be96d21b9
50 changed files with 605 additions and 2405 deletions
593
Cargo.lock
generated
593
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
12
Cargo.toml
12
Cargo.toml
|
|
@ -1,19 +1,19 @@
|
|||
# This file is part of Deja-Vu.
|
||||
# This file is part of Deja-vu.
|
||||
#
|
||||
# Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
# Deja-vu is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Deja-Vu is distributed in the hope that it will be useful, but
|
||||
# Deja-vu is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[workspace]
|
||||
members = ["core", "boot_diags", "deja_vu", "pe_menu"]
|
||||
default-members = ["boot_diags", "deja_vu", "pe_menu"]
|
||||
members = ["core", "deja_vu", "pe_menu"]
|
||||
default-members = ["deja_vu", "pe_menu"]
|
||||
resolver = "2"
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
# This file is part of Deja-Vu.
|
||||
#
|
||||
# Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Deja-Vu is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[package]
|
||||
name = "boot-diags"
|
||||
authors = ["2Shirt <2xShirt@gmail.com>"]
|
||||
edition = "2024"
|
||||
license = "GPL"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
core = { path = "../core" }
|
||||
clap = { version = "4.4.5", features = [
|
||||
"derive",
|
||||
"cargo",
|
||||
"wrap_help",
|
||||
"unicode",
|
||||
"string",
|
||||
"unstable-styles",
|
||||
] }
|
||||
color-eyre = "0.6.3"
|
||||
crossterm = { version = "0.28.1", features = ["event-stream"] }
|
||||
futures = "0.3.30"
|
||||
ratatui = "0.29.0"
|
||||
serde = { version = "1.0.217", features = ["derive"] }
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
toml = "0.8.13"
|
||||
tracing = "0.1.41"
|
||||
tracing-error = "0.2.0"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
||||
check_elevation = "0.2.4"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0.86"
|
||||
vergen-gix = { version = "1.0.0", features = ["build", "cargo"] }
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// This file is part of Deja-Vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use anyhow::Result;
|
||||
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let build = BuildBuilder::all_build()?;
|
||||
let gix = GixBuilder::all_git()?;
|
||||
let cargo = CargoBuilder::all_cargo()?;
|
||||
Emitter::default()
|
||||
.add_instructions(&build)?
|
||||
.add_instructions(&gix)?
|
||||
.add_instructions(&cargo)?
|
||||
.emit()
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,102 +0,0 @@
|
|||
// This file is part of Deja-Vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub enum Type {
|
||||
Bitlocker,
|
||||
BootConfigData,
|
||||
FileSystem,
|
||||
FilesAndFolders,
|
||||
Registry,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Groups {
|
||||
items: HashMap<String, Line>,
|
||||
order: Vec<String>,
|
||||
}
|
||||
|
||||
impl Groups {
|
||||
pub fn new() -> Self {
|
||||
Groups {
|
||||
items: HashMap::new(),
|
||||
order: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Vec<&Line> {
|
||||
let mut lines = Vec::new();
|
||||
self.order.iter().for_each(|key| {
|
||||
if let Some(line) = self.items.get(key) {
|
||||
lines.push(line);
|
||||
}
|
||||
});
|
||||
lines
|
||||
}
|
||||
|
||||
pub fn update(&mut self, title: String, passed: bool, info: String) {
|
||||
if let Some(line) = self.items.get_mut(&title) {
|
||||
line.update(passed, info);
|
||||
} else {
|
||||
self.order.push(title.clone());
|
||||
self.items.insert(
|
||||
title.clone(),
|
||||
Line {
|
||||
title,
|
||||
passed,
|
||||
info: vec![info],
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Line {
|
||||
pub title: String,
|
||||
pub passed: bool,
|
||||
pub info: Vec<String>,
|
||||
}
|
||||
|
||||
impl Line {
|
||||
pub fn update(&mut self, passed: bool, info: String) {
|
||||
self.passed &= passed; // We fail if any tests in this group fail
|
||||
self.info.push(info);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_type(cmd_name: &str) -> Type {
|
||||
if cmd_name == "exa" {
|
||||
return Type::BootConfigData;
|
||||
}
|
||||
if cmd_name == "bcdedit.exe" {
|
||||
return Type::BootConfigData;
|
||||
}
|
||||
if cmd_name == "dir" {
|
||||
return Type::FilesAndFolders;
|
||||
}
|
||||
if cmd_name == "reg.exe" {
|
||||
return Type::Registry;
|
||||
}
|
||||
if cmd_name == "chkdsk.exe" {
|
||||
return Type::FileSystem;
|
||||
}
|
||||
if cmd_name == "manage-bde.exe" {
|
||||
return Type::Bitlocker;
|
||||
}
|
||||
Type::Unknown
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// This file is part of Deja-Vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
mod app;
|
||||
mod diags;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let mut msg = None;
|
||||
if cfg!(windows) {
|
||||
use check_elevation::is_elevated;
|
||||
if !is_elevated().expect("Failed to get elevation status.") {
|
||||
msg.replace("Administrator privedges required for Deja-Vu.");
|
||||
}
|
||||
};
|
||||
match msg {
|
||||
Some(text) => {
|
||||
println!("{text}");
|
||||
}
|
||||
None => {
|
||||
core::errors::init()?;
|
||||
core::logging::init()?;
|
||||
|
||||
let args = core::cli::Cli::parse();
|
||||
let mut app = App::new(args.tick_rate, args.frame_rate)?;
|
||||
app.run().await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"app_title": "Deja-Vu",
|
||||
"app_title": "Deja-vu",
|
||||
"clone_app_path": "C:/Program Files/Some Clone Tool/app.exe",
|
||||
"conemu_path": "C:/Program Files/ConEmu/ConEmu64.exe",
|
||||
"keybindings": {
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"Done": {
|
||||
"<Enter>": "Process",
|
||||
"<Enter>": "Quit",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
|
|
@ -95,66 +95,11 @@
|
|||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"DiagMenu": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<s>": "ScanDisks",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"BootDiags": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<r>": "BootScan",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"BootScan": {
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"BootSetup": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"InjectDrivers": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"SetBootMode": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<q>": "Quit",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
"<Ctrl-z>": "Suspend"
|
||||
},
|
||||
"PEMenu": {
|
||||
"<Enter>": "Process",
|
||||
"<Up>": "KeyUp",
|
||||
"<Down>": "KeyDown",
|
||||
"<q>": "Quit",
|
||||
"<r>": "Restart",
|
||||
"<p>": "Shutdown",
|
||||
"<t>": "OpenTerminal",
|
||||
"<Ctrl-d>": "Quit",
|
||||
"<Ctrl-c>": "Quit",
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
# This file is part of Deja-Vu.
|
||||
# This file is part of Deja-vu.
|
||||
#
|
||||
# Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
# Deja-vu is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Deja-Vu is distributed in the hope that it will be useful, but
|
||||
# Deja-vu is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[package]
|
||||
name = "core"
|
||||
authors = ["2Shirt <2xShirt@gmail.com>"]
|
||||
edition = "2024"
|
||||
edition = "2021"
|
||||
license = "GPL"
|
||||
version = "0.2.0"
|
||||
|
||||
|
|
@ -42,7 +42,6 @@ lazy_static = "1.5.0"
|
|||
libc = "0.2.158"
|
||||
once_cell = "1.20.2"
|
||||
pretty_assertions = "1.4.0"
|
||||
rand = "0.9.0"
|
||||
ratatui = { version = "0.29.0", features = ["serde", "macros"] }
|
||||
raw-cpuid = "11.2.0"
|
||||
regex = "1.11.1"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use anyhow::Result;
|
||||
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::Display;
|
||||
|
|
@ -20,8 +20,6 @@ use crate::{components::popup::Type, line::DVLine, state::Mode, system::disk::Di
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
|
||||
pub enum Action {
|
||||
// App (Boot-Diags)
|
||||
BootScan,
|
||||
// App (Clone)
|
||||
Highlight(usize),
|
||||
InstallDriver,
|
||||
|
|
@ -29,7 +27,6 @@ pub enum Action {
|
|||
ScanDisks,
|
||||
Select(Option<usize>, Option<usize>), // indicies for (source, dest) etc
|
||||
SelectRight(Option<usize>, Option<usize>), // indicies for right info pane
|
||||
TasksComplete,
|
||||
UpdateDiskList(Vec<Disk>),
|
||||
UpdateFooter(String),
|
||||
UpdateLeft(String, Vec<String>, Vec<String>, usize), // (title, labels, items, select_num)
|
||||
|
|
@ -38,10 +35,8 @@ pub enum Action {
|
|||
// 1: For a single choice
|
||||
// 2: For two selections (obviously)
|
||||
UpdateRight(Vec<Vec<DVLine>>, usize, Vec<Vec<DVLine>>), // (labels, start_index, items) - items before start are always shown
|
||||
// App (PE-Menu)
|
||||
// App (PEMenu)
|
||||
OpenTerminal,
|
||||
Restart,
|
||||
Shutdown,
|
||||
// Screens
|
||||
DismissPopup,
|
||||
DisplayPopup(Type, String),
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use clap::Parser;
|
||||
|
||||
|
|
@ -38,7 +38,6 @@ const VERSION_MESSAGE: &str = concat!(
|
|||
")"
|
||||
);
|
||||
|
||||
#[must_use]
|
||||
pub fn version() -> String {
|
||||
let author = clap::crate_authors!();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,23 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::{KeyEvent, MouseEvent};
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Rect, Size},
|
||||
Frame,
|
||||
};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use ratatui::{
|
||||
|
|
@ -31,7 +31,6 @@ pub struct Footer {
|
|||
}
|
||||
|
||||
impl Footer {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
text: String::from("(q) to quit"),
|
||||
|
|
@ -52,7 +51,6 @@ impl Component for Footer {
|
|||
}
|
||||
|
||||
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
||||
#[allow(clippy::single_match)]
|
||||
match action {
|
||||
Action::UpdateFooter(text) => self.text = text,
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,27 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use std::time::Instant;
|
||||
|
||||
use color_eyre::Result;
|
||||
use ratatui::{
|
||||
Frame,
|
||||
layout::{Constraint, Layout, Rect},
|
||||
style::{Style, Stylize},
|
||||
text::Span,
|
||||
widgets::Paragraph,
|
||||
Frame,
|
||||
};
|
||||
|
||||
use super::Component;
|
||||
|
|
@ -46,7 +46,6 @@ impl Default for FpsCounter {
|
|||
}
|
||||
|
||||
impl FpsCounter {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
last_tick_update: Instant::now(),
|
||||
|
|
@ -58,26 +57,24 @@ impl FpsCounter {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn app_tick(&mut self) -> Result<()> {
|
||||
self.tick_count += 1;
|
||||
let now = Instant::now();
|
||||
let elapsed = (now - self.last_tick_update).as_secs_f64();
|
||||
if elapsed >= 1.0 {
|
||||
self.ticks_per_second = f64::from(self.tick_count) / elapsed;
|
||||
self.ticks_per_second = self.tick_count as f64 / elapsed;
|
||||
self.last_tick_update = now;
|
||||
self.tick_count = 0;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn render_tick(&mut self) -> Result<()> {
|
||||
self.frame_count += 1;
|
||||
let now = Instant::now();
|
||||
let elapsed = (now - self.last_frame_update).as_secs_f64();
|
||||
if elapsed >= 1.0 {
|
||||
self.frames_per_second = f64::from(self.frame_count) / elapsed;
|
||||
self.frames_per_second = self.frame_count as f64 / elapsed;
|
||||
self.last_frame_update = now;
|
||||
self.frame_count = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::KeyEvent;
|
||||
|
|
@ -21,7 +21,7 @@ use ratatui::{
|
|||
};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
use super::{Component, state::StatefulList};
|
||||
use super::{state::StatefulList, Component};
|
||||
use crate::{action::Action, config::Config};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -37,7 +37,6 @@ pub struct Left {
|
|||
}
|
||||
|
||||
impl Left {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
select_num: 0,
|
||||
|
|
@ -139,9 +138,13 @@ impl Component for Left {
|
|||
.areas(area);
|
||||
|
||||
// Title
|
||||
let title = Paragraph::new(
|
||||
Line::from(Span::styled(self.title_text.as_str(), Style::default())).centered(),
|
||||
)
|
||||
let title_text = if self.selections[1].is_some() || self.select_num == 1 {
|
||||
"Confirm Selections"
|
||||
} else {
|
||||
self.title_text.as_str()
|
||||
};
|
||||
let title =
|
||||
Paragraph::new(Line::from(Span::styled(title_text, Style::default())).centered())
|
||||
.block(Block::default().borders(Borders::NONE));
|
||||
frame.render_widget(title, title_area);
|
||||
|
||||
|
|
@ -168,7 +171,7 @@ impl Component for Left {
|
|||
.map(|(index, item)| {
|
||||
let mut style = Style::default();
|
||||
let text = if self.selections[0].is_some_and(|first_index| first_index == index) {
|
||||
if let Some(label) = self.labels.first() {
|
||||
if let Some(label) = self.labels.get(0) {
|
||||
style = style.yellow();
|
||||
label.as_str()
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,19 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use rand::random;
|
||||
use ratatui::{
|
||||
prelude::*,
|
||||
widgets::{Block, Borders, Clear, Paragraph, Wrap},
|
||||
|
|
@ -43,7 +42,6 @@ pub struct Popup {
|
|||
}
|
||||
|
||||
impl Popup {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
|
@ -97,20 +95,3 @@ impl Component for Popup {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn fortune() -> String {
|
||||
String::from(match random::<u8>() / 4 {
|
||||
0 => "FUN FACT\n\n\nComputers barely work.",
|
||||
1 => "CRASH OVERRIDE\n\n\n\"Hack the planet!\"",
|
||||
2 => "CATS\n\n\n\"All your base are belong to us!\"",
|
||||
3 => "HMM\n\n\nThis has all happened before...\n\nThis will all happen again.",
|
||||
4 => "CYPHER\n\n\n\"I don’t even see the code. All I see is blonde, brunette, red-head.\"",
|
||||
5 => "CONGRATULATIONS\n\n\nYour did it!",
|
||||
6 => "DID YOU KNOW?\n\n\nmacOS includes a built-in screen reader!",
|
||||
7 => "TIP OF THE DAY\n\n\nNever go full Snappy!",
|
||||
8 => "WORDS OF WISDOM\n\n\n\nIt’s not DNS,\n\nThere’s no way it’s DNS,\n\nIt was DNS.",
|
||||
9 => "HAL 9000\n\n\n\"I'm sorry Dave, I'm afraid I can't do that.\"",
|
||||
_ => "COMPLETE\n\n\nThank you for using this tool!",
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use crossterm::event::KeyEvent;
|
||||
|
|
@ -21,7 +21,7 @@ use ratatui::{
|
|||
};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
use super::{Component, state::StatefulList};
|
||||
use super::{state::StatefulList, Component};
|
||||
use crate::{action::Action, config::Config, line::DVLine};
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
@ -37,7 +37,6 @@ pub struct Right {
|
|||
}
|
||||
|
||||
impl Right {
|
||||
#[must_use]
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
selections: vec![None, None],
|
||||
|
|
@ -151,7 +150,7 @@ impl Component for Right {
|
|||
// First selection
|
||||
if let Some(first_index) = self.get_first() {
|
||||
if let Some(first_desc) = self.list.get(first_index) {
|
||||
if let Some(label) = self.list_labels.first() {
|
||||
if let Some(label) = self.list_labels.get(0) {
|
||||
label
|
||||
.iter()
|
||||
.for_each(|dv| body_text.push(dv.as_line().bold()));
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
|
@ -31,17 +31,14 @@ impl<T: Clone> StatefulList<T> {
|
|||
self.items.clear();
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get(&self, index: usize) -> Option<&T> {
|
||||
self.items.get(index)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_selected(&self) -> Option<T> {
|
||||
self.state.selected().map(|i| self.items[i].clone())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.items.is_empty()
|
||||
}
|
||||
|
|
@ -54,12 +51,11 @@ impl<T: Clone> StatefulList<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn selected(&self) -> Option<usize> {
|
||||
self.state.selected()
|
||||
}
|
||||
|
||||
pub fn select_first_item(&mut self) {
|
||||
fn select_first_item(&mut self) {
|
||||
if self.items.is_empty() {
|
||||
self.state.select(None);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use ratatui::{
|
||||
|
|
@ -31,7 +31,6 @@ pub struct Title {
|
|||
}
|
||||
|
||||
impl Title {
|
||||
#[must_use]
|
||||
pub fn new(text: &str) -> Self {
|
||||
Self {
|
||||
text: String::from(text),
|
||||
|
|
@ -52,7 +51,6 @@ impl Component for Title {
|
|||
}
|
||||
|
||||
fn update(&mut self, action: Action) -> Result<Option<Action>> {
|
||||
#[allow(clippy::match_single_binding)]
|
||||
match action {
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,18 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::missing_panics_doc)]
|
||||
#![allow(clippy::ref_option)]
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#![allow(dead_code)] // Remove this once you start using the code
|
||||
|
||||
use std::{collections::HashMap, env, path::PathBuf};
|
||||
|
|
@ -25,7 +23,7 @@ use derive_deref::{Deref, DerefMut};
|
|||
use directories::ProjectDirs;
|
||||
use lazy_static::lazy_static;
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use serde::{Deserialize, de::Deserializer};
|
||||
use serde::{de::Deserializer, Deserialize};
|
||||
use tracing::error;
|
||||
|
||||
use crate::{action::Action, state::Mode};
|
||||
|
|
@ -56,15 +54,15 @@ pub struct Config {
|
|||
pub styles: Styles,
|
||||
}
|
||||
|
||||
pub static PROJECT_NAME: &str = "DEJA-VU";
|
||||
pub static PROJECT_NAME: &'static str = "DEJA-VU";
|
||||
lazy_static! {
|
||||
//pub static ref PROJECT_NAME: String = env!("CARGO_PKG_NAME").to_uppercase().to_string();
|
||||
pub static ref DATA_FOLDER: Option<PathBuf> =
|
||||
env::var(format!("{PROJECT_NAME}_DATA"))
|
||||
env::var(format!("{}_DATA", PROJECT_NAME))
|
||||
.ok()
|
||||
.map(PathBuf::from);
|
||||
pub static ref CONFIG_FOLDER: Option<PathBuf> =
|
||||
env::var(format!("{PROJECT_NAME}_CONFIG"))
|
||||
env::var(format!("{}_CONFIG", PROJECT_NAME))
|
||||
.ok()
|
||||
.map(PathBuf::from);
|
||||
}
|
||||
|
|
@ -128,7 +126,6 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_data_dir() -> PathBuf {
|
||||
let directory = if let Some(s) = DATA_FOLDER.clone() {
|
||||
s
|
||||
|
|
@ -140,7 +137,6 @@ pub fn get_data_dir() -> PathBuf {
|
|||
directory
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_config_dir() -> PathBuf {
|
||||
let directory = if let Some(s) = CONFIG_FOLDER.clone() {
|
||||
s
|
||||
|
|
@ -153,8 +149,8 @@ pub fn get_config_dir() -> PathBuf {
|
|||
}
|
||||
|
||||
fn project_directory() -> Option<ProjectDirs> {
|
||||
ProjectDirs::from("com", "Deja-Vu", "deja-vu")
|
||||
//ProjectDirs::from("com", "Deja-Vu", env!("CARGO_PKG_NAME"))
|
||||
ProjectDirs::from("com", "Deja-vu", "deja-vu")
|
||||
//ProjectDirs::from("com", "Deja-vu", env!("CARGO_PKG_NAME"))
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deref, DerefMut)]
|
||||
|
|
@ -262,7 +258,6 @@ fn parse_key_code_with_modifiers(
|
|||
Ok(KeyEvent::new(c, modifiers))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn key_event_to_string(key_event: &KeyEvent) -> String {
|
||||
let char;
|
||||
let key_code = match key_event.code {
|
||||
|
|
@ -378,7 +373,6 @@ impl<'de> Deserialize<'de> for Styles {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn parse_style(line: &str) -> Style {
|
||||
let (foreground, background) =
|
||||
line.split_at(line.to_lowercase().find("on ").unwrap_or(line.len()));
|
||||
|
|
@ -441,11 +435,8 @@ fn parse_color(s: &str) -> Option<Color> {
|
|||
.unwrap_or_default();
|
||||
Some(Color::Indexed(c))
|
||||
} else if s.contains("rgb") {
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let red = (s.as_bytes()[3] as char).to_digit(10).unwrap_or_default() as u8;
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let green = (s.as_bytes()[4] as char).to_digit(10).unwrap_or_default() as u8;
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
let blue = (s.as_bytes()[5] as char).to_digit(10).unwrap_or_default() as u8;
|
||||
let c = 16 + red * 36 + green * 6 + blue;
|
||||
Some(Color::Indexed(c))
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use std::env;
|
||||
|
||||
use color_eyre::Result;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
pub mod action;
|
||||
pub mod cli;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use ratatui::{
|
||||
style::{Color, Style},
|
||||
|
|
@ -30,7 +30,6 @@ pub struct DVLine {
|
|||
|
||||
impl DVLine {
|
||||
/// Convert to Line with colored span(s)
|
||||
#[must_use]
|
||||
pub fn as_line(&self) -> Line {
|
||||
let mut spans = Vec::new();
|
||||
zip(self.line_parts.clone(), self.line_colors.clone())
|
||||
|
|
@ -38,7 +37,6 @@ impl DVLine {
|
|||
Line::from(spans)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn blank() -> Self {
|
||||
Self {
|
||||
line_parts: vec![String::new()],
|
||||
|
|
@ -47,11 +45,7 @@ impl DVLine {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_disk_description_right(
|
||||
disk: &Disk,
|
||||
boot_os_indicies: &Option<Vec<usize>>,
|
||||
) -> Vec<DVLine> {
|
||||
pub fn get_disk_description_right(disk: &Disk) -> Vec<DVLine> {
|
||||
let mut description: Vec<DVLine> = vec![
|
||||
DVLine {
|
||||
line_parts: vec![format!(
|
||||
|
|
@ -73,33 +67,15 @@ pub fn get_disk_description_right(
|
|||
line_colors: vec![Color::Blue],
|
||||
},
|
||||
];
|
||||
disk.parts_description
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(index, line)| {
|
||||
let mut line_parts = vec![line.clone()];
|
||||
let mut line_colors = vec![Color::Reset];
|
||||
if let Some(indicies) = boot_os_indicies {
|
||||
let boot_index = indicies.first();
|
||||
if boot_index.is_some_and(|i| i == &index) {
|
||||
line_parts.push(String::from(" <-- Boot Partition"));
|
||||
line_colors.push(Color::Cyan);
|
||||
}
|
||||
let boot_index = indicies.get(1);
|
||||
if boot_index.is_some_and(|i| i == &index) {
|
||||
line_parts.push(String::from(" <-- OS Partition"));
|
||||
line_colors.push(Color::Cyan);
|
||||
}
|
||||
}
|
||||
for line in &disk.parts_description {
|
||||
description.push(DVLine {
|
||||
line_parts,
|
||||
line_colors,
|
||||
});
|
||||
line_parts: vec![line.clone()],
|
||||
line_colors: vec![Color::Reset],
|
||||
});
|
||||
}
|
||||
description
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_part_description(part: &Partition) -> Vec<DVLine> {
|
||||
let description: Vec<DVLine> = vec![
|
||||
DVLine {
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use color_eyre::Result;
|
||||
use tracing_error::ErrorLayer;
|
||||
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
|
||||
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
||||
|
||||
use crate::config;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
|
@ -30,13 +30,6 @@ pub enum Mode {
|
|||
Home,
|
||||
Done,
|
||||
Failed,
|
||||
// Boot Diags
|
||||
DiagMenu,
|
||||
BootDiags,
|
||||
BootScan,
|
||||
BootSetup,
|
||||
InjectDrivers,
|
||||
SetBootMode,
|
||||
// Clone
|
||||
ScanDisks,
|
||||
InstallDrivers,
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
pub mod boot;
|
||||
pub mod cpu;
|
||||
|
|
|
|||
|
|
@ -1,43 +1,33 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::missing_panics_doc)]
|
||||
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use super::{disk::PartitionTableType, drivers::Driver};
|
||||
use crate::tasks::TaskType;
|
||||
use crate::tasks::Task;
|
||||
use color_eyre::Result;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub enum SafeMode {
|
||||
#[default]
|
||||
Disable,
|
||||
Enable,
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn configure_disk(
|
||||
letter_boot: &str,
|
||||
letter_os: &str,
|
||||
system32: &str,
|
||||
table_type: &PartitionTableType,
|
||||
) -> Vec<TaskType> {
|
||||
table_type: PartitionTableType,
|
||||
) -> Vec<Task> {
|
||||
let mut tasks = Vec::new();
|
||||
|
||||
// Create
|
||||
tasks.push(TaskType::CommandWait(
|
||||
tasks.push(Task::Command(
|
||||
PathBuf::from(format!("{system32}/bcdboot.exe")),
|
||||
vec![
|
||||
format!("{letter_os}:\\Windows"),
|
||||
|
|
@ -52,8 +42,8 @@ pub fn configure_disk(
|
|||
));
|
||||
|
||||
// Update boot sector (for legacy setups)
|
||||
if *table_type == PartitionTableType::Legacy {
|
||||
tasks.push(TaskType::CommandWait(
|
||||
if table_type == PartitionTableType::Legacy {
|
||||
tasks.push(Task::Command(
|
||||
PathBuf::from(format!("{system32}/bootsect.exe")),
|
||||
vec![
|
||||
String::from("/nt60"),
|
||||
|
|
@ -65,19 +55,34 @@ pub fn configure_disk(
|
|||
}
|
||||
|
||||
// Lock in safe mode
|
||||
tasks.push(
|
||||
set_mode(letter_boot, &SafeMode::Enable, system32, table_type)
|
||||
.expect("Failed to create set_mode task."),
|
||||
);
|
||||
let bcd_path = match table_type {
|
||||
PartitionTableType::Guid => {
|
||||
format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD")
|
||||
}
|
||||
PartitionTableType::Legacy => {
|
||||
format!("{letter_boot}:\\Boot\\BCD")
|
||||
}
|
||||
};
|
||||
tasks.push(Task::Command(
|
||||
PathBuf::from(format!("{system32}/bcdedit.exe")),
|
||||
vec![
|
||||
String::from("/store"),
|
||||
bcd_path,
|
||||
String::from("/set"),
|
||||
String::from("{default}"),
|
||||
String::from("safeboot"),
|
||||
String::from("minimal"),
|
||||
],
|
||||
));
|
||||
|
||||
// Done
|
||||
tasks
|
||||
}
|
||||
|
||||
pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result<TaskType> {
|
||||
pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result<Task> {
|
||||
//if let Some(driver_path_str) = driver.path.to_str() {
|
||||
let driver_path = driver.path.to_str().unwrap();
|
||||
Ok(TaskType::CommandWait(
|
||||
Ok(Task::Command(
|
||||
PathBuf::from(format!("{system32}/dism.exe")),
|
||||
vec![
|
||||
format!("/image:{letter_os}:\\"),
|
||||
|
|
@ -87,39 +92,3 @@ pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result
|
|||
],
|
||||
))
|
||||
}
|
||||
|
||||
pub fn set_mode(
|
||||
letter_boot: &str,
|
||||
mode: &SafeMode,
|
||||
system32: &str,
|
||||
table_type: &PartitionTableType,
|
||||
) -> Result<TaskType> {
|
||||
let bcd_path = match table_type {
|
||||
PartitionTableType::Guid => {
|
||||
format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD")
|
||||
}
|
||||
PartitionTableType::Legacy => {
|
||||
format!("{letter_boot}:\\Boot\\BCD")
|
||||
}
|
||||
};
|
||||
|
||||
// Build CommandWait
|
||||
let mut cmd_args = vec![String::from("/store"), bcd_path];
|
||||
match mode {
|
||||
SafeMode::Disable => {
|
||||
cmd_args.push(String::from("/deletevalue"));
|
||||
cmd_args.push(String::from("{default}"));
|
||||
cmd_args.push(String::from("safeboot"));
|
||||
}
|
||||
SafeMode::Enable => {
|
||||
cmd_args.push(String::from("/set"));
|
||||
cmd_args.push(String::from("{default}"));
|
||||
cmd_args.push(String::from("safeboot"));
|
||||
cmd_args.push(String::from("minimal"));
|
||||
}
|
||||
}
|
||||
Ok(TaskType::CommandWait(
|
||||
PathBuf::from(format!("{system32}/bcdedit.exe")),
|
||||
cmd_args,
|
||||
))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#[must_use]
|
||||
pub fn get_cpu_name() -> String {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
|
|
@ -67,7 +67,6 @@ impl Disk {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_part_letter(&self, part_index: usize) -> String {
|
||||
// Used to get Boot and OS letters
|
||||
if let Some(part) = self.parts.get(part_index) {
|
||||
|
|
@ -77,12 +76,10 @@ impl Disk {
|
|||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_parts(&self) -> Vec<Partition> {
|
||||
self.parts.clone()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn num_parts(&self) -> usize {
|
||||
self.parts.len()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,18 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_panics_doc)]
|
||||
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs::File,
|
||||
|
|
@ -27,7 +26,7 @@ use tempfile::tempdir;
|
|||
use tracing::{info, warn};
|
||||
|
||||
use crate::system::disk::{
|
||||
Disk, Partition, PartitionTableType, get_disk_serial_number, string_to_bytes,
|
||||
get_disk_serial_number, string_to_bytes, Disk, Partition, PartitionTableType,
|
||||
};
|
||||
|
||||
static DEFAULT_MAX_DISKS: usize = 8;
|
||||
|
|
@ -130,7 +129,7 @@ pub fn get_partition_details(
|
|||
#[must_use]
|
||||
pub fn build_dest_format_script(disk_id: usize, part_type: &PartitionTableType) -> String {
|
||||
let disk_id = format!("{disk_id}");
|
||||
let mut script = vec!["automount enable noerr", "select disk {disk_id}", "clean"];
|
||||
let mut script = vec!["select disk {disk_id}", "clean"];
|
||||
match part_type {
|
||||
PartitionTableType::Guid => {
|
||||
script.push("convert gpt");
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use std::{env, fmt, fs::read_dir, path::PathBuf, process::Command};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,25 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
#![allow(clippy::missing_panics_doc)]
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fmt,
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
sync::{Arc, Mutex},
|
||||
thread::{self, JoinHandle, sleep},
|
||||
thread::{self, sleep, JoinHandle},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
|
|
@ -36,15 +34,8 @@ use crate::{
|
|||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TaskResult {
|
||||
Error(String),
|
||||
Output(String, String, bool), // stdout, stderr, success
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TaskType {
|
||||
CommandNoWait(PathBuf, Vec<String>), // (command, args)
|
||||
CommandWait(PathBuf, Vec<String>), // (command, args)
|
||||
pub enum Task {
|
||||
Command(PathBuf, Vec<String>), // (command, args)
|
||||
Diskpart(String), // (script_as_string)
|
||||
ScanDisks,
|
||||
Sleep,
|
||||
|
|
@ -52,54 +43,14 @@ pub enum TaskType {
|
|||
UpdateDiskList,
|
||||
}
|
||||
|
||||
impl fmt::Display for TaskType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
TaskType::CommandNoWait(cmd_path, _) | TaskType::CommandWait(cmd_path, _) => {
|
||||
write!(
|
||||
f,
|
||||
"Command(\"{}\")",
|
||||
cmd_path.file_name().unwrap().to_string_lossy()
|
||||
)
|
||||
}
|
||||
TaskType::Diskpart(_) => {
|
||||
write!(f, "Diskpart")
|
||||
}
|
||||
TaskType::ScanDisks => write!(f, "ScanDisks"),
|
||||
TaskType::Sleep => write!(f, "Sleep"),
|
||||
TaskType::UpdateDestDisk(_) => write!(f, "UpdateDestDisk"),
|
||||
TaskType::UpdateDiskList => write!(f, "UpdateDiskList"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Task {
|
||||
pub handle: Option<JoinHandle<()>>,
|
||||
pub result: Option<TaskResult>,
|
||||
pub task_type: TaskType,
|
||||
}
|
||||
|
||||
impl Task {
|
||||
#[must_use]
|
||||
pub fn new(task_type: TaskType) -> Task {
|
||||
Task {
|
||||
handle: None,
|
||||
result: None,
|
||||
task_type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Tasks {
|
||||
action_tx: mpsc::UnboundedSender<Action>,
|
||||
disk_list: Arc<Mutex<Vec<disk::Disk>>>,
|
||||
cur_handle: Option<JoinHandle<()>>,
|
||||
cur_task: Option<Task>,
|
||||
handle: Option<JoinHandle<()>>,
|
||||
task_list: VecDeque<Task>,
|
||||
task_rx: mpsc::UnboundedReceiver<TaskResult>,
|
||||
task_tx: mpsc::UnboundedSender<TaskResult>,
|
||||
task_rx: mpsc::UnboundedReceiver<Action>, // Used to forward Actions from Tasks to App
|
||||
task_tx: mpsc::UnboundedSender<Action>, // Used to forward Actions from Tasks to App
|
||||
}
|
||||
|
||||
impl Tasks {
|
||||
|
|
@ -111,186 +62,159 @@ impl Tasks {
|
|||
Tasks {
|
||||
action_tx,
|
||||
disk_list: disk_list_arc,
|
||||
cur_handle: None,
|
||||
cur_task: None,
|
||||
handle: None,
|
||||
task_list: VecDeque::new(),
|
||||
task_rx,
|
||||
task_tx,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, task_type: TaskType) {
|
||||
info!("Adding task: {:?}", &task_type);
|
||||
self.task_list.push_back(Task::new(task_type));
|
||||
pub fn add(&mut self, task: Task) {
|
||||
info!("Adding task: {:?}", &task);
|
||||
self.task_list.push_back(task);
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn idle(&self) -> bool {
|
||||
self.cur_handle.is_none()
|
||||
self.handle.is_none()
|
||||
}
|
||||
|
||||
pub fn poll(&mut self) -> Result<Option<Task>> {
|
||||
let mut return_task: Option<Task> = None;
|
||||
// Handle task channel item(s)
|
||||
if let Ok(result) = self.task_rx.try_recv() {
|
||||
if let Some(mut task) = self.cur_task.take() {
|
||||
task.result.replace(result);
|
||||
self.cur_task.replace(task);
|
||||
}
|
||||
pub fn poll(&mut self) -> Result<()> {
|
||||
// Forward any actions to main app
|
||||
if let Ok(action) = self.task_rx.try_recv() {
|
||||
let result = self.action_tx.send(action.clone());
|
||||
assert!(result.is_ok(), "Failed to send Action: {action:?}");
|
||||
}
|
||||
|
||||
// Check status of current task (if one is running).
|
||||
// NOTE: Action::TasksComplete is sent once all tasks are complete
|
||||
if let Some(task_handle) = self.cur_handle.take() {
|
||||
if task_handle.is_finished() {
|
||||
// Need to return task with handle
|
||||
if let Some(mut cur_task) = self.cur_task.take() {
|
||||
cur_task.handle = Some(task_handle);
|
||||
return_task = Some(cur_task);
|
||||
}
|
||||
// NOTE: Action::NextScreen is sent once all tasks are complete
|
||||
if let Some(handle) = self.handle.take() {
|
||||
if handle.is_finished() {
|
||||
if self.task_list.is_empty() {
|
||||
// No tasks remain
|
||||
self.action_tx.send(Action::TasksComplete)?;
|
||||
self.task_tx.send(Action::NextScreen)?;
|
||||
} else {
|
||||
// Start next task
|
||||
self.start()?;
|
||||
}
|
||||
} else {
|
||||
// TaskType not complete, return handle
|
||||
self.cur_handle.replace(task_handle);
|
||||
// Task not complete, return handle
|
||||
self.handle = Some(handle);
|
||||
}
|
||||
} else if !self.task_list.is_empty() {
|
||||
// No current task but one is available
|
||||
self.start()?;
|
||||
}
|
||||
Ok(return_task)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn start(&mut self) -> Result<()> {
|
||||
self.cur_task = self.task_list.pop_front();
|
||||
if let Some(task) = self.cur_task.take() {
|
||||
if let Some(task) = self.task_list.pop_front() {
|
||||
let task_str = format!("{task:?}");
|
||||
let task_tx = self.task_tx.clone();
|
||||
match task.task_type {
|
||||
TaskType::CommandNoWait(ref cmd_path, ref cmd_args) => {
|
||||
self.cur_handle = None;
|
||||
run_task_command(cmd_path.clone(), cmd_args.clone(), task_tx);
|
||||
match task {
|
||||
Task::Command(ref cmd_path, ref cmd_args) => {
|
||||
let cmd_path = cmd_path.clone();
|
||||
let cmd_args = cmd_args.clone();
|
||||
if cfg!(windows) {
|
||||
self.handle = Some(thread::spawn(move || {
|
||||
let result = Command::new(cmd_path)
|
||||
.args(cmd_args)
|
||||
.stdout(Stdio::piped())
|
||||
.output();
|
||||
if let Some(action) = match result {
|
||||
Ok(output) => {
|
||||
if output.status.success() {
|
||||
None
|
||||
} else {
|
||||
// Command returned an error status
|
||||
let mut msg = String::new();
|
||||
if let Ok(stdout) = String::from_utf8(output.stdout) {
|
||||
msg = String::from(stdout.trim());
|
||||
}
|
||||
TaskType::CommandWait(ref cmd_path, ref cmd_args) => {
|
||||
self.cur_handle = Some(run_task_command(
|
||||
cmd_path.clone(),
|
||||
cmd_args.clone(),
|
||||
task_tx,
|
||||
));
|
||||
if msg.is_empty() {
|
||||
msg = String::from("Generic error");
|
||||
}
|
||||
TaskType::Diskpart(ref script) => {
|
||||
self.cur_handle = Some(run_task_diskpart(script, task_tx));
|
||||
Some(Action::Error(format!("Command failed: {msg}",)))
|
||||
}
|
||||
TaskType::ScanDisks => {
|
||||
}
|
||||
Err(err) => {
|
||||
Some(Action::Error(format!("Failed to run command: {err:?}")))
|
||||
}
|
||||
} {
|
||||
let msg = format!("{:?}", &action);
|
||||
let result = task_tx.send(action);
|
||||
assert!(result.is_ok(), "Failed to send Action: {msg}");
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
// Simulate task if not running under Windows
|
||||
self.handle = Some(thread::spawn(|| sleep(Duration::from_millis(250))));
|
||||
}
|
||||
}
|
||||
Task::Diskpart(ref script) => {
|
||||
if cfg!(windows) {
|
||||
let script = String::from(script);
|
||||
self.handle = Some(thread::spawn(move || {
|
||||
let output = diskpart::run_script_raw(script.as_str());
|
||||
if !output.status.success()
|
||||
&& task_tx
|
||||
.send(Action::Error(String::from(
|
||||
"Diskpart script returned an error",
|
||||
)))
|
||||
.is_err()
|
||||
{
|
||||
panic!("Failed to send Action: {task_str:?}");
|
||||
}
|
||||
}));
|
||||
} else {
|
||||
// Simulate task if not running under Windows
|
||||
self.handle = Some(thread::spawn(|| sleep(Duration::from_millis(250))));
|
||||
}
|
||||
}
|
||||
Task::ScanDisks => {
|
||||
let disk_list_arc = self.disk_list.clone();
|
||||
|
||||
// Queue UpdateDiskList for various components
|
||||
self.add(TaskType::UpdateDiskList);
|
||||
self.add(Task::UpdateDiskList);
|
||||
|
||||
self.cur_handle = Some(thread::spawn(move || {
|
||||
self.handle = Some(thread::spawn(move || {
|
||||
let mut disks = disk_list_arc.lock().unwrap();
|
||||
*disks = disk::get_disks();
|
||||
}));
|
||||
}
|
||||
TaskType::Sleep => {
|
||||
self.cur_handle = Some(thread::spawn(|| sleep(Duration::from_millis(250))));
|
||||
Task::Sleep => {
|
||||
self.handle = Some(thread::spawn(|| sleep(Duration::from_millis(250))));
|
||||
}
|
||||
TaskType::UpdateDestDisk(index) => {
|
||||
Task::UpdateDestDisk(index) => {
|
||||
self.action_tx.send(Action::DisplayPopup(
|
||||
popup::Type::Info,
|
||||
String::from("Refreshing disk info"),
|
||||
))?;
|
||||
|
||||
// Queue UpdateDiskList for various components
|
||||
self.add(TaskType::Sleep);
|
||||
self.add(TaskType::UpdateDiskList);
|
||||
self.add(Task::Sleep);
|
||||
self.add(Task::UpdateDiskList);
|
||||
|
||||
// Update destination disk ~in-place
|
||||
let disk_list_arc = self.disk_list.clone();
|
||||
self.cur_handle = Some(thread::spawn(move || {
|
||||
self.handle = Some(thread::spawn(move || {
|
||||
let mut disks = disk_list_arc.lock().unwrap();
|
||||
let old_disk = &mut disks[index];
|
||||
disks[index] = disk::refresh_disk_info(old_disk);
|
||||
}));
|
||||
}
|
||||
TaskType::UpdateDiskList => {
|
||||
Task::UpdateDiskList => {
|
||||
let disks = self.disk_list.lock().unwrap();
|
||||
let disks_copy = disks.clone();
|
||||
let action_tx = self.action_tx.clone();
|
||||
self.cur_handle = Some(thread::spawn(move || {
|
||||
self.handle = Some(thread::spawn(move || {
|
||||
if let Err(err) = action_tx.send(Action::UpdateDiskList(disks_copy)) {
|
||||
panic!("Failed to send Action: {err:?}");
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
// Done
|
||||
self.cur_task.replace(task);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_bytes_as_str(bytes: Vec<u8>) -> String {
|
||||
match String::from_utf8(bytes) {
|
||||
Ok(s) => s.trim().to_string(),
|
||||
Err(_) => String::from("Failed to parse bytes as UTF-8 text"),
|
||||
}
|
||||
}
|
||||
|
||||
fn run_task_command(
|
||||
cmd_path: PathBuf,
|
||||
cmd_args: Vec<String>,
|
||||
task_tx: mpsc::UnboundedSender<TaskResult>,
|
||||
) -> JoinHandle<()> {
|
||||
if cfg!(windows) {
|
||||
thread::spawn(move || {
|
||||
let result = Command::new(cmd_path)
|
||||
.args(cmd_args)
|
||||
.stdout(Stdio::piped())
|
||||
.output();
|
||||
match result {
|
||||
Err(e) => {
|
||||
task_tx
|
||||
.send(TaskResult::Error(format!("{:?}", &e)))
|
||||
.expect("Failed to propegate error?");
|
||||
}
|
||||
Ok(output) => {
|
||||
let stderr = parse_bytes_as_str(output.stderr.clone());
|
||||
let stdout = parse_bytes_as_str(output.stdout.clone());
|
||||
let task_result = TaskResult::Output(stdout, stderr, output.status.success());
|
||||
let err_str = format!("Failed to send TaskResult: {:?}", &task_result);
|
||||
task_tx
|
||||
.send(task_result)
|
||||
.unwrap_or_else(|_| panic!("{}", err_str));
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// Simulate task if not running under Windows
|
||||
thread::spawn(|| sleep(Duration::from_millis(250)))
|
||||
}
|
||||
}
|
||||
|
||||
fn run_task_diskpart(script: &str, task_tx: mpsc::UnboundedSender<TaskResult>) -> JoinHandle<()> {
|
||||
if cfg!(windows) {
|
||||
let script = script.to_owned();
|
||||
thread::spawn(move || {
|
||||
let output = diskpart::run_script_raw(&script);
|
||||
let stderr = parse_bytes_as_str(output.stderr.clone());
|
||||
let stdout = parse_bytes_as_str(output.stdout.clone());
|
||||
let task_result = TaskResult::Output(stdout, stderr, output.status.success());
|
||||
let err_str = format!("Failed to send TaskResult: {:?}", &task_result);
|
||||
task_tx
|
||||
.send(task_result)
|
||||
.unwrap_or_else(|_| panic!("{}", err_str));
|
||||
})
|
||||
} else {
|
||||
// Simulate task if not running under Windows
|
||||
thread::spawn(|| sleep(Duration::from_millis(250)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
pub mod sample_output;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#[allow(dead_code)]
|
||||
pub static DETAIL_DISK_GPT: &str = "Disk 2 is now the selected disk.
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
#![allow(clippy::missing_errors_doc)]
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
#![allow(dead_code)] // Remove this once you start using the code
|
||||
|
||||
use std::{
|
||||
io::{Stdout, stdout},
|
||||
io::{stdout, Stdout},
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
|
|
@ -85,25 +85,21 @@ impl Tui {
|
|||
})
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn tick_rate(mut self, tick_rate: f64) -> Self {
|
||||
self.tick_rate = tick_rate;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn frame_rate(mut self, frame_rate: f64) -> Self {
|
||||
self.frame_rate = frame_rate;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn mouse(mut self, mouse: bool) -> Self {
|
||||
self.mouse = mouse;
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn paste(mut self, paste: bool) -> Self {
|
||||
self.paste = paste;
|
||||
self
|
||||
|
|
@ -139,7 +135,7 @@ impl Tui {
|
|||
.expect("failed to send init event");
|
||||
loop {
|
||||
let event = tokio::select! {
|
||||
() = cancellation_token.cancelled() => {
|
||||
_ = cancellation_token.cancelled() => {
|
||||
break;
|
||||
}
|
||||
_ = tick_interval.tick() => Event::Tick,
|
||||
|
|
@ -152,7 +148,7 @@ impl Tui {
|
|||
CrosstermEvent::FocusLost => Event::FocusLost,
|
||||
CrosstermEvent::FocusGained => Event::FocusGained,
|
||||
CrosstermEvent::Paste(s) => Event::Paste(s),
|
||||
CrosstermEvent::Key(_) => continue, // ignore other events
|
||||
_ => continue, // ignore other events
|
||||
}
|
||||
Some(Err(_)) => Event::Error,
|
||||
None => break, // the event stream has stopped and will not produce any more events
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
# This file is part of Deja-Vu.
|
||||
# This file is part of Deja-vu.
|
||||
#
|
||||
# Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
# Deja-vu is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Deja-Vu is distributed in the hope that it will be useful, but
|
||||
# Deja-vu is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[package]
|
||||
name = "deja-vu"
|
||||
authors = ["2Shirt <2xShirt@gmail.com>"]
|
||||
edition = "2024"
|
||||
edition = "2021"
|
||||
license = "GPL"
|
||||
version = "0.2.0"
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ tokio-util = "0.7.11"
|
|||
tracing = "0.1.41"
|
||||
tracing-error = "0.2.0"
|
||||
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
|
||||
check_elevation = "0.2.4"
|
||||
rand = "0.8.5"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0.86"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use anyhow::Result;
|
||||
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
||||
|
|
|
|||
|
|
@ -1,42 +1,42 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use core::{
|
||||
action::Action,
|
||||
components::{
|
||||
Component, footer::Footer, fps::FpsCounter, left::Left, popup, right::Right,
|
||||
state::StatefulList, title::Title,
|
||||
footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, state::StatefulList,
|
||||
title::Title, Component,
|
||||
},
|
||||
config::Config,
|
||||
line::{DVLine, get_disk_description_right, get_part_description},
|
||||
line::{get_disk_description_right, get_part_description, DVLine},
|
||||
state::{CloneSettings, Mode},
|
||||
system::{
|
||||
boot, cpu::get_cpu_name, disk::PartitionTableType, diskpart::build_dest_format_script,
|
||||
drivers,
|
||||
},
|
||||
tasks::{Task, TaskResult, TaskType, Tasks},
|
||||
tasks::{Task, Tasks},
|
||||
tui::{Event, Tui},
|
||||
};
|
||||
use std::{
|
||||
env,
|
||||
iter::zip,
|
||||
path::PathBuf,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use color_eyre::Result;
|
||||
use rand::random;
|
||||
use ratatui::{
|
||||
crossterm::event::KeyEvent,
|
||||
layout::{Constraint, Direction, Layout},
|
||||
|
|
@ -100,7 +100,7 @@ impl App {
|
|||
}
|
||||
|
||||
pub fn prev_mode(&mut self) -> Option<Mode> {
|
||||
match self.cur_mode {
|
||||
let new_mode = match self.cur_mode {
|
||||
Mode::Home => Some(Mode::Home),
|
||||
Mode::Failed => Some(Mode::Failed),
|
||||
Mode::Done => Some(Mode::Done),
|
||||
|
|
@ -115,19 +115,15 @@ impl App {
|
|||
| Mode::Clone
|
||||
| Mode::PostClone => None,
|
||||
// Invalid states
|
||||
Mode::BootDiags
|
||||
| Mode::BootScan
|
||||
| Mode::BootSetup
|
||||
| Mode::DiagMenu
|
||||
| Mode::InjectDrivers
|
||||
| Mode::PEMenu
|
||||
| Mode::SetBootMode => panic!("This shouldn't happen?"),
|
||||
}
|
||||
Mode::PEMenu => panic!("This shouldn't happen?"),
|
||||
};
|
||||
new_mode
|
||||
}
|
||||
|
||||
pub fn next_mode(&mut self) -> Option<Mode> {
|
||||
let new_mode = match self.cur_mode {
|
||||
Mode::Home | Mode::InstallDrivers => Mode::ScanDisks,
|
||||
Mode::Home => Mode::ScanDisks,
|
||||
Mode::InstallDrivers => Mode::ScanDisks,
|
||||
Mode::ScanDisks => Mode::SelectDisks,
|
||||
Mode::SelectDisks => Mode::SelectTableType,
|
||||
Mode::SelectTableType => Mode::Confirm,
|
||||
|
|
@ -138,13 +134,7 @@ impl App {
|
|||
Mode::PostClone | Mode::Done => Mode::Done,
|
||||
Mode::Failed => Mode::Failed,
|
||||
// Invalid states
|
||||
Mode::BootDiags
|
||||
| Mode::BootScan
|
||||
| Mode::BootSetup
|
||||
| Mode::DiagMenu
|
||||
| Mode::InjectDrivers
|
||||
| Mode::PEMenu
|
||||
| Mode::SetBootMode => panic!("This shouldn't happen?"),
|
||||
Mode::PEMenu => panic!("This shouldn't happen?"),
|
||||
};
|
||||
|
||||
if new_mode == self.cur_mode {
|
||||
|
|
@ -163,7 +153,7 @@ impl App {
|
|||
Mode::ScanDisks => {
|
||||
self.prev_mode = self.cur_mode;
|
||||
if self.tasks.idle() {
|
||||
self.tasks.add(TaskType::ScanDisks);
|
||||
self.tasks.add(Task::ScanDisks);
|
||||
}
|
||||
self.action_tx.send(Action::DisplayPopup(
|
||||
popup::Type::Info,
|
||||
|
|
@ -176,22 +166,13 @@ impl App {
|
|||
String::from("Formatting destination disk"),
|
||||
))?;
|
||||
|
||||
// Get System32 path
|
||||
let system32 = get_system32_path(&self.action_tx);
|
||||
|
||||
// (Re)Enable volume mounting
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
PathBuf::from(format!("{system32}/mountvol.exe")),
|
||||
vec![String::from("/e")],
|
||||
));
|
||||
|
||||
// Build Diskpart script to format destination disk
|
||||
let disk_list = self.clone.disk_list.lock().unwrap();
|
||||
if let Some(disk_index) = self.clone.disk_index_dest {
|
||||
if let Some(disk) = disk_list.get(disk_index) {
|
||||
let table_type = self.clone.table_type.clone().unwrap();
|
||||
let diskpart_script = build_dest_format_script(disk.id, &table_type);
|
||||
self.tasks.add(TaskType::Diskpart(diskpart_script));
|
||||
self.tasks.add(Task::Diskpart(diskpart_script));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -200,12 +181,12 @@ impl App {
|
|||
popup::Type::Info,
|
||||
String::from("Running Clone Tool"),
|
||||
))?;
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
self.tasks.add(Task::Command(
|
||||
self.config.clone_app_path.clone(),
|
||||
Vec::new(),
|
||||
));
|
||||
if let Some(dest_index) = self.clone.disk_index_dest {
|
||||
self.tasks.add(TaskType::UpdateDestDisk(dest_index));
|
||||
self.tasks.add(Task::UpdateDestDisk(dest_index));
|
||||
}
|
||||
}
|
||||
Mode::PostClone => {
|
||||
|
|
@ -215,7 +196,18 @@ impl App {
|
|||
))?;
|
||||
|
||||
// Get System32 path
|
||||
let system32 = get_system32_path(&self.action_tx);
|
||||
let system32 = if cfg!(windows) {
|
||||
if let Ok(path) = env::var("SYSTEMROOT") {
|
||||
format!("{path}/System32")
|
||||
} else {
|
||||
self.action_tx.send(Action::Error(String::from(
|
||||
"ERROR\n\n\nFailed to find SYSTEMROOT",
|
||||
)))?;
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
String::from(".")
|
||||
};
|
||||
|
||||
// Add actions
|
||||
let disk_list = self.clone.disk_list.lock().unwrap();
|
||||
|
|
@ -235,7 +227,7 @@ impl App {
|
|||
|
||||
// Create boot files
|
||||
for task in
|
||||
boot::configure_disk(&letter_boot, &letter_os, &system32, &table_type)
|
||||
boot::configure_disk(&letter_boot, &letter_os, &system32, table_type)
|
||||
{
|
||||
self.tasks.add(task);
|
||||
}
|
||||
|
|
@ -256,7 +248,7 @@ impl App {
|
|||
}
|
||||
Mode::Done => {
|
||||
self.action_tx
|
||||
.send(Action::DisplayPopup(popup::Type::Success, popup::fortune()))?;
|
||||
.send(Action::DisplayPopup(popup::Type::Success, fortune()))?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -351,9 +343,12 @@ impl App {
|
|||
match action {
|
||||
Action::Tick => {
|
||||
self.last_tick_key_events.drain(..);
|
||||
// Check background task(s)
|
||||
if let Some(task) = self.tasks.poll()? {
|
||||
self.handle_task(&task)?;
|
||||
match self.cur_mode {
|
||||
Mode::ScanDisks | Mode::PreClone | Mode::Clone | Mode::PostClone => {
|
||||
// Check background task
|
||||
self.tasks.poll()?; // Once all are complete Action::NextScreen is sent
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Action::Quit => self.should_quit = true,
|
||||
|
|
@ -374,9 +369,6 @@ impl App {
|
|||
Mode::Confirm => {
|
||||
self.action_tx.send(Action::NextScreen)?;
|
||||
}
|
||||
Mode::Done => {
|
||||
self.action_tx.send(Action::Quit)?;
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
|
||||
|
|
@ -423,7 +415,7 @@ impl App {
|
|||
0 => Some(PartitionTableType::Guid),
|
||||
1 => Some(PartitionTableType::Legacy),
|
||||
index => {
|
||||
panic!("Failed to select PartitionTableType: {index}")
|
||||
panic!("Failed to select PartitionTableType: {}", index)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -476,7 +468,6 @@ impl App {
|
|||
_ => {}
|
||||
};
|
||||
}
|
||||
Action::TasksComplete => self.action_tx.send(Action::NextScreen)?,
|
||||
_ => {}
|
||||
}
|
||||
for component in &mut self.components {
|
||||
|
|
@ -494,39 +485,6 @@ impl App {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_task(&mut self, task: &Task) -> Result<()> {
|
||||
match task.task_type {
|
||||
TaskType::CommandWait(_, _) | TaskType::Diskpart(_) => {
|
||||
// Check result
|
||||
if let Some(result) = &task.result {
|
||||
match result {
|
||||
TaskResult::Error(msg) => {
|
||||
self.action_tx
|
||||
.send(Action::Error(format!("{} Failed: {msg}", task.task_type)))?;
|
||||
}
|
||||
TaskResult::Output(stdout, stderr, success) => {
|
||||
if !success {
|
||||
let msg = if !stdout.is_empty() {
|
||||
stdout.clone()
|
||||
} else if !stderr.is_empty() {
|
||||
stderr.clone()
|
||||
} else {
|
||||
String::from("Unknown Error")
|
||||
};
|
||||
self.action_tx.send(Action::Error(format!(
|
||||
"{} Failed: {msg}",
|
||||
task.task_type
|
||||
)))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn render(&mut self, tui: &mut Tui) -> Result<()> {
|
||||
tui.draw(|frame| {
|
||||
if let [header, _body, footer, left, right, popup] = get_chunks(frame.area())[..] {
|
||||
|
|
@ -608,21 +566,14 @@ fn build_footer_string(cur_mode: Mode) -> String {
|
|||
String::from("(q) to quit")
|
||||
}
|
||||
Mode::SelectParts => String::from("(Enter) to select / (s) to start over / (q) to quit"),
|
||||
Mode::InstallDrivers => String::from("(Enter) to select / (q) to quit"),
|
||||
Mode::SelectDisks => String::from(
|
||||
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit",
|
||||
),
|
||||
Mode::SelectTableType => String::from("(Enter) to select / (b) to go back / (q) to quit"),
|
||||
Mode::Confirm => String::from("(Enter) to confirm / (b) to go back / (q) to quit"),
|
||||
Mode::Done | Mode::Failed => String::from("(Enter) or (q) to quit"),
|
||||
Mode::Done | Mode::Failed | Mode::InstallDrivers => String::from("(Enter) or (q) to quit"),
|
||||
// Invalid states
|
||||
Mode::BootDiags
|
||||
| Mode::BootScan
|
||||
| Mode::BootSetup
|
||||
| Mode::DiagMenu
|
||||
| Mode::InjectDrivers
|
||||
| Mode::PEMenu
|
||||
| Mode::SetBootMode => panic!("This shouldn't happen?"),
|
||||
Mode::PEMenu => panic!("This shouldn't happen?"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -687,13 +638,7 @@ fn build_left_items(app: &App, cur_mode: Mode) -> Action {
|
|||
title = String::from("Done");
|
||||
}
|
||||
// Invalid states
|
||||
Mode::BootDiags
|
||||
| Mode::BootScan
|
||||
| Mode::BootSetup
|
||||
| Mode::DiagMenu
|
||||
| Mode::InjectDrivers
|
||||
| Mode::PEMenu
|
||||
| Mode::SetBootMode => panic!("This shouldn't happen?"),
|
||||
Mode::PEMenu => panic!("This shouldn't happen?"),
|
||||
};
|
||||
Action::UpdateLeft(title, labels, items, select_num)
|
||||
}
|
||||
|
|
@ -746,26 +691,26 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
|
|||
let disk_list = app.clone.disk_list.lock().unwrap();
|
||||
disk_list
|
||||
.iter()
|
||||
.for_each(|disk| items.push(get_disk_description_right(disk, &None)));
|
||||
.for_each(|disk| items.push(get_disk_description_right(&disk)));
|
||||
}
|
||||
Mode::SelectParts => {
|
||||
for s in &["Boot", "OS"] {
|
||||
vec!["Boot", "OS"].iter().for_each(|s| {
|
||||
labels.push(vec![DVLine {
|
||||
line_parts: vec![String::from(*s)],
|
||||
line_colors: vec![Color::Cyan],
|
||||
}]);
|
||||
}
|
||||
}])
|
||||
});
|
||||
if let Some(index) = app.clone.disk_index_dest {
|
||||
start_index = 1;
|
||||
let disk_list = app.clone.disk_list.lock().unwrap();
|
||||
if let Some(disk) = disk_list.get(index) {
|
||||
// Disk Details
|
||||
items.push(get_disk_description_right(disk, &None));
|
||||
items.push(get_disk_description_right(&disk));
|
||||
|
||||
// Partition Details
|
||||
disk.parts
|
||||
.iter()
|
||||
.for_each(|part| items.push(get_part_description(part)));
|
||||
.for_each(|part| items.push(get_part_description(&part)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -774,18 +719,18 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
|
|||
Action::UpdateRight(labels, start_index, items)
|
||||
}
|
||||
|
||||
pub fn get_system32_path(action_tx: &mpsc::UnboundedSender<Action>) -> String {
|
||||
let mut system32_path = String::from(".");
|
||||
if cfg!(windows) {
|
||||
if let Ok(path) = env::var("SYSTEMROOT") {
|
||||
system32_path = format!("{path}/System32");
|
||||
} else {
|
||||
action_tx
|
||||
.send(Action::Error(String::from(
|
||||
"ERROR\n\n\nFailed to find SYSTEMROOT",
|
||||
)))
|
||||
.expect("Failed to find SYSTEMROOT and then failed to send action");
|
||||
}
|
||||
}
|
||||
system32_path
|
||||
fn fortune() -> String {
|
||||
String::from(match random::<u8>() / 4 {
|
||||
0 => "FUN FACT\n\n\nComputers barely work.",
|
||||
1 => "CRASH OVERRIDE\n\n\n\"Hack the planet!\"",
|
||||
2 => "CATS\n\n\n\"All your base are belong to us!\"",
|
||||
3 => "HMM\n\n\nThis has all happened before...\n\nThis will all happen again.",
|
||||
4 => "CYPHER\n\n\n\"I don’t even see the code. All I see is blonde, brunette, red-head.\"",
|
||||
5 => "CONGRATULATIONS\n\n\nYour did it!",
|
||||
6 => "DID YOU KNOW?\n\n\nmacOS includes a built-in screen reader!",
|
||||
7 => "TIP OF THE DAY\n\n\nNever go full Snappy!",
|
||||
8 => "WORDS OF WISDOM\n\n\n\nIt’s not DNS,\n\nThere’s no way it’s DNS,\n\nIt was DNS.",
|
||||
9 => "HAL 9000\n\n\n\"I'm sorry Dave, I'm afraid I can't do that.\"",
|
||||
_ => "COMPLETE\n\n\nThank you for using this tool!",
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use core;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
|
|
@ -22,22 +23,11 @@ mod app;
|
|||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let mut msg = None;
|
||||
if cfg!(windows) {
|
||||
use check_elevation::is_elevated;
|
||||
if !is_elevated().expect("Failed to get elevation status.") {
|
||||
msg.replace("Administrator privedges required for Deja-Vu.");
|
||||
}
|
||||
};
|
||||
if let Some(text) = msg {
|
||||
println!("{text}");
|
||||
} else {
|
||||
core::errors::init()?;
|
||||
core::logging::init()?;
|
||||
|
||||
let args = core::cli::Cli::parse();
|
||||
let mut app = App::new(args.tick_rate, args.frame_rate)?;
|
||||
app.run().await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
name = 'Boot-Diagnostics'
|
||||
command = 'X:\tools\boot-diags.exe'
|
||||
description = "Boot issue assessment tool"
|
||||
use_conemu = true
|
||||
separator = false
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
# This file is part of Deja-Vu.
|
||||
# This file is part of Deja-vu.
|
||||
#
|
||||
# Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
# Deja-vu is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Deja-Vu is distributed in the hope that it will be useful, but
|
||||
# Deja-vu is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
# along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
[package]
|
||||
name = "pe-menu"
|
||||
authors = ["2Shirt <2xShirt@gmail.com>"]
|
||||
edition = "2024"
|
||||
edition = "2021"
|
||||
license = "GPL"
|
||||
version = "0.2.0"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use anyhow::Result;
|
||||
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use core::{
|
||||
action::Action,
|
||||
components::{
|
||||
Component, footer::Footer, fps::FpsCounter, left::Left, popup, right::Right,
|
||||
state::StatefulList, title::Title,
|
||||
footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, state::StatefulList,
|
||||
title::Title, Component,
|
||||
},
|
||||
config::Config,
|
||||
line::DVLine,
|
||||
state::Mode,
|
||||
tasks::{TaskType, Tasks},
|
||||
tasks::{Task, Tasks},
|
||||
tui::{Event, Tui},
|
||||
};
|
||||
use std::{
|
||||
|
|
@ -230,55 +230,25 @@ impl App {
|
|||
// Run selected tool
|
||||
if let Some(tool) = self.list.get_selected() {
|
||||
info!("Run tool: {:?}", &tool);
|
||||
self.tasks.add(build_tool_command(self, &tool));
|
||||
self.tasks.add(build_command(&self, &tool));
|
||||
}
|
||||
}
|
||||
Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
|
||||
Action::Render => self.render(tui)?,
|
||||
Action::SetMode(mode) => {
|
||||
self.mode = mode;
|
||||
self.action_tx.send(Action::UpdateFooter(String::from(
|
||||
"(Enter) to select / (t) for terminal / (p) to power off / (r) to restart",
|
||||
)))?;
|
||||
self.action_tx
|
||||
.send(Action::UpdateFooter(String::from("(Enter) to select")))?;
|
||||
self.action_tx.send(build_left_items(self))?;
|
||||
self.action_tx.send(build_right_items(self))?;
|
||||
self.action_tx.send(Action::Select(None, None))?;
|
||||
}
|
||||
Action::OpenTerminal => {
|
||||
self.tasks.add(TaskType::CommandNoWait(
|
||||
self.tasks.add(Task::Command(
|
||||
PathBuf::from("cmd.exe"),
|
||||
vec![String::from("-new_console:n")],
|
||||
));
|
||||
}
|
||||
Action::Restart => {
|
||||
self.action_tx.send(Action::DisplayPopup(
|
||||
popup::Type::Info,
|
||||
String::from("Restarting..."),
|
||||
))?;
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
PathBuf::from("X:/Windows/System32/sync64.exe"),
|
||||
vec![String::from("-r")],
|
||||
));
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
PathBuf::from("X:/Windows/System32/wpeutil.exe"),
|
||||
vec![String::from("reboot")],
|
||||
));
|
||||
}
|
||||
Action::Shutdown => {
|
||||
// NOTE: Using 'Powering off' to match the key pressed
|
||||
self.action_tx.send(Action::DisplayPopup(
|
||||
popup::Type::Info,
|
||||
String::from("Powering off..."),
|
||||
))?;
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
PathBuf::from("X:/Windows/System32/sync64.exe"),
|
||||
vec![String::from("-r")],
|
||||
));
|
||||
self.tasks.add(TaskType::CommandWait(
|
||||
PathBuf::from("X:/Windows/System32/wpeutil.exe"),
|
||||
vec![String::from("shutdown")],
|
||||
));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
for component in &mut self.components {
|
||||
|
|
@ -371,15 +341,14 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
|
|||
chunks
|
||||
}
|
||||
|
||||
pub fn build_tool_command(app: &App, tool: &Tool) -> TaskType {
|
||||
pub fn build_command(app: &App, tool: &Tool) -> Task {
|
||||
let cmd_path: PathBuf;
|
||||
let mut cmd_args: Vec<String> = Vec::new();
|
||||
let start_index: usize;
|
||||
if tool.use_conemu {
|
||||
cmd_path = app.config.conemu_path.clone();
|
||||
cmd_args.push(String::from("-run"));
|
||||
cmd_args.push(tool.command.clone());
|
||||
cmd_args.push(String::from("-new_console:n"));
|
||||
cmd_args.push(tool.command.clone());
|
||||
start_index = 1;
|
||||
} else {
|
||||
cmd_path = PathBuf::from(tool.command.clone());
|
||||
|
|
@ -392,7 +361,7 @@ pub fn build_tool_command(app: &App, tool: &Tool) -> TaskType {
|
|||
});
|
||||
}
|
||||
}
|
||||
TaskType::CommandNoWait(cmd_path, cmd_args)
|
||||
Task::Command(cmd_path, cmd_args)
|
||||
}
|
||||
|
||||
fn build_left_items(app: &App) -> Action {
|
||||
|
|
@ -453,7 +422,7 @@ pub fn load_tools() -> Vec<Tool> {
|
|||
entries
|
||||
.iter()
|
||||
.map(|entry| {
|
||||
let contents = fs::read_to_string(entry).expect("Failed to read tool config file");
|
||||
let contents = fs::read_to_string(&entry).expect("Failed to read tool config file");
|
||||
let tool: Tool = toml::from_str(&contents).expect("Failed to parse tool config file");
|
||||
tool
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
// This file is part of Deja-Vu.
|
||||
// This file is part of Deja-vu.
|
||||
//
|
||||
// Deja-Vu is free software: you can redistribute it and/or modify it
|
||||
// Deja-vu is free software: you can redistribute it and/or modify it
|
||||
// under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Deja-Vu is distributed in the hope that it will be useful, but
|
||||
// Deja-vu is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
// See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Deja-Vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
use clap::Parser;
|
||||
use color_eyre::Result;
|
||||
use core;
|
||||
|
||||
use crate::app::App;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue