Skip to content

Commit

Permalink
fix: canonicalize the symlink path in method 'canonicalize_input_file…
Browse files Browse the repository at this point in the history
…s'. (#605)

* fix: canonicalize the symlink path in method 'canonicalize_input_files'.

* fix: replace all existing paths with real paths.
  • Loading branch information
zong-zhe committed Jul 12, 2023
1 parent 09ca845 commit 64401fa
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 7 deletions.
3 changes: 3 additions & 0 deletions kclvm/cmd/src/test_data/sym_link/origin/a.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import .sub

a = sub.a
1 change: 1 addition & 0 deletions kclvm/cmd/src/test_data/sym_link/origin/sub/a.k
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a=1
60 changes: 59 additions & 1 deletion kclvm/cmd/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{env, fs, path::PathBuf};
use std::{
env,
fs::{self, remove_file},
path::{Path, PathBuf},
};

use kclvm_config::modfile::KCL_PKG_PATH;

Expand All @@ -7,6 +11,11 @@ use crate::{
vet::vet_command,
};

#[cfg(unix)]
use std::os::unix::fs::symlink;
#[cfg(windows)]
use std::os::windows::fs::symlink_file as symlink;

const ROOT_CMD: &str = "kclvm_cli";

#[test]
Expand Down Expand Up @@ -193,6 +202,7 @@ fn test_run_command() {
test_run_command_with_import();
test_run_command_with_konfig();
test_load_cache_with_different_pkg();
test_kcl_path_is_sym_link();
}

fn test_run_command_with_import() {
Expand Down Expand Up @@ -294,3 +304,51 @@ fn check_run_command_with_env(test_case_path: PathBuf, kcl_pkg_path_env: String)
let expect = expect.replace("\r\n", "\n");
assert_eq!(String::from_utf8(buf).unwrap(), expect);
}

fn test_kcl_path_is_sym_link() {
let origin = "./src/test_data/sym_link/origin";
let link = "./src/test_data/sym_link/sym_link";

let origin_k_file_path = PathBuf::from(origin).join("a.k");
let origin_matches = app().arg_required_else_help(true).get_matches_from(&[
ROOT_CMD,
"run",
origin_k_file_path.to_str().unwrap(),
]);

let mut origin_res = Vec::new();
run_command(
origin_matches.subcommand_matches("run").unwrap(),
&mut origin_res,
)
.unwrap();

// Create a symlink
symlink(
PathBuf::from(origin).canonicalize().unwrap(),
Path::new(link),
)
.unwrap();

let sym_link_k_file_path = PathBuf::from(link).join("a.k");
let mut sym_link_res = Vec::new();
let sym_link_matches = app().arg_required_else_help(true).get_matches_from(&[
ROOT_CMD,
"run",
sym_link_k_file_path.to_str().unwrap(),
]);
run_command(
sym_link_matches.subcommand_matches("run").unwrap(),
&mut sym_link_res,
)
.unwrap();

// compare the result from origin kcl path and symlink kcl path.
assert_eq!(
String::from_utf8(sym_link_res),
String::from_utf8(origin_res)
);

// clean up the symlink
remove_file(link).unwrap();
}
35 changes: 29 additions & 6 deletions kclvm/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use kclvm_parser::LoadProgramOptions;
use kclvm_utils::path::PathPrefix;
use kpm_metadata::fill_pkg_maps_for_k_file;
use std::{
fs::read_dir,
fs::{self, read_dir},
io::{self, ErrorKind},
path::{Path, PathBuf},
};
Expand All @@ -31,25 +31,48 @@ pub fn canonicalize_input_files(

// The first traversal changes the relative path to an absolute path
for (_, file) in k_files.iter().enumerate() {
let path = Path::new(file);
let is_absolute = path.is_absolute();
let is_exist_maybe_symlink = path.exists();
// If the input file or path is a relative path and it is not a absolute path in the KCL module VFS,
// join with the work directory path and convert it to a absolute path.
if !file.starts_with(KCL_MOD_PATH_ENV) && !Path::new(file).is_absolute() {

let abs_path = if !is_absolute && !file.starts_with(KCL_MOD_PATH_ENV) {
let filepath = Path::new(&work_dir).join(file);
match filepath.canonicalize() {
Ok(path) => kcl_paths.push(path.adjust_canonicalization()),
Ok(path) => Some(path.adjust_canonicalization()),
Err(_) => {
kcl_paths.push(filepath.to_string_lossy().to_string());
if check_exist {
return Err(format!(
"Cannot find the kcl file, please check whether the file path {}",
file
));
}
Some(filepath.to_string_lossy().to_string())
}
}
} else {
kcl_paths.push(String::from(file))
}
None
};
// If the input file or path is a symlink, convert it to a real path.
let real_path = if is_exist_maybe_symlink {
match PathBuf::from(file).canonicalize() {
Ok(real_path) => Some(String::from(real_path.to_str().unwrap())),
Err(_) => {
if check_exist {
return Err(format!(
"Cannot find the kcl file, please check whether the file path {}",
file
));
}
Some(file.to_string())
}
}
} else {
None
};

kcl_paths.push(abs_path.unwrap_or(real_path.unwrap_or(file.to_string())));
}

// Get the root path of the project
Expand Down

0 comments on commit 64401fa

Please sign in to comment.