Skip to content

Commit a7fce64

Browse files
committed
🐛 fix ls with link cases
Signed-off-by: Wei Zhang <kweizh@gmail.com>
1 parent 9c66549 commit a7fce64

File tree

3 files changed

+37
-22
lines changed

3 files changed

+37
-22
lines changed

src/display.rs

+2-15
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ fn inner_display_grid(
115115
// Maybe skip showing the directory meta now; show its contents later.
116116
if skip_dirs
117117
&& (matches!(meta.file_type, FileType::Directory { .. })
118-
|| (matches!(meta.file_type, FileType::SymLink { is_dir: true })))
118+
|| (matches!(meta.file_type, FileType::SymLink { is_dir: true }))
119+
&& flags.blocks.0.len() == 1)
119120
{
120121
continue;
121122
}
@@ -961,24 +962,10 @@ mod tests {
961962
std::os::unix::fs::symlink("dir", &link_path).unwrap();
962963
let link = Meta::from_path(&link_path, false, PermissionFlag::Rwx).unwrap();
963964

964-
let grid_flags = Flags {
965-
layout: Layout::Grid,
966-
..Flags::default()
967-
};
968-
969-
let oneline_flags = Flags {
970-
layout: Layout::OneLine,
971-
..Flags::default()
972-
};
973-
974965
const YES: bool = true;
975966
const NO: bool = false;
976967

977968
assert_eq!(should_display_folder_path(0, &[link.clone()]), NO);
978-
assert_eq!(
979-
should_display_folder_path(0, &[link.clone()]),
980-
YES // doesn't matter since this link will be expanded as a directory
981-
);
982969

983970
assert_eq!(
984971
should_display_folder_path(0, &[file.clone(), link.clone()]),

src/meta/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ impl Meta {
7777
match self.file_type {
7878
FileType::Directory { .. } => (),
7979
FileType::SymLink { is_dir: true } => {
80-
if flags.layout == Layout::OneLine && depth != 1 {
80+
if flags.blocks.0.len() > 1 {
8181
return Ok((None, ExitCode::OK));
8282
}
8383
}
@@ -98,14 +98,14 @@ impl Meta {
9898
&& flags.layout != Layout::Tree
9999
{
100100
let mut current_meta = self.clone();
101-
current_meta.name.name = ".".to_owned();
101+
".".clone_into(&mut current_meta.name.name);
102102

103103
let mut parent_meta = Self::from_path(
104104
&self.path.join(Component::ParentDir),
105105
flags.dereference.0,
106106
flags.permission,
107107
)?;
108-
parent_meta.name.name = "..".to_owned();
108+
"..".clone_into(&mut parent_meta.name.name);
109109

110110
current_meta.git_status = cache.and_then(|cache| cache.get(&current_meta.path, true));
111111
parent_meta.git_status = cache.and_then(|cache| cache.get(&parent_meta.path, true));

tests/integration.rs

+32-4
Original file line numberDiff line numberDiff line change
@@ -213,27 +213,42 @@ fn test_list_broken_link_ok() {
213213
.assert()
214214
.stderr(predicate::str::contains(matched).not());
215215
}
216+
217+
// ls link
218+
// should show dir content
216219
#[cfg(unix)]
217220
#[test]
218221
fn test_nosymlink_on_non_long() {
219222
let dir = tempdir();
220-
dir.child("target").touch().unwrap();
223+
dir.child("target").child("inside").touch().unwrap();
221224
let link = dir.path().join("link");
222225
let link_icon = "⇒";
223226
fs::symlink("target", &link).unwrap();
224227

225228
cmd()
226-
.arg("-l")
227229
.arg("--ignore-config")
228230
.arg(&link)
229231
.assert()
230-
.stdout(predicate::str::contains(link_icon));
232+
.stdout(predicate::str::contains(link_icon).not());
233+
}
234+
235+
// ls -l link
236+
// should show the link itself
237+
#[cfg(unix)]
238+
#[test]
239+
fn test_symlink_on_long() {
240+
let dir = tempdir();
241+
dir.child("target").child("inside").touch().unwrap();
242+
let link = dir.path().join("link");
243+
let link_icon = "⇒";
244+
fs::symlink("target", &link).unwrap();
231245

232246
cmd()
247+
.arg("-l")
233248
.arg("--ignore-config")
234249
.arg(&link)
235250
.assert()
236-
.stdout(predicate::str::contains(link_icon).not());
251+
.stdout(predicate::str::contains(link_icon));
237252
}
238253

239254
#[cfg(unix)]
@@ -339,6 +354,8 @@ fn test_show_folder_content_of_symlink() {
339354
.stdout(predicate::str::starts_with("inside"));
340355
}
341356

357+
/// ls -l link
358+
/// should show the link itself
342359
#[cfg(unix)]
343360
#[test]
344361
fn test_no_show_folder_content_of_symlink_for_long() {
@@ -354,6 +371,17 @@ fn test_no_show_folder_content_of_symlink_for_long() {
354371
.assert()
355372
.stdout(predicate::str::starts_with("lrw"))
356373
.stdout(predicate::str::contains("⇒"));
374+
}
375+
376+
/// ls -l link/
377+
/// should show the dir content
378+
#[cfg(unix)]
379+
#[test]
380+
fn test_show_folder_content_of_symlink_for_long_tail_slash() {
381+
let dir = tempdir();
382+
dir.child("target").child("inside").touch().unwrap();
383+
let link = dir.path().join("link");
384+
fs::symlink("target", link).unwrap();
357385

358386
cmd()
359387
.arg("-l")

0 commit comments

Comments
 (0)