1
0
mirror of https://github.com/nushell/nushell.git synced 2025-04-26 06:08:21 +02:00

Add glob to ls

This commit is contained in:
Jonathan Turner 2019-08-02 15:10:06 +12:00
parent aa54995326
commit 6b7d9c1de0
2 changed files with 56 additions and 31 deletions
src
commands
object

View File

@ -1,46 +1,73 @@
use crate::errors::ShellError; use crate::errors::ShellError;
use crate::object::{dir_entry_dict, Primitive, Value}; use crate::object::dir_entry_dict;
use crate::prelude::*; use crate::prelude::*;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> { pub fn ls(args: CommandArgs) -> Result<OutputStream, ShellError> {
let env = args.env.lock().unwrap(); let env = args.env.lock().unwrap();
let path = env.path.to_path_buf(); let path = env.path.to_path_buf();
let cwd = path.clone();
let mut full_path = PathBuf::from(path); let mut full_path = PathBuf::from(path);
match &args.nth(0) { match &args.nth(0) {
Some(Tagged { Some(Tagged { item: value, .. }) => full_path.push(Path::new(&value.as_string()?)),
item: Value::Primitive(Primitive::String(s)),
..
}) => full_path.push(Path::new(&s)),
_ => {} _ => {}
} }
let entries = std::fs::read_dir(&full_path); let entries = glob::glob(&full_path.to_string_lossy());
let entries = match entries { if entries.is_err() {
Err(e) => { return Err(ShellError::string("Invalid pattern."));
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,
};
let mut shell_entries = VecDeque::new(); let mut shell_entries = VecDeque::new();
let entries: Vec<_> = entries.unwrap().collect();
for entry in entries { // If this is a single entry, try to display the contents of the entry if it's a directory
let value = dir_entry_dict(&entry?, args.call_info.name_span)?; if entries.len() == 1 {
shell_entries.push_back(ReturnSuccess::value(value)) if let Ok(entry) = &entries[0] {
if entry.is_dir() {
let entries = std::fs::read_dir(&full_path);
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
for entry in entries {
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))
}
}
Ok(shell_entries.to_output_stream()) Ok(shell_entries.to_output_stream())
} }

View File

@ -10,15 +10,13 @@ pub enum FileType {
} }
crate fn dir_entry_dict( crate fn dir_entry_dict(
entry: &std::fs::DirEntry, filename: &std::path::Path,
metadata: &std::fs::Metadata,
span: impl Into<Span>, span: impl Into<Span>,
) -> Result<Tagged<Value>, ShellError> { ) -> Result<Tagged<Value>, ShellError> {
let mut dict = TaggedDictBuilder::new(span); let mut dict = TaggedDictBuilder::new(span);
let filename = entry.file_name();
dict.insert("name", Value::string(filename.to_string_lossy())); dict.insert("name", Value::string(filename.to_string_lossy()));
let metadata = entry.metadata()?;
let kind = if metadata.is_dir() { let kind = if metadata.is_dir() {
FileType::Directory FileType::Directory
} else if metadata.is_file() { } else if metadata.is_file() {