1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use std::path::PathBuf;
use support_common::error::BridgerError;

pub fn list_externals(
    except_base_path: Option<PathBuf>,
) -> color_eyre::Result<(PathBuf, Vec<String>)> {
    let base_path = except_base_path
        .or(std::env::current_exe()?.parent().map(|v| v.join("")))
        .ok_or_else(|| {
            BridgerError::Custom("Can not get base path for external command".to_string())
        })?;
    tracing::trace!(target: "bridger", "The external base path is: {:?}", base_path);
    let read_dir = std::fs::read_dir(&base_path)?;
    let mut binaries = Vec::new();
    for dir in read_dir {
        let path = dir?.path();
        if !path.is_file() {
            continue;
        }
        let name = match path.file_name() {
            Some(v) => v.to_string_lossy().to_string(),
            None => continue,
        };
        if !support_common::constants::ALLOW_BINARY_PREFIX
            .iter()
            .any(|&item| name.starts_with(item))
        {
            continue;
        }
        if &name == "bridger" || &name == "bridger.exe" {
            continue;
        }
        if let Some(extension) = path.extension().and_then(|item| item.to_str()) {
            if cfg!(windows) {
                match extension {
                    "exe" | "bat" | "cmd" => {}
                    _ => continue,
                }
            } else if extension != "sh" {
                continue;
            }
        }
        binaries.push(name);
    }
    Ok((base_path, binaries))
}