1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-22 15:06:54 -05:00

Fix path normalization in resolve_from_cwd() (#2875)

This commit is contained in:
Nayeem Rahman 2019-09-07 19:13:09 +01:00 committed by Ryan Dahl
parent 2b40fa065c
commit 718c8c4360

View file

@ -139,20 +139,56 @@ pub fn resolve_from_cwd(path: &str) -> Result<(PathBuf, String), ErrBox> {
cwd.join(path) cwd.join(path)
}; };
// HACK: `Url::from_directory_path` is used here because it normalizes the path. // HACK: `Url::parse` is used here because it normalizes the path.
// Joining `/dev/deno/" with "./tests" using `PathBuf` yields `/deno/dev/./tests/`. // Joining `/dev/deno/" with "./tests" using `PathBuf` yields `/deno/dev/./tests/`.
// On the other hand joining `/dev/deno/" with "./tests" using `Url` yields "/dev/deno/tests" // On the other hand joining `/dev/deno/" with "./tests" using `Url` yields "/dev/deno/tests"
// - and that's what we want. // - and that's what we want.
// There exists similar method on `PathBuf` - `PathBuf.canonicalize`, but the problem // There exists similar method on `PathBuf` - `PathBuf.canonicalize`, but the problem
// is `canonicalize` resolves symlinks and we don't want that. // is `canonicalize` resolves symlinks and we don't want that.
// We just want o normalize the path... // We just want to normalize the path...
let resolved_url = Url::from_file_path(resolved_path) // This only works on absolute paths - not worth extracting as a public utility.
.expect("PathBuf should be parseable URL"); let resolved_url =
let normalized_path = resolved_url Url::from_file_path(resolved_path).expect("Path should be absolute");
let normalized_url = Url::parse(resolved_url.as_str())
.expect("String from a URL should parse to a URL");
let normalized_path = normalized_url
.to_file_path() .to_file_path()
.expect("URL from PathBuf should be valid path"); .expect("URL from a path should contain a valid path");
let path_string = normalized_path.to_str().unwrap().to_string(); let path_string = normalized_path.to_str().unwrap().to_string();
Ok((normalized_path, path_string)) Ok((normalized_path, path_string))
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resolve_from_cwd_child() {
let cwd = std::env::current_dir().unwrap();
assert_eq!(resolve_from_cwd("a").unwrap().0, cwd.join("a"));
}
#[test]
fn resolve_from_cwd_dot() {
let cwd = std::env::current_dir().unwrap();
assert_eq!(resolve_from_cwd(".").unwrap().0, cwd);
}
#[test]
fn resolve_from_cwd_parent() {
let cwd = std::env::current_dir().unwrap();
assert_eq!(resolve_from_cwd("a/..").unwrap().0, cwd);
}
#[test]
fn resolve_from_cwd_absolute() {
let expected = if cfg!(windows) {
Path::new("C:\\a")
} else {
Path::new("/a")
};
assert_eq!(resolve_from_cwd("/a").unwrap().0, expected);
}
}