🐛 fix ls with link cases

Signed-off-by: Wei Zhang <kweizh@gmail.com>
This commit is contained in:
Wei Zhang 2024-08-15 00:08:26 +08:00
parent 9c66549207
commit a7fce648ac
3 changed files with 40 additions and 25 deletions

View file

@ -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()]),

View file

@ -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(&current_meta.path, true));
parent_meta.git_status = cache.and_then(|cache| cache.get(&parent_meta.path, true));

View file

@ -213,11 +213,32 @@ 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("--ignore-config")
.arg(&link)
.assert()
.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();
@ -228,12 +249,6 @@ fn test_nosymlink_on_non_long() {
.arg(&link)
.assert()
.stdout(predicate::str::contains(link_icon));
cmd()
.arg("--ignore-config")
.arg(&link)
.assert()
.stdout(predicate::str::contains(link_icon).not());
}
#[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")