Start following symlinks again

This was my favourite feature, so I'm glad to see it back!
This commit is contained in:
Ben S 2015-05-03 13:10:25 +01:00
parent 41aadaeab4
commit 64b97aa9f3
2 changed files with 11 additions and 14 deletions

View File

@ -54,9 +54,10 @@ impl<'a> File<'a> {
/// Create a new File object from the given Path, inside the given Dir, if /// Create a new File object from the given Path, inside the given Dir, if
/// appropriate. Paths specified directly on the command-line have no Dirs. /// appropriate. Paths specified directly on the command-line have no Dirs.
/// ///
/// This uses lstat instead of stat, which doesn't follow symbolic links. /// This uses `symlink_metadata` instead of `metadata`, which doesn't
/// follow symbolic links.
pub fn from_path(path: &Path, parent: Option<&'a Dir>, recurse: bool) -> io::Result<File<'a>> { pub fn from_path(path: &Path, parent: Option<&'a Dir>, recurse: bool) -> io::Result<File<'a>> {
fs::metadata(path).map(|stat| File::with_stat(stat, path, parent, recurse)) // todo: lstat fs::symlink_metadata(path).map(|stat| File::with_stat(stat, path, parent, recurse))
} }
/// Create a new File object from the given Stat result, and other data. /// Create a new File object from the given Stat result, and other data.
@ -93,11 +94,11 @@ impl<'a> File<'a> {
} }
pub fn is_link(&self) -> bool { pub fn is_link(&self) -> bool {
false self.stat.file_type().is_symlink()
} }
pub fn is_pipe(&self) -> bool { pub fn is_pipe(&self) -> bool {
false false // TODO: Still waiting on this one...
} }
/// Whether this file is a dotfile or not. /// Whether this file is a dotfile or not.
@ -167,13 +168,6 @@ impl<'a> File<'a> {
// the target file, colourised in the appropriate style. // the target file, colourised in the appropriate style.
let mut path_prefix = String::new(); let mut path_prefix = String::new();
// The root directory has the name "/", which has to be
// catered for separately, otherwise there'll be two
// slashes in the resulting output.
if file.path.is_absolute() && file.name != "/" {
path_prefix.push_str("/");
}
let path_bytes: Vec<Component> = file.path.components().collect(); let path_bytes: Vec<Component> = file.path.components().collect();
if !path_bytes.is_empty() { if !path_bytes.is_empty() {
// Use init() to add all but the last component of the // Use init() to add all but the last component of the
@ -181,9 +175,12 @@ impl<'a> File<'a> {
// empty list, hence the check. // empty list, hence the check.
for component in path_bytes.init().iter() { for component in path_bytes.init().iter() {
path_prefix.push_str(&*component.as_os_str().to_string_lossy()); path_prefix.push_str(&*component.as_os_str().to_string_lossy());
if component != &Component::RootDir {
path_prefix.push_str("/"); path_prefix.push_str("/");
} }
} }
}
format!("{} {} {}", format!("{} {} {}",
style.paint(name), style.paint(name),
@ -225,7 +222,7 @@ impl<'a> File<'a> {
fn target_file(&self, target_path: &Path) -> Result<File, String> { fn target_file(&self, target_path: &Path) -> Result<File, String> {
let filename = path_filename(target_path); let filename = path_filename(target_path);
// Use stat instead of lstat - we *want* to follow links. // Use plain `metadata` instead of `symlink_metadata` - we *want* to follow links.
if let Ok(stat) = fs::metadata(target_path) { if let Ok(stat) = fs::metadata(target_path) {
Ok(File { Ok(File {
path: target_path.to_path_buf(), path: target_path.to_path_buf(),

View File

@ -1,4 +1,4 @@
#![feature(collections, convert, core, exit_status, fs_ext, fs_mode, fs_time, io, libc, metadata_ext, os, scoped, std_misc)] #![feature(collections, convert, core, exit_status, file_type, fs_ext, fs_mode, fs_time, io, libc, metadata_ext, os, scoped, std_misc, symlink_metadata)]
#![allow(deprecated)] #![allow(deprecated)]
// Other platforms than macos don't need std_misc but you can't // Other platforms than macos don't need std_misc but you can't