mirror of
https://github.com/nushell/nushell
synced 2024-12-27 21:43:09 +00:00
Fix ls relative path and erroring on fake dir (#697)
* Switch to short-names when the path is a relative_path (a dir) and exit with an error if the path does not exist * Remove debugging print line * Show relative filenames... It does not work yet for ls ../ * Try something else to fix relative paths... it works, but the ../ code part is not very pretty * Add canonicalize check and remove code clones * Fix the canonicalize_with issue pointed out by kubouch. Not sure the prefix_str is what kubouch suggested * Fix the canonicalize_with issue pointed out by kubouch. Not sure the prefix_str is what kubouch suggested
This commit is contained in:
parent
a7241f9899
commit
bee5ba3deb
1 changed files with 52 additions and 7 deletions
|
@ -63,11 +63,18 @@ impl Command for Ls {
|
||||||
let short_names = call.has_flag("short-names");
|
let short_names = call.has_flag("short-names");
|
||||||
|
|
||||||
let call_span = call.head;
|
let call_span = call.head;
|
||||||
|
// when we're asking for relative paths like ../../, we need to figure out if we need a prefix for display purposes
|
||||||
|
let mut new_prefix = false;
|
||||||
|
let mut prefix_str = PathBuf::new();
|
||||||
|
|
||||||
let (pattern, prefix) = if let Some(result) =
|
let (pattern, prefix) = if let Some(result) =
|
||||||
call.opt::<Spanned<String>>(engine_state, stack, 0)?
|
call.opt::<Spanned<String>>(engine_state, stack, 0)?
|
||||||
{
|
{
|
||||||
let path = PathBuf::from(&result.item);
|
let curr_dir = current_dir(engine_state, stack)?;
|
||||||
|
let path = match nu_path::canonicalize_with(&result.item, curr_dir) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(_e) => return Err(ShellError::DirectoryNotFound(result.span)),
|
||||||
|
};
|
||||||
|
|
||||||
let (mut path, prefix) = if path.is_relative() {
|
let (mut path, prefix) = if path.is_relative() {
|
||||||
let cwd = current_dir(engine_state, stack)?;
|
let cwd = current_dir(engine_state, stack)?;
|
||||||
|
@ -76,7 +83,12 @@ impl Command for Ls {
|
||||||
(path, None)
|
(path, None)
|
||||||
};
|
};
|
||||||
|
|
||||||
if path.is_dir() {
|
if path.is_file() {
|
||||||
|
(
|
||||||
|
path.to_string_lossy().to_string(),
|
||||||
|
Some(current_dir(engine_state, stack)?),
|
||||||
|
)
|
||||||
|
} else if path.is_dir() {
|
||||||
if permission_denied(&path) {
|
if permission_denied(&path) {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
let error_msg = format!(
|
let error_msg = format!(
|
||||||
|
@ -98,13 +110,28 @@ impl Command for Ls {
|
||||||
if is_empty_dir(&path) {
|
if is_empty_dir(&path) {
|
||||||
return Ok(PipelineData::new(call_span));
|
return Ok(PipelineData::new(call_span));
|
||||||
}
|
}
|
||||||
|
// we figure out how to display a relative path which was requested from a subdirectory, e.g., ls ../
|
||||||
|
let curr_dir = current_dir(engine_state, stack)?;
|
||||||
|
new_prefix = curr_dir.ancestors().any(|x| x.to_path_buf() == path);
|
||||||
|
if new_prefix {
|
||||||
|
for a in curr_dir.ancestors() {
|
||||||
|
if a.to_path_buf() == path {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prefix_str.push(format!("..{}", std::path::MAIN_SEPARATOR));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
path = path.join("*");
|
path = path.join("*");
|
||||||
}
|
}
|
||||||
|
(
|
||||||
|
path.to_string_lossy().to_string(),
|
||||||
|
Some(current_dir(engine_state, stack)?),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(path.to_string_lossy().to_string(), prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
(path.to_string_lossy().to_string(), prefix)
|
|
||||||
} else {
|
} else {
|
||||||
let cwd = current_dir(engine_state, stack)?;
|
let cwd = current_dir(engine_state, stack)?;
|
||||||
(cwd.join("*").to_string_lossy().to_string(), Some(cwd))
|
(cwd.join("*").to_string_lossy().to_string(), Some(cwd))
|
||||||
|
@ -160,9 +187,27 @@ impl Command for Ls {
|
||||||
|
|
||||||
match display_name {
|
match display_name {
|
||||||
Ok(name) => {
|
Ok(name) => {
|
||||||
let entry =
|
let filename = if new_prefix {
|
||||||
dir_entry_dict(&path, name, metadata.as_ref(), call_span, long);
|
match path.file_name() {
|
||||||
|
Some(p) => {
|
||||||
|
format!(
|
||||||
|
"{}{}",
|
||||||
|
prefix_str.to_string_lossy(),
|
||||||
|
p.to_string_lossy()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
None => path.to_string_lossy().to_string(),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
name.to_string()
|
||||||
|
};
|
||||||
|
let entry = dir_entry_dict(
|
||||||
|
&path,
|
||||||
|
filename.as_str(),
|
||||||
|
metadata.as_ref(),
|
||||||
|
call_span,
|
||||||
|
long,
|
||||||
|
);
|
||||||
match entry {
|
match entry {
|
||||||
Ok(value) => Some(value),
|
Ok(value) => Some(value),
|
||||||
Err(err) => Some(Value::Error { error: err }),
|
Err(err) => Some(Value::Error { error: err }),
|
||||||
|
|
Loading…
Reference in a new issue