Skip to content

Commit

Permalink
Fix path normalization in resolve_from_cwd() (#2875)
Browse files Browse the repository at this point in the history
  • Loading branch information
nayeemrmn authored and ry committed Sep 7, 2019
1 parent 2b40fa0 commit 718c8c4
Showing 1 changed file with 42 additions and 6 deletions.
48 changes: 42 additions & 6 deletions cli/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,20 +139,56 @@ pub fn resolve_from_cwd(path: &str) -> Result<(PathBuf, String), ErrBox> {
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/`.
// On the other hand joining `/dev/deno/" with "./tests" using `Url` yields "/dev/deno/tests"
// - and that's what we want.
// There exists similar method on `PathBuf` - `PathBuf.canonicalize`, but the problem
// is `canonicalize` resolves symlinks and we don't want that.
// We just want o normalize the path...
let resolved_url = Url::from_file_path(resolved_path)
.expect("PathBuf should be parseable URL");
let normalized_path = resolved_url
// We just want to normalize the path...
// This only works on absolute paths - not worth extracting as a public utility.
let 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()
.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();

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);
}
}

0 comments on commit 718c8c4

Please sign in to comment.