mkdir: gnu compat: add support of mkdir -p foo/.

This commit is contained in:
Sylvestre Ledru 2022-03-22 23:08:47 +01:00
parent 6b8ab37ad9
commit fbb64b9c5c
2 changed files with 40 additions and 4 deletions

View file

@ -11,7 +11,7 @@
extern crate uucore;
use clap::{crate_version, Arg, ArgMatches, Command, OsValues};
use std::path::Path;
use std::path::{Path, PathBuf};
use uucore::display::Quotable;
#[cfg(not(windows))]
use uucore::error::FromIo;
@ -143,8 +143,17 @@ pub fn uu_app<'a>() -> Command<'a> {
*/
fn exec(dirs: OsValues, recursive: bool, mode: u32, verbose: bool) -> UResult<()> {
for dir in dirs {
let path = Path::new(dir);
show_if_err!(mkdir(path, recursive, mode, verbose));
// Special case to match GNU's behavior:
// mkdir -p foo/. should work and just create foo/
// std::fs::create_dir("foo/."); fails in pure Rust
let path = if recursive && dir.to_string_lossy().ends_with("/.") {
// Do a simple dance to strip the "/."
Path::new(dir).components().collect::<PathBuf>()
} else {
// Normal case
PathBuf::from(dir)
};
show_if_err!(mkdir(path.as_path(), recursive, mode, verbose));
}
Ok(())
}
@ -190,7 +199,6 @@ fn create_dir(path: &Path, recursive: bool, verbose: bool) -> UResult<()> {
}
}
}
match std::fs::create_dir(path) {
Ok(()) => {
if verbose {

View file

@ -11,6 +11,8 @@ static TEST_DIR6: &str = "mkdir_test6";
static TEST_FILE7: &str = "mkdir_test7";
static TEST_DIR8: &str = "mkdir_test8/mkdir_test8_1/mkdir_test8_2";
static TEST_DIR9: &str = "mkdir_test9/../mkdir_test9_1/../mkdir_test9_2";
static TEST_DIR10: &str = "mkdir_test10/.";
static TEST_DIR11: &str = "mkdir_test11/..";
#[test]
fn test_mkdir_mkdir() {
@ -123,3 +125,29 @@ fn test_recursive_reporting() {
.stdout_contains("created directory 'mkdir_test9/../mkdir_test9_1'")
.stdout_contains("created directory 'mkdir_test9/../mkdir_test9_1/../mkdir_test9_2'");
}
#[test]
fn test_mkdir_trailing_dot() {
let scene2 = TestScenario::new("ls");
new_ucmd!()
.arg("-p")
.arg("-v")
.arg("mkdir_test10-2")
.succeeds();
new_ucmd!()
.arg("-p")
.arg("-v")
.arg(TEST_DIR10)
.succeeds()
.stdout_contains("created directory 'mkdir_test10'");
new_ucmd!()
.arg("-p")
.arg("-v")
.arg(TEST_DIR11)
.succeeds()
.stdout_contains("created directory 'mkdir_test11'");
let result = scene2.cmd("ls").arg("-al").run();
println!("ls dest {}", result.stdout_str());
}