fix: msys2 path (github #12)

This commit is contained in:
莯凛 2024-11-24 20:00:31 +08:00 committed by GitHub
parent 6feb88d48f
commit 659235bf2e
5 changed files with 80 additions and 13 deletions

2
Cargo.lock generated
View file

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
version = 4
[[package]]
name = "aho-corasick"

View file

@ -11,10 +11,7 @@ repository = "https://github.com/iffse/pay-respects"
keywords = ["cli", "terminal", "utility", "shell"]
categories = ["command-line-utilities"]
license = "AGPL-3.0"
include = [
"**/*.rs",
"**/*.toml",
]
include = ["**/*.rs", "**/*.toml"]
[dependencies]
colored = "2"
@ -26,7 +23,7 @@ toml = { version = "0.8", optional = true }
serde_json = { version = "1.0", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
curl = { version = "0.4", optional = true }
textwrap = { version = "0.16", features = ["terminal_size"], optional = true}
textwrap = { version = "0.16", features = ["terminal_size"], optional = true }
pay-respects-parser = "0.2.6"
# pay-respects-parser = { path = "../pay-respects-parser" }

View file

@ -1,34 +1,89 @@
use crate::suggestions::find_similar;
pub fn get_path_files() -> Vec<String> {
let path = std::env::var("PATH").unwrap();
#[cfg(target_os = "windows")]
let path = path.split(';').collect::<Vec<&str>>();
#[cfg(not(target_os = "windows"))]
let path = path.split(':').collect::<Vec<&str>>();
let path_env = if cfg!(windows) {
String::from_utf8_lossy(
&std::process::Command::new("bash")
.arg("-c")
.arg("echo $PATH")
.output()
.unwrap()
.stdout,
)
.trim()
.to_owned()
} else {
std::env::var("PATH").unwrap()
};
if cfg!(debug_assertions) {
eprintln!("path_env: {path_env}");
}
let path = path_env.split(':').collect::<Vec<&str>>();
let mut all_executable = vec![];
for p in path {
#[cfg(windows)]
let p = msys2_conv_path(p).expect("Failed to convert path for msys");
if cfg!(debug_assertions) {
eprintln!("p={p}");
}
let files = match std::fs::read_dir(p) {
Ok(files) => files,
Err(_) => continue,
};
for file in files {
let file = file.unwrap();
let file_name = file.file_name().into_string().unwrap();
#[allow(unused_mut)]
let mut file_name = file.file_name().into_string().unwrap();
#[cfg(windows)]
{
let mut ok = false;
let suffixies = [".exe", ".sh", ".ps1"];
for suffix in suffixies {
if let Some(file_name_strip) = file_name.strip_suffix(suffix) {
file_name = file_name_strip.to_owned();
ok = true;
break;
}
}
if !file_name.contains(".") {
ok = true;
}
if !ok {
continue;
}
}
all_executable.push(file_name);
}
}
if cfg!(debug_assertions) {
let mut all_executable = all_executable.clone();
all_executable.sort_unstable();
eprintln!("all_executable={all_executable:?}");
}
all_executable
}
pub fn get_best_match_file(input: &str) -> Option<String> {
let mut input = input.trim_matches(|c| c == '\'' || c == '"').to_owned();
if cfg!(debug_assertions) {
eprintln!("get_best_match_file input: {input}");
}
let mut exit_dirs = Vec::new();
let mut files = loop {
match std::fs::read_dir(&input) {
Ok(files) => break files,
Err(_) => {
if let Some((dirs, exit_dir)) = input.rsplit_once('/') {
if let Some((dirs, exit_dir)) = input.rsplit_once(std::path::MAIN_SEPARATOR) {
exit_dirs.push(exit_dir.to_owned());
input = dirs.to_owned();
} else {
@ -61,3 +116,12 @@ pub fn get_best_match_file(input: &str) -> Option<String> {
Some(input)
}
#[cfg(windows)]
fn msys2_conv_path(p: &str) -> std::io::Result<String> {
std::process::Command::new("cygpath")
.arg("-w")
.arg(p)
.output()
.map(|output| String::from_utf8_lossy(&output.stdout).trim().to_owned())
}

View file

@ -16,6 +16,9 @@ pub fn highlight_difference(
if split_suggested_command == split_last_command {
return None;
}
if split_suggested_command.is_empty() {
return None;
}
let privileged = PRIVILEGE_LIST.contains(&split_suggested_command[0].as_str());

View file

@ -153,6 +153,9 @@ pub fn eval_shell_command(shell: &str, command: &str) -> Vec<String> {
}
pub fn split_command(command: &str) -> Vec<String> {
if cfg!(debug_assertions) {
eprintln!("command: {command}")
}
// this regex splits the command separated by spaces, except when the space
// is escaped by a backslash or surrounded by quotes
let regex = r#"([^\s"'\\]+|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\\ )+|\\|\n"#;