nushell/src/commands/ls.rs

74 lines
2.6 KiB
Rust
Raw Normal View History

2019-05-10 18:59:12 +02:00
use crate::errors::ShellError;
2019-08-02 05:10:06 +02:00
use crate::object::dir_entry_dict;
use crate::prelude::*;
2019-06-03 09:41:28 +02:00
use std::path::{Path, PathBuf};
2019-05-10 18:59:12 +02:00
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
2019-06-13 23:47:25 +02:00
let env = args.env.lock().unwrap();
2019-07-16 21:10:25 +02:00
let path = env.path.to_path_buf();
2019-08-02 05:10:06 +02:00
let cwd = path.clone();
2019-06-13 23:47:25 +02:00
let mut full_path = PathBuf::from(path);
2019-06-22 05:43:37 +02:00
match &args.nth(0) {
2019-08-02 05:10:06 +02:00
Some(Tagged { item: value, .. }) => full_path.push(Path::new(&value.as_string()?)),
2019-06-03 09:41:28 +02:00
_ => {}
}
2019-05-11 10:08:21 +02:00
2019-08-02 05:10:06 +02:00
let entries = glob::glob(&full_path.to_string_lossy());
if entries.is_err() {
return Err(ShellError::string("Invalid pattern."));
}
2019-06-14 03:59:13 +02:00
2019-07-16 21:10:25 +02:00
let mut shell_entries = VecDeque::new();
2019-08-02 05:10:06 +02:00
let entries: Vec<_> = entries.unwrap().collect();
// If this is a single entry, try to display the contents of the entry if it's a directory
if entries.len() == 1 {
if let Ok(entry) = &entries[0] {
if entry.is_dir() {
let entries = std::fs::read_dir(&full_path);
2019-07-16 21:10:25 +02:00
2019-08-02 05:10:06 +02:00
let entries = match entries {
Err(e) => {
if let Some(s) = args.nth(0) {
return Err(ShellError::labeled_error(
e.to_string(),
e.to_string(),
s.span(),
));
} else {
return Err(ShellError::maybe_labeled_error(
e.to_string(),
e.to_string(),
args.call_info.name_span,
));
}
}
Ok(o) => o,
};
for entry in entries {
let entry = entry?;
let filepath = entry.path();
let filename = filepath.strip_prefix(&cwd).unwrap();
let value =
dir_entry_dict(filename, &entry.metadata()?, args.call_info.name_span)?;
shell_entries.push_back(ReturnSuccess::value(value))
}
return Ok(shell_entries.to_output_stream());
}
}
}
// Enumerate the entries from the glob and add each
2019-07-16 21:10:25 +02:00
for entry in entries {
2019-08-02 05:10:06 +02:00
if let Ok(entry) = entry {
let filename = entry.strip_prefix(&cwd).unwrap();
let metadata = std::fs::metadata(&entry)?;
let value = dir_entry_dict(filename, &metadata, args.call_info.name_span)?;
shell_entries.push_back(ReturnSuccess::value(value))
}
2019-05-10 18:59:12 +02:00
}
2019-08-02 05:10:06 +02:00
2019-07-16 21:10:25 +02:00
Ok(shell_entries.to_output_stream())
2019-05-10 18:59:12 +02:00
}