1use crate::DELIMITER;
2use path_clean::PathClean;
3use std::ffi::OsStr;
4use std::path::Path;
5
6pub(crate) fn exec<S, I>(cmd: S, args: I) -> bool
7where
8 I: IntoIterator<Item = S>,
9 S: AsRef<OsStr>,
10{
11 std::process::Command::new(cmd)
12 .envs(std::env::vars())
13 .args(args)
14 .output()
15 .is_ok()
16}
17
18pub fn get_path() -> Vec<String> {
19 let path = std::env::var("PATH")
20 .expect("Failed to get PATH")
21 .to_string();
22 path.split(DELIMITER)
23 .map(|s| s.replace("\\", "/").to_string())
24 .collect()
25}
26
27pub fn has_path(path: &str) -> bool {
28 let path = &expand_path(path);
29 #[cfg(windows)]
30 let path = to_win_path(path).replace("\\", "/");
31 get_path().iter().any(|i| i.eq_ignore_ascii_case(&path))
32}
33
34pub fn to_win_path(path: &str) -> String {
36 let mut path = path.replace("/", "\\");
37 if let Some(s) = path.as_mut_str().get_mut(0..3)
38 && s.ends_with(":\\")
39 {
40 s.make_ascii_uppercase();
41 }
42 path
43}
44
45pub fn is_msys() -> bool {
46 std::env::var("MSYSTEM").is_ok()
47}
48
49pub fn to_msys_path(path: &str) -> String {
51 let mut path = path.replace("\\", "/");
52 if let Some(s) = path.as_mut_str().get_mut(0..3)
53 && s.len() == 3
54 && s.ends_with(":/")
55 {
56 unsafe {
57 let p = s.as_mut_ptr();
58 let name = (*p).to_ascii_lowercase();
59 *p = b'/';
60 *(p.wrapping_add(1)) = name;
61 *(p.wrapping_add(2)) = b'/';
62 };
63 }
64 path
65}
66
67pub(crate) fn expand_path(path: &str) -> String {
68 let expanded = shellexpand::tilde(path);
69 Path::new(&*expanded).clean().to_string_lossy().to_string()
70}
71
72#[cfg(test)]
73mod test {
74 use super::get_path;
75
76 #[test]
77 fn test_get_path() {
78 let path = get_path();
79 assert!(!path.is_empty())
80 }
81}