nu_command/filesystem/
umkdir.rs1#[allow(deprecated)]
2use nu_engine::{command_prelude::*, current_dir};
3use nu_protocol::NuGlob;
4use uu_mkdir::mkdir;
5#[cfg(not(windows))]
6use uucore::mode;
7
8#[derive(Clone)]
9pub struct UMkdir;
10
11const IS_RECURSIVE: bool = true;
12const DEFAULT_MODE: u32 = 0o777;
13
14#[cfg(not(windows))]
15fn get_mode() -> u32 {
16 !mode::get_umask() & DEFAULT_MODE
17}
18
19#[cfg(windows)]
20fn get_mode() -> u32 {
21 DEFAULT_MODE
22}
23
24impl Command for UMkdir {
25 fn name(&self) -> &str {
26 "mkdir"
27 }
28
29 fn description(&self) -> &str {
30 "Create directories, with intermediary directories if required using uutils/coreutils mkdir."
31 }
32
33 fn search_terms(&self) -> Vec<&str> {
34 vec!["directory", "folder", "create", "make_dirs", "coreutils"]
35 }
36
37 fn signature(&self) -> Signature {
38 Signature::build("mkdir")
39 .input_output_types(vec![(Type::Nothing, Type::Nothing)])
40 .rest(
41 "rest",
42 SyntaxShape::OneOf(vec![SyntaxShape::GlobPattern, SyntaxShape::Directory]),
43 "The name(s) of the path(s) to create.",
44 )
45 .switch(
46 "verbose",
47 "print a message for each created directory.",
48 Some('v'),
49 )
50 .category(Category::FileSystem)
51 }
52
53 fn run(
54 &self,
55 engine_state: &EngineState,
56 stack: &mut Stack,
57 call: &Call,
58 _input: PipelineData,
59 ) -> Result<PipelineData, ShellError> {
60 #[allow(deprecated)]
61 let cwd = current_dir(engine_state, stack)?;
62 let mut directories = call
63 .rest::<Spanned<NuGlob>>(engine_state, stack, 0)?
64 .into_iter()
65 .map(|dir| nu_path::expand_path_with(dir.item.as_ref(), &cwd, dir.item.is_expand()))
66 .peekable();
67
68 let is_verbose = call.has_flag(engine_state, stack, "verbose")?;
69
70 if directories.peek().is_none() {
71 return Err(ShellError::MissingParameter {
72 param_name: "requires directory paths".to_string(),
73 span: call.head,
74 });
75 }
76
77 for dir in directories {
78 if let Err(error) = mkdir(&dir, IS_RECURSIVE, get_mode(), is_verbose) {
79 return Err(ShellError::GenericError {
80 error: format!("{}", error),
81 msg: format!("{}", error),
82 span: None,
83 help: None,
84 inner: vec![],
85 });
86 }
87 }
88
89 Ok(PipelineData::empty())
90 }
91
92 fn examples(&self) -> Vec<Example> {
93 vec![
94 Example {
95 description: "Make a directory named foo",
96 example: "mkdir foo",
97 result: None,
98 },
99 Example {
100 description: "Make multiple directories and show the paths created",
101 example: "mkdir -v foo/bar foo2",
102 result: None,
103 },
104 ]
105 }
106}