From aea986948df6375a90b3963e6c930f3a1adfce45 Mon Sep 17 00:00:00 2001 From: KAA the Wise Date: Wed, 27 Sep 2023 23:05:29 +0300 Subject: [PATCH 01/35] mkdir: make `mkdir` public and document it - Made the `mkdir` function public. Added documentation, describing the behavior and parameters - Moved the GNU dot-stripping behavior from `exec` to `mkdir`. --- src/uu/mkdir/src/mkdir.rs | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/uu/mkdir/src/mkdir.rs b/src/uu/mkdir/src/mkdir.rs index 2044855e4..354335d8c 100644 --- a/src/uu/mkdir/src/mkdir.rs +++ b/src/uu/mkdir/src/mkdir.rs @@ -141,21 +141,34 @@ pub fn uu_app() -> Command { */ fn exec(dirs: ValuesRef, recursive: bool, mode: u32, verbose: bool) -> UResult<()> { for dir in dirs { - // 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_strip_dot_for_creation(&PathBuf::from(dir)) - } else { - // Normal case - PathBuf::from(dir) - }; - show_if_err!(mkdir(path.as_path(), recursive, mode, verbose)); + let path_buf = PathBuf::from(dir); + let path = path_buf.as_path(); + + show_if_err!(mkdir(path, recursive, mode, verbose)); } Ok(()) } -fn mkdir(path: &Path, recursive: bool, mode: u32, verbose: bool) -> UResult<()> { +/// Create directory at a given `path`. +/// +/// ## Options +/// +/// * `recursive` --- create parent directories for the `path`, if they do not +/// exist. +/// * `mode` --- file mode for the directories (not implemented on windows). +/// * `verbose` --- print a message for each printed directory. +/// +/// ## Trailing dot +/// +/// To match the GNU behavior, a path with the last directory being a single dot +/// (like `some/path/to/.`) is created (with the dot stripped). +pub fn mkdir(path: &Path, recursive: bool, mode: u32, verbose: bool) -> UResult<()> { + // 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_buf = dir_strip_dot_for_creation(path); + let path = path_buf.as_path(); + create_dir(path, recursive, verbose, false)?; chmod(path, mode) } From e88183174b9592c6a490658f0ef09938459ffcdd Mon Sep 17 00:00:00 2001 From: boxdot Date: Wed, 4 Oct 2023 16:12:02 +0200 Subject: [PATCH 02/35] relpath: remove Closes #5236 --- Cargo.lock | 9 -- Cargo.toml | 2 - GNUmakefile | 1 - docs/compiles_table.csv | 42 ++++---- src/uu/relpath/Cargo.toml | 23 ----- src/uu/relpath/LICENSE | 1 - src/uu/relpath/relpath.md | 8 -- src/uu/relpath/src/main.rs | 1 - src/uu/relpath/src/relpath.rs | 91 ---------------- tests/by-util/test_relpath.rs | 189 ---------------------------------- tests/tests.rs | 4 - util/show-utils.BAT | 4 +- util/show-utils.sh | 4 +- 13 files changed, 25 insertions(+), 354 deletions(-) delete mode 100644 src/uu/relpath/Cargo.toml delete mode 120000 src/uu/relpath/LICENSE delete mode 100644 src/uu/relpath/relpath.md delete mode 100644 src/uu/relpath/src/main.rs delete mode 100644 src/uu/relpath/src/relpath.rs delete mode 100644 tests/by-util/test_relpath.rs diff --git a/Cargo.lock b/Cargo.lock index 33ee7ff14..252be5d67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -470,7 +470,6 @@ dependencies = [ "uu_pwd", "uu_readlink", "uu_realpath", - "uu_relpath", "uu_rm", "uu_rmdir", "uu_runcon", @@ -2866,14 +2865,6 @@ dependencies = [ "uucore", ] -[[package]] -name = "uu_relpath" -version = "0.0.21" -dependencies = [ - "clap", - "uucore", -] - [[package]] name = "uu_rm" version = "0.0.21" diff --git a/Cargo.toml b/Cargo.toml index e7fc2851b..88bd1635b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,7 +100,6 @@ feat_common_core = [ "pwd", "readlink", "realpath", - "relpath", "rm", "rmdir", "seq", @@ -430,7 +429,6 @@ ptx = { optional = true, version = "0.0.21", package = "uu_ptx", path = "src/uu/ pwd = { optional = true, version = "0.0.21", package = "uu_pwd", path = "src/uu/pwd" } readlink = { optional = true, version = "0.0.21", package = "uu_readlink", path = "src/uu/readlink" } realpath = { optional = true, version = "0.0.21", package = "uu_realpath", path = "src/uu/realpath" } -relpath = { optional = true, version = "0.0.21", package = "uu_relpath", path = "src/uu/relpath" } rm = { optional = true, version = "0.0.21", package = "uu_rm", path = "src/uu/rm" } rmdir = { optional = true, version = "0.0.21", package = "uu_rmdir", path = "src/uu/rmdir" } runcon = { optional = true, version = "0.0.21", package = "uu_runcon", path = "src/uu/runcon" } diff --git a/GNUmakefile b/GNUmakefile index c672458a1..ad2d38081 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -102,7 +102,6 @@ PROGS := \ pwd \ readlink \ realpath \ - relpath \ rm \ rmdir \ seq \ diff --git a/docs/compiles_table.csv b/docs/compiles_table.csv index d18854e0e..e263067b7 100644 --- a/docs/compiles_table.csv +++ b/docs/compiles_table.csv @@ -1,21 +1,21 @@ -target,arch,base32,base64,basename,cat,chgrp,chmod,chown,chroot,cksum,comm,cp,csplit,cut,date,df,dircolors,dirname,du,echo,env,expand,expr,factor,false,fmt,fold,groups,hashsum,head,hostid,hostname,id,install,join,kill,link,ln,logname,ls,mkdir,mkfifo,mknod,mktemp,more,mv,nice,nl,nohup,nproc,numfmt,od,paste,pathchk,pinky,printenv,printf,ptx,pwd,readlink,realpath,relpath,rm,rmdir,seq,shred,shuf,sleep,sort,split,stat,stdbuf,sum,sync,tac,tail,tee,test,timeout,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,wc,who,whoami,yes,chcon,pr,dir,vdir,dd,basenc,runcon -aarch64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -i686-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -powerpc64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -riscv64gc-unknown-linux-gnu,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 -x86_64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -aarch64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,101,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,101,0,0,0,0,0,0,0,0 -i686-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 -i686-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 -x86_64-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 -x86_64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 -x86_64-apple-darwin,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -x86_64-unknown-freebsd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -x86_64-unknown-netbsd,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 -aarch64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 -x86_64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 -x86_64-sun-solaris,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 -wasm32-wasi,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 -x86_64-unknown-redox,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 -aarch64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 -x86_64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +target,arch,base32,base64,basename,cat,chgrp,chmod,chown,chroot,cksum,comm,cp,csplit,cut,date,df,dircolors,dirname,du,echo,env,expand,expr,factor,false,fmt,fold,groups,hashsum,head,hostid,hostname,id,install,join,kill,link,ln,logname,ls,mkdir,mkfifo,mknod,mktemp,more,mv,nice,nl,nohup,nproc,numfmt,od,paste,pathchk,pinky,printenv,printf,ptx,pwd,readlink,realpath,rm,rmdir,seq,shred,shuf,sleep,sort,split,stat,stdbuf,sum,sync,tac,tail,tee,test,timeout,touch,tr,true,truncate,tsort,tty,uname,unexpand,uniq,unlink,uptime,users,wc,who,whoami,yes,chcon,pr,dir,vdir,dd,basenc,runcon +aarch64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +i686-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +powerpc64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +riscv64gc-unknown-linux-gnu,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-unknown-linux-gnu,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +aarch64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,101,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,101,0,0,0,0,0,0,0,0 +i686-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 +i686-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 +x86_64-pc-windows-gnu,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 +x86_64-pc-windows-msvc,0,0,0,0,0,101,101,101,101,0,0,0,0,0,0,0,0,0,101,0,0,0,101,0,0,0,0,101,0,0,0,0,101,101,0,101,0,0,0,0,0,101,101,0,0,0,101,0,101,0,0,0,0,101,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,101,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,101,0,101,0,101,0,0,0,0,0,0,0,0,0 +x86_64-apple-darwin,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +x86_64-unknown-freebsd,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +x86_64-unknown-netbsd,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 +aarch64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 +x86_64-linux-android,0,0,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,0,0,0,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,101,0,0,101,0,0,0,0,101,0,0,0,0,0,0,101,0,0,0,101,101,0,101,0,0,0,0,0,0,0,0,0 +x86_64-sun-solaris,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +wasm32-wasi,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-unknown-redox,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +aarch64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 +x86_64-fuchsia,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101 diff --git a/src/uu/relpath/Cargo.toml b/src/uu/relpath/Cargo.toml deleted file mode 100644 index 0df32efd2..000000000 --- a/src/uu/relpath/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "uu_relpath" -version = "0.0.21" -authors = ["uutils developers"] -license = "MIT" -description = "relpath ~ (uutils) display relative path of PATHNAME_TO from PATHNAME_FROM" - -homepage = "https://github.com/uutils/coreutils" -repository = "https://github.com/uutils/coreutils/tree/main/src/uu/relpath" -keywords = ["coreutils", "uutils", "cross-platform", "cli", "utility"] -categories = ["command-line-utilities"] -edition = "2021" - -[lib] -path = "src/relpath.rs" - -[dependencies] -clap = { workspace = true } -uucore = { workspace = true, features = ["fs"] } - -[[bin]] -name = "relpath" -path = "src/main.rs" diff --git a/src/uu/relpath/LICENSE b/src/uu/relpath/LICENSE deleted file mode 120000 index 5853aaea5..000000000 --- a/src/uu/relpath/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../../../LICENSE \ No newline at end of file diff --git a/src/uu/relpath/relpath.md b/src/uu/relpath/relpath.md deleted file mode 100644 index a1ff9bf4a..000000000 --- a/src/uu/relpath/relpath.md +++ /dev/null @@ -1,8 +0,0 @@ -# relpath - -``` -relpath [-d DIR] TO [FROM] -``` - -Convert TO destination to the relative path from the FROM dir. -If FROM path is omitted, current working dir will be used. \ No newline at end of file diff --git a/src/uu/relpath/src/main.rs b/src/uu/relpath/src/main.rs deleted file mode 100644 index b7dba76ce..000000000 --- a/src/uu/relpath/src/main.rs +++ /dev/null @@ -1 +0,0 @@ -uucore::bin!(uu_relpath); diff --git a/src/uu/relpath/src/relpath.rs b/src/uu/relpath/src/relpath.rs deleted file mode 100644 index aa8b5caab..000000000 --- a/src/uu/relpath/src/relpath.rs +++ /dev/null @@ -1,91 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. - -// spell-checker:ignore (ToDO) subpath absto absfrom absbase - -use clap::{crate_version, Arg, Command}; -use std::env; -use std::path::{Path, PathBuf}; -use uucore::display::println_verbatim; -use uucore::error::{FromIo, UResult}; -use uucore::fs::{canonicalize, MissingHandling, ResolveMode}; -use uucore::{format_usage, help_about, help_usage}; - -const USAGE: &str = help_usage!("relpath.md"); -const ABOUT: &str = help_about!("relpath.md"); - -mod options { - pub const DIR: &str = "DIR"; - pub const TO: &str = "TO"; - pub const FROM: &str = "FROM"; -} - -#[uucore::main] -pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - - let matches = uu_app().get_matches_from(args); - - let to = Path::new(matches.get_one::(options::TO).unwrap()).to_path_buf(); // required - let from = match matches.get_one::(options::FROM) { - Some(p) => Path::new(p).to_path_buf(), - None => env::current_dir().unwrap(), - }; - let absto = canonicalize(to, MissingHandling::Normal, ResolveMode::Logical) - .map_err_context(String::new)?; - let absfrom = canonicalize(from, MissingHandling::Normal, ResolveMode::Logical) - .map_err_context(String::new)?; - - if matches.contains_id(options::DIR) { - let base = Path::new(&matches.get_one::(options::DIR).unwrap()).to_path_buf(); - let absbase = canonicalize(base, MissingHandling::Normal, ResolveMode::Logical) - .map_err_context(String::new)?; - if !absto.as_path().starts_with(absbase.as_path()) - || !absfrom.as_path().starts_with(absbase.as_path()) - { - return println_verbatim(absto).map_err_context(String::new); - } - } - - let mut suffix_pos = 0; - for (f, t) in absfrom.components().zip(absto.components()) { - if f == t { - suffix_pos += 1; - } else { - break; - } - } - - let mut result = PathBuf::new(); - absfrom - .components() - .skip(suffix_pos) - .map(|_| result.push("..")) - .last(); - absto - .components() - .skip(suffix_pos) - .map(|x| result.push(x.as_os_str())) - .last(); - - println_verbatim(result).map_err_context(String::new) -} - -pub fn uu_app() -> Command { - Command::new(uucore::util_name()) - .version(crate_version!()) - .about(ABOUT) - .override_usage(format_usage(USAGE)) - .infer_long_args(true) - .arg(Arg::new(options::DIR).short('d').help( - "If any of FROM and TO is not subpath of DIR, output absolute path instead of relative", - )) - .arg( - Arg::new(options::TO) - .value_hint(clap::ValueHint::AnyPath) - .required(true), - ) - .arg(Arg::new(options::FROM).value_hint(clap::ValueHint::AnyPath)) -} diff --git a/tests/by-util/test_relpath.rs b/tests/by-util/test_relpath.rs deleted file mode 100644 index f506e01c5..000000000 --- a/tests/by-util/test_relpath.rs +++ /dev/null @@ -1,189 +0,0 @@ -// This file is part of the uutils coreutils package. -// -// For the full copyright and license information, please view the LICENSE -// file that was distributed with this source code. -use crate::common::util::TestScenario; -use std::borrow::Cow; -use std::path::Path; - -struct TestCase<'a> { - from: &'a str, - to: &'a str, - expected: &'a str, -} - -const TESTS: [TestCase; 10] = [ - TestCase { - from: "A/B/C", - to: "A", - expected: "../..", - }, - TestCase { - from: "A/B/C", - to: "A/B", - expected: "..", - }, - TestCase { - from: "A/B/C", - to: "A/B/C", - expected: "", - }, - TestCase { - from: "A/B/C", - to: "A/B/C/D", - expected: "D", - }, - TestCase { - from: "A/B/C", - to: "A/B/C/D/E", - expected: "D/E", - }, - TestCase { - from: "A/B/C", - to: "A/B/D", - expected: "../D", - }, - TestCase { - from: "A/B/C", - to: "A/B/D/E", - expected: "../D/E", - }, - TestCase { - from: "A/B/C", - to: "A/D", - expected: "../../D", - }, - TestCase { - from: "A/B/C", - to: "D/E/F", - expected: "../../../D/E/F", - }, - TestCase { - from: "A/B/C", - to: "A/D/E", - expected: "../../D/E", - }, -]; - -#[allow(clippy::needless_lifetimes)] -fn convert_path<'a>(path: &'a str) -> Cow<'a, str> { - #[cfg(windows)] - return path.replace('/', "\\").into(); - #[cfg(not(windows))] - return path.into(); -} - -#[test] -fn test_relpath_with_from_no_d() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - for test in &TESTS { - let from: &str = &convert_path(test.from); - let to: &str = &convert_path(test.to); - let expected: &str = &convert_path(test.expected); - - at.mkdir_all(to); - at.mkdir_all(from); - - scene - .ucmd() - .arg(to) - .arg(from) - .succeeds() - .stdout_only(&format!("{expected}\n")); - } -} - -#[test] -fn test_relpath_with_from_with_d() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - for test in &TESTS { - let from: &str = &convert_path(test.from); - let to: &str = &convert_path(test.to); - let pwd = at.as_string(); - at.mkdir_all(to); - at.mkdir_all(from); - - // d is part of subpath -> expect relative path - let mut _result_stdout = scene - .ucmd() - .arg(to) - .arg(from) - .arg(&format!("-d{pwd}")) - .succeeds() - .stdout_move_str(); - // relax rules for windows test environment - #[cfg(not(windows))] - assert!(Path::new(&_result_stdout).is_relative()); - - // d is not part of subpath -> expect absolute path - _result_stdout = scene - .ucmd() - .arg(to) - .arg(from) - .arg("-dnon_existing") // spell-checker:disable-line - .succeeds() - .stdout_move_str(); - assert!(Path::new(&_result_stdout).is_absolute()); - } -} - -#[test] -fn test_relpath_no_from_no_d() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - for test in &TESTS { - let to: &str = &convert_path(test.to); - at.mkdir_all(to); - - let _result_stdout = scene.ucmd().arg(to).succeeds().stdout_move_str(); - #[cfg(not(windows))] - assert_eq!(_result_stdout, format!("{to}\n")); - // relax rules for windows test environment - #[cfg(windows)] - assert!(_result_stdout.ends_with(&format!("{to}\n"))); - } -} - -#[test] -fn test_relpath_no_from_with_d() { - let scene = TestScenario::new(util_name!()); - let at = &scene.fixtures; - - for test in &TESTS { - let to: &str = &convert_path(test.to); - let pwd = at.as_string(); - at.mkdir_all(to); - - // d is part of subpath -> expect relative path - let _result_stdout = scene - .ucmd() - .arg(to) - .arg(&format!("-d{pwd}")) - .succeeds() - .stdout_move_str(); - // relax rules for windows test environment - #[cfg(not(windows))] - assert!(Path::new(&_result_stdout).is_relative()); - - // d is not part of subpath -> expect absolute path - let result_stdout = scene - .ucmd() - .arg(to) - .arg("-dnon_existing") // spell-checker:disable-line - .succeeds() - .stdout_move_str(); - assert!(Path::new(&result_stdout).is_absolute()); - } -} - -#[test] -fn test_relpath_no_to() { - new_ucmd!() - .fails() - .stderr_contains("required arguments were not provided"); -} diff --git a/tests/tests.rs b/tests/tests.rs index 8d4a6855c..1fb5735eb 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -269,10 +269,6 @@ mod test_readlink; #[path = "by-util/test_realpath.rs"] mod test_realpath; -#[cfg(feature = "relpath")] -#[path = "by-util/test_relpath.rs"] -mod test_relpath; - #[cfg(feature = "rm")] #[path = "by-util/test_rm.rs"] mod test_rm; diff --git a/util/show-utils.BAT b/util/show-utils.BAT index 9fa5e2ffa..f6d900734 100644 --- a/util/show-utils.BAT +++ b/util/show-utils.BAT @@ -2,7 +2,7 @@ @echo off @rem ::# spell-checker:ignore (CMD) ERRORLEVEL -@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath relpath rmdir shuf tsort unexpand +@rem ::# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand @rem ::# spell-checker:ignore (jq) deps startswith set "ME=%~0" @@ -12,7 +12,7 @@ set "ME_parent_dir=%~dp0.\.." @rem refs: , @rem :: default ("Tier 1" cross-platform) utility list -set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath relpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" +set "default_utils=base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" set "project_dir=%ME_parent_dir%" cd "%project_dir%" diff --git a/util/show-utils.sh b/util/show-utils.sh index b6a0f9856..dda01abe2 100755 --- a/util/show-utils.sh +++ b/util/show-utils.sh @@ -1,6 +1,6 @@ #!/bin/sh -# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath relpath rmdir shuf tsort unexpand +# spell-checker:ignore (utils) cksum coreutils dircolors hashsum mkdir mktemp printenv printf readlink realpath rmdir shuf tsort unexpand # spell-checker:ignore (jq) deps startswith ME="${0}" @@ -12,7 +12,7 @@ ME_parent_dir_abs="$(realpath -mP -- "${ME_parent_dir}" || realpath -- "${ME_par # refs: , # default ("Tier 1" cross-platform) utility list -default_utils="base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath relpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" +default_utils="base32 base64 basename cat cksum comm cp cut date dircolors dirname echo env expand expr factor false fmt fold hashsum head join link ln ls mkdir mktemp more mv nl od paste printenv printf ptx pwd readlink realpath rm rmdir seq shred shuf sleep sort split sum tac tail tee test tr true truncate tsort unexpand uniq wc yes" project_main_dir="${ME_parent_dir_abs}" # printf 'project_main_dir="%s"\n' "${project_main_dir}" From b87e1f56764db61beae80970d3a7a52fee53cfa7 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 5 Oct 2023 09:31:43 +0200 Subject: [PATCH 03/35] chown: move uid & gid detections into their own functions --- src/uu/chown/src/chown.rs | 95 ++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index 8e97d5652..ea25050bb 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -195,6 +195,53 @@ pub fn uu_app() -> Command { ) } +/// Parses the user string to extract the UID. +fn parse_uid(user: &str, spec: &str, sep: char) -> UResult> { + if user.is_empty() { + return Ok(None); + } + match Passwd::locate(user) { + Ok(u) => Ok(Some(u.uid)), // We have been able to get the uid + Err(_) => { + // we have NOT been able to find the uid + // but we could be in the case where we have user.group + if spec.contains('.') && !spec.contains(':') && sep == ':' { + // but the input contains a '.' but not a ':' + // we might have something like username.groupname + // So, try to parse it this way + return parse_spec(spec, '.').map(|(uid, _)| uid); + } else { + // It's possible that the `user` string contains a + // numeric user ID, in which case, we respect that. + match user.parse() { + Ok(uid) => Ok(Some(uid)), + Err(_) => Err(USimpleError::new( + 1, + format!("invalid user: {}", spec.quote()), + )), + } + } + } + } +} + +/// Parses the group string to extract the GID. +fn parse_gid(group: &str, spec: &str) -> UResult> { + if group.is_empty() { + return Ok(None); + } + match Group::locate(group) { + Ok(g) => Ok(Some(g.gid)), + Err(_) => match group.parse() { + Ok(gid) => Ok(Some(gid)), + Err(_) => Err(USimpleError::new( + 1, + format!("invalid group: {}", spec.quote()), + )), + }, + } +} + /// Parse the owner/group specifier string into a user ID and a group ID. /// /// The `spec` can be of the form: @@ -213,52 +260,8 @@ fn parse_spec(spec: &str, sep: char) -> UResult<(Option, Option)> { let user = args.next().unwrap_or(""); let group = args.next().unwrap_or(""); - let uid = if user.is_empty() { - None - } else { - Some(match Passwd::locate(user) { - Ok(u) => u.uid, // We have been able to get the uid - Err(_) => - // we have NOT been able to find the uid - // but we could be in the case where we have user.group - { - if spec.contains('.') && !spec.contains(':') && sep == ':' { - // but the input contains a '.' but not a ':' - // we might have something like username.groupname - // So, try to parse it this way - return parse_spec(spec, '.'); - } else { - // It's possible that the `user` string contains a - // numeric user ID, in which case, we respect that. - match user.parse() { - Ok(uid) => uid, - Err(_) => { - return Err(USimpleError::new( - 1, - format!("invalid user: {}", spec.quote()), - )) - } - } - } - } - }) - }; - let gid = if group.is_empty() { - None - } else { - Some(match Group::locate(group) { - Ok(g) => g.gid, - Err(_) => match group.parse() { - Ok(gid) => gid, - Err(_) => { - return Err(USimpleError::new( - 1, - format!("invalid group: {}", spec.quote()), - )); - } - }, - }) - }; + let uid = parse_uid(user, spec, sep)?; + let gid = parse_gid(group, spec)?; if user.chars().next().map(char::is_numeric).unwrap_or(false) && group.is_empty() From d756a05be6f420b56a96a7d103c37227e720f23e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Thu, 5 Oct 2023 19:18:00 +0200 Subject: [PATCH 04/35] touch: fix clippy warning - redundant guard --- src/uu/touch/src/touch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/touch/src/touch.rs b/src/uu/touch/src/touch.rs index 6555773ee..d9399a051 100644 --- a/src/uu/touch/src/touch.rs +++ b/src/uu/touch/src/touch.rs @@ -489,7 +489,7 @@ fn pathbuf_from_stdout() -> UResult { format!("GetFinalPathNameByHandleW failed with code {ret}"), )) } - e if e == 0 => { + 0 => { return Err(USimpleError::new( 1, format!( From 7c3de4084294bef465ff38132b60884a7c40c4b3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 6 Oct 2023 05:01:49 +0000 Subject: [PATCH 05/35] chore(deps): update rust crate byteorder to 1.5.0 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 33ee7ff14..19ea899d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -211,9 +211,9 @@ checksum = "ad152d03a2c813c80bb94fedbf3a3f02b28f793e39e7c214c8a0bcc196343de7" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" diff --git a/Cargo.toml b/Cargo.toml index e7fc2851b..83697cf00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -262,7 +262,7 @@ bigdecimal = "0.4" binary-heap-plus = "0.5.0" bstr = "1.6" bytecount = "0.6.4" -byteorder = "1.4.3" +byteorder = "1.5.0" chrono = { version = "^0.4.31", default-features = false, features = [ "std", "alloc", From 4760b1f340dfe30f23fdc8676211c7ae48b963da Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 6 Oct 2023 07:49:36 +0200 Subject: [PATCH 06/35] chown: remove unnecessary return --- src/uu/chown/src/chown.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/chown/src/chown.rs b/src/uu/chown/src/chown.rs index ea25050bb..0e9b8b242 100644 --- a/src/uu/chown/src/chown.rs +++ b/src/uu/chown/src/chown.rs @@ -209,7 +209,7 @@ fn parse_uid(user: &str, spec: &str, sep: char) -> UResult> { // but the input contains a '.' but not a ':' // we might have something like username.groupname // So, try to parse it this way - return parse_spec(spec, '.').map(|(uid, _)| uid); + parse_spec(spec, '.').map(|(uid, _)| uid) } else { // It's possible that the `user` string contains a // numeric user ID, in which case, we respect that. From 6dd53c7a717daac2dcc5f71f4efcf3c4351e7154 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 6 Oct 2023 10:11:26 +0200 Subject: [PATCH 07/35] clippy: fix warnings in tests --- tests/by-util/test_cp.rs | 1 - tests/by-util/test_split.rs | 40 ++++++++++++++++++------------------- tests/by-util/test_tee.rs | 17 +++++++++++++--- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 15713587c..9894087e8 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1545,7 +1545,6 @@ fn test_cp_preserve_links_case_7() { .arg("dest") .fails() .stderr_contains("not replacing"); - (); assert!(at.dir_exists("dest")); assert!(at.plus("dest").join("f").exists()); diff --git a/tests/by-util/test_split.rs b/tests/by-util/test_split.rs index 6fc3a3706..ce80844cf 100644 --- a/tests/by-util/test_split.rs +++ b/tests/by-util/test_split.rs @@ -438,7 +438,7 @@ fn test_split_obs_lines_within_combined_shorts() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; let name = "obs-lines-within-shorts"; - RandomFile::new(&at, name).add_lines(400); + RandomFile::new(at, name).add_lines(400); scene .ucmd() @@ -446,9 +446,9 @@ fn test_split_obs_lines_within_combined_shorts() { .succeeds() .no_stderr() .no_stdout(); - let glob = Glob::new(&at, ".", r"x\d\d$"); + let glob = Glob::new(at, ".", r"x\d\d$"); assert_eq!(glob.count(), 2); - assert_eq!(glob.collate(), at.read_bytes(name)) + assert_eq!(glob.collate(), at.read_bytes(name)); } /// Test for obsolete lines option as part of combined short options with tailing suffix length with value @@ -470,7 +470,7 @@ fn test_split_obs_lines_starts_combined_shorts() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; let name = "obs-lines-starts-shorts"; - RandomFile::new(&at, name).add_lines(400); + RandomFile::new(at, name).add_lines(400); scene .ucmd() @@ -478,9 +478,9 @@ fn test_split_obs_lines_starts_combined_shorts() { .succeeds() .no_stderr() .no_stdout(); - let glob = Glob::new(&at, ".", r"x\d\d$"); + let glob = Glob::new(at, ".", r"x\d\d$"); assert_eq!(glob.count(), 2); - assert_eq!(glob.collate(), at.read_bytes(name)) + assert_eq!(glob.collate(), at.read_bytes(name)); } /// Test for using both obsolete lines (standalone) option and short/long lines option simultaneously @@ -585,7 +585,7 @@ fn test_split_multiple_obs_lines_standalone() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; let name = "multiple-obs-lines"; - RandomFile::new(&at, name).add_lines(400); + RandomFile::new(at, name).add_lines(400); scene .ucmd() @@ -593,9 +593,9 @@ fn test_split_multiple_obs_lines_standalone() { .succeeds() .no_stderr() .no_stdout(); - let glob = Glob::new(&at, ".", r"x[[:alpha:]][[:alpha:]]$"); + let glob = Glob::new(at, ".", r"x[[:alpha:]][[:alpha:]]$"); assert_eq!(glob.count(), 2); - assert_eq!(glob.collate(), at.read_bytes(name)) + assert_eq!(glob.collate(), at.read_bytes(name)); } /// Test for using more than one obsolete lines option within combined shorts @@ -605,7 +605,7 @@ fn test_split_multiple_obs_lines_within_combined() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; let name = "multiple-obs-lines"; - RandomFile::new(&at, name).add_lines(400); + RandomFile::new(at, name).add_lines(400); scene .ucmd() @@ -613,9 +613,9 @@ fn test_split_multiple_obs_lines_within_combined() { .succeeds() .no_stderr() .no_stdout(); - let glob = Glob::new(&at, ".", r"x\d\d$"); + let glob = Glob::new(at, ".", r"x\d\d$"); assert_eq!(glob.count(), 2); - assert_eq!(glob.collate(), at.read_bytes(name)) + assert_eq!(glob.collate(), at.read_bytes(name)); } /// Test for using both obsolete lines option within combined shorts with conflicting -n option simultaneously @@ -1543,8 +1543,8 @@ fn test_split_separator_nul_lines() { ucmd.args(&["--lines=2", "-t", "\\0", "separator_nul.txt"]) .succeeds(); - assert_eq!(file_read(&at, "xaa"), "1\02\0"); - assert_eq!(file_read(&at, "xab"), "3\04\0"); + assert_eq!(file_read(&at, "xaa"), "1\x002\0"); + assert_eq!(file_read(&at, "xab"), "3\x004\0"); assert_eq!(file_read(&at, "xac"), "5\0"); assert!(!at.plus("xad").exists()); } @@ -1555,8 +1555,8 @@ fn test_split_separator_nul_line_bytes() { ucmd.args(&["--line-bytes=4", "-t", "\\0", "separator_nul.txt"]) .succeeds(); - assert_eq!(file_read(&at, "xaa"), "1\02\0"); - assert_eq!(file_read(&at, "xab"), "3\04\0"); + assert_eq!(file_read(&at, "xaa"), "1\x002\0"); + assert_eq!(file_read(&at, "xab"), "3\x004\0"); assert_eq!(file_read(&at, "xac"), "5\0"); assert!(!at.plus("xad").exists()); } @@ -1567,8 +1567,8 @@ fn test_split_separator_nul_number_l() { ucmd.args(&["--number=l/3", "--separator=\\0", "separator_nul.txt"]) .succeeds(); - assert_eq!(file_read(&at, "xaa"), "1\02\0"); - assert_eq!(file_read(&at, "xab"), "3\04\0"); + assert_eq!(file_read(&at, "xaa"), "1\x002\0"); + assert_eq!(file_read(&at, "xab"), "3\x004\0"); assert_eq!(file_read(&at, "xac"), "5\0"); assert!(!at.plus("xad").exists()); } @@ -1579,8 +1579,8 @@ fn test_split_separator_nul_number_r() { ucmd.args(&["--number=r/3", "--separator=\\0", "separator_nul.txt"]) .succeeds(); - assert_eq!(file_read(&at, "xaa"), "1\04\0"); - assert_eq!(file_read(&at, "xab"), "2\05\0"); + assert_eq!(file_read(&at, "xaa"), "1\x004\0"); + assert_eq!(file_read(&at, "xab"), "2\x005\0"); assert_eq!(file_read(&at, "xac"), "3\0"); assert!(!at.plus("xad").exists()); } diff --git a/tests/by-util/test_tee.rs b/tests/by-util/test_tee.rs index 6f04edfc3..2b3fd2670 100644 --- a/tests/by-util/test_tee.rs +++ b/tests/by-util/test_tee.rs @@ -3,6 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use crate::common::util::TestScenario; +use std::fmt::Write; // tests for basic tee functionality. // inspired by: @@ -74,7 +75,10 @@ fn test_tee_append() { fn test_tee_no_more_writeable_1() { // equals to 'tee /dev/full out2 (); + let content = (1..=10).fold(String::new(), |mut output, x| { + let _ = writeln!(output, "{x}"); + output + }); let file_out = "tee_file_out"; ucmd.arg("/dev/full") @@ -94,7 +98,10 @@ fn test_tee_no_more_writeable_2() { // but currently there is no way to redirect stdout to /dev/full // so this test is disabled let (_at, mut ucmd) = at_and_ucmd!(); - let _content = (1..=10).map(|x| format!("{x}\n")).collect::(); + let _content = (1..=10).fold(String::new(), |mut output, x| { + let _ = writeln!(output, "{x}"); + output + }); let file_out_a = "tee_file_out_a"; let file_out_b = "tee_file_out_b"; @@ -114,6 +121,7 @@ fn test_tee_no_more_writeable_2() { mod linux_only { use crate::common::util::{AtPath, TestScenario, UCommand}; + use std::fmt::Write; use std::fs::File; use std::process::{Output, Stdio}; @@ -135,7 +143,10 @@ mod linux_only { } fn run_tee(proc: &mut UCommand) -> (String, Output) { - let content = (1..=100_000).map(|x| format!("{x}\n")).collect::(); + let content = (1..=100_000).fold(String::new(), |mut output, x| { + let _ = writeln!(output, "{x}"); + output + }); #[allow(deprecated)] let output = proc From fa2a14ccd262f102ca04e47529d5f79a556a1692 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 22:55:30 +0800 Subject: [PATCH 08/35] expr: unify debug message --- src/uu/expr/src/syntax_tree.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index b3cd329ba..335405d06 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -52,7 +52,7 @@ impl AstNode { operands, } => { println!( - "Node( {} ) at #{} (evaluate -> {:?})", + "Node( {} ) at #{} ( evaluate -> {:?} )", op_type, token_idx, self.evaluate() From 6091bafe08178f88f57aed9d28a1e1dda659bfd4 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Mon, 25 Sep 2023 18:24:20 -0400 Subject: [PATCH 09/35] feat(mv): expose functionality, document for nushell --- src/uu/mv/src/mv.rs | 169 +++++++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 57 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 43f8eb6b6..267179bbf 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (ToDO) sourcepath targetpath +// spell-checker:ignore (ToDO) sourcepath targetpath nushell mod error; @@ -23,6 +23,7 @@ use uucore::backup_control::{self, source_is_target_backup, BackupMode}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; use uucore::fs::{are_hardlinks_or_one_way_symlink_to_same_file, are_hardlinks_to_same_file}; +use uucore::libc::ENOTEMPTY; use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; @@ -32,23 +33,56 @@ use fs_extra::dir::{ }; use crate::error::MvError; +/// Options contains all the possible behaviors and flags for mv. +/// +/// All options are public so that the options can be programmatically +/// constructed by other crates, such as nushell. That means that this struct +/// is part of our public API. It should therefore not be changed without good +/// reason. +/// The fields are documented with the arguments that determine their value. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Options { + /// specifies overwrite behavior + /// '-n' '--no-clobber' + /// '-i' '--interactive' + /// '-f' '--force' + pub overwrite: OverwriteMode, -pub struct Behavior { - overwrite: OverwriteMode, - backup: BackupMode, - suffix: String, - update: UpdateMode, - target_dir: Option, - no_target_dir: bool, - verbose: bool, - strip_slashes: bool, - progress_bar: bool, + /// `--backup[=CONTROL]`, `-b` + pub backup: BackupMode, + + /// '-S' --suffix' backup suffix + pub suffix: String, + + /// Available update mode "--update-mode=all|none|older" + pub update: UpdateMode, + + /// Specifies target directory + /// '-t, --target-directory=DIRECTORY' + pub target_dir: Option, + + /// Treat destination as a normal file + /// '-T, --no-target-directory + pub no_target_dir: bool, + + /// '-v, --verbose' + pub verbose: bool, + + /// '--strip-trailing-slashes' + pub strip_slashes: bool, + + /// '-g, --progress' + pub progress_bar: bool, } -#[derive(Clone, Eq, PartialEq)] +/// specifies behavior of the overwrite flag +#[derive(Clone, Debug, Eq, PartialEq)] pub enum OverwriteMode { + /// '-n' '--no-clobber' do not overwrite NoClobber, + /// '-i' '--interactive' prompt before overwrite Interactive, + ///'-f' '--force' overwrite without prompt Force, } @@ -116,7 +150,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } } - let behavior = Behavior { + let opts = Options { overwrite: overwrite_mode, backup: backup_mode, suffix: backup_suffix, @@ -128,7 +162,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { progress_bar: matches.get_flag(OPT_PROGRESS), }; - exec(&files[..], &behavior) + exec_mv(&files[..], &opts) } pub fn uu_app() -> Command { @@ -220,7 +254,7 @@ pub fn uu_app() -> Command { ) } -fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { +pub fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { // This does not exactly match the GNU implementation: // The GNU mv defaults to Force, but if more than one of the // overwrite options are supplied, only the last takes effect. @@ -235,10 +269,10 @@ fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { } } -fn parse_paths(files: &[OsString], b: &Behavior) -> Vec { +fn parse_paths(files: &[OsString], opts: &Options) -> Vec { let paths = files.iter().map(Path::new); - if b.strip_slashes { + if opts.strip_slashes { paths .map(|p| p.components().as_path().to_owned()) .collect::>() @@ -247,8 +281,10 @@ fn parse_paths(files: &[OsString], b: &Behavior) -> Vec { } } -fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { - if b.backup == BackupMode::SimpleBackup && source_is_target_backup(source, target, &b.suffix) { +fn handle_two_paths(source: &Path, target: &Path, opts: &Options) -> UResult<()> { + if opts.backup == BackupMode::SimpleBackup + && source_is_target_backup(source, target, &opts.suffix) + { return Err(io::Error::new( io::ErrorKind::NotFound, format!( @@ -266,7 +302,7 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { if (source.eq(target) || are_hardlinks_to_same_file(source, target) || are_hardlinks_or_one_way_symlink_to_same_file(source, target)) - && b.backup == BackupMode::NoBackup + && opts.backup == BackupMode::NoBackup { if source.eq(Path::new(".")) || source.ends_with("/.") || source.is_file() { return Err( @@ -278,19 +314,19 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { } if target.is_dir() { - if b.no_target_dir { + if opts.no_target_dir { if source.is_dir() { - rename(source, target, b, None).map_err_context(|| { + rename(source, target, opts, None).map_err_context(|| { format!("cannot move {} to {}", source.quote(), target.quote()) }) } else { Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into()) } } else { - move_files_into_dir(&[source.to_path_buf()], target, b) + move_files_into_dir(&[source.to_path_buf()], target, opts) } } else if target.exists() && source.is_dir() { - match b.overwrite { + match opts.overwrite { OverwriteMode::NoClobber => return Ok(()), OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}? ", target.quote()) { @@ -305,12 +341,12 @@ fn handle_two_paths(source: &Path, target: &Path, b: &Behavior) -> UResult<()> { ) .into()) } else { - rename(source, target, b, None).map_err(|e| USimpleError::new(1, format!("{e}"))) + rename(source, target, opts, None).map_err(|e| USimpleError::new(1, format!("{e}"))) } } -fn handle_multiple_paths(paths: &[PathBuf], b: &Behavior) -> UResult<()> { - if b.no_target_dir { +fn handle_multiple_paths(paths: &[PathBuf], opts: &Options) -> UResult<()> { + if opts.no_target_dir { return Err(UUsageError::new( 1, format!("mv: extra operand {}", paths[2].quote()), @@ -319,24 +355,29 @@ fn handle_multiple_paths(paths: &[PathBuf], b: &Behavior) -> UResult<()> { let target_dir = paths.last().unwrap(); let sources = &paths[..paths.len() - 1]; - move_files_into_dir(sources, target_dir, b) + move_files_into_dir(sources, target_dir, opts) } -fn exec(files: &[OsString], b: &Behavior) -> UResult<()> { - let paths = parse_paths(files, b); +/// Execute mv command, moving 'source' to 'target', where +/// 'target' is a directory. If 'target' does not exist, and source is a single +/// file or directory, then 'source' will be renamed to 'target'. +/// +/// returns MvError | UError +pub fn exec_mv(files: &[OsString], opts: &Options) -> UResult<()> { + let paths = parse_paths(files, opts); - if let Some(ref name) = b.target_dir { - return move_files_into_dir(&paths, &PathBuf::from(name), b); + if let Some(ref name) = opts.target_dir { + return move_files_into_dir(&paths, &PathBuf::from(name), opts); } match paths.len() { - 2 => handle_two_paths(&paths[0], &paths[1], b), - _ => handle_multiple_paths(&paths, b), + 2 => handle_two_paths(&paths[0], &paths[1], opts), + _ => handle_multiple_paths(&paths, opts), } } #[allow(clippy::cognitive_complexity)] -fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UResult<()> { +fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, opts: &Options) -> UResult<()> { if !target_dir.is_dir() { return Err(MvError::NotADirectory(target_dir.quote().to_string()).into()); } @@ -345,7 +386,7 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR .canonicalize() .unwrap_or_else(|_| target_dir.to_path_buf()); - let multi_progress = b.progress_bar.then(MultiProgress::new); + let multi_progress = opts.progress_bar.then(MultiProgress::new); let count_progress = if let Some(ref multi_progress) = multi_progress { if files.len() > 1 { @@ -396,24 +437,37 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR } } - match rename(sourcepath, &targetpath, b, multi_progress.as_ref()) { + match rename(sourcepath, &targetpath, opts, multi_progress.as_ref()) { Err(e) if e.to_string().is_empty() => set_exit_code(1), Err(e) => { - let e = e.map_err_context(|| { - format!( - "cannot move {} to {}", - sourcepath.quote(), - targetpath.quote() - ) - }); - match multi_progress { - Some(ref pb) => pb.suspend(|| show!(e)), - None => show!(e), - }; + match e.raw_os_error() { + Some(ENOTEMPTY) => { + // The error message was changed to match GNU's decision + // when an issue was filed. These will match when merged upstream. + let e = e + .map_err_context(|| format!("cannot overwrite {}", targetpath.quote())); + match multi_progress { + Some(ref pb) => pb.suspend(|| show!(e)), + None => show!(e), + }; + } + _ => { + let e = e.map_err_context(|| { + format!( + "cannot move {} to {}", + sourcepath.quote(), + targetpath.quote() + ) + }); + match multi_progress { + Some(ref pb) => pb.suspend(|| show!(e)), + None => show!(e), + }; + } + } } Ok(()) => (), } - if let Some(ref pb) = count_progress { pb.inc(1); } @@ -424,29 +478,30 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, b: &Behavior) -> UR fn rename( from: &Path, to: &Path, - b: &Behavior, + opts: &Options, multi_progress: Option<&MultiProgress>, ) -> io::Result<()> { let mut backup_path = None; if to.exists() { - if b.update == UpdateMode::ReplaceIfOlder && b.overwrite == OverwriteMode::Interactive { + if opts.update == UpdateMode::ReplaceIfOlder && opts.overwrite == OverwriteMode::Interactive + { // `mv -i --update old new` when `new` exists doesn't move anything // and exit with 0 return Ok(()); } - if b.update == UpdateMode::ReplaceNone { + if opts.update == UpdateMode::ReplaceNone { return Ok(()); } - if (b.update == UpdateMode::ReplaceIfOlder) + if (opts.update == UpdateMode::ReplaceIfOlder) && fs::metadata(from)?.modified()? <= fs::metadata(to)?.modified()? { return Ok(()); } - match b.overwrite { + match opts.overwrite { OverwriteMode::NoClobber => { let err_msg = format!("not replacing {}", to.quote()); return Err(io::Error::new(io::ErrorKind::Other, err_msg)); @@ -459,7 +514,7 @@ fn rename( OverwriteMode::Force => {} }; - backup_path = backup_control::get_backup_path(b.backup, to, &b.suffix); + backup_path = backup_control::get_backup_path(opts.backup, to, &opts.suffix); if let Some(ref backup_path) = backup_path { rename_with_fallback(to, backup_path, multi_progress)?; } @@ -472,14 +527,14 @@ fn rename( if is_empty_dir(to) { fs::remove_dir(to)?; } else { - return Err(io::Error::new(io::ErrorKind::Other, "Directory not empty")); + return Err(io::Error::from_raw_os_error(ENOTEMPTY)); } } } rename_with_fallback(from, to, multi_progress)?; - if b.verbose { + if opts.verbose { let message = match backup_path { Some(path) => format!( "renamed {} -> {} (backup: {})", From 4a44a106a0442cf53f02efb2fc317a9b695125e9 Mon Sep 17 00:00:00 2001 From: PThorpe92 Date: Thu, 28 Sep 2023 15:11:48 -0400 Subject: [PATCH 10/35] feat: expose mv externals + document for nushell --- src/uu/mv/src/mv.rs | 59 +++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 267179bbf..9888389ae 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -19,11 +19,11 @@ use std::os::unix; #[cfg(windows)] use std::os::windows; use std::path::{Path, PathBuf}; -use uucore::backup_control::{self, source_is_target_backup, BackupMode}; +pub use uucore::backup_control::BackupMode; +use uucore::backup_control::{self, source_is_target_backup}; use uucore::display::Quotable; use uucore::error::{set_exit_code, FromIo, UError, UResult, USimpleError, UUsageError}; use uucore::fs::{are_hardlinks_or_one_way_symlink_to_same_file, are_hardlinks_to_same_file}; -use uucore::libc::ENOTEMPTY; use uucore::update_control::{self, UpdateMode}; use uucore::{format_usage, help_about, help_section, help_usage, prompt_yes, show}; @@ -33,12 +33,13 @@ use fs_extra::dir::{ }; use crate::error::MvError; + /// Options contains all the possible behaviors and flags for mv. /// /// All options are public so that the options can be programmatically -/// constructed by other crates, such as nushell. That means that this struct -/// is part of our public API. It should therefore not be changed without good -/// reason. +/// constructed by other crates, such as nushell. That means that this struct is +/// part of our public API. It should therefore not be changed without good reason. +/// /// The fields are documented with the arguments that determine their value. #[derive(Debug, Clone, Eq, PartialEq)] pub struct Options { @@ -162,7 +163,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { progress_bar: matches.get_flag(OPT_PROGRESS), }; - exec_mv(&files[..], &opts) + mv(&files[..], &opts) } pub fn uu_app() -> Command { @@ -254,7 +255,7 @@ pub fn uu_app() -> Command { ) } -pub fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { +fn determine_overwrite_mode(matches: &ArgMatches) -> OverwriteMode { // This does not exactly match the GNU implementation: // The GNU mv defaults to Force, but if more than one of the // overwrite options are supplied, only the last takes effect. @@ -358,12 +359,10 @@ fn handle_multiple_paths(paths: &[PathBuf], opts: &Options) -> UResult<()> { move_files_into_dir(sources, target_dir, opts) } -/// Execute mv command, moving 'source' to 'target', where +/// Execute the mv command. This moves 'source' to 'target', where /// 'target' is a directory. If 'target' does not exist, and source is a single /// file or directory, then 'source' will be renamed to 'target'. -/// -/// returns MvError | UError -pub fn exec_mv(files: &[OsString], opts: &Options) -> UResult<()> { +pub fn mv(files: &[OsString], opts: &Options) -> UResult<()> { let paths = parse_paths(files, opts); if let Some(ref name) = opts.target_dir { @@ -440,31 +439,17 @@ fn move_files_into_dir(files: &[PathBuf], target_dir: &Path, opts: &Options) -> match rename(sourcepath, &targetpath, opts, multi_progress.as_ref()) { Err(e) if e.to_string().is_empty() => set_exit_code(1), Err(e) => { - match e.raw_os_error() { - Some(ENOTEMPTY) => { - // The error message was changed to match GNU's decision - // when an issue was filed. These will match when merged upstream. - let e = e - .map_err_context(|| format!("cannot overwrite {}", targetpath.quote())); - match multi_progress { - Some(ref pb) => pb.suspend(|| show!(e)), - None => show!(e), - }; - } - _ => { - let e = e.map_err_context(|| { - format!( - "cannot move {} to {}", - sourcepath.quote(), - targetpath.quote() - ) - }); - match multi_progress { - Some(ref pb) => pb.suspend(|| show!(e)), - None => show!(e), - }; - } - } + let e = e.map_err_context(|| { + format!( + "cannot move {} to {}", + sourcepath.quote(), + targetpath.quote() + ) + }); + match multi_progress { + Some(ref pb) => pb.suspend(|| show!(e)), + None => show!(e), + }; } Ok(()) => (), } @@ -527,7 +512,7 @@ fn rename( if is_empty_dir(to) { fs::remove_dir(to)?; } else { - return Err(io::Error::from_raw_os_error(ENOTEMPTY)); + return Err(io::Error::new(io::ErrorKind::Other, "Directory not empty")); } } } From 2c2e01205cfbe4b6337a207102485fd2dc64e443 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 23:50:22 +0800 Subject: [PATCH 11/35] expr: short-circuit evaluation for | --- src/uu/expr/src/syntax_tree.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 335405d06..ad421edb7 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -155,8 +155,24 @@ impl AstNode { } } pub fn operand_values(&self) -> Result, String> { - if let Self::Node { operands, .. } = self { + if let Self::Node { + operands, op_type, .. + } = self + { let mut out = Vec::with_capacity(operands.len()); + let mut operands = operands.iter(); + + if op_type == "|" { + if let Some(value) = operands.next() { + let value = value.evaluate()?; + out.push(value.clone()); + if value_as_bool(&value) { + out.push(String::from("dummy")); + return Ok(out); + } + } + } + for operand in operands { let value = operand.evaluate()?; out.push(value); From 5a732dd21a9aa0987f973eda4ffe919b9985be29 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Fri, 6 Oct 2023 23:50:44 +0800 Subject: [PATCH 12/35] tests/expr: add test expr 1 \| a / 5 --- tests/by-util/test_expr.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index ea5a964d9..99445d566 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -123,6 +123,11 @@ fn test_or() { .args(&["-14", "|", "1"]) .succeeds() .stdout_only("-14\n"); + + new_ucmd!() + .args(&["1", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("1\n"); } #[test] From 0df561e256905c9477bd316b68a9fb56d36a47c6 Mon Sep 17 00:00:00 2001 From: Luv_Ray Date: Sat, 7 Oct 2023 00:19:56 +0800 Subject: [PATCH 13/35] expr: add comment in syntax_tree.rs --- src/uu/expr/src/syntax_tree.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index ad421edb7..eaa6be1f5 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -161,7 +161,8 @@ impl AstNode { { let mut out = Vec::with_capacity(operands.len()); let mut operands = operands.iter(); - + // check the first value before `|`, stop evaluate and return directly if it is true. + // push dummy to pass the check of `len() == 2` if op_type == "|" { if let Some(value) = operands.next() { let value = value.evaluate()?; From 7bf4b7f6748812e29daf3fb91180e4dfceb6ce30 Mon Sep 17 00:00:00 2001 From: Luv_Ray Date: Sat, 7 Oct 2023 00:42:04 +0800 Subject: [PATCH 14/35] tests/expr: add tests in test_expr.rs --- tests/by-util/test_expr.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index 99445d566..a463f086b 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -128,6 +128,16 @@ fn test_or() { .args(&["1", "|", "a", "/", "5"]) .succeeds() .stdout_only("1\n"); + + new_ucmd!() + .args(&["foo", "|", "a", "/", "5"]) + .succeeds() + .stdout_only("foo\n"); + + new_ucmd!() + .args(&["0", "|", "10", "/", "5"]) + .succeeds() + .stdout_only("2\n"); } #[test] From 98cfb0c322b33d571647ba7c0ac6831624266eae Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Fri, 6 Oct 2023 22:08:04 +0200 Subject: [PATCH 15/35] Binary sizes: handle when 0 (relpath removal) --- .github/workflows/CICD.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index a9f04e3cf..61c12dad0 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -610,6 +610,12 @@ jobs: check() { # Warn if the size increases by more than 5% threshold='1.05' + + if [[ "$2" -eq 0 || "$3" -eq 0 ]]; then + echo "::warning file=$4::Invalid size for $1. Sizes cannot be 0." + return + fi + ratio=$(jq -n "$2 / $3") echo "$1: size=$2, previous_size=$3, ratio=$ratio, threshold=$threshold" if [[ "$(jq -n "$ratio > $threshold")" == 'true' ]]; then From e5d70d444ae7ca3a3100190ea87c22edfecab121 Mon Sep 17 00:00:00 2001 From: Zhuoxun Yang Date: Sat, 7 Oct 2023 10:41:10 +0800 Subject: [PATCH 16/35] tests/expr: format --- tests/by-util/test_expr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/by-util/test_expr.rs b/tests/by-util/test_expr.rs index a463f086b..4637d51c7 100644 --- a/tests/by-util/test_expr.rs +++ b/tests/by-util/test_expr.rs @@ -128,7 +128,7 @@ fn test_or() { .args(&["1", "|", "a", "/", "5"]) .succeeds() .stdout_only("1\n"); - + new_ucmd!() .args(&["foo", "|", "a", "/", "5"]) .succeeds() From 959bfa0160165b8ed23f1db4cd9ea43264f3aadd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Oct 2023 02:43:46 +0000 Subject: [PATCH 17/35] chore(deps): update rust crate libc to 0.2.149 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2c872e2d..a3c3e7096 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1200,9 +1200,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.148" +version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" [[package]] name = "libloading" diff --git a/Cargo.toml b/Cargo.toml index 783c84ccf..e59ed7bd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -286,7 +286,7 @@ glob = "0.3.1" half = "2.3" indicatif = "0.17" itertools = "0.11.0" -libc = "0.2.148" +libc = "0.2.149" lscolors = { version = "0.15.0", default-features = false, features = [ "nu-ansi-term", ] } From e1b7f254a63a00b1b33a8842ca6280b183df8eb6 Mon Sep 17 00:00:00 2001 From: Sanpi Date: Sat, 7 Oct 2023 10:39:19 +0200 Subject: [PATCH 18/35] ls: fix panic when file removed too quickly Fixes #5371 --- src/uu/ls/src/ls.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 301aefaf3..c80d4cbe6 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -2888,7 +2888,11 @@ fn classify_file(path: &PathData, out: &mut BufWriter) -> Option { Some('=') } else if file_type.is_fifo() { Some('|') - } else if file_type.is_file() && file_is_executable(path.md(out).as_ref().unwrap()) { + } else if file_type.is_file() + // Safe unwrapping if the file was removed between listing and display + // See https://github.com/uutils/coreutils/issues/5371 + && path.md(out).map(file_is_executable).unwrap_or_default() + { Some('*') } else { None From 3e1d3cacebe447dfa4efa8d5b722abc9ad0bca3d Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 7 Oct 2023 13:37:24 +0200 Subject: [PATCH 19/35] head: remove clippy::cognitive_complexity by moving some content in a function (#5366) * head: remove a clippy::cognitive_complexity by moving some content into a function * Remove duplicate comment --- src/uu/head/src/parse.rs | 129 +++++++++++++++++++++------------------ 1 file changed, 69 insertions(+), 60 deletions(-) diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs index 90e1f2ce0..179435c7a 100644 --- a/src/uu/head/src/parse.rs +++ b/src/uu/head/src/parse.rs @@ -13,7 +13,6 @@ pub enum ParseError { } /// Parses obsolete syntax /// head -NUM\[kmzv\] // spell-checker:disable-line -#[allow(clippy::cognitive_complexity)] pub fn parse_obsolete(src: &str) -> Option, ParseError>> { let mut chars = src.char_indices(); if let Some((_, '-')) = chars.next() { @@ -30,65 +29,7 @@ pub fn parse_obsolete(src: &str) -> Option } } if has_num { - match src[1..=num_end].parse::() { - Ok(num) => { - let mut quiet = false; - let mut verbose = false; - let mut zero_terminated = false; - let mut multiplier = None; - let mut c = last_char; - loop { - // not that here, we only match lower case 'k', 'c', and 'm' - match c { - // we want to preserve order - // this also saves us 1 heap allocation - 'q' => { - quiet = true; - verbose = false; - } - 'v' => { - verbose = true; - quiet = false; - } - 'z' => zero_terminated = true, - 'c' => multiplier = Some(1), - 'b' => multiplier = Some(512), - 'k' => multiplier = Some(1024), - 'm' => multiplier = Some(1024 * 1024), - '\0' => {} - _ => return Some(Err(ParseError::Syntax)), - } - if let Some((_, next)) = chars.next() { - c = next; - } else { - break; - } - } - let mut options = Vec::new(); - if quiet { - options.push(OsString::from("-q")); - } - if verbose { - options.push(OsString::from("-v")); - } - if zero_terminated { - options.push(OsString::from("-z")); - } - if let Some(n) = multiplier { - options.push(OsString::from("-c")); - let num = match num.checked_mul(n) { - Some(n) => n, - None => return Some(Err(ParseError::Overflow)), - }; - options.push(OsString::from(format!("{num}"))); - } else { - options.push(OsString::from("-n")); - options.push(OsString::from(format!("{num}"))); - } - Some(Ok(options.into_iter())) - } - Err(_) => Some(Err(ParseError::Overflow)), - } + process_num_block(&src[1..=num_end], last_char, &mut chars) } else { None } @@ -96,6 +37,74 @@ pub fn parse_obsolete(src: &str) -> Option None } } + +/// Processes the numeric block of the input string to generate the appropriate options. +fn process_num_block( + src: &str, + last_char: char, + chars: &mut std::str::CharIndices, +) -> Option, ParseError>> { + match src.parse::() { + Ok(num) => { + let mut quiet = false; + let mut verbose = false; + let mut zero_terminated = false; + let mut multiplier = None; + let mut c = last_char; + loop { + // note that here, we only match lower case 'k', 'c', and 'm' + match c { + // we want to preserve order + // this also saves us 1 heap allocation + 'q' => { + quiet = true; + verbose = false; + } + 'v' => { + verbose = true; + quiet = false; + } + 'z' => zero_terminated = true, + 'c' => multiplier = Some(1), + 'b' => multiplier = Some(512), + 'k' => multiplier = Some(1024), + 'm' => multiplier = Some(1024 * 1024), + '\0' => {} + _ => return Some(Err(ParseError::Syntax)), + } + if let Some((_, next)) = chars.next() { + c = next; + } else { + break; + } + } + let mut options = Vec::new(); + if quiet { + options.push(OsString::from("-q")); + } + if verbose { + options.push(OsString::from("-v")); + } + if zero_terminated { + options.push(OsString::from("-z")); + } + if let Some(n) = multiplier { + options.push(OsString::from("-c")); + let num = match num.checked_mul(n) { + Some(n) => n, + None => return Some(Err(ParseError::Overflow)), + }; + options.push(OsString::from(format!("{num}"))); + } else { + options.push(OsString::from("-n")); + options.push(OsString::from(format!("{num}"))); + } + Some(Ok(options.into_iter())) + } + Err(_) => Some(Err(ParseError::Overflow)), + } +} + /// Parses an -c or -n argument, /// the bool specifies whether to read from the end pub fn parse_num(src: &str) -> Result<(u64, bool), ParseSizeError> { From 2ba7400d05ec32320acdd52a395546c9ee0f2327 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 7 Oct 2023 15:15:44 +0200 Subject: [PATCH 20/35] clippy: suppress cognitive_complexity lint for two functions --- src/uu/ls/src/ls.rs | 1 + src/uu/split/src/split.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 301aefaf3..9dec8749d 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1856,6 +1856,7 @@ impl PathData { } } +#[allow(clippy::cognitive_complexity)] pub fn list(locs: Vec<&Path>, config: &Config) -> UResult<()> { let mut files = Vec::::new(); let mut dirs = Vec::::new(); diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 756248539..bfd595e4f 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -1714,6 +1714,7 @@ where Ok(()) } +#[allow(clippy::cognitive_complexity)] fn split(settings: &Settings) -> UResult<()> { let mut reader = BufReader::new(if settings.input == "-" { Box::new(stdin()) as Box From f86469f6d5c6d0903162aa04cedf872fc0520d67 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sat, 7 Oct 2023 14:11:15 +0200 Subject: [PATCH 21/35] head: add some empty lines --- src/uu/head/src/head.rs | 13 ++++++++++++- src/uu/head/src/parse.rs | 8 ++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/uu/head/src/head.rs b/src/uu/head/src/head.rs index c60bbfe99..d6e4db5a7 100644 --- a/src/uu/head/src/head.rs +++ b/src/uu/head/src/head.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (vars) zlines BUFWRITER seekable +// spell-checker:ignore (vars) BUFWRITER seekable use clap::{crate_version, Arg, ArgAction, ArgMatches, Command}; use std::ffi::OsString; @@ -31,6 +31,7 @@ mod options { pub const FILES_NAME: &str = "FILE"; pub const PRESUME_INPUT_PIPE: &str = "-PRESUME-INPUT-PIPE"; } + mod parse; mod take; use take::take_all_but; @@ -519,6 +520,7 @@ mod tests { use std::io::Cursor; use super::*; + fn options(args: &str) -> Result { let combined = "head ".to_owned() + args; let args = combined.split_whitespace().map(OsString::from); @@ -526,6 +528,7 @@ mod tests { .get_matches_from(arg_iterate(args).map_err(|_| String::from("Arg iterate failed"))?); HeadOptions::get_from(&matches) } + #[test] fn test_args_modes() { let args = options("-n -10M -vz").unwrap(); @@ -533,6 +536,7 @@ mod tests { assert!(args.verbose); assert_eq!(args.mode, Mode::AllButLastLines(10 * 1024 * 1024)); } + #[test] fn test_gnu_compatibility() { let args = options("-n 1 -c 1 -n 5 -c kiB -vqvqv").unwrap(); // spell-checker:disable-line @@ -542,6 +546,7 @@ mod tests { assert_eq!(options("-2b").unwrap().mode, Mode::FirstBytes(1024)); assert_eq!(options("-5 -c 1").unwrap().mode, Mode::FirstBytes(1)); } + #[test] fn all_args_test() { assert!(options("--silent").unwrap().quiet); @@ -559,11 +564,13 @@ mod tests { assert_eq!(options("--bytes 15").unwrap().mode, Mode::FirstBytes(15)); assert_eq!(options("-c 15").unwrap().mode, Mode::FirstBytes(15)); } + #[test] fn test_options_errors() { assert!(options("-n IsThisTheRealLife?").is_err()); assert!(options("-c IsThisJustFantasy").is_err()); } + #[test] fn test_options_correct_defaults() { let opts = HeadOptions::default(); @@ -574,6 +581,7 @@ mod tests { assert_eq!(opts.mode, Mode::FirstLines(10)); assert!(opts.files.is_empty()); } + fn arg_outputs(src: &str) -> Result { let split = src.split_whitespace().map(OsString::from); match arg_iterate(split) { @@ -586,6 +594,7 @@ mod tests { Err(_) => Err(()), } } + #[test] fn test_arg_iterate() { // test that normal args remain unchanged @@ -610,6 +619,7 @@ mod tests { //test that empty args remain unchanged assert_eq!(arg_outputs("head"), Ok("head".to_owned())); } + #[test] #[cfg(target_os = "linux")] fn test_arg_iterate_bad_encoding() { @@ -618,6 +628,7 @@ mod tests { // this arises from a conversion from OsString to &str assert!(arg_iterate(vec![OsString::from("head"), invalid].into_iter()).is_err()); } + #[test] fn read_early_exit() { let mut empty = std::io::BufReader::new(std::io::Cursor::new(Vec::new())); diff --git a/src/uu/head/src/parse.rs b/src/uu/head/src/parse.rs index 179435c7a..7f7dd48f8 100644 --- a/src/uu/head/src/parse.rs +++ b/src/uu/head/src/parse.rs @@ -11,6 +11,7 @@ pub enum ParseError { Syntax, Overflow, } + /// Parses obsolete syntax /// head -NUM\[kmzv\] // spell-checker:disable-line pub fn parse_obsolete(src: &str) -> Option, ParseError>> { @@ -135,6 +136,7 @@ pub fn parse_num(src: &str) -> Result<(u64, bool), ParseSizeError> { #[cfg(test)] mod tests { use super::*; + fn obsolete(src: &str) -> Option, ParseError>> { let r = parse_obsolete(src); match r { @@ -145,9 +147,11 @@ mod tests { None => None, } } + fn obsolete_result(src: &[&str]) -> Option, ParseError>> { Some(Ok(src.iter().map(|s| s.to_string()).collect())) } + #[test] fn test_parse_numbers_obsolete() { assert_eq!(obsolete("-5"), obsolete_result(&["-n", "5"])); @@ -167,16 +171,19 @@ mod tests { obsolete_result(&["-z", "-c", "110100480"]) ); } + #[test] fn test_parse_errors_obsolete() { assert_eq!(obsolete("-5n"), Some(Err(ParseError::Syntax))); assert_eq!(obsolete("-5c5"), Some(Err(ParseError::Syntax))); } + #[test] fn test_parse_obsolete_no_match() { assert_eq!(obsolete("-k"), None); assert_eq!(obsolete("asd"), None); } + #[test] #[cfg(target_pointer_width = "64")] fn test_parse_obsolete_overflow_x64() { @@ -189,6 +196,7 @@ mod tests { Some(Err(ParseError::Overflow)) ); } + #[test] #[cfg(target_pointer_width = "32")] fn test_parse_obsolete_overflow_x32() { From 849051f9681b7d65b319942ae0c3bcd8fbe234b4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Oct 2023 22:22:06 +0000 Subject: [PATCH 22/35] chore(deps): update rust crate num-traits to 0.2.17 --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3c3e7096..197368abf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1404,9 +1404,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] diff --git a/Cargo.toml b/Cargo.toml index e59ed7bd7..8eecb2b8f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -296,7 +296,7 @@ nix = { version = "0.27", default-features = false } nom = "7.1.3" notify = { version = "=6.0.1", features = ["macos_kqueue"] } num-bigint = "0.4.4" -num-traits = "0.2.16" +num-traits = "0.2.17" number_prefix = "0.4" once_cell = "1.18.0" onig = { version = "~6.4", default-features = false } From 7e08562ee6bc71fb5e6b6d0aa19a80549627f5eb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 8 Oct 2023 15:02:01 +0200 Subject: [PATCH 23/35] expr: add some empty lines --- src/uu/expr/src/syntax_tree.rs | 8 ++++++++ src/uu/expr/src/tokens.rs | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index eaa6be1f5..4ca723a4d 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -31,10 +31,12 @@ pub enum AstNode { operands: OperandsList, }, } + impl AstNode { fn debug_dump(&self) { self.debug_dump_impl(1); } + fn debug_dump_impl(&self, depth: usize) { for _ in 0..depth { print!("\t",); @@ -71,12 +73,14 @@ impl AstNode { operands, }) } + fn new_leaf(token_idx: usize, value: &str) -> Box { Box::new(Self::Leaf { token_idx, value: value.into(), }) } + pub fn evaluate(&self) -> Result { match self { Self::Leaf { value, .. } => Ok(value.clone()), @@ -154,6 +158,7 @@ impl AstNode { }, } } + pub fn operand_values(&self) -> Result, String> { if let Self::Node { operands, op_type, .. @@ -257,6 +262,7 @@ fn ast_from_rpn(rpn: &mut TokenStack) -> Result, String> { } } } + fn maybe_ast_node( token_idx: usize, op_type: &str, @@ -520,6 +526,7 @@ fn prefix_operator_substr(values: &[String]) -> String { fn bool_as_int(b: bool) -> u8 { u8::from(b) } + fn bool_as_string(b: bool) -> String { if b { "1".to_string() @@ -527,6 +534,7 @@ fn bool_as_string(b: bool) -> String { "0".to_string() } } + fn value_as_bool(s: &str) -> bool { if s.is_empty() { return false; diff --git a/src/uu/expr/src/tokens.rs b/src/uu/expr/src/tokens.rs index b4e4c7da5..3c5cac060 100644 --- a/src/uu/expr/src/tokens.rs +++ b/src/uu/expr/src/tokens.rs @@ -38,6 +38,7 @@ pub enum Token { value: String, }, } + impl Token { fn new_infix_op(v: &str, left_assoc: bool, precedence: u8) -> Self { Self::InfixOp { @@ -46,6 +47,7 @@ impl Token { value: v.into(), } } + fn new_value(v: &str) -> Self { Self::Value { value: v.into() } } @@ -56,12 +58,14 @@ impl Token { _ => false, } } + fn is_a_number(&self) -> bool { match self { Self::Value { value, .. } => value.parse::().is_ok(), _ => false, } } + fn is_a_close_paren(&self) -> bool { matches!(*self, Self::ParClose) } From 4ed58718a8bb0b167520c538df2c1722f8fffe45 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:31:50 +0200 Subject: [PATCH 24/35] github action: extract the warnings into a variable --- .github/workflows/CICD.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 61c12dad0..f7db7b8a2 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -231,10 +231,11 @@ jobs: run: | ## `cargo clippy` lint testing unset fault + CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new" fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') # * convert any warnings to GHA UI annotations; ref: - S=$(cargo clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} -- -W clippy::default_trait_access -W clippy::manual_string_new -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; } + S=$(cargo clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} -- ${CLIPPY_FLAGS} -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; } if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi style_spellcheck: From 6d245491563d5f40c7cfece8ffcfa49695e5ddc3 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:32:03 +0200 Subject: [PATCH 25/35] github action: enable clippy::cognitive_complexity --- .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 f7db7b8a2..b448b76d0 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -231,7 +231,7 @@ jobs: run: | ## `cargo clippy` lint testing unset fault - CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new" + CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new -W clippy::cognitive_complexity" fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') # * convert any warnings to GHA UI annotations; ref: From 5ac1aef20ec3d639db72207e537d84750c828c87 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:34:37 +0200 Subject: [PATCH 26/35] github action: move the fuzzing action into it own file/task --- .github/workflows/CICD.yml | 50 --------------------------- .github/workflows/fuzzing.yml | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 50 deletions(-) create mode 100644 .github/workflows/fuzzing.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 61c12dad0..39eea1593 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -125,56 +125,6 @@ jobs: S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - fuzz: - name: Run the fuzzers - runs-on: ubuntu-latest - env: - RUN_FOR: 60 - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@nightly - - name: Install `cargo-fuzz` - run: cargo install cargo-fuzz - - uses: Swatinem/rust-cache@v2 - - name: Run fuzz_date for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_test for XX seconds - continue-on-error: true - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_expr for XX seconds - continue-on-error: true - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_glob for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_size for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - - name: Run fuzz_parse_time for XX seconds - shell: bash - run: | - ## Run it - cd fuzz - cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - style_lint: name: Style/lint runs-on: ${{ matrix.job.os }} diff --git a/.github/workflows/fuzzing.yml b/.github/workflows/fuzzing.yml new file mode 100644 index 000000000..677df2c9f --- /dev/null +++ b/.github/workflows/fuzzing.yml @@ -0,0 +1,64 @@ +name: Fuzzing + +# spell-checker:ignore fuzzer + +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + fuzz: + name: Run the fuzzers + runs-on: ubuntu-latest + env: + RUN_FOR: 60 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + - name: Install `cargo-fuzz` + run: cargo install cargo-fuzz + - uses: Swatinem/rust-cache@v2 + - name: Run fuzz_date for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_date -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_test for XX seconds + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_test -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_expr for XX seconds + continue-on-error: true + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_expr -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_glob for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_glob -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_size for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_size -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 + - name: Run fuzz_parse_time for XX seconds + shell: bash + run: | + ## Run it + cd fuzz + cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 From 8e8a91be5d4d9628542e23f0c4daaaced42622e4 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:46:11 +0200 Subject: [PATCH 27/35] Ignore more cognitive_complexity --- src/uu/cp/src/copydir.rs | 1 + src/uu/id/src/id.rs | 1 + src/uu/install/src/install.rs | 1 + src/uu/od/src/inputdecoder.rs | 1 + src/uu/od/src/output_info.rs | 1 + src/uu/od/src/parse_inputs.rs | 2 ++ src/uu/od/src/parse_nrofbytes.rs | 1 + src/uu/od/src/peekreader.rs | 1 + src/uu/od/src/prn_char.rs | 2 ++ src/uu/od/src/prn_float.rs | 2 ++ src/uu/od/src/prn_int.rs | 2 ++ src/uu/stat/src/stat.rs | 2 ++ 12 files changed, 17 insertions(+) diff --git a/src/uu/cp/src/copydir.rs b/src/uu/cp/src/copydir.rs index ac44ce687..a8b941364 100644 --- a/src/uu/cp/src/copydir.rs +++ b/src/uu/cp/src/copydir.rs @@ -447,6 +447,7 @@ mod tests { use super::ends_with_slash_dot; #[test] + #[allow(clippy::cognitive_complexity)] fn test_ends_with_slash_dot() { assert!(ends_with_slash_dot("/.")); assert!(ends_with_slash_dot("./.")); diff --git a/src/uu/id/src/id.rs b/src/uu/id/src/id.rs index 49ad54925..8b16ba8b7 100644 --- a/src/uu/id/src/id.rs +++ b/src/uu/id/src/id.rs @@ -109,6 +109,7 @@ struct State { } #[uucore::main] +#[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; diff --git a/src/uu/install/src/install.rs b/src/uu/install/src/install.rs index 02cf8345d..63ba52b1c 100644 --- a/src/uu/install/src/install.rs +++ b/src/uu/install/src/install.rs @@ -526,6 +526,7 @@ fn is_potential_directory_path(path: &Path) -> bool { /// /// Returns a Result type with the Err variant containing the error message. /// +#[allow(clippy::cognitive_complexity)] fn standard(mut paths: Vec, b: &Behavior) -> UResult<()> { // first check that paths contains at least one element if paths.is_empty() { diff --git a/src/uu/od/src/inputdecoder.rs b/src/uu/od/src/inputdecoder.rs index 6f08eba12..e63eaed14 100644 --- a/src/uu/od/src/inputdecoder.rs +++ b/src/uu/od/src/inputdecoder.rs @@ -166,6 +166,7 @@ mod tests { #[test] #[allow(clippy::float_cmp)] + #[allow(clippy::cognitive_complexity)] fn smoke_test() { let data = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xff, 0xff]; let mut input = PeekReader::new(Cursor::new(&data)); diff --git a/src/uu/od/src/output_info.rs b/src/uu/od/src/output_info.rs index 96c01f906..993bba329 100644 --- a/src/uu/od/src/output_info.rs +++ b/src/uu/od/src/output_info.rs @@ -208,6 +208,7 @@ impl TypeSizeInfo for TypeInfo { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_calculate_alignment() { // For this example `byte_size_block` is 8 and 'print_width_block' is 23: // 1777777777777777777777 1777777777777777777777 diff --git a/src/uu/od/src/parse_inputs.rs b/src/uu/od/src/parse_inputs.rs index 74dc5a13a..241d842af 100644 --- a/src/uu/od/src/parse_inputs.rs +++ b/src/uu/od/src/parse_inputs.rs @@ -213,6 +213,7 @@ mod tests { } #[test] + #[allow(clippy::cognitive_complexity)] fn test_parse_inputs_with_offset() { // offset is found without filename, so stdin will be used. assert_eq!( @@ -355,6 +356,7 @@ mod tests { } #[test] + #[allow(clippy::cognitive_complexity)] fn test_parse_offset_operand() { assert_eq!(8, parse_offset_operand_str("10").unwrap()); // default octal assert_eq!(0, parse_offset_operand_str("0").unwrap()); diff --git a/src/uu/od/src/parse_nrofbytes.rs b/src/uu/od/src/parse_nrofbytes.rs index a5c81f68b..431b2a71f 100644 --- a/src/uu/od/src/parse_nrofbytes.rs +++ b/src/uu/od/src/parse_nrofbytes.rs @@ -79,6 +79,7 @@ pub fn parse_number_of_bytes(s: &str) -> Result { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_parse_number_of_bytes() { // octal input assert_eq!(8, parse_number_of_bytes("010").unwrap()); diff --git a/src/uu/od/src/peekreader.rs b/src/uu/od/src/peekreader.rs index 239faab92..82f139c72 100644 --- a/src/uu/od/src/peekreader.rs +++ b/src/uu/od/src/peekreader.rs @@ -186,6 +186,7 @@ mod tests { } #[test] + #[allow(clippy::cognitive_complexity)] fn test_peek_read_with_smaller_buffer() { let mut sut = PeekReader::new(Cursor::new(&b"abcdefghij"[..])); diff --git a/src/uu/od/src/prn_char.rs b/src/uu/od/src/prn_char.rs index db12d9d4f..36a00a67b 100644 --- a/src/uu/od/src/prn_char.rs +++ b/src/uu/od/src/prn_char.rs @@ -99,6 +99,7 @@ pub fn format_ascii_dump(bytes: &[u8]) -> String { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_format_item_a() { assert_eq!(" nul", format_item_a(0x00)); assert_eq!(" soh", format_item_a(0x01)); @@ -114,6 +115,7 @@ fn test_format_item_a() { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_format_item_c() { assert_eq!(" \\0", format_item_c(&[0x00])); assert_eq!(" 001", format_item_c(&[0x01])); diff --git a/src/uu/od/src/prn_float.rs b/src/uu/od/src/prn_float.rs index af632d66b..f4d018bd8 100644 --- a/src/uu/od/src/prn_float.rs +++ b/src/uu/od/src/prn_float.rs @@ -91,6 +91,7 @@ fn format_float(f: f64, width: usize, precision: usize) -> String { #[test] #[allow(clippy::excessive_precision)] +#[allow(clippy::cognitive_complexity)] fn test_format_flo32() { assert_eq!(format_flo32(1.0), " 1.0000000"); assert_eq!(format_flo32(9.9999990), " 9.9999990"); @@ -167,6 +168,7 @@ fn test_format_flo32() { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_format_flo64() { assert_eq!(format_flo64(1.0), " 1.0000000000000000"); assert_eq!(format_flo64(10.0), " 10.000000000000000"); diff --git a/src/uu/od/src/prn_int.rs b/src/uu/od/src/prn_int.rs index c214b7525..f843ff77c 100644 --- a/src/uu/od/src/prn_int.rs +++ b/src/uu/od/src/prn_int.rs @@ -89,6 +89,7 @@ int_writer_signed!(FORMAT_ITEM_DEC32S, 4, 12, format_item_dec_s32, DEC!()); // m int_writer_signed!(FORMAT_ITEM_DEC64S, 8, 21, format_item_dec_s64, DEC!()); // max: -9223372036854775808 #[test] +#[allow(clippy::cognitive_complexity)] fn test_sign_extend() { assert_eq!( 0xffff_ffff_ffff_ff80u64 as i64, @@ -179,6 +180,7 @@ fn test_format_item_dec_u() { } #[test] +#[allow(clippy::cognitive_complexity)] fn test_format_item_dec_s() { assert_eq!(" 0", format_item_dec_s8(0)); assert_eq!(" 127", format_item_dec_s8(0x7f)); diff --git a/src/uu/stat/src/stat.rs b/src/uu/stat/src/stat.rs index c36b45006..055393578 100644 --- a/src/uu/stat/src/stat.rs +++ b/src/uu/stat/src/stat.rs @@ -404,6 +404,7 @@ fn print_unsigned_hex( } impl Stater { + #[allow(clippy::cognitive_complexity)] fn generate_tokens(format_str: &str, use_printf: bool) -> UResult> { let mut tokens = Vec::new(); let bound = format_str.len(); @@ -609,6 +610,7 @@ impl Stater { ret } + #[allow(clippy::cognitive_complexity)] fn do_stat(&self, file: &OsStr, stdin_is_fifo: bool) -> i32 { let display_name = file.to_string_lossy(); let file = if cfg!(unix) && display_name == "-" { From 4d122d7dd0e03d2e3f30ad91576947ee06e616b8 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:51:06 +0200 Subject: [PATCH 28/35] Move rustfmt + clippy + typo check into it own workflow --- .github/workflows/CICD.yml | 160 -------------------------- .github/workflows/code-quality.yml | 175 +++++++++++++++++++++++++++++ 2 files changed, 175 insertions(+), 160 deletions(-) create mode 100644 .github/workflows/code-quality.yml diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index b448b76d0..3b78fa6e2 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -82,49 +82,6 @@ jobs: grep --ignore-case "all deps seem to have been used" udeps.log || { printf "%s\n" "::${fault_type} ::${fault_prefix}: \`cargo udeps\`: style violation (unused dependency found)" ; fault=true ; } if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - style_format: - name: Style/format - runs-on: ${{ matrix.job.os }} - strategy: - fail-fast: false - matrix: - job: - - { os: ubuntu-latest , features: feat_os_unix } - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - components: rustfmt - - uses: Swatinem/rust-cache@v2 - - name: Initialize workflow variables - id: vars - shell: bash - run: | - ## VARs setup - outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - # failure mode - unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in - ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; - *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; - esac; - outputs FAIL_ON_FAULT FAULT_TYPE - # target-specific options - # * CARGO_FEATURES_OPTION - CARGO_FEATURES_OPTION='' ; - if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi - outputs CARGO_FEATURES_OPTION - - name: "`cargo fmt` testing" - shell: bash - run: | - ## `cargo fmt` testing - unset fault - fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" - fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') - # * convert any errors/warnings to GHA UI annotations; ref: - S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } - if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - fuzz: name: Run the fuzzers runs-on: ubuntu-latest @@ -175,114 +132,6 @@ jobs: cd fuzz cargo +nightly fuzz run fuzz_parse_time -- -max_total_time=${{ env.RUN_FOR }} -detect_leaks=0 - style_lint: - name: Style/lint - runs-on: ${{ matrix.job.os }} - env: - SCCACHE_GHA_ENABLED: "true" - RUSTC_WRAPPER: "sccache" - strategy: - fail-fast: false - matrix: - job: - - { os: ubuntu-latest , features: feat_os_unix } - - { os: macos-latest , features: feat_os_macos } - - { os: windows-latest , features: feat_os_windows } - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - components: clippy - - uses: Swatinem/rust-cache@v2 - - name: Run sccache-cache - uses: mozilla-actions/sccache-action@v0.0.3 - - name: Initialize workflow variables - id: vars - shell: bash - run: | - ## VARs setup - outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - # failure mode - unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in - ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; - *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; - esac; - outputs FAIL_ON_FAULT FAULT_TYPE - # target-specific options - # * CARGO_FEATURES_OPTION - CARGO_FEATURES_OPTION='--all-features' ; - if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features ${{ matrix.job.features }}' ; fi - outputs CARGO_FEATURES_OPTION - # * determine sub-crate utility list - UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})" - echo UTILITY_LIST=${UTILITY_LIST} - CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)" - outputs CARGO_UTILITY_LIST_OPTIONS - - name: Install/setup prerequisites - shell: bash - run: | - ## Install/setup prerequisites - case '${{ matrix.job.os }}' in - macos-latest) brew install coreutils ;; # needed for show-utils.sh - esac - - name: "`cargo clippy` lint testing" - shell: bash - run: | - ## `cargo clippy` lint testing - unset fault - CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new -W clippy::cognitive_complexity" - fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" - fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') - # * convert any warnings to GHA UI annotations; ref: - S=$(cargo clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} -- ${CLIPPY_FLAGS} -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; } - if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - - style_spellcheck: - name: Style/spelling - runs-on: ${{ matrix.job.os }} - strategy: - matrix: - job: - - { os: ubuntu-latest , features: feat_os_unix } - steps: - - uses: actions/checkout@v4 - - name: Initialize workflow variables - id: vars - shell: bash - run: | - ## VARs setup - outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } - # failure mode - unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in - ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; - *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; - esac; - outputs FAIL_ON_FAULT FAULT_TYPE - - name: Install/setup prerequisites - shell: bash - run: | - ## Install/setup prerequisites - # * pin installed cspell to v4.2.8 (cspell v5+ is broken for NodeJS < v12) - ## maint: [2021-11-10; rivy] `cspell` version may be advanced to v5 when used with NodeJS >= v12 - sudo apt-get -y update ; sudo apt-get -y install npm ; sudo npm install cspell@4.2.8 -g ; - - name: Run `cspell` - shell: bash - run: | - ## Run `cspell` - unset fault - fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" - fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') - # * find cspell configuration ; note: avoid quotes around ${cfg_file} b/c `cspell` (v4) doesn't correctly dequote the config argument (or perhaps a subshell expansion issue?) - cfg_files=($(shopt -s nullglob ; echo {.vscode,.}/{,.}c[sS]pell{.json,.config{.js,.cjs,.json,.yaml,.yml},.yaml,.yml} ;)) - cfg_file=${cfg_files[0]} - unset CSPELL_CFG_OPTION ; if [ -n "$cfg_file" ]; then CSPELL_CFG_OPTION="--config $cfg_file" ; fi - # * `cspell` - ## maint: [2021-11-10; rivy] the `--no-progress` option for `cspell` is a `cspell` v5+ option - # S=$(cspell ${CSPELL_CFG_OPTION} --no-summary --no-progress "**/*") && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n "s/${PWD//\//\\/}\/(.*):(.*):(.*) - (.*)/::${fault_type} file=\1,line=\2,col=\3::${fault_type^^}: \4 (file:'\1', line:\2)/p" ; fault=true ; true ; } - S=$(cspell ${CSPELL_CFG_OPTION} --no-summary "**/*") && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n "s/${PWD//\//\\/}\/(.*):(.*):(.*) - (.*)/::${fault_type} file=\1,line=\2,col=\3::${fault_type^^}: \4 (file:'\1', line:\2)/p" ; fault=true ; true ; } - if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi - doc_warnings: name: Documentation/warnings runs-on: ${{ matrix.job.os }} @@ -1081,15 +930,6 @@ jobs: name: toybox-result.json path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }} - toml_format: - runs-on: ubuntu-latest - steps: - - name: Clone repository - uses: actions/checkout@v4 - - - name: Check - run: npx --yes @taplo/cli fmt --check - coverage: name: Code Coverage runs-on: ${{ matrix.job.os }} diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml new file mode 100644 index 000000000..c67483280 --- /dev/null +++ b/.github/workflows/code-quality.yml @@ -0,0 +1,175 @@ +name: Code Quality + +# spell-checker:ignore TERMUX reactivecircus Swatinem noaudio pkill swiftshader dtolnay juliangruber + +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +# End the current execution if there is a new changeset in the PR. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} + +jobs: + + style_format: + name: Style/format + runs-on: ${{ matrix.job.os }} + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: feat_os_unix } + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: rustfmt + - uses: Swatinem/rust-cache@v2 + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } + # failure mode + unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in + ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; + *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; + esac; + outputs FAIL_ON_FAULT FAULT_TYPE + # target-specific options + # * CARGO_FEATURES_OPTION + CARGO_FEATURES_OPTION='' ; + if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features "${{ matrix.job.features }}"' ; fi + outputs CARGO_FEATURES_OPTION + - name: "`cargo fmt` testing" + shell: bash + run: | + ## `cargo fmt` testing + unset fault + fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" + fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') + # * convert any errors/warnings to GHA UI annotations; ref: + S=$(cargo fmt -- --check) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s\n" "$S" | sed -E -n -e "s/^Diff[[:space:]]+in[[:space:]]+${PWD//\//\\/}\/(.*)[[:space:]]+at[[:space:]]+[^0-9]+([0-9]+).*$/::${fault_type} file=\1,line=\2::${fault_prefix}: \`cargo fmt\`: style violation (file:'\1', line:\2; use \`cargo fmt -- \"\1\"\`)/p" ; fault=true ; } + if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi + + style_lint: + name: Style/lint + runs-on: ${{ matrix.job.os }} + env: + SCCACHE_GHA_ENABLED: "true" + RUSTC_WRAPPER: "sccache" + strategy: + fail-fast: false + matrix: + job: + - { os: ubuntu-latest , features: feat_os_unix } + - { os: macos-latest , features: feat_os_macos } + - { os: windows-latest , features: feat_os_windows } + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + components: clippy + - uses: Swatinem/rust-cache@v2 + - name: Run sccache-cache + uses: mozilla-actions/sccache-action@v0.0.3 + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } + # failure mode + unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in + ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; + *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; + esac; + outputs FAIL_ON_FAULT FAULT_TYPE + # target-specific options + # * CARGO_FEATURES_OPTION + CARGO_FEATURES_OPTION='--all-features' ; + if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features ${{ matrix.job.features }}' ; fi + outputs CARGO_FEATURES_OPTION + # * determine sub-crate utility list + UTILITY_LIST="$(./util/show-utils.sh ${CARGO_FEATURES_OPTION})" + echo UTILITY_LIST=${UTILITY_LIST} + CARGO_UTILITY_LIST_OPTIONS="$(for u in ${UTILITY_LIST}; do echo -n "-puu_${u} "; done;)" + outputs CARGO_UTILITY_LIST_OPTIONS + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + case '${{ matrix.job.os }}' in + macos-latest) brew install coreutils ;; # needed for show-utils.sh + esac + - name: "`cargo clippy` lint testing" + shell: bash + run: | + ## `cargo clippy` lint testing + unset fault + CLIPPY_FLAGS="-W clippy::default_trait_access -W clippy::manual_string_new -W clippy::cognitive_complexity" + fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" + fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') + # * convert any warnings to GHA UI annotations; ref: + S=$(cargo clippy --all-targets ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} -- ${CLIPPY_FLAGS} -D warnings 2>&1) && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n -e '/^error:/{' -e "N; s/^error:[[:space:]]+(.*)\\n[[:space:]]+-->[[:space:]]+(.*):([0-9]+):([0-9]+).*$/::${fault_type} file=\2,line=\3,col=\4::${fault_prefix}: \`cargo clippy\`: \1 (file:'\2', line:\3)/p;" -e '}' ; fault=true ; } + if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi + + style_spellcheck: + name: Style/spelling + runs-on: ${{ matrix.job.os }} + strategy: + matrix: + job: + - { os: ubuntu-latest , features: feat_os_unix } + steps: + - uses: actions/checkout@v4 + - name: Initialize workflow variables + id: vars + shell: bash + run: | + ## VARs setup + outputs() { step_id="${{ github.action }}"; for var in "$@" ; do echo steps.${step_id}.outputs.${var}="${!var}"; echo "${var}=${!var}" >> $GITHUB_OUTPUT; done; } + # failure mode + unset FAIL_ON_FAULT ; case '${{ env.STYLE_FAIL_ON_FAULT }}' in + ''|0|f|false|n|no|off) FAULT_TYPE=warning ;; + *) FAIL_ON_FAULT=true ; FAULT_TYPE=error ;; + esac; + outputs FAIL_ON_FAULT FAULT_TYPE + - name: Install/setup prerequisites + shell: bash + run: | + ## Install/setup prerequisites + # * pin installed cspell to v4.2.8 (cspell v5+ is broken for NodeJS < v12) + ## maint: [2021-11-10; rivy] `cspell` version may be advanced to v5 when used with NodeJS >= v12 + sudo apt-get -y update ; sudo apt-get -y install npm ; sudo npm install cspell@4.2.8 -g ; + - name: Run `cspell` + shell: bash + run: | + ## Run `cspell` + unset fault + fault_type="${{ steps.vars.outputs.FAULT_TYPE }}" + fault_prefix=$(echo "$fault_type" | tr '[:lower:]' '[:upper:]') + # * find cspell configuration ; note: avoid quotes around ${cfg_file} b/c `cspell` (v4) doesn't correctly dequote the config argument (or perhaps a subshell expansion issue?) + cfg_files=($(shopt -s nullglob ; echo {.vscode,.}/{,.}c[sS]pell{.json,.config{.js,.cjs,.json,.yaml,.yml},.yaml,.yml} ;)) + cfg_file=${cfg_files[0]} + unset CSPELL_CFG_OPTION ; if [ -n "$cfg_file" ]; then CSPELL_CFG_OPTION="--config $cfg_file" ; fi + # * `cspell` + ## maint: [2021-11-10; rivy] the `--no-progress` option for `cspell` is a `cspell` v5+ option + # S=$(cspell ${CSPELL_CFG_OPTION} --no-summary --no-progress "**/*") && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n "s/${PWD//\//\\/}\/(.*):(.*):(.*) - (.*)/::${fault_type} file=\1,line=\2,col=\3::${fault_type^^}: \4 (file:'\1', line:\2)/p" ; fault=true ; true ; } + S=$(cspell ${CSPELL_CFG_OPTION} --no-summary "**/*") && printf "%s\n" "$S" || { printf "%s\n" "$S" ; printf "%s" "$S" | sed -E -n "s/${PWD//\//\\/}\/(.*):(.*):(.*) - (.*)/::${fault_type} file=\1,line=\2,col=\3::${fault_type^^}: \4 (file:'\1', line:\2)/p" ; fault=true ; true ; } + if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi + + toml_format: + runs-on: ubuntu-latest + steps: + - name: Clone repository + uses: actions/checkout@v4 + + - name: Check + run: npx --yes @taplo/cli fmt --check From 02ab93c141f3b17d713276226ff1eaa555847c6c Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sun, 8 Oct 2023 17:54:36 +0200 Subject: [PATCH 29/35] github action: name the toml task --- .github/workflows/code-quality.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index c67483280..abcfd90ab 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -166,6 +166,7 @@ jobs: if [ -n "${{ steps.vars.outputs.FAIL_ON_FAULT }}" ] && [ -n "$fault" ]; then exit 1 ; fi toml_format: + name: Style/toml runs-on: ubuntu-latest steps: - name: Clone repository From 2c9e091ebee4e9d5b85ac46015d8727ae654ffdc Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 07:07:38 +0200 Subject: [PATCH 30/35] Bump errno from 0.3.1 to 0.3.5 --- Cargo.lock | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 197368abf..d4da11736 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -783,25 +783,14 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" dependencies = [ - "errno-dragonfly", "libc", "windows-sys 0.48.0", ] -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - [[package]] name = "exacl" version = "0.11.0" From 2883c0a9689ead143ae4a8b38536447939d890fd Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 15:16:50 +0200 Subject: [PATCH 31/35] uucore: remove commented out import --- src/uucore/src/lib/features/tokenize/sub.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uucore/src/lib/features/tokenize/sub.rs b/src/uucore/src/lib/features/tokenize/sub.rs index 447616ae6..c65a37a68 100644 --- a/src/uucore/src/lib/features/tokenize/sub.rs +++ b/src/uucore/src/lib/features/tokenize/sub.rs @@ -18,7 +18,6 @@ use std::iter::Peekable; use std::process::exit; use std::slice::Iter; use std::str::Chars; -// use std::collections::HashSet; use super::num_format::format_field::{FieldType, FormatField}; use super::num_format::num_format; From b38ac2cb7488e0006c5a98f87bc36b9ce07dc150 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 9 Oct 2023 15:28:12 +0200 Subject: [PATCH 32/35] uucore: remove commented out enum FChar --- .../tokenize/num_format/format_field.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/uucore/src/lib/features/tokenize/num_format/format_field.rs b/src/uucore/src/lib/features/tokenize/num_format/format_field.rs index 036ee286d..bd57b0ecd 100644 --- a/src/uucore/src/lib/features/tokenize/num_format/format_field.rs +++ b/src/uucore/src/lib/features/tokenize/num_format/format_field.rs @@ -17,23 +17,6 @@ pub enum FieldType { Charf, } -// #[allow(non_camel_case_types)] -// pub enum FChar { -// d, -// e, -// E, -// i, -// f, -// F, -// g, -// G, -// u, -// x, -// X, -// o -// } -// - // a Sub Tokens' fields are stored // as a single object so they can be more simply // passed by ref to num_format in a Sub method From d2cacdfce27adbf9c64b1cd4d72f05daf6d48f45 Mon Sep 17 00:00:00 2001 From: Howard Su Date: Mon, 9 Oct 2023 09:38:06 +0800 Subject: [PATCH 33/35] Fix overflow error on WSL. Default to 0 when the values are non-sense. --- src/uu/df/src/table.rs | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/uu/df/src/table.rs b/src/uu/df/src/table.rs index 4c3d08f45..e1f7fd82e 100644 --- a/src/uu/df/src/table.rs +++ b/src/uu/df/src/table.rs @@ -152,8 +152,10 @@ impl From for Row { ffree, .. } = fs.usage; - let bused = blocks - bfree; - let fused = files - ffree; + + // On Windows WSL, files can be less than ffree. Protect such cases via saturating_sub. + let bused = blocks.saturating_sub(bfree); + let fused = files.saturating_sub(ffree); Self { file: fs.file, fs_device: dev_name, @@ -815,4 +817,35 @@ mod tests { assert_eq!(get_formatted_values(1000, 1000, 0), vec!("1", "1", "0")); assert_eq!(get_formatted_values(1001, 1000, 1), vec!("2", "1", "1")); } + + #[test] + fn test_row_converter_with_invalid_numbers() { + // copy from wsl linux + let d = crate::Filesystem { + file: None, + mount_info: crate::MountInfo { + dev_id: "28".to_string(), + dev_name: "none".to_string(), + fs_type: "9p".to_string(), + mount_dir: "/usr/lib/wsl/drivers".to_string(), + mount_option: "ro,nosuid,nodev,noatime".to_string(), + mount_root: "/".to_string(), + remote: false, + dummy: false, + }, + usage: crate::table::FsUsage { + blocksize: 4096, + blocks: 244029695, + bfree: 125085030, + bavail: 125085030, + bavail_top_bit_set: false, + files: 999, + ffree: 1000000, + }, + }; + + let row = Row::from(d); + + assert_eq!(row.inodes_used, 0); + } } From 536dbae90aed66f2a6261e84363342a94e4f59a7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 10 Oct 2023 07:58:16 +0200 Subject: [PATCH 34/35] Bump bstr and regex bstr from 1.6 -> 1.7 regex from 1.9.6 -> 1.10.0 --- Cargo.lock | 16 ++++++++-------- Cargo.toml | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4da11736..9d43cc65d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -188,9 +188,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" dependencies = [ "memchr", "regex-automata", @@ -1728,9 +1728,9 @@ checksum = "f1bfbf25d7eb88ddcbb1ec3d755d0634da8f7657b2cb8b74089121409ab8228f" [[package]] name = "regex" -version = "1.9.6" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +checksum = "d119d7c7ca818f8a53c300863d4f87566aac09943aef5b355bb83969dae75d87" dependencies = [ "aho-corasick", "memchr", @@ -1740,9 +1740,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.9" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +checksum = "465c6fc0621e4abc4187a2bda0937bfd4f722c2730b29562e19689ea796c9a4b" dependencies = [ "aho-corasick", "memchr", @@ -1751,9 +1751,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "c3cbb081b9784b07cceb8824c8583f86db4814d172ab043f3c23f7dc600bf83d" [[package]] name = "relative-path" diff --git a/Cargo.toml b/Cargo.toml index 8eecb2b8f..df729a765 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -259,7 +259,7 @@ test = ["uu_test"] [workspace.dependencies] bigdecimal = "0.4" binary-heap-plus = "0.5.0" -bstr = "1.6" +bstr = "1.7" bytecount = "0.6.4" byteorder = "1.5.0" chrono = { version = "^0.4.31", default-features = false, features = [ @@ -309,7 +309,7 @@ rand = { version = "0.8", features = ["small_rng"] } rand_core = "0.6" rayon = "1.8" redox_syscall = "0.4" -regex = "1.9.6" +regex = "1.10.0" rstest = "0.18.2" rust-ini = "0.19.0" same-file = "1.0.6" From 95a1a08de3d44240112fc1c3e959b268cf216678 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 10 Oct 2023 09:07:32 +0200 Subject: [PATCH 35/35] Add two words to the ignore spell list --- src/uu/df/src/table.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/df/src/table.rs b/src/uu/df/src/table.rs index e1f7fd82e..f6e094204 100644 --- a/src/uu/df/src/table.rs +++ b/src/uu/df/src/table.rs @@ -2,7 +2,7 @@ // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore tmpfs Pcent Itotal Iused Iavail Ipcent +// spell-checker:ignore tmpfs Pcent Itotal Iused Iavail Ipcent nosuid nodev //! The filesystem usage data table. //! //! A table ([`Table`]) comprises a header row ([`Header`]) and a