command_stream/commands/
mkdir.rs1use crate::commands::CommandContext;
4use crate::utils::{trace_lazy, CommandResult, VirtualUtils};
5use std::fs;
6
7pub async fn mkdir(ctx: CommandContext) -> CommandResult {
11 if ctx.args.is_empty() {
12 return VirtualUtils::missing_operand_error("mkdir");
13 }
14
15 let mut create_parents = false;
17 let mut dirs = Vec::new();
18
19 for arg in &ctx.args {
20 if arg == "-p" {
21 create_parents = true;
22 } else if arg.starts_with('-') {
23 } else {
25 dirs.push(arg.clone());
26 }
27 }
28
29 if dirs.is_empty() {
30 return VirtualUtils::missing_operand_error("mkdir");
31 }
32
33 let cwd = ctx.get_cwd();
34
35 for dir in dirs {
36 let resolved_path = VirtualUtils::resolve_path(&dir, Some(&cwd));
37
38 trace_lazy("VirtualCommand", || {
39 format!(
40 "mkdir: creating directory {:?}, parents: {}",
41 resolved_path, create_parents
42 )
43 });
44
45 let result = if create_parents {
46 fs::create_dir_all(&resolved_path)
47 } else {
48 fs::create_dir(&resolved_path)
49 };
50
51 if let Err(e) = result {
52 return CommandResult::error(format!(
53 "mkdir: cannot create directory '{}': {}\n",
54 dir, e
55 ));
56 }
57 }
58
59 CommandResult::success_empty()
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use tempfile::tempdir;
66
67 #[tokio::test]
68 async fn test_mkdir_simple() {
69 let temp = tempdir().unwrap();
70 let new_dir = temp.path().join("new_directory");
71
72 let ctx = CommandContext::new(vec![new_dir.to_string_lossy().to_string()]);
73 let result = mkdir(ctx).await;
74
75 assert!(result.is_success());
76 assert!(new_dir.exists());
77 }
78
79 #[tokio::test]
80 async fn test_mkdir_with_parents() {
81 let temp = tempdir().unwrap();
82 let nested_dir = temp.path().join("a/b/c/d");
83
84 let ctx = CommandContext::new(vec![
85 "-p".to_string(),
86 nested_dir.to_string_lossy().to_string(),
87 ]);
88 let result = mkdir(ctx).await;
89
90 assert!(result.is_success());
91 assert!(nested_dir.exists());
92 }
93
94 #[tokio::test]
95 async fn test_mkdir_missing_operand() {
96 let ctx = CommandContext::new(vec![]);
97 let result = mkdir(ctx).await;
98
99 assert!(!result.is_success());
100 assert!(result.stderr.contains("missing operand"));
101 }
102}