From b8191670c7271c23a896d5142066e752944f6cd2 Mon Sep 17 00:00:00 2001 From: Ben S Date: Sat, 11 Jun 2016 16:54:06 +0100 Subject: [PATCH] Fix, and add tests for, slashes in link paths --- src/fs/file.rs | 8 ++++---- src/output/mod.rs | 36 +++++++++++++++++++++++++----------- tests/links.rs | 21 +++++++++++++++++++++ 3 files changed, 50 insertions(+), 15 deletions(-) create mode 100644 tests/links.rs diff --git a/src/fs/file.rs b/src/fs/file.rs index 75a9eae..6725a04 100644 --- a/src/fs/file.rs +++ b/src/fs/file.rs @@ -163,12 +163,12 @@ impl<'dir> File<'dir> { /// returns a File object from the path the link points to. /// /// If statting the file fails (usually because the file on the - /// other end doesn't exist), returns the *filename* of the file + /// other end doesn't exist), returns the path to the file /// that should be there. - pub fn link_target(&self) -> Result, String> { + pub fn link_target(&self) -> Result, PathBuf> { let path = match fs::read_link(&self.path) { Ok(path) => path, - Err(_) => return Err(self.name.clone()), + Err(_) => panic!("This was not a link!"), }; let target_path = match self.dir { @@ -192,7 +192,7 @@ impl<'dir> File<'dir> { }) } else { - Err(target_path.display().to_string()) + Err(target_path) } } diff --git a/src/output/mod.rs b/src/output/mod.rs index 6464e07..f6aa294 100644 --- a/src/output/mod.rs +++ b/src/output/mod.rs @@ -24,14 +24,21 @@ pub fn filename(file: &File, colours: &Colours, links: bool) -> TextCellContents if file.dir.is_none() { if let Some(ref parent) = file.path.parent() { - if parent.components().count() > 0 { - bits.push(Style::default().paint(parent.to_string_lossy().to_string())); - bits.push(Style::default().paint("/")); + let coconut = parent.components().count(); + + if coconut == 1 && parent.has_root() { + bits.push(colours.symlink_path.paint("/")); + } + else if coconut > 1 { + bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string())); + bits.push(colours.symlink_path.paint("/")); } } } - bits.push(file_colour(colours, &file).paint(file.name.clone())); + if !file.name.is_empty() { + bits.push(file_colour(colours, &file).paint(file.name.clone())); + } if links && file.is_link() { match file.link_target() { @@ -42,22 +49,29 @@ pub fn filename(file: &File, colours: &Colours, links: bool) -> TextCellContents if let Some(ref parent) = target.path.parent() { let coconut = parent.components().count(); - if coconut != 0 { - if !(coconut == 1 && parent.has_root()) { - bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string())); - } + + if coconut == 1 && parent.has_root() { + bits.push(colours.symlink_path.paint("/")); + } + else if coconut > 1 { + bits.push(colours.symlink_path.paint(parent.to_string_lossy().to_string())); bits.push(colours.symlink_path.paint("/")); } } + else { + bits.push(colours.symlink_path.paint("/")); + } - bits.push(file_colour(colours, &target).paint(target.name)); + if !target.name.is_empty() { + bits.push(file_colour(colours, &target).paint(target.name)); + } }, - Err(filename) => { + Err(broken_path) => { bits.push(Style::default().paint(" ")); bits.push(colours.broken_arrow.paint("->")); bits.push(Style::default().paint(" ")); - bits.push(colours.broken_filename.paint(filename)); + bits.push(colours.broken_filename.paint(broken_path.display().to_string())); }, } } diff --git a/tests/links.rs b/tests/links.rs new file mode 100644 index 0000000..7f222d6 --- /dev/null +++ b/tests/links.rs @@ -0,0 +1,21 @@ +extern crate exa; +use exa::Exa; + +/// -------------------------------------------------------------------------- +/// These tests assume that the ‘generate annoying testcases’ script has been +/// run first. Otherwise, they will break! +/// -------------------------------------------------------------------------- + + +static LINKS: &'static str = concat!( + "\x1B[36m", "broken", "\x1B[0m", " ", "\x1B[31m", "->", "\x1B[0m", " ", "\x1B[4;31m", "testcases/links/nowhere", "\x1B[0m", '\n', + "\x1B[36m", "root", "\x1B[0m", " ", "\x1B[38;5;244m", "->", "\x1B[0m", " ", "\x1B[36m", "/", "\x1B[0m", '\n', + "\x1B[36m", "usr", "\x1B[0m", " ", "\x1B[38;5;244m", "->", "\x1B[0m", " ", "\x1B[36m", "/", "\x1B[1;34m", "usr", "\x1B[0m", '\n', +); + +#[test] +fn links() { + let mut output = Vec::::new(); + Exa::new( &[ "-1", "testcases/links" ], &mut output).unwrap().run().unwrap(); + assert_eq!(output, LINKS.as_bytes()); +}