use crate::commands::CommandContext;
use crate::utils::{trace_lazy, CommandResult, VirtualUtils};
use std::fs;
pub async fn mkdir(ctx: CommandContext) -> CommandResult {
if ctx.args.is_empty() {
return VirtualUtils::missing_operand_error("mkdir");
}
let mut create_parents = false;
let mut dirs = Vec::new();
for arg in &ctx.args {
if arg == "-p" {
create_parents = true;
} else if arg.starts_with('-') {
} else {
dirs.push(arg.clone());
}
}
if dirs.is_empty() {
return VirtualUtils::missing_operand_error("mkdir");
}
let cwd = ctx.get_cwd();
for dir in dirs {
let resolved_path = VirtualUtils::resolve_path(&dir, Some(&cwd));
trace_lazy("VirtualCommand", || {
format!(
"mkdir: creating directory {:?}, parents: {}",
resolved_path, create_parents
)
});
let result = if create_parents {
fs::create_dir_all(&resolved_path)
} else {
fs::create_dir(&resolved_path)
};
if let Err(e) = result {
return CommandResult::error(format!(
"mkdir: cannot create directory '{}': {}\n",
dir, e
));
}
}
CommandResult::success_empty()
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[tokio::test]
async fn test_mkdir_simple() {
let temp = tempdir().unwrap();
let new_dir = temp.path().join("new_directory");
let ctx = CommandContext::new(vec![new_dir.to_string_lossy().to_string()]);
let result = mkdir(ctx).await;
assert!(result.is_success());
assert!(new_dir.exists());
}
#[tokio::test]
async fn test_mkdir_with_parents() {
let temp = tempdir().unwrap();
let nested_dir = temp.path().join("a/b/c/d");
let ctx = CommandContext::new(vec![
"-p".to_string(),
nested_dir.to_string_lossy().to_string(),
]);
let result = mkdir(ctx).await;
assert!(result.is_success());
assert!(nested_dir.exists());
}
#[tokio::test]
async fn test_mkdir_missing_operand() {
let ctx = CommandContext::new(vec![]);
let result = mkdir(ctx).await;
assert!(!result.is_success());
assert!(result.stderr.contains("missing operand"));
}
}