feat(wave-1): 适配器框架与安全基座(schema校验/dry-run/exec沙箱/密钥库/日志脱敏/字段拆分)
This commit is contained in:
@@ -15,10 +15,14 @@ pub fn detect_env() -> PlatformEnv {
|
||||
#[cfg(not(windows))]
|
||||
let (os, os_version) = (String::from("linux"), linux_os_version());
|
||||
|
||||
let (distro, distro_version) = distro_info();
|
||||
|
||||
PlatformEnv {
|
||||
os,
|
||||
os_version,
|
||||
arch: std::env::consts::ARCH.to_string(),
|
||||
distro,
|
||||
distro_version,
|
||||
shells: detect_shells(),
|
||||
runtimes: detect_runtimes(),
|
||||
path_entries: path_entries(),
|
||||
@@ -26,6 +30,31 @@ pub fn detect_env() -> PlatformEnv {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn distro_info() -> (Option<String>, Option<String>) {
|
||||
(None, None)
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn distro_info() -> (Option<String>, Option<String>) {
|
||||
parse_os_release(&std::fs::read_to_string("/etc/os-release").unwrap_or_default())
|
||||
}
|
||||
|
||||
/// 解析 os-release 内容,返回 (发行版名, 版本号)。
|
||||
/// 独立成纯函数以便跨平台单元测试。
|
||||
pub fn parse_os_release(content: &str) -> (Option<String>, Option<String>) {
|
||||
let mut id = None;
|
||||
let mut ver = None;
|
||||
for line in content.lines() {
|
||||
if let Some(v) = line.strip_prefix("ID=") {
|
||||
id = Some(v.trim().trim_matches('"').to_string());
|
||||
} else if let Some(v) = line.strip_prefix("VERSION_ID=") {
|
||||
ver = Some(v.trim().trim_matches('"').to_string());
|
||||
}
|
||||
}
|
||||
(id, ver)
|
||||
}
|
||||
|
||||
/// 从命令输出中提取首个版本号(如 "v24.18.0" -> "24.18.0")。
|
||||
/// 规则:取第一段以数字开头、由数字与点组成的子串,尾部点剔除。
|
||||
pub fn extract_version(output: &str) -> Option<String> {
|
||||
@@ -95,7 +124,7 @@ fn resolve_program(program: &str) -> Option<PathBuf> {
|
||||
}
|
||||
|
||||
/// 探测一个可执行文件:返回状态 / 版本 / 路径。
|
||||
/// 结果分类:installed / not_in_path / exec_failed / version_unparseable。
|
||||
/// 结果分类:installed / not_in_path / permission_denied / exec_failed / version_unparseable。
|
||||
fn probe(program: &str, args: &[&str]) -> Option<RuntimeInfo> {
|
||||
let path = resolve_program(program);
|
||||
let path_str = path.as_ref().map(|p| p.to_string_lossy().to_string());
|
||||
@@ -119,9 +148,15 @@ fn probe(program: &str, args: &[&str]) -> Option<RuntimeInfo> {
|
||||
|
||||
let output = match cmd.output() {
|
||||
Ok(o) => o,
|
||||
Err(_) => {
|
||||
Err(e) => {
|
||||
// 架构 §5:把「权限不足」与一般执行失败拆分开(总工 Wave 0 🟡)
|
||||
let status = if e.kind() == std::io::ErrorKind::PermissionDenied {
|
||||
"permission_denied"
|
||||
} else {
|
||||
"exec_failed"
|
||||
};
|
||||
return Some(RuntimeInfo {
|
||||
status: "exec_failed".into(),
|
||||
status: status.into(),
|
||||
version: None,
|
||||
path: path_str,
|
||||
});
|
||||
@@ -296,6 +331,29 @@ mod tests {
|
||||
assert_eq!(extract_version("v1.2.3."), Some("1.2.3".into()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_os_release_distro_and_version() {
|
||||
let content = "NAME=\"Ubuntu\"\nVERSION=\"24.04.1 LTS (Noble Numbat)\"\nID=ubuntu\nID_LIKE=debian\nVERSION_ID=\"24.04\"\n";
|
||||
let (distro, ver) = parse_os_release(content);
|
||||
assert_eq!(distro.as_deref(), Some("ubuntu"));
|
||||
assert_eq!(ver.as_deref(), Some("24.04"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_os_release_missing_fields() {
|
||||
let (distro, ver) = parse_os_release("NAME=\"Other\"\n");
|
||||
assert_eq!(distro, None);
|
||||
assert_eq!(ver, None);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[test]
|
||||
fn windows_distro_is_none() {
|
||||
let env = detect_env();
|
||||
assert_eq!(env.distro, None);
|
||||
assert_eq!(env.distro_version, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn env_has_path_on_windows() {
|
||||
// PATH 变量在任何真实 Windows/Linux 上都存在
|
||||
|
||||
@@ -11,6 +11,12 @@ pub struct PlatformEnv {
|
||||
pub os_version: String,
|
||||
/// 架构(std::env::consts::ARCH,如 x86_64)
|
||||
pub arch: String,
|
||||
/// Linux 发行版名称(如 "ubuntu");Windows 为 None。
|
||||
/// 架构 §5 原 `distro?: ubuntu + version` 合并字段,本波拆分为
|
||||
/// `distro` + `distro_version` 两个字段(总工 Wave 0 🟡)。
|
||||
pub distro: Option<String>,
|
||||
/// Linux 发行版版本(如 "22.04");Windows 为 None。
|
||||
pub distro_version: Option<String>,
|
||||
pub shells: Shells,
|
||||
pub runtimes: Runtimes,
|
||||
/// PATH 条目(Windows 用 ';' 分割,Linux 用 ':')
|
||||
@@ -41,7 +47,7 @@ pub struct Runtimes {
|
||||
/// 单个运行时探测结果
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
|
||||
pub struct RuntimeInfo {
|
||||
/// installed | not_installed | not_in_path | exec_failed | version_unparseable
|
||||
/// installed | not_in_path | permission_denied | exec_failed | version_unparseable
|
||||
pub status: String,
|
||||
pub version: Option<String>,
|
||||
/// 解析到的可执行文件绝对路径(PATH 搜索)
|
||||
|
||||
Reference in New Issue
Block a user