mirror of
https://github.com/nushell/nushell
synced 2024-12-28 05:53:09 +00:00
add mkdir command
This commit is contained in:
parent
8550f50522
commit
bdfe8c0888
5 changed files with 94 additions and 17 deletions
|
@ -35,6 +35,7 @@ pub fn create_default_context() -> Rc<RefCell<EngineState>> {
|
|||
working_set.add_decl(Box::new(LetEnv));
|
||||
working_set.add_decl(Box::new(Lines));
|
||||
working_set.add_decl(Box::new(Ls));
|
||||
working_set.add_decl(Box::new(Mkdir));
|
||||
working_set.add_decl(Box::new(Module));
|
||||
working_set.add_decl(Box::new(Mv));
|
||||
working_set.add_decl(Box::new(Ps));
|
||||
|
|
74
crates/nu-command/src/filesystem/mkdir.rs
Normal file
74
crates/nu-command/src/filesystem/mkdir.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::env::current_dir;
|
||||
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EvaluationContext};
|
||||
use nu_protocol::{ShellError, Signature, SyntaxShape, Value, ValueStream};
|
||||
|
||||
pub struct Mkdir;
|
||||
|
||||
impl Command for Mkdir {
|
||||
fn name(&self) -> &str {
|
||||
"mkdir"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("mkdir")
|
||||
.rest(
|
||||
"rest",
|
||||
SyntaxShape::Filepath,
|
||||
"the name(s) of the path(s) to create",
|
||||
)
|
||||
.switch("show-created-paths", "show the path(s) created.", Some('s'))
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Make directories, creates intermediary directories as required."
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
context: &EvaluationContext,
|
||||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
let path = current_dir()?;
|
||||
let mut directories = call
|
||||
.rest::<String>(context, 0)?
|
||||
.into_iter()
|
||||
.map(|dir| path.join(dir))
|
||||
.peekable();
|
||||
|
||||
let show_created_paths = call.has_flag("show-created-paths");
|
||||
let mut stream: VecDeque<Value> = VecDeque::new();
|
||||
|
||||
if directories.peek().is_none() {
|
||||
return Err(ShellError::MissingParameter(
|
||||
"requires directory paths".to_string(),
|
||||
call.head,
|
||||
));
|
||||
}
|
||||
|
||||
for (i, dir) in directories.enumerate() {
|
||||
let span = call.positional[i].span;
|
||||
let dir_res = std::fs::create_dir_all(&dir);
|
||||
|
||||
if let Err(reason) = dir_res {
|
||||
return Err(ShellError::CreateNotPossible(
|
||||
format!("failed to create directory: {}", reason),
|
||||
call.positional[i].span,
|
||||
));
|
||||
}
|
||||
|
||||
if show_created_paths {
|
||||
let val = format!("{:}", dir.to_string_lossy());
|
||||
stream.push_back(Value::String { val, span });
|
||||
}
|
||||
}
|
||||
|
||||
let stream = ValueStream::from_stream(stream.into_iter());
|
||||
let span = call.head;
|
||||
Ok(Value::Stream { stream, span })
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
mod cd;
|
||||
mod cp;
|
||||
mod ls;
|
||||
mod mkdir;
|
||||
mod mv;
|
||||
mod touch;
|
||||
mod util;
|
||||
|
@ -8,5 +9,6 @@ mod util;
|
|||
pub use cd::Cd;
|
||||
pub use cp::Cp;
|
||||
pub use ls::Ls;
|
||||
pub use mkdir::Mkdir;
|
||||
pub use mv::Mv;
|
||||
pub use touch::Touch;
|
||||
|
|
|
@ -32,25 +32,21 @@ impl Command for Touch {
|
|||
call: &Call,
|
||||
_input: Value,
|
||||
) -> Result<Value, ShellError> {
|
||||
touch(context, call)
|
||||
}
|
||||
}
|
||||
let target: String = call.req(context, 0)?;
|
||||
let rest: Vec<String> = call.rest(context, 1)?;
|
||||
|
||||
fn touch(context: &EvaluationContext, call: &Call) -> Result<Value, ShellError> {
|
||||
let target: String = call.req(context, 0)?;
|
||||
let rest: Vec<String> = call.rest(context, 1)?;
|
||||
|
||||
for (index, item) in vec![target].into_iter().chain(rest).enumerate() {
|
||||
match OpenOptions::new().write(true).create(true).open(&item) {
|
||||
Ok(_) => continue,
|
||||
Err(err) => {
|
||||
return Err(ShellError::CreateNotPossible(
|
||||
format!("Failed to create file: {}", err),
|
||||
call.positional[index].span,
|
||||
));
|
||||
for (index, item) in vec![target].into_iter().chain(rest).enumerate() {
|
||||
match OpenOptions::new().write(true).create(true).open(&item) {
|
||||
Ok(_) => continue,
|
||||
Err(err) => {
|
||||
return Err(ShellError::CreateNotPossible(
|
||||
format!("Failed to create file: {}", err),
|
||||
call.positional[index].span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
Ok(Value::Nothing { span: call.head })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,10 @@ pub enum ShellError {
|
|||
#[diagnostic(code(nu::shell::unknown_operator), url(docsrs))]
|
||||
UnknownOperator(String, #[label = "unsupported operator"] Span),
|
||||
|
||||
#[error("Missing parameter: {0}.")]
|
||||
#[diagnostic(code(nu::shell::missing_parameter), url(docsrs))]
|
||||
MissingParameter(String, #[label = "missing parameter: {0}"] Span),
|
||||
|
||||
#[error("External commands not yet supported")]
|
||||
#[diagnostic(code(nu::shell::external_commands), url(docsrs))]
|
||||
ExternalNotSupported(#[label = "external not supported"] Span),
|
||||
|
|
Loading…
Reference in a new issue