mirror of
https://github.com/nushell/nushell.git
synced 2024-12-23 15:39:06 +01:00
fix ls
and ls tests (#931)
* fix `ls` and ls tests * tweak to ls so it doesn't scream on empty dirs * clippy * reworked `ls` to put in what was left out
This commit is contained in:
parent
c2f6dfa75c
commit
8204cc4f28
@ -6,8 +6,8 @@ use nu_engine::CallExt;
|
|||||||
use nu_protocol::ast::Call;
|
use nu_protocol::ast::Call;
|
||||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
Category, DataSource, IntoInterruptiblePipelineData, PipelineData, PipelineMetadata,
|
Category, DataSource, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData,
|
||||||
ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
PipelineMetadata, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||||
};
|
};
|
||||||
use pathdiff::diff_paths;
|
use pathdiff::diff_paths;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -67,27 +67,70 @@ impl Command for Ls {
|
|||||||
let full_paths = call.has_flag("full-paths");
|
let full_paths = call.has_flag("full-paths");
|
||||||
let du = call.has_flag("du");
|
let du = call.has_flag("du");
|
||||||
let ctrl_c = engine_state.ctrlc.clone();
|
let ctrl_c = engine_state.ctrlc.clone();
|
||||||
|
|
||||||
let call_span = call.head;
|
let call_span = call.head;
|
||||||
let cwd = current_dir(engine_state, stack)?;
|
let cwd = current_dir(engine_state, stack)?;
|
||||||
|
|
||||||
let pattern_arg = call.opt::<Spanned<String>>(engine_state, stack, 0)?;
|
let pattern_arg = call.opt::<Spanned<String>>(engine_state, stack, 0)?;
|
||||||
|
|
||||||
let pattern = if let Some(pattern) = pattern_arg {
|
let (path, p_tag) = match pattern_arg {
|
||||||
pattern
|
Some(p) => {
|
||||||
|
let p_tag = p.span;
|
||||||
|
let mut p = PathBuf::from(p.item);
|
||||||
|
if p.is_dir() {
|
||||||
|
if permission_denied(&p) {
|
||||||
|
#[cfg(unix)]
|
||||||
|
let error_msg = format!(
|
||||||
|
"The permissions of {:o} do not allow access for this user",
|
||||||
|
p.metadata()
|
||||||
|
.expect(
|
||||||
|
"this shouldn't be called since we already know there is a dir"
|
||||||
|
)
|
||||||
|
.permissions()
|
||||||
|
.mode()
|
||||||
|
& 0o0777
|
||||||
|
);
|
||||||
|
#[cfg(not(unix))]
|
||||||
|
let error_msg = String::from("Permission denied");
|
||||||
|
return Err(ShellError::SpannedLabeledError(
|
||||||
|
"Permission denied".to_string(),
|
||||||
|
error_msg,
|
||||||
|
p_tag,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
if is_empty_dir(&p) {
|
||||||
|
return Ok(Value::nothing(call_span).into_pipeline_data());
|
||||||
|
}
|
||||||
|
p.push("*");
|
||||||
|
}
|
||||||
|
(p, p_tag)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
if is_empty_dir(current_dir(engine_state, stack)?) {
|
||||||
|
return Ok(Value::nothing(call_span).into_pipeline_data());
|
||||||
} else {
|
} else {
|
||||||
Spanned {
|
(PathBuf::from("./*"), call_span)
|
||||||
item: cwd.join("*").to_string_lossy().to_string(),
|
}
|
||||||
span: call_span,
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let (prefix, glob) = nu_engine::glob_from(&pattern, &cwd, call_span)?;
|
let hidden_dir_specified = is_hidden_dir(&path);
|
||||||
|
|
||||||
|
let glob_path = Spanned {
|
||||||
|
item: path.display().to_string(),
|
||||||
|
span: p_tag,
|
||||||
|
};
|
||||||
|
let (prefix, paths) = nu_engine::glob_from(&glob_path, &cwd, call_span)?;
|
||||||
|
|
||||||
|
let mut paths_peek = paths.peekable();
|
||||||
|
if paths_peek.peek().is_none() {
|
||||||
|
return Err(ShellError::LabeledError(
|
||||||
|
format!("No matches found for {}", &path.display().to_string()),
|
||||||
|
"no matches found".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let hidden_dir_specified = is_hidden_dir(&pattern.item);
|
|
||||||
let mut hidden_dirs = vec![];
|
let mut hidden_dirs = vec![];
|
||||||
|
|
||||||
Ok(glob
|
Ok(paths_peek
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(move |x| match x {
|
.filter_map(move |x| match x {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
@ -163,6 +206,20 @@ impl Command for Ls {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn permission_denied(dir: impl AsRef<Path>) -> bool {
|
||||||
|
match dir.as_ref().read_dir() {
|
||||||
|
Err(e) => matches!(e.kind(), std::io::ErrorKind::PermissionDenied),
|
||||||
|
Ok(_) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_empty_dir(dir: impl AsRef<Path>) -> bool {
|
||||||
|
match dir.as_ref().read_dir() {
|
||||||
|
Err(_) => true,
|
||||||
|
Ok(mut s) => s.next().is_none(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_hidden_dir(dir: impl AsRef<Path>) -> bool {
|
fn is_hidden_dir(dir: impl AsRef<Path>) -> bool {
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
{
|
{
|
||||||
|
@ -67,8 +67,6 @@ fn lists_regular_files_using_question_mark_wildcard() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: jt: needs more work
|
|
||||||
#[ignore]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lists_all_files_in_directories_from_stream() {
|
fn lists_all_files_in_directories_from_stream() {
|
||||||
Playground::setup("ls_test_4", |dirs, sandbox| {
|
Playground::setup("ls_test_4", |dirs, sandbox| {
|
||||||
@ -90,7 +88,7 @@ fn lists_all_files_in_directories_from_stream() {
|
|||||||
r#"
|
r#"
|
||||||
echo dir_a dir_b
|
echo dir_a dir_b
|
||||||
| each { ls $it }
|
| each { ls $it }
|
||||||
| length
|
| flatten | length
|
||||||
"#
|
"#
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -115,8 +113,6 @@ fn does_not_fail_if_glob_matches_empty_directory() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: jt: needs more work
|
|
||||||
#[ignore]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn fails_when_glob_doesnt_match() {
|
fn fails_when_glob_doesnt_match() {
|
||||||
Playground::setup("ls_test_5", |dirs, sandbox| {
|
Playground::setup("ls_test_5", |dirs, sandbox| {
|
||||||
@ -292,8 +288,6 @@ fn lists_files_including_starting_with_dot() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: jt: needs more work
|
|
||||||
#[ignore]
|
|
||||||
#[test]
|
#[test]
|
||||||
fn list_all_columns() {
|
fn list_all_columns() {
|
||||||
Playground::setup("ls_test_all_columns", |dirs, sandbox| {
|
Playground::setup("ls_test_all_columns", |dirs, sandbox| {
|
||||||
@ -306,14 +300,14 @@ fn list_all_columns() {
|
|||||||
// Normal Operation
|
// Normal Operation
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
cwd: dirs.test(),
|
cwd: dirs.test(),
|
||||||
"ls | get | to md"
|
"ls | columns | to md"
|
||||||
);
|
);
|
||||||
let expected = ["name", "type", "size", "modified"].join("");
|
let expected = ["name", "type", "size", "modified"].join("");
|
||||||
assert_eq!(actual.out, expected, "column names are incorrect for ls");
|
assert_eq!(actual.out, expected, "column names are incorrect for ls");
|
||||||
// Long
|
// Long
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
cwd: dirs.test(),
|
cwd: dirs.test(),
|
||||||
"ls -l | get | to md"
|
"ls -l | columns | to md"
|
||||||
);
|
);
|
||||||
let expected = {
|
let expected = {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
@ -322,10 +316,10 @@ fn list_all_columns() {
|
|||||||
"name",
|
"name",
|
||||||
"type",
|
"type",
|
||||||
"target",
|
"target",
|
||||||
"num_links",
|
|
||||||
"inode",
|
|
||||||
"readonly",
|
"readonly",
|
||||||
"mode",
|
"mode",
|
||||||
|
"num_links",
|
||||||
|
"inode",
|
||||||
"uid",
|
"uid",
|
||||||
"group",
|
"group",
|
||||||
"size",
|
"size",
|
||||||
|
Loading…
Reference in New Issue
Block a user