From 6245029445fc781fd22f508ef28c8835230c57c1 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 8 Oct 2022 15:02:56 -0500 Subject: [PATCH 01/42] rm: rm3 now passes --- src/uu/rm/src/rm.rs | 154 +++++++++++++++++++++++++++------------ tests/by-util/test_rm.rs | 103 ++++++++++++++++++++++++++ 2 files changed, 211 insertions(+), 46 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 5406979f7..f3a4f2f4e 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -13,10 +13,8 @@ extern crate uucore; use clap::{crate_version, Arg, Command}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; -use std::fs; -use std::fs::File; -use std::io::ErrorKind; -use std::io::{stderr, stdin, BufRead, Write}; +use std::fs::{self, File, Metadata}; +use std::io::{stderr, stdin, BufRead, ErrorKind, Write}; use std::ops::BitOr; use std::path::{Path, PathBuf}; use uucore::display::Quotable; @@ -365,12 +363,7 @@ fn handle_dir(path: &Path, options: &Options) -> bool { } fn remove_dir(path: &Path, options: &Options) -> bool { - let response = if options.interactive == InteractiveMode::Always { - prompt_file(path, true) - } else { - true - }; - if response { + if prompt_file(path, options, true) { if let Ok(mut read_dir) = fs::read_dir(path) { if options.dir || options.recursive { if read_dir.next().is_none() { @@ -415,12 +408,7 @@ fn remove_dir(path: &Path, options: &Options) -> bool { } fn remove_file(path: &Path, options: &Options) -> bool { - let response = if options.interactive == InteractiveMode::Always { - prompt_file(path, false) - } else { - true - }; - if response && prompt_write_protected(path, false, options) { + if prompt_file(path, options, false) { match fs::remove_file(path) { Ok(_) => { if options.verbose { @@ -442,46 +430,122 @@ fn remove_file(path: &Path, options: &Options) -> bool { false } -fn prompt_write_protected(path: &Path, is_dir: bool, options: &Options) -> bool { +fn prompt_file(path: &Path, options: &Options, is_dir: bool) -> bool { + // If interactive is Never we never want to send prompts if options.interactive == InteractiveMode::Never { return true; } - match File::open(path) { - Ok(_) => true, - Err(err) => { - if err.kind() == ErrorKind::PermissionDenied { - if is_dir { - prompt(&(format!("rm: remove write-protected directory {}? ", path.quote()))) - } else { - if fs::metadata(path).unwrap().len() == 0 { - return prompt( - &(format!( - "rm: remove write-protected regular empty file {}? ", - path.quote() - )), - ); + // If interactive is Always we want to check if the file is symlink to prompt the right message + if options.interactive == InteractiveMode::Always { + if let Ok(metadata) = fs::symlink_metadata(path) { + if metadata.is_symlink() { + return prompt(&(format!("remove symbolic link {}? ", path.quote()))); + } + } + } + if is_dir { + // We can't use metadata.permissions.readonly for directories because it only works on files + // So we have to handle wether a directory is writable on not manually + if let Ok(metadata) = fs::metadata(path) { + handle_writable_directory(path, options, &metadata) + } else { + true + } + } else { + // File::open(path) doesn't open the file in write mode so we need to use file options to open it in also write mode to check if it can written too + match File::options().read(true).write(true).open(path) { + Ok(file) => { + if let Ok(metadata) = file.metadata() { + if metadata.permissions().readonly() { + if metadata.len() == 0 { + prompt( + &(format!( + "remove write-protected regular empty file {}? ", + path.quote() + )), + ) + } else { + prompt( + &(format!( + "remove write-protected regular file {}? ", + path.quote() + )), + ) + } + } else if options.interactive == InteractiveMode::Always { + if metadata.len() == 0 { + prompt(&(format!("remove regular empty file {}? ", path.quote()))) + } else { + prompt(&(format!("remove file {}? ", path.quote()))) + } + } else { + true } - prompt(&(format!("rm: remove write-protected regular file {}? ", path.quote()))) + } else { + true + } + } + Err(err) => { + if err.kind() == ErrorKind::PermissionDenied { + if let Ok(metadata) = fs::metadata(path) { + if metadata.len() == 0 { + prompt( + &(format!( + "remove write-protected regular empty file {}? ", + path.quote() + )), + ) + } else { + prompt( + &(format!( + "remove write-protected regular file {}? ", + path.quote() + )), + ) + } + } else { + prompt(&(format!("remove write-protected regular file {}? ", path.quote()))) + } + } else { + true } - } else { - true } } } } -fn prompt_descend(path: &Path) -> bool { - prompt(&(format!("rm: descend into directory {}? ", path.quote()))) +// For directories finding if they are writable or not is a hassle. In Unix we can use the built-in rust crate to to check mode bits. But other os don't have something similar afaik +#[cfg(unix)] +fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { + use std::os::unix::fs::PermissionsExt; + let mode = metadata.permissions().mode(); + let user_write_permission = (mode & 0b1_1100_0000) >> 6; + let user_writable = !matches!(user_write_permission, 0o0 | 0o1 | 0o4 | 0o5); + if !user_writable { + prompt(&(format!("remove write-protected directory {}? ", path.quote()))) + } else if options.interactive == InteractiveMode::Always { + prompt(&(format!("remove directory {}? ", path.quote()))) + } else { + true + } } -fn prompt_file(path: &Path, is_dir: bool) -> bool { - if is_dir { - prompt(&(format!("rm: remove directory {}? ", path.quote()))) +// I have this here for completeness but it will always return "remove directory {}" because metadata.permissions().readonly() only works for file not directories +#[cfg(not(unix))] +fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { + if metadata.permissions().readonly() { + prompt(&(format!("remove write-protected directory {}? ", path.quote()))) + } else if options.interactive == InteractiveMode::Always { + prompt(&(format!("remove directory {}? ", path.quote()))) } else { - prompt(&(format!("rm: remove file {}? ", path.quote()))) + true } } +fn prompt_descend(path: &Path) -> bool { + prompt(&(format!("descend into directory {}? ", path.quote()))) +} + fn normalize(path: &Path) -> PathBuf { // copied from https://github.com/rust-lang/cargo/blob/2e4cfc2b7d43328b207879228a2ca7d427d188bb/src/cargo/util/paths.rs#L65-L90 // both projects are MIT https://github.com/rust-lang/cargo/blob/master/LICENSE-MIT @@ -491,7 +555,7 @@ fn normalize(path: &Path) -> PathBuf { } fn prompt(msg: &str) -> bool { - let _ = stderr().write_all(msg.as_bytes()); + let _ = stderr().write_all(format!("{}: {}", uucore::util_name(), msg).as_bytes()); let _ = stderr().flush(); let mut buf = Vec::new(); @@ -505,15 +569,13 @@ fn prompt(msg: &str) -> bool { } #[cfg(not(windows))] -fn is_symlink_dir(_metadata: &fs::Metadata) -> bool { +fn is_symlink_dir(_metadata: &Metadata) -> bool { false } #[cfg(windows)] -use std::os::windows::prelude::MetadataExt; - -#[cfg(windows)] -fn is_symlink_dir(metadata: &fs::Metadata) -> bool { +fn is_symlink_dir(metadata: &Metadata) -> bool { + use std::os::windows::prelude::MetadataExt; use winapi::um::winnt::FILE_ATTRIBUTE_DIRECTORY; metadata.file_type().is_symlink() diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index b600c2090..60b1f12b8 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -400,6 +400,109 @@ fn test_rm_descend_directory() { assert!(!at.file_exists(file_2)); } +#[cfg(feature = "chmod")] +#[test] +fn test_rm_prompts() { + use std::io::Write; + use std::process::Child; + + // Needed for talking with stdin on platforms where CRLF or LF matters + const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" }; + + let mut answers = vec![ + "rm: descend into directory 'a'?", + "rm: remove write-protected regular empty file 'a/empty-no-write'?", + "rm: remove symbolic link 'a/slink'?", + "rm: remove symbolic link 'a/slink-dot'?", + "rm: remove write-protected regular file 'a/f-no-write'?", + "rm: remove regular empty file 'a/empty'?", + "rm: remove directory 'a/b'?", + "rm: remove write-protected directory 'a/b-no-write'?", + "rm: remove directory 'a'?", + ]; + + answers.sort(); + + let yes = format!("y{}", END_OF_LINE); + + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + at.mkdir("a/"); + + let file_1 = "a/empty"; + let file_2 = "a/empty-no-write"; + let file_3 = "a/f-no-write"; + + at.touch(file_1); + at.touch(file_2); + at.make_file(file_3) + .write_all(b"not-empty") + .expect("Couldn't write to a/f-no-write"); + + at.symlink_dir("a/empty-f", "a/slink"); + at.symlink_dir(".", "a/slink-dot"); + + let dir_1 = "a/b/"; + let dir_2 = "a/b-no-write/"; + + at.mkdir(dir_1); + at.mkdir(dir_2); + + scene + .ccmd("chmod") + .arg("u-w") + .arg(file_3) + .arg(dir_2) + .arg(file_2) + .succeeds(); + + let mut child: Child = scene.ucmd().arg("-ri").arg("a").run_no_wait(); + + let mut child_stdin = child.stdin.take().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + + let output = child.wait_with_output().unwrap(); + + let mut trimmed_output = Vec::new(); + for string in String::from_utf8(output.stderr) + .expect("Couldn't convert output.stderr to string") + .split("rm: ") + { + if !string.is_empty() { + let trimmed_string = format!("rm: {}", string).trim().to_string(); + trimmed_output.push(trimmed_string); + } + } + + trimmed_output.sort(); + + assert!(trimmed_output.len() == answers.len()); + + for (i, checking_string) in trimmed_output.iter().enumerate() { + assert!(checking_string == answers[i]); + } + + assert!(!at.dir_exists("a")); +} + #[test] #[ignore = "issue #3722"] fn test_rm_directory_rights_rm1() { From 30adc8e037b3cdf6f5bce61c17a4be489b4e18f5 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 8 Oct 2022 15:22:09 -0500 Subject: [PATCH 02/42] Added windows version of handle_writable_directory --- src/uu/rm/src/rm.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index f3a4f2f4e..fd3dd4a5c 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -530,7 +530,23 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata } } +// For windows we can use windows metadata trait and file attirubtes to see if a directory is readonly +#[cfg(windows)] +fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { + use std::os::windows::prelude::MetadataExt; + use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; + let user_writable = (metadata.file_attributes() & FILE_ATTRIBUTE_READONLY) != 0; + if !user_writable { + prompt(&(format!("remove write-protected directory {}? ", path.quote()))) + } else if options.interactive == InteractiveMode::Always { + prompt(&(format!("remove directory {}? ", path.quote()))) + } else { + true + } +} + // I have this here for completeness but it will always return "remove directory {}" because metadata.permissions().readonly() only works for file not directories +#[cfg(not(windows))] #[cfg(not(unix))] fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { if metadata.permissions().readonly() { From 1f50df2af6f6c2726205cfdbfde96e0f9c40efc7 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 8 Oct 2022 16:47:27 -0500 Subject: [PATCH 03/42] Fixed spelling error --- src/uu/rm/src/rm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index fd3dd4a5c..bd8cb7dcb 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -530,7 +530,7 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata } } -// For windows we can use windows metadata trait and file attirubtes to see if a directory is readonly +// For windows we can use windows metadata trait and file attributes to see if a directory is readonly #[cfg(windows)] fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { use std::os::windows::prelude::MetadataExt; From 6856ce0bf40f6c8376592d72294473d2494e361c Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 8 Oct 2022 16:51:14 -0500 Subject: [PATCH 04/42] Fixed handle_writable_directory on windows --- src/uu/rm/src/rm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index bd8cb7dcb..a72a88393 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -535,8 +535,8 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { use std::os::windows::prelude::MetadataExt; use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; - let user_writable = (metadata.file_attributes() & FILE_ATTRIBUTE_READONLY) != 0; - if !user_writable { + let not_user_writable = (metadata.file_attributes() & FILE_ATTRIBUTE_READONLY) != 0; + if not_user_writable { prompt(&(format!("remove write-protected directory {}? ", path.quote()))) } else if options.interactive == InteractiveMode::Always { prompt(&(format!("remove directory {}? ", path.quote()))) From 50d2948aa1bc25cb8f463d5964517c23f8ecde83 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sun, 9 Oct 2022 17:24:36 -0500 Subject: [PATCH 05/42] Fixed rm --force argument not forcing prompt to not show up --- src/uu/rm/src/rm.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index a72a88393..b5adcf9e8 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -98,7 +98,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let options = Options { force, interactive: { - if matches.contains_id(OPT_PROMPT) { + if force { + InteractiveMode::Never + } else if matches.contains_id(OPT_PROMPT) { InteractiveMode::Always } else if matches.contains_id(OPT_PROMPT_MORE) { InteractiveMode::Once From 3c39a57da0a32ec20beb4a03be31a09136e4b18f Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Mon, 10 Oct 2022 12:43:01 -0500 Subject: [PATCH 06/42] Check force position in rm --- src/uu/rm/src/rm.rs | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index b5adcf9e8..576094d5d 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -88,17 +88,38 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.map(ToString::to_string).collect()) .unwrap_or_default(); - let force = matches.contains_id(OPT_FORCE); + let force_index_option = matches.index_of(OPT_FORCE); - if files.is_empty() && !force { + // If -f(--force) is before any -i (or variants) we want prompts else no prompts + let force_first: bool = { + if let Some(force_index) = force_index_option { + let prompt_index_option = matches.index_of(OPT_PROMPT); + let prompt_more_index_option = matches.index_of(OPT_PROMPT_MORE); + let interactive_index_option = matches.index_of(OPT_INTERACTIVE); + + if let Some(prompt_index) = prompt_index_option { + prompt_index > force_index + } else if let Some(prompt_more_index_index) = prompt_more_index_option { + prompt_more_index_index > force_index + } else if let Some(interactive_index) = interactive_index_option { + interactive_index > force_index + } else { + true + } + } else { + true + } + }; + + if files.is_empty() && force_index_option.is_none() { // Still check by hand and not use clap // Because "rm -f" is a thing return Err(UUsageError::new(1, "missing operand")); } else { let options = Options { - force, + force: force_index_option.is_some(), interactive: { - if force { + if force_index_option.is_some() && !force_first { InteractiveMode::Never } else if matches.contains_id(OPT_PROMPT) { InteractiveMode::Always From 70bf4f36a04a3cb6200b787494a4857191015613 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Mon, 10 Oct 2022 13:48:34 -0500 Subject: [PATCH 07/42] Added test to check rm force prompts order --- tests/by-util/test_rm.rs | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 60b1f12b8..dcf85f4d1 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -503,6 +503,48 @@ fn test_rm_prompts() { assert!(!at.dir_exists("a")); } +#[test] +fn test_rm_force_prompts_order() { + use std::io::Write; + use std::process::Child; + + // Needed for talking with stdin on platforms where CRLF or LF matters + const END_OF_LINE: &str = if cfg!(windows) { "\r\n" } else { "\n" }; + + let yes = format!("y{}", END_OF_LINE); + + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + + let empty_file = "empty"; + + at.touch(empty_file); + + // This should cause rm to prompt to remove regular empty file + let mut child: Child = scene.ucmd().arg("-fi").arg(empty_file).run_no_wait(); + + let mut child_stdin = child.stdin.take().unwrap(); + child_stdin.write_all(yes.as_bytes()).unwrap(); + child_stdin.flush().unwrap(); + + let output = child.wait_with_output().unwrap(); + let string_output = + String::from_utf8(output.stderr).expect("Couldn't convert output.stderr to string"); + assert!(string_output.trim() == String::from("rm: remove regular empty file 'empty'?")); + assert!(!at.file_exists(empty_file)); + + at.touch(empty_file); + + // This should not cause rm to prompt to remove regular empty file + scene + .ucmd() + .arg("-if") + .arg(empty_file) + .succeeds() + .no_stderr(); + assert!(!at.file_exists(empty_file)); +} + #[test] #[ignore = "issue #3722"] fn test_rm_directory_rights_rm1() { From 0507270f90d32698d5bfd86bcf2e109c6c6c0e1a Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Mon, 10 Oct 2022 13:52:05 -0500 Subject: [PATCH 08/42] Clippy is going to be the death of me --- tests/by-util/test_rm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index dcf85f4d1..98273fedd 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -530,7 +530,7 @@ fn test_rm_force_prompts_order() { let output = child.wait_with_output().unwrap(); let string_output = String::from_utf8(output.stderr).expect("Couldn't convert output.stderr to string"); - assert!(string_output.trim() == String::from("rm: remove regular empty file 'empty'?")); + assert!(string_output.trim() == "rm: remove regular empty file 'empty'?"); assert!(!at.file_exists(empty_file)); at.touch(empty_file); From 3a1098489e6a7b1b71b77ca8c7e6b4a35af3363e Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Mon, 10 Oct 2022 15:01:17 -0500 Subject: [PATCH 09/42] Small fix --- src/uu/rm/src/rm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 576094d5d..f83c09031 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -104,7 +104,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else if let Some(interactive_index) = interactive_index_option { interactive_index > force_index } else { - true + false } } else { true From 355136936fc158dd0cfdad8c109d54bc28d0434a Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Tue, 11 Oct 2022 15:45:20 -0500 Subject: [PATCH 10/42] Fixed force rm --- src/uu/rm/src/rm.rs | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index f83c09031..2143bb8e3 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -91,23 +91,33 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let force_index_option = matches.index_of(OPT_FORCE); // If -f(--force) is before any -i (or variants) we want prompts else no prompts - let force_first: bool = { + let force_prompt_never: bool = { if let Some(force_index) = force_index_option { let prompt_index_option = matches.index_of(OPT_PROMPT); let prompt_more_index_option = matches.index_of(OPT_PROMPT_MORE); let interactive_index_option = matches.index_of(OPT_INTERACTIVE); + let mut result = true; + if let Some(prompt_index) = prompt_index_option { - prompt_index > force_index - } else if let Some(prompt_more_index_index) = prompt_more_index_option { - prompt_more_index_index > force_index - } else if let Some(interactive_index) = interactive_index_option { - interactive_index > force_index - } else { - false + if result { + result = prompt_index <= force_index; + } } + if let Some(prompt_more_index_index) = prompt_more_index_option { + if result { + result = prompt_more_index_index <= force_index; + } + } + if let Some(interactive_index) = interactive_index_option { + if result { + result = interactive_index <= force_index; + } + } + + result } else { - true + false } }; @@ -119,7 +129,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let options = Options { force: force_index_option.is_some(), interactive: { - if force_index_option.is_some() && !force_first { + if force_index_option.is_some() && force_prompt_never { InteractiveMode::Never } else if matches.contains_id(OPT_PROMPT) { InteractiveMode::Always From e11dd50eb4f3572a52b5c92dae76b977349e8998 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Wed, 12 Oct 2022 16:54:38 -0500 Subject: [PATCH 11/42] Added comments --- src/uu/rm/src/rm.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 2143bb8e3..a8932b7f5 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -99,16 +99,19 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut result = true; + // if we have rm -i -f if let Some(prompt_index) = prompt_index_option { if result { result = prompt_index <= force_index; } } + // if we have rm -I -f if let Some(prompt_more_index_index) = prompt_more_index_option { if result { result = prompt_more_index_index <= force_index; } } + // if we have rm --interactive -f if let Some(interactive_index) = interactive_index_option { if result { result = interactive_index <= force_index; From a3f35a726cb48cc65189ce968b6e64cd16b44c6b Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Wed, 12 Oct 2022 17:31:28 -0500 Subject: [PATCH 12/42] Add override for prompting --- src/uu/rm/src/rm.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index a8932b7f5..ead7a63b6 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -194,12 +194,13 @@ pub fn uu_app<'a>() -> Command<'a> { .arg( Arg::new(OPT_PROMPT) .short('i') - .help("prompt before every removal"), + .help("prompt before every removal") + .overrides_with_all(&[OPT_PROMPT_MORE, OPT_INTERACTIVE]), ) .arg(Arg::new(OPT_PROMPT_MORE).short('I').help( "prompt once before removing more than three files, or when removing recursively. \ Less intrusive than -i, while still giving some protection against most mistakes", - )) + ).overrides_with_all(&[OPT_PROMPT, OPT_INTERACTIVE])) .arg( Arg::new(OPT_INTERACTIVE) .long(OPT_INTERACTIVE) @@ -208,7 +209,8 @@ pub fn uu_app<'a>() -> Command<'a> { prompts always", ) .value_name("WHEN") - .takes_value(true), + .takes_value(true) + .overrides_with_all(&[OPT_PROMPT, OPT_PROMPT_MORE]), ) .arg( Arg::new(OPT_ONE_FILE_SYSTEM) From fddc8c9d9d6896ceb91932cdb273013aa07b05d8 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Thu, 13 Oct 2022 17:22:59 -0500 Subject: [PATCH 13/42] More readable unix write permissions for directory using libc --- src/uu/rm/Cargo.toml | 3 +++ src/uu/rm/src/rm.rs | 8 +++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index e992d86d1..3196c71ce 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -20,6 +20,9 @@ walkdir = "2.2" remove_dir_all = "0.7.0" uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs"] } +[target.'cfg(unix)'.dependencies] +libc = "0.2.135" + [target.'cfg(windows)'.dependencies] winapi = { version="0.3", features=[] } diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index ead7a63b6..fa4d8cc35 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -557,8 +557,8 @@ fn prompt_file(path: &Path, options: &Options, is_dir: bool) -> bool { fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { use std::os::unix::fs::PermissionsExt; let mode = metadata.permissions().mode(); - let user_write_permission = (mode & 0b1_1100_0000) >> 6; - let user_writable = !matches!(user_write_permission, 0o0 | 0o1 | 0o4 | 0o5); + // Check if directory has user write permissions + let user_writable = (mode & libc::S_IWUSR) != 0; if !user_writable { prompt(&(format!("remove write-protected directory {}? ", path.quote()))) } else if options.interactive == InteractiveMode::Always { @@ -587,9 +587,7 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata #[cfg(not(windows))] #[cfg(not(unix))] fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { - if metadata.permissions().readonly() { - prompt(&(format!("remove write-protected directory {}? ", path.quote()))) - } else if options.interactive == InteractiveMode::Always { + if options.interactive == InteractiveMode::Always { prompt(&(format!("remove directory {}? ", path.quote()))) } else { true From e89d9d091da44a0e15653c0acf0b4341680004b1 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Thu, 13 Oct 2022 17:37:11 -0500 Subject: [PATCH 14/42] Forgot .lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 097df2a5e..8700897d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2691,6 +2691,7 @@ name = "uu_rm" version = "0.0.16" dependencies = [ "clap", + "libc", "remove_dir_all 0.7.0", "uucore", "walkdir", From 21b066a58e38b808953919636819aaf0f18ff740 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Thu, 13 Oct 2022 17:40:27 -0500 Subject: [PATCH 15/42] Why is S_IWUSR showing up as a u16 on macos --- src/uu/rm/src/rm.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index fa4d8cc35..b17ea2d63 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -558,7 +558,8 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata use std::os::unix::fs::PermissionsExt; let mode = metadata.permissions().mode(); // Check if directory has user write permissions - let user_writable = (mode & libc::S_IWUSR) != 0; + // Why is S_IWUSR showing up as a u16 on macos? + let user_writable = (mode & (libc::S_IWUSR as u32)) != 0; if !user_writable { prompt(&(format!("remove write-protected directory {}? ", path.quote()))) } else if options.interactive == InteractiveMode::Always { From 430652193be939b9dbdd2487fa1c951da2d67af3 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 15 Oct 2022 15:08:28 -0500 Subject: [PATCH 16/42] Fixed merge conflicts --- Cargo.lock | 2 +- src/uu/rm/src/rm.rs | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 763d24fa9..149099e8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2713,7 +2713,7 @@ name = "uu_rm" version = "0.0.16" dependencies = [ "clap 4.0.14", - "libc" + "libc", "remove_dir_all 0.7.0", "uucore", "walkdir", diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index f94c4ce46..b45938a86 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -196,11 +196,14 @@ pub fn uu_app() -> Command { .overrides_with_all(&[OPT_PROMPT_MORE, OPT_INTERACTIVE]) .action(ArgAction::SetTrue), ) - .arg(Arg::new(OPT_PROMPT_MORE).short('I').help( - "prompt once before removing more than three files, or when removing recursively. \ - Less intrusive than -i, while still giving some protection against most mistakes", - ).overrides_with_all(&[OPT_PROMPT, OPT_INTERACTIVE]) - ).action(ArgAction::SetTrue)) + .arg( + Arg::new(OPT_PROMPT_MORE) + .short('I') + .help("prompt once before removing more than three files, or when removing recursively. \ + Less intrusive than -i, while still giving some protection against most mistakes") + .overrides_with_all(&[OPT_PROMPT, OPT_INTERACTIVE]) + .action(ArgAction::SetTrue), + ) .arg( Arg::new(OPT_INTERACTIVE) .long(OPT_INTERACTIVE) @@ -208,7 +211,7 @@ pub fn uu_app() -> Command { "prompt according to WHEN: never, once (-I), or always (-i). Without WHEN, \ prompts always", ) - .value_name("WHEN"), + .value_name("WHEN") .overrides_with_all(&[OPT_PROMPT, OPT_PROMPT_MORE]), ) .arg( From 1c507c6739f7ce3bc3efa82ca23cc8203e185e86 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 15 Oct 2022 17:39:10 -0500 Subject: [PATCH 17/42] Updated to clap4 --- src/uu/rm/src/rm.rs | 70 ++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index b45938a86..8898f546f 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{crate_version, Arg, ArgAction, Command}; +use clap::{crate_version, Arg, ArgAction, Command, parser::ValueSource}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs::{self, File, Metadata}; @@ -85,51 +85,61 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.map(ToString::to_string).collect()) .unwrap_or_default(); - let force_index_option = matches.index_of(OPT_FORCE); + let force_flag = matches.get_flag(OPT_FORCE); // If -f(--force) is before any -i (or variants) we want prompts else no prompts - let force_prompt_never: bool = { - if let Some(force_index) = force_index_option { - let prompt_index_option = matches.index_of(OPT_PROMPT); - let prompt_more_index_option = matches.index_of(OPT_PROMPT_MORE); - let interactive_index_option = matches.index_of(OPT_INTERACTIVE); - - let mut result = true; - - // if we have rm -i -f - if let Some(prompt_index) = prompt_index_option { - if result { - result = prompt_index <= force_index; + let force_prompt_never: bool = if force_flag { + if matches.value_source(OPT_FORCE) == Some(ValueSource::CommandLine) { + if let Some(force_index) = matches.index_of(OPT_FORCE) { + let mut result = true; + + // if we have rm -i -f + if matches.value_source(OPT_PROMPT) == Some(ValueSource::CommandLine) { + if let Some(prompt_index) = matches.index_of(OPT_PROMPT) { + if result { + result = prompt_index <= force_index; + } + } } - } - // if we have rm -I -f - if let Some(prompt_more_index_index) = prompt_more_index_option { - if result { - result = prompt_more_index_index <= force_index; + + // if we have rm -I -f + if matches.value_source(OPT_PROMPT_MORE) == Some(ValueSource::CommandLine) { + if let Some(prompt_more_index_index) = matches.index_of(OPT_PROMPT_MORE) { + if result { + result = prompt_more_index_index <= force_index; + } + } } - } - // if we have rm --interactive -f - if let Some(interactive_index) = interactive_index_option { - if result { - result = interactive_index <= force_index; - } - } - result + // if we have rm --interactive -f + if matches.value_source(OPT_INTERACTIVE) == Some(ValueSource::CommandLine) { + if let Some(interactive_index) = matches.index_of(OPT_INTERACTIVE) { + if result { + result = interactive_index <= force_index; + } + } + } + + result + } else { + false + } } else { false } + } else { + false }; - if files.is_empty() && force_index_option.is_none() { + if files.is_empty() && !force_flag { // Still check by hand and not use clap // Because "rm -f" is a thing return Err(UUsageError::new(1, "missing operand")); } else { let options = Options { - force: force_index_option.is_some(), + force: force_flag, interactive: { - if force_index_option.is_some() && force_prompt_never { + if force_flag && force_prompt_never { InteractiveMode::Never } else if matches.get_flag(OPT_PROMPT) { InteractiveMode::Always From b3b90e453cc9cc9e1b25cb6eac71562480da5fbe Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 15 Oct 2022 17:41:11 -0500 Subject: [PATCH 18/42] Forgot fmt again --- src/uu/rm/src/rm.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 8898f546f..db16cda11 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -10,7 +10,7 @@ #[macro_use] extern crate uucore; -use clap::{crate_version, Arg, ArgAction, Command, parser::ValueSource}; +use clap::{crate_version, parser::ValueSource, Arg, ArgAction, Command}; use remove_dir_all::remove_dir_all; use std::collections::VecDeque; use std::fs::{self, File, Metadata}; @@ -92,7 +92,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if matches.value_source(OPT_FORCE) == Some(ValueSource::CommandLine) { if let Some(force_index) = matches.index_of(OPT_FORCE) { let mut result = true; - + // if we have rm -i -f if matches.value_source(OPT_PROMPT) == Some(ValueSource::CommandLine) { if let Some(prompt_index) = matches.index_of(OPT_PROMPT) { @@ -101,14 +101,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } } - + // if we have rm -I -f if matches.value_source(OPT_PROMPT_MORE) == Some(ValueSource::CommandLine) { if let Some(prompt_more_index_index) = matches.index_of(OPT_PROMPT_MORE) { if result { result = prompt_more_index_index <= force_index; } - } + } } // if we have rm --interactive -f @@ -117,9 +117,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { if result { result = interactive_index <= force_index; } - } + } } - + result } else { false From b612ce5cd7e1ce2b6503dd2e1f4a757af708f608 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sun, 16 Oct 2022 10:57:12 -0500 Subject: [PATCH 19/42] Cleaner force_prompt_never --- src/uu/rm/src/rm.rs | 45 ++++++++------------------------------------- 1 file changed, 8 insertions(+), 37 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index db16cda11..190298aa6 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -88,47 +88,18 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let force_flag = matches.get_flag(OPT_FORCE); // If -f(--force) is before any -i (or variants) we want prompts else no prompts - let force_prompt_never: bool = if force_flag { + let force_prompt_never: bool = force_flag && { if matches.value_source(OPT_FORCE) == Some(ValueSource::CommandLine) { - if let Some(force_index) = matches.index_of(OPT_FORCE) { - let mut result = true; - - // if we have rm -i -f - if matches.value_source(OPT_PROMPT) == Some(ValueSource::CommandLine) { - if let Some(prompt_index) = matches.index_of(OPT_PROMPT) { - if result { - result = prompt_index <= force_index; - } - } - } - - // if we have rm -I -f - if matches.value_source(OPT_PROMPT_MORE) == Some(ValueSource::CommandLine) { - if let Some(prompt_more_index_index) = matches.index_of(OPT_PROMPT_MORE) { - if result { - result = prompt_more_index_index <= force_index; - } - } - } - - // if we have rm --interactive -f - if matches.value_source(OPT_INTERACTIVE) == Some(ValueSource::CommandLine) { - if let Some(interactive_index) = matches.index_of(OPT_INTERACTIVE) { - if result { - result = interactive_index <= force_index; - } - } - } - - result - } else { - false - } + let force_index = matches.index_of(OPT_FORCE).unwrap_or(0); + [OPT_PROMPT, OPT_PROMPT_MORE, OPT_INTERACTIVE] + .iter() + .any(|opt| { + matches.value_source(opt) == Some(ValueSource::CommandLine) + && matches.index_of(opt).unwrap_or(0) < force_index + }) } else { false } - } else { - false }; if files.is_empty() && !force_flag { From 03578a7acae1c9434508c13a4a3ccd16bab82f46 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sun, 16 Oct 2022 13:14:17 -0500 Subject: [PATCH 20/42] Fixed invert issue --- src/uu/rm/src/rm.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 190298aa6..93f99eea3 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -91,11 +91,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let force_prompt_never: bool = force_flag && { if matches.value_source(OPT_FORCE) == Some(ValueSource::CommandLine) { let force_index = matches.index_of(OPT_FORCE).unwrap_or(0); - [OPT_PROMPT, OPT_PROMPT_MORE, OPT_INTERACTIVE] + ![OPT_PROMPT, OPT_PROMPT_MORE, OPT_INTERACTIVE] .iter() - .any(|opt| { - matches.value_source(opt) == Some(ValueSource::CommandLine) - && matches.index_of(opt).unwrap_or(0) < force_index + .any(|flag| { + matches.value_source(flag) == Some(ValueSource::CommandLine) + && matches.index_of(flag).unwrap_or(0) > force_index }) } else { false @@ -110,7 +110,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let options = Options { force: force_flag, interactive: { - if force_flag && force_prompt_never { + if force_prompt_never { InteractiveMode::Never } else if matches.get_flag(OPT_PROMPT) { InteractiveMode::Always From 2e61580b9966a1fdff7798435b76cdbbe64cac03 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Mon, 17 Oct 2022 17:40:33 -0500 Subject: [PATCH 21/42] Cleaner force_prompt_never --- src/uu/rm/src/rm.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 93f99eea3..b8362adfc 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -89,17 +89,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // If -f(--force) is before any -i (or variants) we want prompts else no prompts let force_prompt_never: bool = force_flag && { - if matches.value_source(OPT_FORCE) == Some(ValueSource::CommandLine) { - let force_index = matches.index_of(OPT_FORCE).unwrap_or(0); - ![OPT_PROMPT, OPT_PROMPT_MORE, OPT_INTERACTIVE] - .iter() - .any(|flag| { - matches.value_source(flag) == Some(ValueSource::CommandLine) - && matches.index_of(flag).unwrap_or(0) > force_index - }) - } else { - false - } + let force_index = matches.index_of(OPT_FORCE).unwrap_or(0); + ![OPT_PROMPT, OPT_PROMPT_MORE, OPT_INTERACTIVE] + .iter() + .any(|flag| { + matches.value_source(flag) == Some(ValueSource::CommandLine) + && matches.index_of(flag).unwrap_or(0) > force_index + }) }; if files.is_empty() && !force_flag { From 5968f53ef434e64772e3f424b2fc6181fe390933 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Thu, 20 Oct 2022 15:42:55 -0500 Subject: [PATCH 22/42] Fixed merge conflict --- src/uu/rm/src/rm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 07c50c2d3..4741d948b 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -550,7 +550,7 @@ fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata #[cfg(windows)] fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { use std::os::windows::prelude::MetadataExt; - use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; + use windows_sys::Win32::Storage::FileSystem::FILE_ATTRIBUTE_READONLY; let not_user_writable = (metadata.file_attributes() & FILE_ATTRIBUTE_READONLY) != 0; if not_user_writable { prompt(&(format!("remove write-protected directory {}? ", path.quote()))) From c6a88c8374d08ecd79e3a91481faeab4dd30a155 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Oct 2022 08:19:47 +0000 Subject: [PATCH 23/42] build(deps): bump binary-heap-plus from 0.4.1 to 0.5.0 Bumps [binary-heap-plus](https://github.com/sekineh/binary-heap-plus-rs) from 0.4.1 to 0.5.0. - [Release notes](https://github.com/sekineh/binary-heap-plus-rs/releases) - [Changelog](https://github.com/sekineh/binary-heap-plus-rs/blob/master/CHANGELOG.md) - [Commits](https://github.com/sekineh/binary-heap-plus-rs/commits) --- updated-dependencies: - dependency-name: binary-heap-plus dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- src/uu/sort/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc8cf8424..9d4a5a37d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "binary-heap-plus" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f068638f8ff9e118a9361e66a411eff410e7fb3ecaa23bf9272324f8fc606d7" +checksum = "e4551d8382e911ecc0d0f0ffb602777988669be09447d536ff4388d1def11296" dependencies = [ "compare", ] diff --git a/src/uu/sort/Cargo.toml b/src/uu/sort/Cargo.toml index bcfb7bfa3..2dcf8b2c8 100644 --- a/src/uu/sort/Cargo.toml +++ b/src/uu/sort/Cargo.toml @@ -15,7 +15,7 @@ edition = "2021" path = "src/sort.rs" [dependencies] -binary-heap-plus = "0.4.1" +binary-heap-plus = "0.5.0" clap = { version = "4.0", features = ["wrap_help", "cargo"] } compare = "0.1.0" ctrlc = { version = "3.0", features = ["termination"] } From 7fd988a7ffb753a0bca1b71cd85e4af9115230df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 22 Oct 2022 08:19:48 +0000 Subject: [PATCH 24/42] build(deps): bump clap_complete from 4.0.2 to 4.0.3 Bumps [clap_complete](https://github.com/clap-rs/clap) from 4.0.2 to 4.0.3. - [Release notes](https://github.com/clap-rs/clap/releases) - [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md) - [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.0.2...clap_complete-v4.0.3) --- updated-dependencies: - dependency-name: clap_complete dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cc8cf8424..979f6b514 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -285,9 +285,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cba7abac9b56dfe2f035098cdb3a43946f276e6db83b72c4e692343f9aab9a" +checksum = "dfe581a2035db4174cdbdc91265e1aba50f381577f0510d0ad36c7bc59cc84a3" dependencies = [ "clap 4.0.18", ] From 744481c8008b70e99f6e2dd4148f7636d51baa8d Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 22 Oct 2022 18:00:17 -0500 Subject: [PATCH 25/42] Updated handle_writable_directory comment --- src/uu/rm/src/rm.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index 4741d948b..f65ebb2fa 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -530,6 +530,7 @@ fn prompt_file(path: &Path, options: &Options, is_dir: bool) -> bool { } // For directories finding if they are writable or not is a hassle. In Unix we can use the built-in rust crate to to check mode bits. But other os don't have something similar afaik +// Most cases are covered by keep eye out for edge cases #[cfg(unix)] fn handle_writable_directory(path: &Path, options: &Options, metadata: &Metadata) -> bool { use std::os::unix::fs::PermissionsExt; From d48a65096682fe8259c4709bfbf9efae8cb30db3 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 23 Oct 2022 17:40:30 -0400 Subject: [PATCH 26/42] cp: restrict copy through dangling symlink with -f Change `cp` to terminate with an error when attempting to copy through a dangling symbolic link with the `--force` option. Before this commit, touch src ln -s no-such-file dest cp -f src dest would incorrectly replace `dest` with the contents of `src`. After this commit, it correctly fails with the error message cp: not writing through dangling symlink 'dest' --- src/uu/cp/src/cp.rs | 16 +++++++++++----- tests/by-util/test_cp.rs | 13 +++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 3a1697039..b81a31e54 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -1264,10 +1264,6 @@ fn copy_file( symlinked_files: &mut HashSet, source_in_command_line: bool, ) -> CopyResult<()> { - if file_or_link_exists(dest) { - handle_existing_dest(source, dest, options, source_in_command_line)?; - } - // Fail if dest is a dangling symlink or a symlink this program created previously if dest.is_symlink() { if FileInformation::from_path(dest, false) @@ -1281,7 +1277,13 @@ fn copy_file( ))); } let copy_contents = options.dereference(source_in_command_line) || !source.is_symlink(); - if copy_contents && !dest.exists() { + if copy_contents + && !dest.exists() + && !matches!( + options.overwrite, + OverwriteMode::Clobber(ClobberMode::RemoveDestination) + ) + { return Err(Error::Error(format!( "not writing through dangling symlink '{}'", dest.display() @@ -1289,6 +1291,10 @@ fn copy_file( } } + if file_or_link_exists(dest) { + handle_existing_dest(source, dest, options, source_in_command_line)?; + } + if options.verbose { println!("{}", context_for(source, dest)); } diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 8285905c5..cb0f38484 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1827,6 +1827,19 @@ fn test_copy_through_dangling_symlink_no_dereference_2() { .stderr_only("cp: not writing through dangling symlink 'target'"); } +/// Test that copy through a dangling symbolic link fails, even with --force. +#[test] +#[cfg(not(windows))] +fn test_copy_through_dangling_symlink_force() { + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("src"); + at.symlink_file("no-such-file", "dest"); + ucmd.args(&["--force", "src", "dest"]) + .fails() + .stderr_only("cp: not writing through dangling symlink 'dest'"); + assert!(!at.file_exists("dest")); +} + #[test] #[cfg(unix)] fn test_cp_archive_on_nonexistent_file() { From c7af9a6a80adfd458edea7ce1eadcdec57f97b14 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Thu, 27 Oct 2022 13:41:55 -0500 Subject: [PATCH 27/42] Bump libc version from "0.2.135" to "0.2.136" --- src/uu/rm/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 1467f7568..75bde3d3e 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -21,7 +21,7 @@ remove_dir_all = "0.7.0" uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs"] } [target.'cfg(unix)'.dependencies] -libc = "0.2.135" +libc = "0.2.136" [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.42.0", default-features = false, features = ["Win32_Storage_FileSystem"] } From 4b4222ffe357e452d23d43a0359d007465f6ea60 Mon Sep 17 00:00:00 2001 From: Pat Laster Date: Sat, 29 Oct 2022 11:09:52 -0500 Subject: [PATCH 28/42] Bump libc version from "0.2.136" to "0.2.137" --- src/uu/rm/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/rm/Cargo.toml b/src/uu/rm/Cargo.toml index 75bde3d3e..3cd49b11b 100644 --- a/src/uu/rm/Cargo.toml +++ b/src/uu/rm/Cargo.toml @@ -21,7 +21,7 @@ remove_dir_all = "0.7.0" uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs"] } [target.'cfg(unix)'.dependencies] -libc = "0.2.136" +libc = "0.2.137" [target.'cfg(windows)'.dependencies] windows-sys = { version = "0.42.0", default-features = false, features = ["Win32_Storage_FileSystem"] } From d5ab502f42ddc494067fc17e79657a8e0bf65e2d Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 30 Oct 2022 23:52:55 +0200 Subject: [PATCH 29/42] build: harden GnuComment.yml permissions Signed-off-by: Alex --- .github/workflows/GnuComment.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/GnuComment.yml b/.github/workflows/GnuComment.yml index d1e34807c..bb64232a9 100644 --- a/.github/workflows/GnuComment.yml +++ b/.github/workflows/GnuComment.yml @@ -6,8 +6,13 @@ on: types: - completed +permissions: {} jobs: post-comment: + permissions: + actions: read # to list workflow runs artifacts + pull-requests: write # to comment on pr + runs-on: ubuntu-latest if: > github.event.workflow_run.event == 'pull_request' From 5d27c19853e3dbc4579b4d89d81e970b4f1d5e33 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 31 Oct 2022 09:26:28 +0100 Subject: [PATCH 30/42] numfmt: add test for "--field -" (all fields) --- tests/by-util/test_numfmt.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index 49de861fb..bcae09aa3 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -399,6 +399,14 @@ fn test_format_selected_field_range() { .stdout_only("1K 2000 3000 4000 5000 6K\n"); } +#[test] +fn test_format_all_fields() { + new_ucmd!() + .args(&["--from=auto", "--field", "-", "1K 2K 3K 4K 5K 6K"]) + .succeeds() + .stdout_only("1000 2000 3000 4000 5000 6000\n"); +} + #[test] fn test_should_succeed_if_range_out_of_bounds() { new_ucmd!() From 27c233f294bb38b2dc0321f5e83c016c94288283 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 31 Oct 2022 14:53:41 +0100 Subject: [PATCH 31/42] numfmt: allow "-" in field list --- src/uu/numfmt/src/numfmt.rs | 11 +++++++---- tests/by-util/test_numfmt.rs | 12 ++++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index f6a1f2739..d490d3fee 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -158,12 +158,15 @@ fn parse_options(args: &ArgMatches) -> Result { Ok(0) }?; - let fields = match args.get_one::(options::FIELD).unwrap().as_str() { - "-" => vec![Range { + let fields = args.get_one::(options::FIELD).unwrap().as_str(); + // a lone "-" means "all fields", even as part of a list of fields + let fields = if fields.split(',').any(|x| x == "-") { + vec![Range { low: 1, high: std::usize::MAX, - }], - v => Range::from_list(v)?, + }] + } else { + Range::from_list(fields)? }; let format = match args.get_one::(options::FORMAT) { diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index bcae09aa3..f4fa94298 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -401,10 +401,14 @@ fn test_format_selected_field_range() { #[test] fn test_format_all_fields() { - new_ucmd!() - .args(&["--from=auto", "--field", "-", "1K 2K 3K 4K 5K 6K"]) - .succeeds() - .stdout_only("1000 2000 3000 4000 5000 6000\n"); + let all_fields_patterns = vec!["-", "-,3", "3,-", "1,-,3"]; + + for pattern in all_fields_patterns { + new_ucmd!() + .args(&["--from=auto", "--field", pattern, "1K 2K 3K 4K 5K 6K"]) + .succeeds() + .stdout_only("1000 2000 3000 4000 5000 6000\n"); + } } #[test] From 2d4810b91b8741db9cf902a8fb9428d17a5ecfa6 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 1 Nov 2022 10:04:46 +0100 Subject: [PATCH 32/42] numfmt: allow ' ' as field separator --- src/uu/numfmt/src/numfmt.rs | 2 +- src/uucore/src/lib/mods/ranges.rs | 2 +- tests/by-util/test_numfmt.rs | 7 ++++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/uu/numfmt/src/numfmt.rs b/src/uu/numfmt/src/numfmt.rs index d490d3fee..1e826e68e 100644 --- a/src/uu/numfmt/src/numfmt.rs +++ b/src/uu/numfmt/src/numfmt.rs @@ -160,7 +160,7 @@ fn parse_options(args: &ArgMatches) -> Result { let fields = args.get_one::(options::FIELD).unwrap().as_str(); // a lone "-" means "all fields", even as part of a list of fields - let fields = if fields.split(',').any(|x| x == "-") { + let fields = if fields.split(&[',', ' ']).any(|x| x == "-") { vec![Range { low: 1, high: std::usize::MAX, diff --git a/src/uucore/src/lib/mods/ranges.rs b/src/uucore/src/lib/mods/ranges.rs index aba4c9ca2..76a61b9a6 100644 --- a/src/uucore/src/lib/mods/ranges.rs +++ b/src/uucore/src/lib/mods/ranges.rs @@ -75,7 +75,7 @@ impl Range { pub fn from_list(list: &str) -> Result, String> { let mut ranges = Vec::new(); - for item in list.split(',') { + for item in list.split(&[',', ' ']) { let range_item = FromStr::from_str(item) .map_err(|e| format!("range {} was invalid: {}", item.quote(), e))?; ranges.push(range_item); diff --git a/tests/by-util/test_numfmt.rs b/tests/by-util/test_numfmt.rs index f4fa94298..108c26fd0 100644 --- a/tests/by-util/test_numfmt.rs +++ b/tests/by-util/test_numfmt.rs @@ -373,6 +373,11 @@ fn test_format_selected_fields() { .args(&["--from=auto", "--field", "1,4,3", "1K 2K 3K 4K 5K 6K"]) .succeeds() .stdout_only("1000 2K 3000 4000 5K 6K\n"); + + new_ucmd!() + .args(&["--from=auto", "--field", "1,4 3", "1K 2K 3K 4K 5K 6K"]) + .succeeds() + .stdout_only("1000 2K 3000 4000 5K 6K\n"); } #[test] @@ -401,7 +406,7 @@ fn test_format_selected_field_range() { #[test] fn test_format_all_fields() { - let all_fields_patterns = vec!["-", "-,3", "3,-", "1,-,3"]; + let all_fields_patterns = vec!["-", "-,3", "3,-", "1,-,3", "- 3"]; for pattern in all_fields_patterns { new_ucmd!() From 4fdfedf61eaba399b8cd093e730f3daa328226ba Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 2 Nov 2022 10:20:04 +0100 Subject: [PATCH 33/42] build-gnu: fix test for numfmt --- util/build-gnu.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/build-gnu.sh b/util/build-gnu.sh index a9df0f401..4ef9b4744 100755 --- a/util/build-gnu.sh +++ b/util/build-gnu.sh @@ -218,6 +218,9 @@ sed -i -e "s/ginstall: creating directory/install: creating directory/g" tests/i # disable this test case sed -i -Ez "s/\n([^\n#]*pad-3\.2[^\n]*)\n([^\n]*)\n([^\n]*)/\n# uutils\/numfmt supports padding = LONG_MIN\n#\1\n#\2\n#\3/" tests/misc/numfmt.pl +# Update the GNU error message to match the one generated by clap +sed -i -e "s/\$prog: multiple field specifications/error: The argument '--field ' was provided more than once, but cannot be used multiple times\n\nUsage: numfmt [OPTION]... [NUMBER]...\n\n\nFor more information try '--help'/g" tests/misc/numfmt.pl + # GNU doesn't support width > INT_MAX # disable these test cases sed -i -E "s|^([^#]*2_31.*)$|#\1|g" tests/misc/printf-cov.pl From 7b88276462970a246b6931a854b5637089dc7420 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Nov 2022 06:05:35 +0000 Subject: [PATCH 34/42] build(deps): bump vmactions/freebsd-vm from 0.2.9 to 0.3.0 Bumps [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm) from 0.2.9 to 0.3.0. - [Release notes](https://github.com/vmactions/freebsd-vm/releases) - [Commits](https://github.com/vmactions/freebsd-vm/compare/v0.2.9...v0.3.0) --- updated-dependencies: - dependency-name: vmactions/freebsd-vm dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/CICD.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index d09cd40f2..1fb086fc8 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -897,7 +897,7 @@ jobs: - uses: Swatinem/rust-cache@v1 - name: Prepare, build and test ## spell-checker:ignore (ToDO) sshfs usesh vmactions - uses: vmactions/freebsd-vm@v0.2.9 + uses: vmactions/freebsd-vm@v0.3.0 with: usesh: true # sync: sshfs From cce8d766fed0baf9238c00cef9182a48f66a37c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Nov 2022 06:30:15 +0000 Subject: [PATCH 35/42] build(deps): bump byte-unit from 4.0.14 to 4.0.17 Bumps [byte-unit](https://github.com/magiclen/byte-unit) from 4.0.14 to 4.0.17. - [Release notes](https://github.com/magiclen/byte-unit/releases) - [Commits](https://github.com/magiclen/byte-unit/compare/v4.0.14...v4.0.17) --- updated-dependencies: - dependency-name: byte-unit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 08669a761..7c0e2d18d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -190,10 +190,11 @@ checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d" [[package]] name = "byte-unit" -version = "4.0.14" +version = "4.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ebf10dda65f19ff0f42ea15572a359ed60d7fc74fdc984d90310937be0014b" +checksum = "581ad4b3d627b0c09a0ccb2912148f839acaca0b93cf54cbe42b6c674e86079c" dependencies = [ + "serde", "utf8-width", ] From 53c4b0b81e528adc340dd803bf597fa3fad1bb4c Mon Sep 17 00:00:00 2001 From: David Matos Date: Sun, 30 Oct 2022 19:57:39 +0100 Subject: [PATCH 36/42] mktemp: allow default missing value --- src/uu/mktemp/src/mktemp.rs | 3 +++ tests/by-util/test_mktemp.rs | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index 5e7234b76..a00664d95 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -440,6 +440,9 @@ pub fn uu_app() -> Command { may contain slashes, but mktemp creates only the final component", ) .value_name("DIR") + // Allows use of default argument just by setting --tmpdir. Else, + // use provided input to generate tmpdir + .num_args(0..=1) .value_hint(clap::ValueHint::DirPath), ) .arg( diff --git a/tests/by-util/test_mktemp.rs b/tests/by-util/test_mktemp.rs index 57448474f..d19f5d6d1 100644 --- a/tests/by-util/test_mktemp.rs +++ b/tests/by-util/test_mktemp.rs @@ -825,3 +825,9 @@ fn test_nonexistent_dir_prefix() { ); } } + +#[test] +fn test_default_missing_value() { + let scene = TestScenario::new(util_name!()); + scene.ucmd().arg("-d").arg("--tmpdir").succeeds(); +} From c2a6f6c77b3dacac9047865e87e91666917f4d08 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 3 Nov 2022 21:14:38 +0100 Subject: [PATCH 37/42] Remove unused dependencies --- Cargo.lock | 3 --- src/uu/dir/Cargo.toml | 1 - src/uu/dircolors/Cargo.toml | 1 - src/uu/vdir/Cargo.toml | 1 - 4 files changed, 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd09545da..a29b073f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2358,7 +2358,6 @@ name = "uu_dir" version = "0.0.16" dependencies = [ "clap 4.0.18", - "selinux", "uu_ls", "uucore", ] @@ -2368,7 +2367,6 @@ name = "uu_dircolors" version = "0.0.16" dependencies = [ "clap 4.0.18", - "glob", "uucore", ] @@ -3136,7 +3134,6 @@ name = "uu_vdir" version = "0.0.16" dependencies = [ "clap 4.0.18", - "selinux", "uu_ls", "uucore", ] diff --git a/src/uu/dir/Cargo.toml b/src/uu/dir/Cargo.toml index 37d16cee8..4ddb9cdd9 100644 --- a/src/uu/dir/Cargo.toml +++ b/src/uu/dir/Cargo.toml @@ -17,7 +17,6 @@ path = "src/dir.rs" [dependencies] clap = { version = "4.0", features = ["wrap_help", "cargo", "env"] } uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs"] } -selinux = { version = "0.3", optional = true } uu_ls = { version = ">=0.0.16", path="../ls"} [[bin]] diff --git a/src/uu/dircolors/Cargo.toml b/src/uu/dircolors/Cargo.toml index 0c2294a57..578fbbd38 100644 --- a/src/uu/dircolors/Cargo.toml +++ b/src/uu/dircolors/Cargo.toml @@ -16,7 +16,6 @@ path = "src/dircolors.rs" [dependencies] clap = { version = "4.0", features = ["wrap_help", "cargo"] } -glob = "0.3.0" uucore = { version=">=0.0.16", package="uucore", path="../../uucore" } [[bin]] diff --git a/src/uu/vdir/Cargo.toml b/src/uu/vdir/Cargo.toml index b4328ed8d..d62b20b39 100644 --- a/src/uu/vdir/Cargo.toml +++ b/src/uu/vdir/Cargo.toml @@ -17,7 +17,6 @@ path = "src/vdir.rs" [dependencies] clap = { version = "4.0", features = ["wrap_help", "cargo", "env"] } uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["entries", "fs"] } -selinux = { version="0.3", optional = true } uu_ls = { version = ">=0.0.16", path="../ls"} [[bin]] From c44c7ac7b288b9dc8110985a6f56f193fd634a66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 4 Nov 2022 06:07:50 +0000 Subject: [PATCH 38/42] build(deps): bump num_cpus from 1.13.1 to 1.14.0 Bumps [num_cpus](https://github.com/seanmonstar/num_cpus) from 1.13.1 to 1.14.0. - [Release notes](https://github.com/seanmonstar/num_cpus/releases) - [Changelog](https://github.com/seanmonstar/num_cpus/blob/master/CHANGELOG.md) - [Commits](https://github.com/seanmonstar/num_cpus/compare/v1.13.1...v1.14.0) --- updated-dependencies: - dependency-name: num_cpus dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- src/uu/nproc/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd09545da..87ac0034f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1342,9 +1342,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" dependencies = [ "hermit-abi", "libc", diff --git a/src/uu/nproc/Cargo.toml b/src/uu/nproc/Cargo.toml index 057062a73..45c1dd81f 100644 --- a/src/uu/nproc/Cargo.toml +++ b/src/uu/nproc/Cargo.toml @@ -16,7 +16,7 @@ path = "src/nproc.rs" [dependencies] libc = "0.2.137" -num_cpus = "1.10" +num_cpus = "1.14" clap = { version = "4.0", features = ["wrap_help", "cargo"] } uucore = { version=">=0.0.16", package="uucore", path="../../uucore", features=["fs"] } From 59f37d88d017ba613fe90933f560b29f0d088d3d Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 4 Nov 2022 08:54:51 +0100 Subject: [PATCH 39/42] rm: fix "needless borrow" clippy warnings --- src/uu/rm/src/rm.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index f65ebb2fa..5be19893b 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -170,7 +170,7 @@ pub fn uu_app() -> Command { Arg::new(OPT_PROMPT) .short('i') .help("prompt before every removal") - .overrides_with_all(&[OPT_PROMPT_MORE, OPT_INTERACTIVE]) + .overrides_with_all([OPT_PROMPT_MORE, OPT_INTERACTIVE]) .action(ArgAction::SetTrue), ) .arg( @@ -178,7 +178,7 @@ pub fn uu_app() -> Command { .short('I') .help("prompt once before removing more than three files, or when removing recursively. \ Less intrusive than -i, while still giving some protection against most mistakes") - .overrides_with_all(&[OPT_PROMPT, OPT_INTERACTIVE]) + .overrides_with_all([OPT_PROMPT, OPT_INTERACTIVE]) .action(ArgAction::SetTrue), ) .arg( @@ -189,7 +189,7 @@ pub fn uu_app() -> Command { prompts always", ) .value_name("WHEN") - .overrides_with_all(&[OPT_PROMPT, OPT_PROMPT_MORE]), + .overrides_with_all([OPT_PROMPT, OPT_PROMPT_MORE]), ) .arg( Arg::new(OPT_ONE_FILE_SYSTEM) From 96ef306cb34bb1cfb9a920065fa47f34d84f1810 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 4 Nov 2022 09:11:24 +0100 Subject: [PATCH 40/42] Fix "unwrap or else default" clippy warning --- src/uucore/src/lib/features/fsext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uucore/src/lib/features/fsext.rs b/src/uucore/src/lib/features/fsext.rs index f306f34de..68e2b7a55 100644 --- a/src/uucore/src/lib/features/fsext.rs +++ b/src/uucore/src/lib/features/fsext.rs @@ -303,7 +303,7 @@ impl MountInfo { let mut mn_info = Self { dev_id: volume_name, dev_name, - fs_type: fs_type.unwrap_or_else(|| "".to_string()), + fs_type: fs_type.unwrap_or_default(), mount_root, mount_dir: "".to_string(), mount_option: "".to_string(), From 7df36bb1538cb97207e8ff2a16402453a40cd45f Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 4 Nov 2022 09:52:09 +0100 Subject: [PATCH 41/42] mv: fix "needless borrow" clippy warnings --- src/uu/mv/src/mv.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 4697fac4a..671aea0ad 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -475,11 +475,11 @@ fn rename_symlink_fallback(from: &Path, to: &Path) -> io::Result<()> { { if path_symlink_points_to.exists() { if path_symlink_points_to.is_dir() { - windows::fs::symlink_dir(&path_symlink_points_to, &to)?; + windows::fs::symlink_dir(&path_symlink_points_to, to)?; } else { - windows::fs::symlink_file(&path_symlink_points_to, &to)?; + windows::fs::symlink_file(&path_symlink_points_to, to)?; } - fs::remove_file(&from)?; + fs::remove_file(from)?; } else { return Err(io::Error::new( io::ErrorKind::NotFound, From 8114abc95659e4e94b8e2216dc8131aa57d3852b Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 4 Nov 2022 11:10:35 +0100 Subject: [PATCH 42/42] Fix "needless borrow" clippy warning in env test --- tests/by-util/test_env.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_env.rs b/tests/by-util/test_env.rs index 3172320f3..9b6452548 100644 --- a/tests/by-util/test_env.rs +++ b/tests/by-util/test_env.rs @@ -220,7 +220,7 @@ fn test_change_directory() { let out = scene .ucmd() .arg("--chdir") - .arg(&temporary_path) + .arg(temporary_path) .args(&pwd) .succeeds() .stdout_move_str();