mirror of
https://github.com/LHY0125/PathEditor.git
synced 2026-06-29 01:45:54 +08:00
fix: 架构审查修复 — broadcast、目标校验、import_csv 警告、workspace 元数据统一
- HIGH: CLI 所有修改命令补 broadcast_env_change() - HIGH: --system/--user 互斥校验,不再静默忽略 - MEDIUM: gui/Cargo.toml 删冗余 serde_json(log 保留,lib.rs 实际使用) - MEDIUM: import_csv 对跳过行输出 log::warn - MEDIUM: ProfilePathEntry 从 core 重导出 - LOW: Cargo workspace.package 统一元数据 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -5,3 +5,10 @@ members = [
|
||||
"gui",
|
||||
"cli",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "5.0.0"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
authors = ["刘航宇"]
|
||||
repository = "https://github.com/LHY0125/PathEditor"
|
||||
|
||||
+4
-8
@@ -1,16 +1,12 @@
|
||||
[package]
|
||||
name = "patheditor-cli"
|
||||
version = "5.0.0"
|
||||
description = "PathEditor CLI — command-line interface for Windows PATH management"
|
||||
authors = ["刘航宇"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
[dependencies]
|
||||
path-editor-core = { path = "../core" }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
[[bin]]
|
||||
name = "patheditor"
|
||||
path = "src/main.rs"
|
||||
|
||||
+15
-9
@@ -110,14 +110,15 @@ fn exit_err(msg: &str) -> ! {
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
fn pick_target(system: bool, _user: bool) -> &'static str {
|
||||
fn ensure_single_target(system: bool, user: bool) -> &'static str {
|
||||
if system && user { exit_err("不能同时指定 --system 和 --user"); }
|
||||
if system { "system" } else { "user" }
|
||||
}
|
||||
|
||||
type SaveFn = fn(Vec<String>) -> Result<(), String>;
|
||||
|
||||
fn load_and_save(system: bool, f: impl FnOnce(Vec<String>) -> Vec<String>) {
|
||||
let target = pick_target(system, false);
|
||||
let target = ensure_single_target(system, false);
|
||||
let (list, save): (Vec<String>, SaveFn) = if target == "system" {
|
||||
(core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e)),
|
||||
core::registry::save_system_paths)
|
||||
@@ -156,17 +157,18 @@ fn cmd_list(system: bool, user: bool, json_out: bool) {
|
||||
}
|
||||
|
||||
fn cmd_add(path: String, system: bool, user: bool) {
|
||||
let target = pick_target(system, user);
|
||||
let target = ensure_single_target(system, user);
|
||||
load_and_save(system || false, |mut list| {
|
||||
list.push(path.clone());
|
||||
list
|
||||
});
|
||||
let label = if target == "system" { "系统" } else { "用户" };
|
||||
println!("已添加到{} PATH: {path}", label);
|
||||
core::system::broadcast_env_change();
|
||||
}
|
||||
|
||||
fn cmd_remove(index: usize, system: bool) {
|
||||
let target = pick_target(system, false);
|
||||
let target = ensure_single_target(system, false);
|
||||
let mut list = if target == "system" {
|
||||
core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e))
|
||||
} else {
|
||||
@@ -177,10 +179,11 @@ fn cmd_remove(index: usize, system: bool) {
|
||||
let save: SaveFn = if target == "system" { core::registry::save_system_paths } else { core::registry::save_user_paths };
|
||||
save(list).unwrap_or_else(|e| exit_err(&e));
|
||||
println!("已删除: {removed}");
|
||||
core::system::broadcast_env_change();
|
||||
}
|
||||
|
||||
fn cmd_edit(index: usize, new_path: String, system: bool) {
|
||||
let target = pick_target(system, false);
|
||||
let target = ensure_single_target(system, false);
|
||||
let mut list = if target == "system" {
|
||||
core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e))
|
||||
} else {
|
||||
@@ -191,6 +194,7 @@ fn cmd_edit(index: usize, new_path: String, system: bool) {
|
||||
let save: SaveFn = if target == "system" { core::registry::save_system_paths } else { core::registry::save_user_paths };
|
||||
save(list).unwrap_or_else(|e| exit_err(&e));
|
||||
println!("已编辑: {old} → {new_path}");
|
||||
core::system::broadcast_env_change();
|
||||
}
|
||||
|
||||
fn cmd_move(index: usize, steps: usize, system: bool, up: bool) {
|
||||
@@ -208,10 +212,11 @@ fn cmd_move(index: usize, steps: usize, system: bool, up: bool) {
|
||||
});
|
||||
let dir = if up { "上移" } else { "下移" };
|
||||
println!("{dir} {steps} 格完成");
|
||||
core::system::broadcast_env_change();
|
||||
}
|
||||
|
||||
fn cmd_clean(system: bool, user: bool, dry_run: bool, json_out: bool) {
|
||||
let target = pick_target(system, user);
|
||||
let target = ensure_single_target(system, user);
|
||||
let list = if target == "system" {
|
||||
core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e))
|
||||
} else {
|
||||
@@ -231,6 +236,7 @@ fn cmd_clean(system: bool, user: bool, dry_run: bool, json_out: bool) {
|
||||
let save: SaveFn = if target == "system" { core::registry::save_system_paths } else { core::registry::save_user_paths };
|
||||
save(kept).unwrap_or_else(|e| exit_err(&e));
|
||||
println!("清理完成:移除 {} 条,保留 {} 条", removed.len(), kept_count);
|
||||
core::system::broadcast_env_change();
|
||||
if !removed.is_empty() {
|
||||
for r in &removed { println!(" 已移除: {}", r); }
|
||||
}
|
||||
@@ -238,7 +244,7 @@ fn cmd_clean(system: bool, user: bool, dry_run: bool, json_out: bool) {
|
||||
}
|
||||
|
||||
fn cmd_toggle(index: usize, system: bool, user: bool, enable: bool) {
|
||||
let target = pick_target(system, user);
|
||||
let target = ensure_single_target(system, user);
|
||||
let list = if target == "system" {
|
||||
core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e))
|
||||
} else {
|
||||
@@ -357,8 +363,8 @@ fn profile_list(json_out: bool) {
|
||||
fn profile_save(name: String) {
|
||||
let sys = core::registry::load_system_paths().unwrap_or_else(|e| exit_err(&e));
|
||||
let usr = core::registry::load_user_paths().unwrap_or_else(|e| exit_err(&e));
|
||||
let sys_entries = sys.into_iter().map(|p| core::profiles::ProfilePathEntry { path: p, enabled: true }).collect();
|
||||
let usr_entries = usr.into_iter().map(|p| core::profiles::ProfilePathEntry { path: p, enabled: true }).collect();
|
||||
let sys_entries = sys.into_iter().map(|p| core::ProfilePathEntry { path: p, enabled: true }).collect();
|
||||
let usr_entries = usr.into_iter().map(|p| core::ProfilePathEntry { path: p, enabled: true }).collect();
|
||||
core::profiles::save_profile(&name, sys_entries, usr_entries).unwrap_or_else(|e| exit_err(&e));
|
||||
println!("已保存配置: {name}");
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,10 +1,10 @@
|
||||
[package]
|
||||
name = "path-editor-core"
|
||||
version = "5.0.0"
|
||||
description = "PathEditor core library — shared between GUI and CLI"
|
||||
authors = ["刘航宇"]
|
||||
license = "MIT"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
+7
-3
@@ -36,13 +36,17 @@ fn import_csv(content: &str) -> Result<(Vec<String>, Vec<String>), String> {
|
||||
let mut sys = Vec::new();
|
||||
let mut usr = Vec::new();
|
||||
for line in content.lines() {
|
||||
let fields: Vec<&str> = line.split(',').collect();
|
||||
let trimmed = line.trim();
|
||||
if trimmed.is_empty() { continue; }
|
||||
let fields: Vec<&str> = trimmed.split(',').collect();
|
||||
if fields.len() >= 2 {
|
||||
match fields[0].trim() {
|
||||
match fields[0].trim().to_lowercase().as_str() {
|
||||
"system" | "sys" => sys.push(fields[1].trim().to_string()),
|
||||
"user" | "usr" => usr.push(fields[1].trim().to_string()),
|
||||
_ => {}
|
||||
_ => { log::warn!("import_csv: 无法识别的类型字段,已跳过: {trimmed}"); }
|
||||
}
|
||||
} else {
|
||||
log::warn!("import_csv: 格式不正确(缺逗号),已跳过: {trimmed}");
|
||||
}
|
||||
}
|
||||
if sys.is_empty() && usr.is_empty() {
|
||||
|
||||
+1
-1
@@ -6,5 +6,5 @@ pub mod registry;
|
||||
pub mod scanner;
|
||||
pub mod system;
|
||||
|
||||
pub use profiles::{ProfileData, ProfileMeta};
|
||||
pub use profiles::{ProfileData, ProfileMeta, ProfilePathEntry};
|
||||
pub use scanner::{ConflictEntry, ConflictLocation, ToolGroup};
|
||||
|
||||
+5
-6
@@ -1,11 +1,11 @@
|
||||
[package]
|
||||
name = "patheditor"
|
||||
version = "5.0.0"
|
||||
description = "Windows PATH Environment Variable Editor"
|
||||
authors = ["刘航宇"]
|
||||
license = "MIT"
|
||||
repository = "https://github.com/LHY0125/PathEditor"
|
||||
edition = "2021"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version = "1.77.2"
|
||||
|
||||
[lib]
|
||||
@@ -17,7 +17,6 @@ tauri-build = { version = "2.6.2", features = [] }
|
||||
|
||||
[dependencies]
|
||||
path-editor-core = { path = "../core" }
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
log = "0.4"
|
||||
tauri = { version = "2.11.2", features = [] }
|
||||
|
||||
Reference in New Issue
Block a user