From a7fce648acb87a6a85be9b4fa9c2270600a8a50d Mon Sep 17 00:00:00 2001 From: Wei Zhang Date: Thu, 15 Aug 2024 00:08:26 +0800 Subject: [PATCH] :bug: fix ls with link cases Signed-off-by: Wei Zhang --- src/display.rs | 17 ++--------------- src/meta/mod.rs | 6 +++--- tests/integration.rs | 36 ++++++++++++++++++++++++++++++++---- 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/src/display.rs b/src/display.rs index 7c8b55c3b..6729529dd 100644 --- a/src/display.rs +++ b/src/display.rs @@ -115,7 +115,8 @@ fn inner_display_grid( // Maybe skip showing the directory meta now; show its contents later. if skip_dirs && (matches!(meta.file_type, FileType::Directory { .. }) - || (matches!(meta.file_type, FileType::SymLink { is_dir: true }))) + || (matches!(meta.file_type, FileType::SymLink { is_dir: true })) + && flags.blocks.0.len() == 1) { continue; } @@ -961,24 +962,10 @@ mod tests { std::os::unix::fs::symlink("dir", &link_path).unwrap(); let link = Meta::from_path(&link_path, false, PermissionFlag::Rwx).unwrap(); - let grid_flags = Flags { - layout: Layout::Grid, - ..Flags::default() - }; - - let oneline_flags = Flags { - layout: Layout::OneLine, - ..Flags::default() - }; - const YES: bool = true; const NO: bool = false; assert_eq!(should_display_folder_path(0, &[link.clone()]), NO); - assert_eq!( - should_display_folder_path(0, &[link.clone()]), - YES // doesn't matter since this link will be expanded as a directory - ); assert_eq!( should_display_folder_path(0, &[file.clone(), link.clone()]), diff --git a/src/meta/mod.rs b/src/meta/mod.rs index a10680bbd..57ebbe45b 100644 --- a/src/meta/mod.rs +++ b/src/meta/mod.rs @@ -77,7 +77,7 @@ impl Meta { match self.file_type { FileType::Directory { .. } => (), FileType::SymLink { is_dir: true } => { - if flags.layout == Layout::OneLine && depth != 1 { + if flags.blocks.0.len() > 1 { return Ok((None, ExitCode::OK)); } } @@ -98,14 +98,14 @@ impl Meta { && flags.layout != Layout::Tree { let mut current_meta = self.clone(); - current_meta.name.name = ".".to_owned(); + ".".clone_into(&mut current_meta.name.name); let mut parent_meta = Self::from_path( &self.path.join(Component::ParentDir), flags.dereference.0, flags.permission, )?; - parent_meta.name.name = "..".to_owned(); + "..".clone_into(&mut parent_meta.name.name); current_meta.git_status = cache.and_then(|cache| cache.get(¤t_meta.path, true)); parent_meta.git_status = cache.and_then(|cache| cache.get(&parent_meta.path, true)); diff --git a/tests/integration.rs b/tests/integration.rs index 91fec677b..72442331c 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -213,27 +213,42 @@ fn test_list_broken_link_ok() { .assert() .stderr(predicate::str::contains(matched).not()); } + +// ls link +// should show dir content #[cfg(unix)] #[test] fn test_nosymlink_on_non_long() { let dir = tempdir(); - dir.child("target").touch().unwrap(); + dir.child("target").child("inside").touch().unwrap(); let link = dir.path().join("link"); let link_icon = "⇒"; fs::symlink("target", &link).unwrap(); cmd() - .arg("-l") .arg("--ignore-config") .arg(&link) .assert() - .stdout(predicate::str::contains(link_icon)); + .stdout(predicate::str::contains(link_icon).not()); +} + +// ls -l link +// should show the link itself +#[cfg(unix)] +#[test] +fn test_symlink_on_long() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + let link_icon = "⇒"; + fs::symlink("target", &link).unwrap(); cmd() + .arg("-l") .arg("--ignore-config") .arg(&link) .assert() - .stdout(predicate::str::contains(link_icon).not()); + .stdout(predicate::str::contains(link_icon)); } #[cfg(unix)] @@ -339,6 +354,8 @@ fn test_show_folder_content_of_symlink() { .stdout(predicate::str::starts_with("inside")); } +/// ls -l link +/// should show the link itself #[cfg(unix)] #[test] fn test_no_show_folder_content_of_symlink_for_long() { @@ -354,6 +371,17 @@ fn test_no_show_folder_content_of_symlink_for_long() { .assert() .stdout(predicate::str::starts_with("lrw")) .stdout(predicate::str::contains("⇒")); +} + +/// ls -l link/ +/// should show the dir content +#[cfg(unix)] +#[test] +fn test_show_folder_content_of_symlink_for_long_tail_slash() { + let dir = tempdir(); + dir.child("target").child("inside").touch().unwrap(); + let link = dir.path().join("link"); + fs::symlink("target", link).unwrap(); cmd() .arg("-l")