From 7015c9b90a7ae28b76b943ea9f5669c5a3357002 Mon Sep 17 00:00:00 2001 From: mrbeanc Date: Sun, 24 Dec 2023 13:21:46 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8Dget=5Frelative=5Fpath(?= =?UTF-8?q?)=E4=B8=8D=E8=83=BD=E5=A4=84=E7=90=86=E4=B8=8A=E7=BA=A7?= =?UTF-8?q?=E7=9B=AE=E5=BD=95=E6=96=87=E4=BB=B6=E7=9A=84bug=EF=BC=8C?= =?UTF-8?q?=E5=A6=82[../a.txt]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/util.rs | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/src/utils/util.rs b/src/utils/util.rs index d46cf4c..4222f62 100644 --- a/src/utils/util.rs +++ b/src/utils/util.rs @@ -332,15 +332,38 @@ pub fn list_workdir_files() -> Vec { } } -/// 获取相对于dir的相对路径 +/// 获取相对于dir的 规范化 相对路径(不包含../ ./) pub fn get_relative_path(path: &Path, dir: &Path) -> PathBuf { - let path = if path.is_relative() { + // 先统一为绝对路径 + let abs_path = if path.is_relative() { get_absolute_path(path) } else { path.to_path_buf() }; - let relative_path = path.strip_prefix(dir).unwrap(); - relative_path.to_path_buf() + // 要考虑path在dir的上级目录的情况,要输出../../xxx + let common_dir = get_common_dir(&abs_path, dir); + let mut rel_path = PathBuf::new(); + let mut _dir = dir.to_path_buf(); + while _dir != common_dir { + rel_path.push(".."); + _dir.pop(); + } + rel_path.join(abs_path.strip_prefix(common_dir).unwrap()) +} + +/// 获取两个路径的公共目录 +pub fn get_common_dir(p1: &Path, p2: &Path) -> PathBuf { + let p1 = get_absolute_path(p1); + let p2 = get_absolute_path(p2); + let mut common_dir = PathBuf::new(); + for (c1, c2) in p1.components().zip(p2.components()) { + if c1 == c2 { + common_dir.push(c1); + } else { + break; + } + } + common_dir } /// 获取相较于工作区(Working Dir)的相对路径 @@ -348,6 +371,11 @@ pub fn to_workdir_relative_path(path: &Path) -> PathBuf { get_relative_path(path, &get_working_dir().unwrap()) } +/// 获取相较于当前目录的 规范化 相对路径(不包含../ ./) +pub fn to_cur_relative_path(path: &Path) -> PathBuf { + get_relative_path(path, &cur_dir()) +} + /// 获取相较于工作区(Working Dir)的绝对路径 pub fn to_workdir_absolute_path(path: &Path) -> PathBuf { get_absolute_path_to_dir(path, &get_working_dir().unwrap()) @@ -524,6 +552,16 @@ mod tests { assert_eq!(abs_path, cur_dir); } + #[test] + fn test_get_relative_path() { + setup_test_with_clean_mit(); + let path = Path::new("../../src\\main.rs"); + let rel_path = get_relative_path(&path, &cur_dir()); + println!("{:?}", rel_path); + + assert_eq!(rel_path, unify_path_separator(path)); + } + #[test] fn test_to_workdir_absolute_path() { setup_test_with_clean_mit();