From 6b18873666e17ab68ffce799b1707c030166738f Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Mon, 10 Aug 2026 14:40:37 +0800 Subject: fix: strip verbatim prefix from canonicalized paths on Windows Refactor `find_project_root` to use `deverbatim` on canonicalized paths, removing the `\\?\` prefix on Windows to ensure proper path handling. --- mingling_cli/src/proj_mgr/cmd_class_add.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/mingling_cli/src/proj_mgr/cmd_class_add.rs b/mingling_cli/src/proj_mgr/cmd_class_add.rs index 5973252..456ec2f 100644 --- a/mingling_cli/src/proj_mgr/cmd_class_add.rs +++ b/mingling_cli/src/proj_mgr/cmd_class_add.rs @@ -54,7 +54,7 @@ pub fn class_add(args: EntryClassAdd) -> Next { /// Walk upward from `start` to find the first directory containing `.mling`. fn find_project_root(start: &Path) -> Option { - let mut dir = fs::canonicalize(start).ok()?; + let mut dir = deverbatim(&fs::canonicalize(start).ok()?); loop { if dir.join(".mling").is_dir() { return Some(dir); @@ -65,6 +65,28 @@ fn find_project_root(start: &Path) -> Option { } } +/// Deverbatim a Windows path: strip the `\\?\` prefix that `fs::canonicalize` +/// may add. On non-Windows platforms this is a no-op. +/// +/// On Windows, canonical paths sometimes carry a verbatim prefix like +/// `\\?\C:\...`. This function removes that prefix. For UNC paths such as +/// `\\?\UNC\server\share`, the prefix is converted back to the conventional +/// `\\server\share` form. +fn deverbatim(path: &Path) -> PathBuf { + if !cfg!(windows) { + return path.to_path_buf(); + } + let as_string = path.to_string_lossy(); + if let Some(rest) = as_string.strip_prefix(r"\\?\") { + // Turns `\\?\UNC\server\share` back into `\\server\share`. + if let Some(share) = rest.strip_prefix("UNC\\") { + return PathBuf::from(format!(r"\\{share}")); + } + return PathBuf::from(rest.to_owned()); + } + path.to_path_buf() +} + /// Read `.mling/classes.toml`, find the class template and render it with the /// name-derived parameters into `/.rs`. #[chain(routeify)] -- cgit