mirror of
https://github.com/tweag/nickel.git
synced 2024-10-05 15:47:33 +03:00
Convert paths to absolute before normalization (#1489)
* Add test * Fix test * Convert paths to absolute before normalization The path normalization function doesn't work on paths starting with '..'. One fix is to make paths absolute. * Add comment
This commit is contained in:
parent
c4ac9c368a
commit
dc76b14556
3
.gitignore
vendored
3
.gitignore
vendored
@ -27,3 +27,6 @@
|
||||
# Python virtual env
|
||||
.venv/
|
||||
venv/
|
||||
|
||||
# helix configuration
|
||||
.helix/
|
||||
|
@ -289,7 +289,7 @@ impl Cache {
|
||||
pub fn add_file(&mut self, path: impl Into<OsString>) -> io::Result<FileId> {
|
||||
let path = path.into();
|
||||
let timestamp = timestamp(&path)?;
|
||||
let normalized = normalize_path(PathBuf::from(&path).as_path());
|
||||
let normalized = normalize_path(&path)?;
|
||||
self.add_file_(normalized, timestamp)
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ impl Cache {
|
||||
/// If it was not in cache, try to read it from the filesystem and add it as a new entry.
|
||||
pub fn get_or_add_file(&mut self, path: impl Into<OsString>) -> io::Result<CacheOp<FileId>> {
|
||||
let path = path.into();
|
||||
let normalized = normalize_path(PathBuf::from(&path).as_path());
|
||||
let normalized = normalize_path(&path)?;
|
||||
match self.id_or_new_timestamp_of(&path)? {
|
||||
SourceState::UpToDate(id) => Ok(CacheOp::Cached(id)),
|
||||
SourceState::Stale(timestamp) => {
|
||||
@ -1241,7 +1241,18 @@ fn with_parent(path: &OsStr, parent: Option<PathBuf>) -> PathBuf {
|
||||
|
||||
/// Normalize the path of a file for unique identification in the cache.
|
||||
///
|
||||
/// This implementation (including the commend below) was taken from cargo-util.
|
||||
/// The returned path will be an absolute path.
|
||||
pub fn normalize_path(path: &OsStr) -> std::io::Result<OsString> {
|
||||
let mut path = PathBuf::from(path);
|
||||
if path.is_relative() {
|
||||
path = std::env::current_dir()?.join(path);
|
||||
}
|
||||
Ok(normalize_abs_path(&path))
|
||||
}
|
||||
|
||||
/// Normalize the path (assumed to be absolute) of a file for unique identification in the cache.
|
||||
///
|
||||
/// This implementation (including the comment below) was taken from cargo-util.
|
||||
///
|
||||
/// CAUTION: This does not resolve symlinks (unlike
|
||||
/// [`std::fs::canonicalize`]). This may cause incorrect or surprising
|
||||
@ -1249,7 +1260,7 @@ fn with_parent(path: &OsStr, parent: Option<PathBuf>) -> PathBuf {
|
||||
/// [`std::fs::canonicalize`] can be hard to use correctly, since it can often
|
||||
/// fail, or on Windows returns annoying device paths. This is a problem Cargo
|
||||
/// needs to improve on.
|
||||
pub fn normalize_path(path: &Path) -> OsString {
|
||||
fn normalize_abs_path(path: &Path) -> OsString {
|
||||
use std::path::Component;
|
||||
|
||||
let mut components = path.components().peekable();
|
||||
|
@ -0,0 +1,2 @@
|
||||
# test.type = 'pass'
|
||||
import "../root_path.ncl"
|
@ -37,6 +37,25 @@ fn check_annotated_nickel_file(path: &str) {
|
||||
.expect("Failed to join thread")
|
||||
}
|
||||
|
||||
// Like check_annotated_nickel_file, but runs the test from the directory of
|
||||
// the test file itself (and opens the test file with a relative path). This
|
||||
// is mainly for integration testing path normalization.
|
||||
#[test_resources("core/tests/integration/imports/imported/import_parent.ncl")]
|
||||
fn check_from_dir(path: &str) {
|
||||
let test: TestCase<Test> =
|
||||
read_annotated_test_case(path).expect("Failed to parse annotated program");
|
||||
|
||||
let path = project_root().join(path);
|
||||
let dir = std::env::current_dir().unwrap();
|
||||
let test_dir = path.parent().unwrap();
|
||||
std::env::set_current_dir(test_dir).unwrap();
|
||||
run_test(
|
||||
test,
|
||||
String::from(path.file_name().unwrap().to_string_lossy()),
|
||||
);
|
||||
std::env::set_current_dir(dir).unwrap();
|
||||
}
|
||||
|
||||
fn run_test(test_case: TestCase<Test>, path: String) {
|
||||
let repeat = test_case.annotation.repeat.unwrap_or(1);
|
||||
let eval_strategy = test_case.annotation.eval.unwrap_or(EvalStrategy::Standard);
|
||||
|
Loading…
Reference in New Issue
Block a user