mirror of
https://github.com/TECHNOFAB11/pay-respects.git
synced 2025-12-11 22:10:09 +01:00
feat: prompt to install missing command
This commit is contained in:
parent
ab3534f0ef
commit
c99c736ad5
7 changed files with 351 additions and 23 deletions
222
Cargo.lock
generated
222
Cargo.lock
generated
|
|
@ -17,6 +17,12 @@ version = "1.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base62"
|
||||
version = "2.0.3"
|
||||
|
|
@ -45,6 +51,12 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.1"
|
||||
|
|
@ -95,6 +107,31 @@ version = "0.8.20"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crossterm_winapi",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl"
|
||||
version = "0.4.47"
|
||||
|
|
@ -125,6 +162,12 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
|
|
@ -153,6 +196,24 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4"
|
||||
|
||||
[[package]]
|
||||
name = "fuzzy-matcher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||
dependencies = [
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fxhash"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.1"
|
||||
|
|
@ -221,6 +282,23 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inquire"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"crossterm",
|
||||
"dyn-clone",
|
||||
"fuzzy-matcher",
|
||||
"fxhash",
|
||||
"newline-converter",
|
||||
"once_cell",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.11"
|
||||
|
|
@ -289,6 +367,16 @@ version = "0.4.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
|
|
@ -301,6 +389,27 @@ version = "2.7.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "newline-converter"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "normpath"
|
||||
version = "1.3.0"
|
||||
|
|
@ -334,12 +443,36 @@ dependencies = [
|
|||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pay-respects"
|
||||
version = "0.5.14"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"curl",
|
||||
"inquire",
|
||||
"pay-respects-parser",
|
||||
"regex-lite",
|
||||
"rust-i18n",
|
||||
|
|
@ -387,6 +520,15 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
|
|
@ -527,6 +669,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.215"
|
||||
|
|
@ -591,6 +739,36 @@ version = "1.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-mio"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "1.0.1"
|
||||
|
|
@ -691,6 +869,16 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.7.8"
|
||||
|
|
@ -773,6 +961,12 @@ version = "0.1.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.14"
|
||||
|
|
@ -795,6 +989,28 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
|
|
@ -804,6 +1020,12 @@ dependencies = [
|
|||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ serde = { version = "1.0", features = ["derive"], optional = true }
|
|||
curl = { version = "0.4", optional = true }
|
||||
textwrap = { version = "0.16", features = ["terminal_size"], optional = true }
|
||||
|
||||
inquire = "0.7.5"
|
||||
|
||||
pay-respects-parser = "0.2.6"
|
||||
# pay-respects-parser = { path = "../pay-respects-parser" }
|
||||
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ pub fn get_best_match_file(input: &str) -> Option<String> {
|
|||
})
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
let best_match = find_similar(&exit_dir, &dir_files);
|
||||
let best_match = find_similar(&exit_dir, &dir_files, Some(1));
|
||||
best_match.as_ref()?;
|
||||
|
||||
input = format!("{}/{}", input, best_match.unwrap());
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ mod rules;
|
|||
mod shell;
|
||||
mod style;
|
||||
mod suggestions;
|
||||
mod system;
|
||||
|
||||
#[cfg(feature = "runtime-rules")]
|
||||
mod replaces;
|
||||
|
|
|
|||
64
src/modes.rs
64
src/modes.rs
|
|
@ -1,8 +1,10 @@
|
|||
use crate::shell::{command_output, get_shell, PRIVILEGE_LIST};
|
||||
use crate::style::highlight_difference;
|
||||
use crate::suggestions::{split_command, suggest_typo};
|
||||
use crate::suggestions::{best_match_path, split_command};
|
||||
use crate::system;
|
||||
use crate::{shell, suggestions};
|
||||
use colored::Colorize;
|
||||
use inquire::*;
|
||||
|
||||
pub fn suggestion() {
|
||||
let shell = get_shell();
|
||||
|
|
@ -78,21 +80,51 @@ pub fn cnf() {
|
|||
false => split_command.first().expect(&t!("no-command")).as_str(),
|
||||
};
|
||||
|
||||
let best_match = suggest_typo(&[executable.to_owned()], vec!["path".to_string()]);
|
||||
if best_match == executable {
|
||||
eprintln!("{}: command not found: {}", shell, executable);
|
||||
return;
|
||||
}
|
||||
match PRIVILEGE_LIST.contains(&split_command[0].as_str()) {
|
||||
true => {
|
||||
split_command[1] = best_match;
|
||||
let best_match = best_match_path(executable);
|
||||
if best_match.is_some() {
|
||||
let best_match = best_match.unwrap();
|
||||
match PRIVILEGE_LIST.contains(&split_command[0].as_str()) {
|
||||
true => {
|
||||
split_command[1] = best_match;
|
||||
}
|
||||
false => {
|
||||
split_command[0] = best_match;
|
||||
}
|
||||
}
|
||||
false => {
|
||||
split_command[0] = best_match;
|
||||
}
|
||||
}
|
||||
let suggestion = split_command.join(" ");
|
||||
let suggestion = split_command.join(" ");
|
||||
|
||||
let highlighted_suggestion = highlight_difference(&shell, &suggestion, &last_command).unwrap();
|
||||
let _ = suggestions::confirm_suggestion(&shell, &suggestion, &highlighted_suggestion);
|
||||
let highlighted_suggestion =
|
||||
highlight_difference(&shell, &suggestion, &last_command).unwrap();
|
||||
let _ = suggestions::confirm_suggestion(&shell, &suggestion, &highlighted_suggestion);
|
||||
} else {
|
||||
let package_manager = match system::get_package_manager(&shell) {
|
||||
Some(package_manager) => package_manager,
|
||||
None => {
|
||||
eprintln!("no package manager found");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let packages = match system::get_packages(&shell, &package_manager, executable) {
|
||||
Some(packages) => packages,
|
||||
None => {
|
||||
eprintln!("no package found");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let ans = Select::new("Select a package to install", packages).prompt();
|
||||
let package = match ans {
|
||||
Ok(package) => package,
|
||||
Err(_) => {
|
||||
eprintln!("no package selected");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// retry after installing package
|
||||
if system::install_package(&shell, &package_manager, &package) {
|
||||
let _ = suggestions::confirm_suggestion(&shell, &last_command, &last_command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ pub fn suggest_command(shell: &str, last_command: &str, error_msg: &str) -> Opti
|
|||
// skip for commands with no arguments,
|
||||
// very likely to be an error showing the usage
|
||||
if PRIVILEGE_LIST.contains(&split_command[0].as_str()) && split_command.len() > 2
|
||||
|| !PRIVILEGE_LIST.contains(&split_command[0].as_str()) && split_command.len() > 1 {
|
||||
|| !PRIVILEGE_LIST.contains(&split_command[0].as_str()) && split_command.len() > 1
|
||||
{
|
||||
let suggest = ai_suggestion(last_command, error_msg);
|
||||
if let Some(suggest) = suggest {
|
||||
let warn = format!("{}:", t!("ai-suggestion")).bold().blue();
|
||||
|
|
@ -184,7 +185,7 @@ pub fn suggest_typo(typos: &[String], candidates: Vec<String>) -> String {
|
|||
if path_files.is_empty() {
|
||||
path_files = get_path_files();
|
||||
};
|
||||
if let Some(suggest) = find_similar(typo, &path_files) {
|
||||
if let Some(suggest) = find_similar(typo, &path_files, Some(2)) {
|
||||
suggestions.push(suggest);
|
||||
} else {
|
||||
suggestions.push(typo.to_string());
|
||||
|
|
@ -199,7 +200,7 @@ pub fn suggest_typo(typos: &[String], candidates: Vec<String>) -> String {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
} else if let Some(suggest) = find_similar(typo, &candidates) {
|
||||
} else if let Some(suggest) = find_similar(typo, &candidates, Some(2)) {
|
||||
suggestions.push(suggest);
|
||||
} else {
|
||||
suggestions.push(typo.to_string());
|
||||
|
|
@ -208,8 +209,19 @@ pub fn suggest_typo(typos: &[String], candidates: Vec<String>) -> String {
|
|||
suggestions.join(" ")
|
||||
}
|
||||
|
||||
pub fn find_similar(typo: &str, candidates: &[String]) -> Option<String> {
|
||||
let mut min_distance = { std::cmp::max(2, typo.chars().count() / 2 + 1) };
|
||||
pub fn best_match_path(typo: &str) -> Option<String> {
|
||||
let path_files = get_path_files();
|
||||
find_similar(typo, &path_files, Some(3))
|
||||
}
|
||||
|
||||
// higher the threshold, the stricter the comparison
|
||||
// 1: anything
|
||||
// 2: 50% similarity
|
||||
// 3: 33% similarity
|
||||
// ... etc
|
||||
pub fn find_similar(typo: &str, candidates: &[String], threshold: Option<usize>) -> Option<String> {
|
||||
let threshold = threshold.unwrap_or(2);
|
||||
let mut min_distance = typo.chars().count() / threshold + 1;
|
||||
let mut min_distance_index = None;
|
||||
for (i, candidate) in candidates.iter().enumerate() {
|
||||
if candidate.is_empty() {
|
||||
|
|
@ -344,4 +356,3 @@ fn run_suggestion(shell: &str, command: &str) -> std::process::ExitStatus {
|
|||
.wait()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
|
|
|
|||
60
src/system.rs
Normal file
60
src/system.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use std::io::stderr;
|
||||
use std::process::Command;
|
||||
use std::process::Stdio;
|
||||
|
||||
pub fn get_package_manager(shell: &str) -> Option<String> {
|
||||
let package_managers = vec!["pacman", "apt", "dnf"];
|
||||
|
||||
for package_manager in package_managers {
|
||||
let success = Command::new(shell)
|
||||
.arg("-c")
|
||||
.arg(format!("command -v {}", package_manager))
|
||||
.output()
|
||||
.expect("failed to execute process")
|
||||
.status
|
||||
.success();
|
||||
|
||||
if success {
|
||||
return Some(package_manager.to_string());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_packages(shell: &str, package_manager: &str, executable: &str) -> Option<Vec<String>> {
|
||||
match package_manager {
|
||||
"pacman" => {
|
||||
let result = Command::new(shell)
|
||||
.arg("-c")
|
||||
.arg(format!("pacman -Fq /usr/bin/{}", executable))
|
||||
.output()
|
||||
.expect("failed to execute process");
|
||||
if result.status.success() {
|
||||
let output = String::from_utf8_lossy(&result.stdout)
|
||||
.lines()
|
||||
.map(|line| line.split_whitespace().next().unwrap().to_string())
|
||||
.collect();
|
||||
Some(output)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => unreachable!("Unsupported package manager"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn install_package(shell: &str, package_manager: &str, package: &str) -> bool {
|
||||
match package_manager {
|
||||
"pacman" => Command::new(shell)
|
||||
.arg("-c")
|
||||
.arg(format!("sudo pacman -S {}", package))
|
||||
.stdout(stderr())
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()
|
||||
.expect("failed to execute process")
|
||||
.wait()
|
||||
.unwrap()
|
||||
.success(),
|
||||
_ => unreachable!("Unsupported package manager"),
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue