Merge branch 'boot-diags' into dev

This commit is contained in:
2Shirt 2025-03-22 19:59:26 -07:00
commit 6970f2db3e
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
50 changed files with 2135 additions and 396 deletions

268
Cargo.lock generated
View file

@ -32,7 +32,7 @@ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
"version_check", "version_check",
"zerocopy", "zerocopy 0.7.35",
] ]
[[package]] [[package]]
@ -184,6 +184,27 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "boot-diags"
version = "0.1.0"
dependencies = [
"anyhow",
"check_elevation",
"clap",
"color-eyre",
"core",
"crossterm",
"futures",
"ratatui",
"serde",
"tokio",
"toml",
"tracing",
"tracing-error",
"tracing-subscriber",
"vergen-gix",
]
[[package]] [[package]]
name = "bstr" name = "bstr"
version = "1.11.3" version = "1.11.3"
@ -270,10 +291,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "check_elevation"
version = "4.5.26" version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8eb5e908ef3a6efbe1ed62520fb7287959888c88485abe072543190ecc66783" checksum = "34f7310b71e7b968cdadd13480b9e4f2def9f173f67fd7317e8eddb8d7a4ba00"
dependencies = [
"windows",
]
[[package]]
name = "clap"
version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@ -281,9 +311,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.26" version = "4.5.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b01801b5fc6a0a232407abc821660c9c6d25a1cafc0d4f85f29fb8d9afc121" checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@ -412,7 +442,7 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"once_cell", "once_cell",
"tiny-keccak", "tiny-keccak",
] ]
@ -445,6 +475,7 @@ dependencies = [
"libc", "libc",
"once_cell", "once_cell",
"pretty_assertions", "pretty_assertions",
"rand",
"ratatui", "ratatui",
"raw-cpuid", "raw-cpuid",
"regex", "regex",
@ -465,9 +496,9 @@ dependencies = [
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.16" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
dependencies = [ dependencies = [
"libc", "libc",
] ]
@ -510,9 +541,9 @@ dependencies = [
[[package]] [[package]]
name = "crunchy" name = "crunchy"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
@ -564,10 +595,10 @@ name = "deja-vu"
version = "0.2.0" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"check_elevation",
"clap", "clap",
"color-eyre", "color-eyre",
"core", "core",
"rand",
"ratatui", "ratatui",
"serde", "serde",
"serde_json", "serde_json",
@ -905,7 +936,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -1700,9 +1743,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.7.0" version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.15.2", "hashbrown 0.15.2",
@ -1750,9 +1793,9 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]] [[package]]
name = "jiff" name = "jiff"
version = "0.1.24" version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2bb0c2e28117985a4d90e3bc70092bc8f226f434c7ec7e23dd9ff99c5c5721a" checksum = "c607c728e28764fecde611a2764a3a5db19ae21dcec46f292244f5cc5c085a81"
dependencies = [ dependencies = [
"jiff-tzdb-platform", "jiff-tzdb-platform",
"log", "log",
@ -1909,7 +1952,7 @@ checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [ dependencies = [
"libc", "libc",
"log", "log",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
@ -2012,7 +2055,7 @@ dependencies = [
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec",
"windows-targets", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -2137,7 +2180,7 @@ version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [ dependencies = [
"zerocopy", "zerocopy 0.7.35",
] ]
[[package]] [[package]]
@ -2180,20 +2223,20 @@ dependencies = [
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.5" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [ dependencies = [
"libc",
"rand_chacha", "rand_chacha",
"rand_core", "rand_core",
"zerocopy 0.8.14",
] ]
[[package]] [[package]]
name = "rand_chacha" name = "rand_chacha"
version = "0.3.1" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [ dependencies = [
"ppv-lite86", "ppv-lite86",
"rand_core", "rand_core",
@ -2201,11 +2244,12 @@ dependencies = [
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.4" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.3.1",
"zerocopy 0.8.14",
] ]
[[package]] [[package]]
@ -2254,7 +2298,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
"libredox", "libredox",
"thiserror", "thiserror",
] ]
@ -2334,9 +2378,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.43" version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
@ -2353,9 +2397,9 @@ checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]] [[package]]
name = "same-file" name = "same-file"
@ -2403,9 +2447,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.137" version = "1.0.138"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -2599,13 +2643,13 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.15.0" version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"fastrand", "fastrand",
"getrandom", "getrandom 0.3.1",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.59.0", "windows-sys 0.59.0",
@ -2898,9 +2942,9 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217"
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.14" version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
@ -2971,11 +3015,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.12.0" version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
dependencies = [ dependencies = [
"getrandom", "getrandom 0.2.15",
] ]
[[package]] [[package]]
@ -3056,6 +3100,15 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
dependencies = [
"wit-bindgen-rt",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"
@ -3087,13 +3140,32 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9"
dependencies = [
"windows-core",
"windows-targets 0.48.5",
]
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets 0.48.5",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -3102,7 +3174,22 @@ version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [ dependencies = [
"windows-targets", "windows-targets 0.52.6",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
] ]
[[package]] [[package]]
@ -3111,28 +3198,46 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [ dependencies = [
"windows_aarch64_gnullvm", "windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc", "windows_aarch64_msvc 0.52.6",
"windows_i686_gnu", "windows_i686_gnu 0.52.6",
"windows_i686_gnullvm", "windows_i686_gnullvm",
"windows_i686_msvc", "windows_i686_msvc 0.52.6",
"windows_x86_64_gnu", "windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc", "windows_x86_64_msvc 0.52.6",
] ]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]] [[package]]
name = "windows_aarch64_gnullvm" name = "windows_aarch64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]] [[package]]
name = "windows_aarch64_msvc" name = "windows_aarch64_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]] [[package]]
name = "windows_i686_gnu" name = "windows_i686_gnu"
version = "0.52.6" version = "0.52.6"
@ -3145,24 +3250,48 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]] [[package]]
name = "windows_i686_msvc" name = "windows_i686_msvc"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]] [[package]]
name = "windows_x86_64_gnu" name = "windows_x86_64_gnu"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]] [[package]]
name = "windows_x86_64_gnullvm" name = "windows_x86_64_gnullvm"
version = "0.52.6" version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "windows_x86_64_msvc" name = "windows_x86_64_msvc"
version = "0.52.6" version = "0.52.6"
@ -3171,13 +3300,22 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.24" version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8d71a593cc5c42ad7876e2c1fda56f314f3754c084128833e64f1345ff8a03a" checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
]
[[package]] [[package]]
name = "write16" name = "write16"
version = "1.0.0" version = "1.0.0"
@ -3238,7 +3376,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"zerocopy-derive", "zerocopy-derive 0.7.35",
]
[[package]]
name = "zerocopy"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
dependencies = [
"zerocopy-derive 0.8.14",
] ]
[[package]] [[package]]
@ -3252,6 +3399,17 @@ dependencies = [
"syn 2.0.96", "syn 2.0.96",
] ]
[[package]]
name = "zerocopy-derive"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.96",
]
[[package]] [[package]]
name = "zerofrom" name = "zerofrom"
version = "0.1.5" version = "0.1.5"

View file

@ -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 # under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (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 # WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. # See the GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # 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] [workspace]
members = ["core", "deja_vu", "pe_menu"] members = ["core", "boot_diags", "deja_vu", "pe_menu"]
default-members = ["deja_vu", "pe_menu"] default-members = ["boot_diags", "deja_vu", "pe_menu"]
resolver = "2" resolver = "2"

47
boot_diags/Cargo.toml Normal file
View file

@ -0,0 +1,47 @@
# 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 = "2021"
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"] }

28
boot_diags/build.rs Normal file
View file

@ -0,0 +1,28 @@
// 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()
}

1045
boot_diags/src/app.rs Normal file

File diff suppressed because it is too large Load diff

102
boot_diags/src/diags.rs Normal file
View file

@ -0,0 +1,102 @@
// 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
}

48
boot_diags/src/main.rs Normal file
View file

@ -0,0 +1,48 @@
// 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 core;
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(())
}

View file

@ -1,5 +1,5 @@
{ {
"app_title": "Deja-vu", "app_title": "Deja-Vu",
"clone_app_path": "C:/Program Files/Some Clone Tool/app.exe", "clone_app_path": "C:/Program Files/Some Clone Tool/app.exe",
"conemu_path": "C:/Program Files/ConEmu/ConEmu64.exe", "conemu_path": "C:/Program Files/ConEmu/ConEmu64.exe",
"keybindings": { "keybindings": {
@ -82,7 +82,7 @@
"<Ctrl-z>": "Suspend" "<Ctrl-z>": "Suspend"
}, },
"Done": { "Done": {
"<Enter>": "Quit", "<Enter>": "Process",
"<q>": "Quit", "<q>": "Quit",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
@ -95,11 +95,66 @@
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",
"<Ctrl-z>": "Suspend" "<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": { "PEMenu": {
"<Enter>": "Process", "<Enter>": "Process",
"<Up>": "KeyUp", "<Up>": "KeyUp",
"<Down>": "KeyDown", "<Down>": "KeyDown",
"<q>": "Quit", "<q>": "Quit",
"<r>": "Restart",
"<p>": "Shutdown",
"<t>": "OpenTerminal", "<t>": "OpenTerminal",
"<Ctrl-d>": "Quit", "<Ctrl-d>": "Quit",
"<Ctrl-c>": "Quit", "<Ctrl-c>": "Quit",

View file

@ -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 # under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (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 # WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. # See the GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # 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] [package]
name = "core" name = "core"
@ -42,6 +42,7 @@ lazy_static = "1.5.0"
libc = "0.2.158" libc = "0.2.158"
once_cell = "1.20.2" once_cell = "1.20.2"
pretty_assertions = "1.4.0" pretty_assertions = "1.4.0"
rand = "0.9.0"
ratatui = { version = "0.29.0", features = ["serde", "macros"] } ratatui = { version = "0.29.0", features = ["serde", "macros"] }
raw-cpuid = "11.2.0" raw-cpuid = "11.2.0"
regex = "1.11.1" regex = "1.11.1"

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 anyhow::Result;
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder}; use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 serde::{Deserialize, Serialize};
use strum::Display; use strum::Display;
@ -20,6 +20,8 @@ use crate::{components::popup::Type, line::DVLine, state::Mode, system::disk::Di
#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
pub enum Action { pub enum Action {
// App (Boot-Diags)
BootScan,
// App (Clone) // App (Clone)
Highlight(usize), Highlight(usize),
InstallDriver, InstallDriver,
@ -27,6 +29,7 @@ pub enum Action {
ScanDisks, ScanDisks,
Select(Option<usize>, Option<usize>), // indicies for (source, dest) etc Select(Option<usize>, Option<usize>), // indicies for (source, dest) etc
SelectRight(Option<usize>, Option<usize>), // indicies for right info pane SelectRight(Option<usize>, Option<usize>), // indicies for right info pane
TasksComplete,
UpdateDiskList(Vec<Disk>), UpdateDiskList(Vec<Disk>),
UpdateFooter(String), UpdateFooter(String),
UpdateLeft(String, Vec<String>, Vec<String>, usize), // (title, labels, items, select_num) UpdateLeft(String, Vec<String>, Vec<String>, usize), // (title, labels, items, select_num)
@ -35,8 +38,10 @@ pub enum Action {
// 1: For a single choice // 1: For a single choice
// 2: For two selections (obviously) // 2: For two selections (obviously)
UpdateRight(Vec<Vec<DVLine>>, usize, Vec<Vec<DVLine>>), // (labels, start_index, items) - items before start are always shown UpdateRight(Vec<Vec<DVLine>>, usize, Vec<Vec<DVLine>>), // (labels, start_index, items) - items before start are always shown
// App (PEMenu) // App (PE-Menu)
OpenTerminal, OpenTerminal,
Restart,
Shutdown,
// Screens // Screens
DismissPopup, DismissPopup,
DisplayPopup(Type, String), DisplayPopup(Type, String),

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 clap::Parser;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use crossterm::event::{KeyEvent, MouseEvent}; use crossterm::event::{KeyEvent, MouseEvent};

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use ratatui::{ use ratatui::{

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 std::time::Instant;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;
@ -138,14 +138,10 @@ impl Component for Left {
.areas(area); .areas(area);
// Title // Title
let title_text = if self.selections[1].is_some() || self.select_num == 1 { let title = Paragraph::new(
"Confirm Selections" Line::from(Span::styled(self.title_text.as_str(), Style::default())).centered(),
} else { )
self.title_text.as_str() .block(Block::default().borders(Borders::NONE));
};
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); frame.render_widget(title, title_area);
// Body (Blank) // Body (Blank)

View file

@ -1,19 +1,20 @@
// 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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use rand::random;
use ratatui::{ use ratatui::{
prelude::*, prelude::*,
widgets::{Block, Borders, Clear, Paragraph, Wrap}, widgets::{Block, Borders, Clear, Paragraph, Wrap},
@ -95,3 +96,19 @@ impl Component for Popup {
Ok(()) Ok(())
} }
} }
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 dont 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\nIts not DNS,\n\nTheres no way its 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!",
})
}

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use crossterm::event::KeyEvent; use crossterm::event::KeyEvent;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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; use std::collections::HashMap;
@ -55,7 +55,7 @@ impl<T: Clone> StatefulList<T> {
self.state.selected() self.state.selected()
} }
fn select_first_item(&mut self) { pub fn select_first_item(&mut self) {
if self.items.is_empty() { if self.items.is_empty() {
self.state.select(None); self.state.select(None);
} else { } else {

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use ratatui::{ use ratatui::{

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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)] // Remove this once you start using the code #![allow(dead_code)] // Remove this once you start using the code
@ -149,8 +149,8 @@ pub fn get_config_dir() -> PathBuf {
} }
fn project_directory() -> Option<ProjectDirs> { fn project_directory() -> Option<ProjectDirs> {
ProjectDirs::from("com", "Deja-vu", "deja-vu") ProjectDirs::from("com", "Deja-Vu", "deja-vu")
//ProjectDirs::from("com", "Deja-vu", env!("CARGO_PKG_NAME")) //ProjectDirs::from("com", "Deja-Vu", env!("CARGO_PKG_NAME"))
} }
#[derive(Clone, Debug, Default, Deref, DerefMut)] #[derive(Clone, Debug, Default, Deref, DerefMut)]

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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; use std::env;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 action;
pub mod cli; pub mod cli;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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::{ use ratatui::{
style::{Color, Style}, style::{Color, Style},
@ -45,7 +45,10 @@ impl DVLine {
} }
} }
pub fn get_disk_description_right(disk: &Disk) -> Vec<DVLine> { pub fn get_disk_description_right(
disk: &Disk,
boot_os_indicies: Option<Vec<usize>>,
) -> Vec<DVLine> {
let mut description: Vec<DVLine> = vec![ let mut description: Vec<DVLine> = vec![
DVLine { DVLine {
line_parts: vec![format!( line_parts: vec![format!(
@ -67,12 +70,29 @@ pub fn get_disk_description_right(disk: &Disk) -> Vec<DVLine> {
line_colors: vec![Color::Blue], line_colors: vec![Color::Blue],
}, },
]; ];
for line in &disk.parts_description { disk.parts_description
description.push(DVLine { .iter()
line_parts: vec![line.clone()], .enumerate()
line_colors: vec![Color::Reset], .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.get(0);
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);
}
}
description.push(DVLine {
line_parts,
line_colors,
});
}); });
}
description description
} }

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 color_eyre::Result;
use tracing_error::ErrorLayer; use tracing_error::ErrorLayer;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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}; use std::sync::{Arc, Mutex};
@ -30,6 +30,13 @@ pub enum Mode {
Home, Home,
Done, Done,
Failed, Failed,
// Boot Diags
DiagMenu,
BootDiags,
BootScan,
BootSetup,
InjectDrivers,
SetBootMode,
// Clone // Clone
ScanDisks, ScanDisks,
InstallDrivers, InstallDrivers,

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 boot;
pub mod cpu; pub mod cpu;

View file

@ -1,33 +1,40 @@
// 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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 super::{disk::PartitionTableType, drivers::Driver}; use super::{disk::PartitionTableType, drivers::Driver};
use crate::tasks::Task; use crate::tasks::TaskType;
use color_eyre::Result; use color_eyre::Result;
use std::path::PathBuf; use std::path::PathBuf;
#[derive(Clone, Debug, Default)]
pub enum SafeMode {
#[default]
Disable,
Enable,
}
pub fn configure_disk( pub fn configure_disk(
letter_boot: &str, letter_boot: &str,
letter_os: &str, letter_os: &str,
system32: &str, system32: &str,
table_type: PartitionTableType, table_type: PartitionTableType,
) -> Vec<Task> { ) -> Vec<TaskType> {
let mut tasks = Vec::new(); let mut tasks = Vec::new();
// Create // Create
tasks.push(Task::Command( tasks.push(TaskType::CommandWait(
PathBuf::from(format!("{system32}/bcdboot.exe")), PathBuf::from(format!("{system32}/bcdboot.exe")),
vec![ vec![
format!("{letter_os}:\\Windows"), format!("{letter_os}:\\Windows"),
@ -43,7 +50,7 @@ pub fn configure_disk(
// Update boot sector (for legacy setups) // Update boot sector (for legacy setups)
if table_type == PartitionTableType::Legacy { if table_type == PartitionTableType::Legacy {
tasks.push(Task::Command( tasks.push(TaskType::CommandWait(
PathBuf::from(format!("{system32}/bootsect.exe")), PathBuf::from(format!("{system32}/bootsect.exe")),
vec![ vec![
String::from("/nt60"), String::from("/nt60"),
@ -55,34 +62,19 @@ pub fn configure_disk(
} }
// Lock in safe mode // Lock in safe mode
let bcd_path = match table_type { tasks.push(
PartitionTableType::Guid => { set_mode(letter_boot, SafeMode::Enable, system32, &table_type)
format!("{letter_boot}:\\EFI\\Microsoft\\Boot\\BCD") .expect("Failed to create set_mode task."),
} );
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 // Done
tasks tasks
} }
pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result<Task> { pub fn inject_driver(driver: &Driver, letter_os: &str, system32: &str) -> Result<TaskType> {
//if let Some(driver_path_str) = driver.path.to_str() { //if let Some(driver_path_str) = driver.path.to_str() {
let driver_path = driver.path.to_str().unwrap(); let driver_path = driver.path.to_str().unwrap();
Ok(Task::Command( Ok(TaskType::CommandWait(
PathBuf::from(format!("{system32}/dism.exe")), PathBuf::from(format!("{system32}/dism.exe")),
vec![ vec![
format!("/image:{letter_os}:\\"), format!("/image:{letter_os}:\\"),
@ -92,3 +84,39 @@ 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,
))
}

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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] #[must_use]
pub fn get_cpu_name() -> String { pub fn get_cpu_name() -> String {

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 serde::{Deserialize, Serialize};
use std::{ use std::{

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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::{ use std::{
collections::HashMap, collections::HashMap,
@ -129,7 +129,7 @@ pub fn get_partition_details(
#[must_use] #[must_use]
pub fn build_dest_format_script(disk_id: usize, part_type: &PartitionTableType) -> String { pub fn build_dest_format_script(disk_id: usize, part_type: &PartitionTableType) -> String {
let disk_id = format!("{disk_id}"); let disk_id = format!("{disk_id}");
let mut script = vec!["select disk {disk_id}", "clean"]; let mut script = vec!["automount enable noerr", "select disk {disk_id}", "clean"];
match part_type { match part_type {
PartitionTableType::Guid => { PartitionTableType::Guid => {
script.push("convert gpt"); script.push("convert gpt");

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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}; use std::{env, fmt, fs::read_dir, path::PathBuf, process::Command};

View file

@ -1,21 +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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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::{ use std::{
collections::VecDeque, collections::VecDeque,
fmt,
path::PathBuf, path::PathBuf,
process::{Command, Stdio}, process::{Command, Stdio},
sync::{Arc, Mutex}, sync::{Arc, Mutex},
@ -34,23 +35,69 @@ use crate::{
}; };
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Task { pub enum TaskResult {
Command(PathBuf, Vec<String>), // (command, args) Error(String),
Diskpart(String), // (script_as_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)
Diskpart(String), // (script_as_string)
ScanDisks, ScanDisks,
Sleep, Sleep,
UpdateDestDisk(usize), // (disk_index) UpdateDestDisk(usize), // (disk_index)
UpdateDiskList, 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 {
pub fn new(task_type: TaskType) -> Task {
Task {
handle: None,
result: None,
task_type,
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Tasks { pub struct Tasks {
action_tx: mpsc::UnboundedSender<Action>, action_tx: mpsc::UnboundedSender<Action>,
disk_list: Arc<Mutex<Vec<disk::Disk>>>, disk_list: Arc<Mutex<Vec<disk::Disk>>>,
handle: Option<JoinHandle<()>>, cur_handle: Option<JoinHandle<()>>,
cur_task: Option<Task>,
task_list: VecDeque<Task>, task_list: VecDeque<Task>,
task_rx: mpsc::UnboundedReceiver<Action>, // Used to forward Actions from Tasks to App task_rx: mpsc::UnboundedReceiver<TaskResult>,
task_tx: mpsc::UnboundedSender<Action>, // Used to forward Actions from Tasks to App task_tx: mpsc::UnboundedSender<TaskResult>,
} }
impl Tasks { impl Tasks {
@ -62,159 +109,181 @@ impl Tasks {
Tasks { Tasks {
action_tx, action_tx,
disk_list: disk_list_arc, disk_list: disk_list_arc,
handle: None, cur_handle: None,
cur_task: None,
task_list: VecDeque::new(), task_list: VecDeque::new(),
task_rx, task_rx,
task_tx, task_tx,
} }
} }
pub fn add(&mut self, task: Task) { pub fn add(&mut self, task_type: TaskType) {
info!("Adding task: {:?}", &task); info!("Adding task: {:?}", &task_type);
self.task_list.push_back(task); self.task_list.push_back(Task::new(task_type));
} }
pub fn idle(&self) -> bool { pub fn idle(&self) -> bool {
self.handle.is_none() self.cur_handle.is_none()
} }
pub fn poll(&mut self) -> Result<()> { pub fn poll(&mut self) -> Result<Option<Task>> {
// Forward any actions to main app let mut return_task: Option<Task> = None;
if let Ok(action) = self.task_rx.try_recv() { // Handle task channel item(s)
let result = self.action_tx.send(action.clone()); if let Ok(result) = self.task_rx.try_recv() {
assert!(result.is_ok(), "Failed to send Action: {action:?}"); if let Some(mut task) = self.cur_task.take() {
task.result.replace(result);
self.cur_task.replace(task);
}
} }
// Check status of current task (if one is running). // Check status of current task (if one is running).
// NOTE: Action::NextScreen is sent once all tasks are complete // NOTE: Action::TasksComplete is sent once all tasks are complete
if let Some(handle) = self.handle.take() { if let Some(task_handle) = self.cur_handle.take() {
if handle.is_finished() { 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);
}
if self.task_list.is_empty() { if self.task_list.is_empty() {
// No tasks remain // No tasks remain
self.task_tx.send(Action::NextScreen)?; self.action_tx.send(Action::TasksComplete)?;
} else { } else {
// Start next task // Start next task
self.start()?; self.start()?;
} }
} else { } else {
// Task not complete, return handle // TaskType not complete, return handle
self.handle = Some(handle); self.cur_handle.replace(task_handle);
} }
} else if !self.task_list.is_empty() { } else if !self.task_list.is_empty() {
// No current task but one is available // No current task but one is available
self.start()?; self.start()?;
} }
Ok(()) Ok(return_task)
} }
pub fn start(&mut self) -> Result<()> { pub fn start(&mut self) -> Result<()> {
if let Some(task) = self.task_list.pop_front() { self.cur_task = self.task_list.pop_front();
let task_str = format!("{task:?}"); if let Some(task) = self.cur_task.take() {
let task_tx = self.task_tx.clone(); let task_tx = self.task_tx.clone();
match task { match task.task_type {
Task::Command(ref cmd_path, ref cmd_args) => { TaskType::CommandNoWait(ref cmd_path, ref cmd_args) => {
let cmd_path = cmd_path.clone(); self.cur_handle = None;
let cmd_args = cmd_args.clone(); run_task_command(cmd_path.clone(), cmd_args.clone(), task_tx);
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());
}
if msg.is_empty() {
msg = String::from("Generic error");
}
Some(Action::Error(format!("Command failed: {msg}",)))
}
}
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) => { TaskType::CommandWait(ref cmd_path, ref cmd_args) => {
if cfg!(windows) { self.cur_handle = Some(run_task_command(
let script = String::from(script); cmd_path.clone(),
self.handle = Some(thread::spawn(move || { cmd_args.clone(),
let output = diskpart::run_script_raw(script.as_str()); task_tx,
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 => { TaskType::Diskpart(ref script) => {
self.cur_handle = Some(run_task_diskpart(&script, task_tx));
}
TaskType::ScanDisks => {
let disk_list_arc = self.disk_list.clone(); let disk_list_arc = self.disk_list.clone();
// Queue UpdateDiskList for various components // Queue UpdateDiskList for various components
self.add(Task::UpdateDiskList); self.add(TaskType::UpdateDiskList);
self.handle = Some(thread::spawn(move || { self.cur_handle = Some(thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap(); let mut disks = disk_list_arc.lock().unwrap();
*disks = disk::get_disks(); *disks = disk::get_disks()
})); }));
} }
Task::Sleep => { TaskType::Sleep => {
self.handle = Some(thread::spawn(|| sleep(Duration::from_millis(250)))); self.cur_handle = Some(thread::spawn(|| sleep(Duration::from_millis(250))));
} }
Task::UpdateDestDisk(index) => { TaskType::UpdateDestDisk(index) => {
self.action_tx.send(Action::DisplayPopup( self.action_tx.send(Action::DisplayPopup(
popup::Type::Info, popup::Type::Info,
String::from("Refreshing disk info"), String::from("Refreshing disk info"),
))?; ))?;
// Queue UpdateDiskList for various components // Queue UpdateDiskList for various components
self.add(Task::Sleep); self.add(TaskType::Sleep);
self.add(Task::UpdateDiskList); self.add(TaskType::UpdateDiskList);
// Update destination disk ~in-place // Update destination disk ~in-place
let disk_list_arc = self.disk_list.clone(); let disk_list_arc = self.disk_list.clone();
self.handle = Some(thread::spawn(move || { self.cur_handle = Some(thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap(); let mut disks = disk_list_arc.lock().unwrap();
let old_disk = &mut disks[index]; let old_disk = &mut disks[index];
disks[index] = disk::refresh_disk_info(old_disk); disks[index] = disk::refresh_disk_info(old_disk);
})); }));
} }
Task::UpdateDiskList => { TaskType::UpdateDiskList => {
let disks = self.disk_list.lock().unwrap(); let disks = self.disk_list.lock().unwrap();
let disks_copy = disks.clone(); let disks_copy = disks.clone();
let action_tx = self.action_tx.clone(); let action_tx = self.action_tx.clone();
self.handle = Some(thread::spawn(move || { self.cur_handle = Some(thread::spawn(move || {
if let Err(err) = action_tx.send(Action::UpdateDiskList(disks_copy)) { if let Err(err) = action_tx.send(Action::UpdateDiskList(disks_copy)) {
panic!("Failed to send Action: {err:?}"); panic!("Failed to send Action: {err:?}");
} }
})); }));
} }
} }
// Done
self.cur_task.replace(task);
} }
Ok(()) 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.to_owned());
let stdout = parse_bytes_as_str(output.stdout.to_owned());
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).expect(err_str.as_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.to_owned());
let stdout = parse_bytes_as_str(output.stdout.to_owned());
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).expect(err_str.as_str());
})
} else {
// Simulate task if not running under Windows
thread::spawn(|| sleep(Duration::from_millis(250)))
}
}

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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; pub mod sample_output;

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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)] #[allow(dead_code)]
pub static DETAIL_DISK_GPT: &str = "Disk 2 is now the selected disk. pub static DETAIL_DISK_GPT: &str = "Disk 2 is now the selected disk.

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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)] // Remove this once you start using the code #![allow(dead_code)] // Remove this once you start using the code

View file

@ -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 # under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (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 # WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. # See the GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # 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] [package]
name = "deja-vu" name = "deja-vu"
@ -39,7 +39,7 @@ tokio-util = "0.7.11"
tracing = "0.1.41" tracing = "0.1.41"
tracing-error = "0.2.0" tracing-error = "0.2.0"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] } tracing-subscriber = { version = "0.3.18", features = ["env-filter", "serde"] }
rand = "0.8.5" check_elevation = "0.2.4"
[build-dependencies] [build-dependencies]
anyhow = "1.0.86" anyhow = "1.0.86"

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 anyhow::Result;
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder}; use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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::{ use core::{
action::Action, action::Action,
@ -26,17 +26,17 @@ use core::{
boot, cpu::get_cpu_name, disk::PartitionTableType, diskpart::build_dest_format_script, boot, cpu::get_cpu_name, disk::PartitionTableType, diskpart::build_dest_format_script,
drivers, drivers,
}, },
tasks::{Task, Tasks}, tasks::{Task, TaskResult, TaskType, Tasks},
tui::{Event, Tui}, tui::{Event, Tui},
}; };
use std::{ use std::{
env, env,
iter::zip, iter::zip,
path::PathBuf,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use color_eyre::Result; use color_eyre::Result;
use rand::random;
use ratatui::{ use ratatui::{
crossterm::event::KeyEvent, crossterm::event::KeyEvent,
layout::{Constraint, Direction, Layout}, layout::{Constraint, Direction, Layout},
@ -115,7 +115,13 @@ impl App {
| Mode::Clone | Mode::Clone
| Mode::PostClone => None, | Mode::PostClone => None,
// Invalid states // Invalid states
Mode::PEMenu => panic!("This shouldn't happen?"), Mode::BootDiags
| Mode::BootScan
| Mode::BootSetup
| Mode::DiagMenu
| Mode::InjectDrivers
| Mode::PEMenu
| Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
new_mode new_mode
} }
@ -134,7 +140,13 @@ impl App {
Mode::PostClone | Mode::Done => Mode::Done, Mode::PostClone | Mode::Done => Mode::Done,
Mode::Failed => Mode::Failed, Mode::Failed => Mode::Failed,
// Invalid states // Invalid states
Mode::PEMenu => panic!("This shouldn't happen?"), Mode::BootDiags
| Mode::BootScan
| Mode::BootSetup
| Mode::DiagMenu
| Mode::InjectDrivers
| Mode::PEMenu
| Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
if new_mode == self.cur_mode { if new_mode == self.cur_mode {
@ -153,7 +165,7 @@ impl App {
Mode::ScanDisks => { Mode::ScanDisks => {
self.prev_mode = self.cur_mode; self.prev_mode = self.cur_mode;
if self.tasks.idle() { if self.tasks.idle() {
self.tasks.add(Task::ScanDisks); self.tasks.add(TaskType::ScanDisks);
} }
self.action_tx.send(Action::DisplayPopup( self.action_tx.send(Action::DisplayPopup(
popup::Type::Info, popup::Type::Info,
@ -166,13 +178,33 @@ impl App {
String::from("Formatting destination disk"), String::from("Formatting destination disk"),
))?; ))?;
// Get System32 path
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(".")
};
// (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 // Build Diskpart script to format destination disk
let disk_list = self.clone.disk_list.lock().unwrap(); let disk_list = self.clone.disk_list.lock().unwrap();
if let Some(disk_index) = self.clone.disk_index_dest { if let Some(disk_index) = self.clone.disk_index_dest {
if let Some(disk) = disk_list.get(disk_index) { if let Some(disk) = disk_list.get(disk_index) {
let table_type = self.clone.table_type.clone().unwrap(); let table_type = self.clone.table_type.clone().unwrap();
let diskpart_script = build_dest_format_script(disk.id, &table_type); let diskpart_script = build_dest_format_script(disk.id, &table_type);
self.tasks.add(Task::Diskpart(diskpart_script)); self.tasks.add(TaskType::Diskpart(diskpart_script));
} }
} }
} }
@ -181,12 +213,12 @@ impl App {
popup::Type::Info, popup::Type::Info,
String::from("Running Clone Tool"), String::from("Running Clone Tool"),
))?; ))?;
self.tasks.add(Task::Command( self.tasks.add(TaskType::CommandWait(
self.config.clone_app_path.clone(), self.config.clone_app_path.clone(),
Vec::new(), Vec::new(),
)); ));
if let Some(dest_index) = self.clone.disk_index_dest { if let Some(dest_index) = self.clone.disk_index_dest {
self.tasks.add(Task::UpdateDestDisk(dest_index)); self.tasks.add(TaskType::UpdateDestDisk(dest_index));
} }
} }
Mode::PostClone => { Mode::PostClone => {
@ -248,7 +280,7 @@ impl App {
} }
Mode::Done => { Mode::Done => {
self.action_tx self.action_tx
.send(Action::DisplayPopup(popup::Type::Success, fortune()))?; .send(Action::DisplayPopup(popup::Type::Success, popup::fortune()))?;
} }
_ => {} _ => {}
} }
@ -343,12 +375,9 @@ impl App {
match action { match action {
Action::Tick => { Action::Tick => {
self.last_tick_key_events.drain(..); self.last_tick_key_events.drain(..);
match self.cur_mode { // Check background task(s)
Mode::ScanDisks | Mode::PreClone | Mode::Clone | Mode::PostClone => { if let Some(task) = self.tasks.poll()? {
// Check background task self.handle_task(&task)?;
self.tasks.poll()?; // Once all are complete Action::NextScreen is sent
}
_ => {}
} }
} }
Action::Quit => self.should_quit = true, Action::Quit => self.should_quit = true,
@ -369,6 +398,9 @@ impl App {
Mode::Confirm => { Mode::Confirm => {
self.action_tx.send(Action::NextScreen)?; self.action_tx.send(Action::NextScreen)?;
} }
Mode::Done => {
self.action_tx.send(Action::Quit)?;
}
_ => {} _ => {}
}, },
Action::Resize(w, h) => self.handle_resize(tui, w, h)?, Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
@ -468,6 +500,7 @@ impl App {
_ => {} _ => {}
}; };
} }
Action::TasksComplete => self.action_tx.send(Action::NextScreen)?,
_ => {} _ => {}
} }
for component in &mut self.components { for component in &mut self.components {
@ -485,6 +518,39 @@ impl App {
Ok(()) 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<()> { fn render(&mut self, tui: &mut Tui) -> Result<()> {
tui.draw(|frame| { tui.draw(|frame| {
if let [header, _body, footer, left, right, popup] = get_chunks(frame.area())[..] { if let [header, _body, footer, left, right, popup] = get_chunks(frame.area())[..] {
@ -566,14 +632,21 @@ fn build_footer_string(cur_mode: Mode) -> String {
String::from("(q) to quit") String::from("(q) to quit")
} }
Mode::SelectParts => String::from("(Enter) to select / (s) to start over / (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( Mode::SelectDisks => String::from(
"(Enter) to select / / (i) to install driver / (r) to rescan / (q) to quit", "(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::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::Confirm => String::from("(Enter) to confirm / (b) to go back / (q) to quit"),
Mode::Done | Mode::Failed | Mode::InstallDrivers => String::from("(Enter) or (q) to quit"), Mode::Done | Mode::Failed => String::from("(Enter) or (q) to quit"),
// Invalid states // Invalid states
Mode::PEMenu => panic!("This shouldn't happen?"), Mode::BootDiags
| Mode::BootScan
| Mode::BootSetup
| Mode::DiagMenu
| Mode::InjectDrivers
| Mode::PEMenu
| Mode::SetBootMode => panic!("This shouldn't happen?"),
} }
} }
@ -638,7 +711,13 @@ fn build_left_items(app: &App, cur_mode: Mode) -> Action {
title = String::from("Done"); title = String::from("Done");
} }
// Invalid states // Invalid states
Mode::PEMenu => panic!("This shouldn't happen?"), Mode::BootDiags
| Mode::BootScan
| Mode::BootSetup
| Mode::DiagMenu
| Mode::InjectDrivers
| Mode::PEMenu
| Mode::SetBootMode => panic!("This shouldn't happen?"),
}; };
Action::UpdateLeft(title, labels, items, select_num) Action::UpdateLeft(title, labels, items, select_num)
} }
@ -691,7 +770,7 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
disk_list disk_list
.iter() .iter()
.for_each(|disk| items.push(get_disk_description_right(&disk))); .for_each(|disk| items.push(get_disk_description_right(&disk, None)));
} }
Mode::SelectParts => { Mode::SelectParts => {
vec!["Boot", "OS"].iter().for_each(|s| { vec!["Boot", "OS"].iter().for_each(|s| {
@ -705,7 +784,7 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
let disk_list = app.clone.disk_list.lock().unwrap(); let disk_list = app.clone.disk_list.lock().unwrap();
if let Some(disk) = disk_list.get(index) { if let Some(disk) = disk_list.get(index) {
// Disk Details // Disk Details
items.push(get_disk_description_right(&disk)); items.push(get_disk_description_right(&disk, None));
// Partition Details // Partition Details
disk.parts disk.parts
@ -718,19 +797,3 @@ fn build_right_items(app: &App, cur_mode: Mode) -> Action {
} }
Action::UpdateRight(labels, start_index, items) Action::UpdateRight(labels, start_index, items)
} }
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 dont 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\nIts not DNS,\n\nTheres no way its 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!",
})
}

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 clap::Parser;
use color_eyre::Result; use color_eyre::Result;
@ -23,11 +23,25 @@ mod app;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
core::errors::init()?; let mut msg = None;
core::logging::init()?; 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 args = core::cli::Cli::parse();
let mut app = App::new(args.tick_rate, args.frame_rate)?; let mut app = App::new(args.tick_rate, args.frame_rate)?;
app.run().await?; app.run().await?;
}
}
Ok(()) Ok(())
} }

View file

@ -0,0 +1,5 @@
name = 'Boot-Diagnostics'
command = 'X:\tools\boot-diags.exe'
description = "Boot issue assessment tool"
use_conemu = true
separator = false

View file

@ -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 # under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (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 # WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details. # See the GNU General Public License for more details.
# #
# You should have received a copy of the GNU General Public License # 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] [package]
name = "pe-menu" name = "pe-menu"

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 anyhow::Result;
use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder}; use vergen_gix::{BuildBuilder, CargoBuilder, Emitter, GixBuilder};

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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::{ use core::{
action::Action, action::Action,
@ -22,7 +22,7 @@ use core::{
config::Config, config::Config,
line::DVLine, line::DVLine,
state::Mode, state::Mode,
tasks::{Task, Tasks}, tasks::{TaskType, Tasks},
tui::{Event, Tui}, tui::{Event, Tui},
}; };
use std::{ use std::{
@ -230,25 +230,55 @@ impl App {
// Run selected tool // Run selected tool
if let Some(tool) = self.list.get_selected() { if let Some(tool) = self.list.get_selected() {
info!("Run tool: {:?}", &tool); info!("Run tool: {:?}", &tool);
self.tasks.add(build_command(&self, &tool)); self.tasks.add(build_tool_command(&self, &tool));
} }
} }
Action::Resize(w, h) => self.handle_resize(tui, w, h)?, Action::Resize(w, h) => self.handle_resize(tui, w, h)?,
Action::Render => self.render(tui)?, Action::Render => self.render(tui)?,
Action::SetMode(mode) => { Action::SetMode(mode) => {
self.mode = mode; self.mode = mode;
self.action_tx self.action_tx.send(Action::UpdateFooter(String::from(
.send(Action::UpdateFooter(String::from("(Enter) to select")))?; "(Enter) to select / (t) for terminal / (p) to power off / (r) to restart",
)))?;
self.action_tx.send(build_left_items(self))?; self.action_tx.send(build_left_items(self))?;
self.action_tx.send(build_right_items(self))?; self.action_tx.send(build_right_items(self))?;
self.action_tx.send(Action::Select(None, None))?; self.action_tx.send(Action::Select(None, None))?;
} }
Action::OpenTerminal => { Action::OpenTerminal => {
self.tasks.add(Task::Command( self.tasks.add(TaskType::CommandNoWait(
PathBuf::from("cmd.exe"), PathBuf::from("cmd.exe"),
vec![String::from("-new_console:n")], 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 { for component in &mut self.components {
@ -341,14 +371,15 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
chunks chunks
} }
pub fn build_command(app: &App, tool: &Tool) -> Task { pub fn build_tool_command(app: &App, tool: &Tool) -> TaskType {
let cmd_path: PathBuf; let cmd_path: PathBuf;
let mut cmd_args: Vec<String> = Vec::new(); let mut cmd_args: Vec<String> = Vec::new();
let start_index: usize; let start_index: usize;
if tool.use_conemu { if tool.use_conemu {
cmd_path = app.config.conemu_path.clone(); cmd_path = app.config.conemu_path.clone();
cmd_args.push(String::from("-new_console:n")); cmd_args.push(String::from("-run"));
cmd_args.push(tool.command.clone()); cmd_args.push(tool.command.clone());
cmd_args.push(String::from("-new_console:n"));
start_index = 1; start_index = 1;
} else { } else {
cmd_path = PathBuf::from(tool.command.clone()); cmd_path = PathBuf::from(tool.command.clone());
@ -361,7 +392,7 @@ pub fn build_command(app: &App, tool: &Tool) -> Task {
}); });
} }
} }
Task::Command(cmd_path, cmd_args) TaskType::CommandNoWait(cmd_path, cmd_args)
} }
fn build_left_items(app: &App) -> Action { fn build_left_items(app: &App) -> Action {

View file

@ -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 // under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (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 // WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. // See the GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // 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 clap::Parser;
use color_eyre::Result; use color_eyre::Result;