From 117ab7737ac1aa61ef4759837ee7718ba016f860 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sat, 2 Dec 2023 17:25:57 +0000 Subject: [PATCH 01/27] Optimize expr for numerical values --- src/uu/expr/src/expr.rs | 2 +- src/uu/expr/src/syntax_tree.rs | 106 +++++++++++++++++++++------------ 2 files changed, 69 insertions(+), 39 deletions(-) diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index c271f0935..91d7a8788 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -108,7 +108,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.into_iter().map(|s| s.as_ref()).collect::>()) .unwrap_or_default(); - let res = AstNode::parse(&token_strings)?.eval()?; + let res = AstNode::parse(&token_strings)?.eval()?.to_string(); println!("{res}"); if !is_truthy(&res) { return Err(1.into()); diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index f81f1da1e..705864f3a 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -6,6 +6,7 @@ // spell-checker:ignore (ToDO) ints paren prec multibytes use num_bigint::BigInt; +use num_traits::ToPrimitive; use onig::{Regex, RegexOptions, Syntax}; use crate::{ExprError, ExprResult}; @@ -45,7 +46,7 @@ pub enum StringOp { } impl BinOp { - fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { + fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { match self { Self::Relation(op) => op.eval(left, right), Self::Numeric(op) => op.eval(left, right), @@ -55,10 +56,10 @@ impl BinOp { } impl RelationOp { - fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult { + fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult { let a = a.eval()?; let b = b.eval()?; - let b = if let (Ok(a), Ok(b)) = (a.parse::(), b.parse::()) { + let b = if let (NumOrStr::Num(a), NumOrStr::Num(b)) = (&a, &b) { match self { Self::Lt => a < b, Self::Leq => a <= b, @@ -79,24 +80,22 @@ impl RelationOp { } }; if b { - Ok("1".into()) + Ok(NumOrStr::Num(BigInt::from(1))) } else { - Ok("0".into()) + Ok(NumOrStr::Num(BigInt::from(0))) } } } impl NumericOp { - fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { + fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { let a: BigInt = left .eval()? - .parse() - .map_err(|_| ExprError::NonIntegerArgument)?; + .to_bigint()?; let b: BigInt = right .eval()? - .parse() - .map_err(|_| ExprError::NonIntegerArgument)?; - Ok(match self { + .to_bigint()?; + Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, Self::Mul => a * b, @@ -110,67 +109,66 @@ impl NumericOp { }; a % b } - } - .to_string()) + })) } } impl StringOp { - fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { + fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { match self { Self::Or => { let left = left.eval()?; - if is_truthy(&left) { + if is_truthy(&left.to_string()) { return Ok(left); } let right = right.eval()?; - if is_truthy(&right) { + if is_truthy(&right.to_string()) { return Ok(right); } - Ok("0".into()) + Ok(NumOrStr::Num(BigInt::from(0))) } Self::And => { let left = left.eval()?; - if !is_truthy(&left) { - return Ok("0".into()); + if !is_truthy(&left.to_string()) { + return Ok(NumOrStr::Num(BigInt::from(0))); } let right = right.eval()?; - if !is_truthy(&right) { - return Ok("0".into()); + if !is_truthy(&right.to_string()) { + return Ok(NumOrStr::Num(BigInt::from(0))); } Ok(left) } Self::Match => { let left = left.eval()?; let right = right.eval()?; - let re_string = format!("^{}", &right); + let re_string = format!("^{}", right.to_string()); let re = Regex::with_options( &re_string, RegexOptions::REGEX_OPTION_NONE, Syntax::grep(), ) .map_err(|_| ExprError::InvalidRegexExpression)?; - Ok(if re.captures_len() > 0 { - re.captures(&left) + Ok(NumOrStr::Str(if re.captures_len() > 0 { + re.captures(&left.to_string()) .map(|captures| captures.at(1).unwrap()) .unwrap_or("") .to_string() } else { - re.find(&left) + re.find(&left.to_string()) .map_or("0".to_string(), |(start, end)| (end - start).to_string()) - }) + })) } Self::Index => { let left = left.eval()?; let right = right.eval()?; - for (current_idx, ch_h) in left.chars().enumerate() { - for ch_n in right.chars() { + for (current_idx, ch_h) in left.to_string().chars().enumerate() { + for ch_n in right.to_string().chars() { if ch_n == ch_h { - return Ok((current_idx + 1).to_string()); + return Ok(NumOrStr::Num(BigInt::from(current_idx + 1))); } } } - Ok("0".to_string()) + Ok(NumOrStr::Num(BigInt::from(0))) } } } @@ -200,6 +198,38 @@ const PRECEDENCE: &[&[(&str, BinOp)]] = &[ &[(":", BinOp::String(StringOp::Match))], ]; +#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)] +pub enum NumOrStr { + Num(BigInt), + Str(String), +} + +impl NumOrStr { + pub fn to_usize(self: NumOrStr) -> Option { + match self.to_bigint() { + Ok(num) => {num.to_usize()} + Err(_) => {None}, + } + } + + pub fn to_string(self: &NumOrStr) -> String { + match self { + NumOrStr::Num(num) => {num.to_string()} + NumOrStr::Str(str) => {str.to_string()}, + } + } + + pub fn to_bigint(self: NumOrStr) -> ExprResult { + match self { + NumOrStr::Num(num) => {Ok(num)} + NumOrStr::Str(str) => { match str.parse::() { + Ok(val) => {Ok(val)}, + Err(_) => {Err(ExprError::NonIntegerArgument)} + }}, + } + } +} + #[derive(Debug, PartialEq, Eq)] pub enum AstNode { Leaf { @@ -225,9 +255,9 @@ impl AstNode { Parser::new(input).parse() } - pub fn eval(&self) -> ExprResult { + pub fn eval(&self) -> ExprResult { match self { - Self::Leaf { value } => Ok(value.into()), + Self::Leaf { value } => Ok(NumOrStr::Str(value.to_string())), Self::BinOp { op_type, left, @@ -238,7 +268,7 @@ impl AstNode { pos, length, } => { - let string = string.eval()?; + let string = string.eval()?.to_string(); // The GNU docs say: // @@ -247,16 +277,16 @@ impl AstNode { // // So we coerce errors into 0 to make that the only case we // have to care about. - let pos: usize = pos.eval()?.parse().unwrap_or(0); - let length: usize = length.eval()?.parse().unwrap_or(0); + let pos: usize = pos.eval()?.to_usize().unwrap_or(0); + let length: usize = length.eval()?.to_usize().unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { - return Ok(String::new()); + return Ok(NumOrStr::Str(String::new())); }; - Ok(string.chars().skip(pos).take(length).collect()) + Ok(NumOrStr::Str(string.chars().skip(pos).take(length).collect())) } - Self::Length { string } => Ok(string.eval()?.chars().count().to_string()), + Self::Length { string } => Ok(NumOrStr::Num(BigInt::from(string.eval()?.to_string().chars().count()))), } } } From d8a64a90ece80fc029860f66d7bf8858c79f9e91 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sun, 3 Dec 2023 15:09:12 +0000 Subject: [PATCH 02/27] Formatting fixes in expr --- src/uu/expr/src/syntax_tree.rs | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 705864f3a..1c74b9710 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -89,12 +89,8 @@ impl RelationOp { impl NumericOp { fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { - let a: BigInt = left - .eval()? - .to_bigint()?; - let b: BigInt = right - .eval()? - .to_bigint()?; + let a: BigInt = left.eval()?.to_bigint()?; + let b: BigInt = right.eval()?.to_bigint()?; Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, @@ -207,25 +203,25 @@ pub enum NumOrStr { impl NumOrStr { pub fn to_usize(self: NumOrStr) -> Option { match self.to_bigint() { - Ok(num) => {num.to_usize()} - Err(_) => {None}, + Ok(num) => num.to_usize(), + Err(_) => None, } } pub fn to_string(self: &NumOrStr) -> String { match self { - NumOrStr::Num(num) => {num.to_string()} - NumOrStr::Str(str) => {str.to_string()}, + NumOrStr::Num(num) => num.to_string(), + NumOrStr::Str(str) => str.to_string(), } } pub fn to_bigint(self: NumOrStr) -> ExprResult { match self { - NumOrStr::Num(num) => {Ok(num)} - NumOrStr::Str(str) => { match str.parse::() { - Ok(val) => {Ok(val)}, - Err(_) => {Err(ExprError::NonIntegerArgument)} - }}, + NumOrStr::Num(num) => Ok(num), + NumOrStr::Str(str) => match str.parse::() { + Ok(val) => Ok(val), + Err(_) => Err(ExprError::NonIntegerArgument), + }, } } } @@ -284,9 +280,13 @@ impl AstNode { return Ok(NumOrStr::Str(String::new())); }; - Ok(NumOrStr::Str(string.chars().skip(pos).take(length).collect())) + Ok(NumOrStr::Str( + string.chars().skip(pos).take(length).collect(), + )) } - Self::Length { string } => Ok(NumOrStr::Num(BigInt::from(string.eval()?.to_string().chars().count()))), + Self::Length { string } => Ok(NumOrStr::Num(BigInt::from( + string.eval()?.to_string().chars().count(), + ))), } } } From f8573d555133f22cfdfbfa198a265138277d3f36 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sun, 3 Dec 2023 20:03:50 +0000 Subject: [PATCH 03/27] code and styling fixes in expr --- src/uu/expr/src/expr.rs | 4 +- src/uu/expr/src/syntax_tree.rs | 130 ++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 51 deletions(-) diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index 91d7a8788..b46034f84 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -13,7 +13,7 @@ use uucore::{ format_usage, help_about, help_section, help_usage, }; -use crate::syntax_tree::is_truthy; +use crate::syntax_tree::{is_truthy, NumOrStr}; mod syntax_tree; @@ -110,7 +110,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let res = AstNode::parse(&token_strings)?.eval()?.to_string(); println!("{res}"); - if !is_truthy(&res) { + if !is_truthy(&NumOrStr::from(res)) { return Err(1.into()); } Ok(()) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 1c74b9710..79ba8d9ae 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -57,8 +57,8 @@ impl BinOp { impl RelationOp { fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult { - let a = a.eval()?; - let b = b.eval()?; + let a = a.eval()?.coerce_num(); + let b = b.eval()?.coerce_num(); let b = if let (NumOrStr::Num(a), NumOrStr::Num(b)) = (&a, &b) { match self { Self::Lt => a < b, @@ -80,17 +80,17 @@ impl RelationOp { } }; if b { - Ok(NumOrStr::Num(BigInt::from(1))) + Ok(NumOrStr::from(1)) } else { - Ok(NumOrStr::Num(BigInt::from(0))) + Ok(NumOrStr::from(0)) } } } impl NumericOp { fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { - let a: BigInt = left.eval()?.to_bigint()?; - let b: BigInt = right.eval()?.to_bigint()?; + let a = left.eval()?.to_bigint()?; + let b = right.eval()?.to_bigint()?; Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, @@ -114,23 +114,23 @@ impl StringOp { match self { Self::Or => { let left = left.eval()?; - if is_truthy(&left.to_string()) { + if is_truthy(&left) { return Ok(left); } let right = right.eval()?; - if is_truthy(&right.to_string()) { + if is_truthy(&right) { return Ok(right); } - Ok(NumOrStr::Num(BigInt::from(0))) + Ok(NumOrStr::from(0)) } Self::And => { let left = left.eval()?; - if !is_truthy(&left.to_string()) { - return Ok(NumOrStr::Num(BigInt::from(0))); + if !is_truthy(&left) { + return Ok(NumOrStr::from(0)); } let right = right.eval()?; - if !is_truthy(&right.to_string()) { - return Ok(NumOrStr::Num(BigInt::from(0))); + if !is_truthy(&right) { + return Ok(NumOrStr::from(0)); } Ok(left) } @@ -144,7 +144,7 @@ impl StringOp { Syntax::grep(), ) .map_err(|_| ExprError::InvalidRegexExpression)?; - Ok(NumOrStr::Str(if re.captures_len() > 0 { + Ok(NumOrStr::from(if re.captures_len() > 0 { re.captures(&left.to_string()) .map(|captures| captures.at(1).unwrap()) .unwrap_or("") @@ -155,16 +155,16 @@ impl StringOp { })) } Self::Index => { - let left = left.eval()?; - let right = right.eval()?; - for (current_idx, ch_h) in left.to_string().chars().enumerate() { + let left = left.eval()?.to_string(); + let right = right.eval()?.to_string(); + for (current_idx, ch_h) in left.chars().enumerate() { for ch_n in right.to_string().chars() { if ch_n == ch_h { - return Ok(NumOrStr::Num(BigInt::from(current_idx + 1))); + return Ok(NumOrStr::from(current_idx + 1)); } } } - Ok(NumOrStr::Num(BigInt::from(0))) + Ok(NumOrStr::from(0)) } } } @@ -200,27 +200,54 @@ pub enum NumOrStr { Str(String), } +impl From for NumOrStr { + fn from(num: usize) -> NumOrStr { + NumOrStr::Num(BigInt::from(num)) + } +} + +impl From for NumOrStr { + fn from(num: BigInt) -> NumOrStr { + NumOrStr::Num(num) + } +} + +impl From for NumOrStr { + fn from(str: String) -> NumOrStr { + NumOrStr::Str(str) + } +} + impl NumOrStr { - pub fn to_usize(self: NumOrStr) -> Option { + pub fn to_usize(self: Self) -> Option { match self.to_bigint() { Ok(num) => num.to_usize(), Err(_) => None, } } - pub fn to_string(self: &NumOrStr) -> String { + pub fn to_string(self: Self) -> String { match self { - NumOrStr::Num(num) => num.to_string(), - NumOrStr::Str(str) => str.to_string(), + Self::Num(num) => num.to_string(), + Self::Str(str) => str.to_string(), } } - pub fn to_bigint(self: NumOrStr) -> ExprResult { + pub fn to_bigint(self: Self) -> ExprResult { match self { - NumOrStr::Num(num) => Ok(num), - NumOrStr::Str(str) => match str.parse::() { - Ok(val) => Ok(val), - Err(_) => Err(ExprError::NonIntegerArgument), + Self::Num(num) => Ok(num), + Self::Str(str) => str + .parse::() + .map_err(|_| ExprError::NonIntegerArgument), + } + } + + pub fn coerce_num(self: Self) -> NumOrStr { + match self { + Self::Num(num) => Self::from(num), + Self::Str(str) => match str.parse::() { + Ok(num) => Self::from(num), + Err(_) => Self::from(str), }, } } @@ -253,7 +280,7 @@ impl AstNode { pub fn eval(&self) -> ExprResult { match self { - Self::Leaf { value } => Ok(NumOrStr::Str(value.to_string())), + Self::Leaf { value } => Ok(NumOrStr::from(value.to_string())), Self::BinOp { op_type, left, @@ -277,16 +304,16 @@ impl AstNode { let length: usize = length.eval()?.to_usize().unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { - return Ok(NumOrStr::Str(String::new())); + return Ok(NumOrStr::from(String::new())); }; - Ok(NumOrStr::Str( - string.chars().skip(pos).take(length).collect(), + Ok(NumOrStr::from( + string.chars().skip(pos).take(length).collect::(), )) } - Self::Length { string } => Ok(NumOrStr::Num(BigInt::from( - string.eval()?.to_string().chars().count(), - ))), + Self::Length { string } => { + Ok(NumOrStr::from(string.eval()?.to_string().chars().count())) + } } } } @@ -429,21 +456,26 @@ impl<'a> Parser<'a> { /// Determine whether `expr` should evaluate the string as "truthy" /// /// Truthy strings are either empty or match the regex "-?0+". -pub fn is_truthy(s: &str) -> bool { - // Edge case: `-` followed by nothing is truthy - if s == "-" { - return true; +pub fn is_truthy(s: &NumOrStr) -> bool { + match s { + NumOrStr::Num(num) => num == &BigInt::from(0), + NumOrStr::Str(str) => { + // Edge case: `-` followed by nothing is truthy + if str == "-" { + return true; + } + + let mut bytes = str.bytes(); + + // Empty string is falsy + let Some(first) = bytes.next() else { + return false; + }; + + let is_zero = (first == b'-' || first == b'0') && bytes.all(|b| b == b'0'); + !is_zero + } } - - let mut bytes = s.bytes(); - - // Empty string is falsy - let Some(first) = bytes.next() else { - return false; - }; - - let is_zero = (first == b'-' || first == b'0') && bytes.all(|b| b == b'0'); - !is_zero } #[cfg(test)] From 5672e3d9bdec3acc1d1ab22b0217b5fac17ab10b Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sun, 3 Dec 2023 22:07:56 +0000 Subject: [PATCH 04/27] Fix errors --- src/uu/expr/src/syntax_tree.rs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 79ba8d9ae..a4cb99a83 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -5,7 +5,7 @@ // spell-checker:ignore (ToDO) ints paren prec multibytes -use num_bigint::BigInt; +use num_bigint::{BigInt, ParseBigIntError}; use num_traits::ToPrimitive; use onig::{Regex, RegexOptions, Syntax}; @@ -57,9 +57,9 @@ impl BinOp { impl RelationOp { fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult { - let a = a.eval()?.coerce_num(); - let b = b.eval()?.coerce_num(); - let b = if let (NumOrStr::Num(a), NumOrStr::Num(b)) = (&a, &b) { + let a = a.eval()?; + let b = b.eval()?; + let b = if let (Ok(a), Ok(b)) = (&a.coerce_bigint(), &b.coerce_bigint()) { match self { Self::Lt => a < b, Self::Leq => a <= b, @@ -242,13 +242,10 @@ impl NumOrStr { } } - pub fn coerce_num(self: Self) -> NumOrStr { + pub fn coerce_bigint(self: &Self) -> Result { match self { - Self::Num(num) => Self::from(num), - Self::Str(str) => match str.parse::() { - Ok(num) => Self::from(num), - Err(_) => Self::from(str), - }, + Self::Num(num) => Ok(num.clone()), + Self::Str(str) => str.parse::(), } } } @@ -458,7 +455,7 @@ impl<'a> Parser<'a> { /// Truthy strings are either empty or match the regex "-?0+". pub fn is_truthy(s: &NumOrStr) -> bool { match s { - NumOrStr::Num(num) => num == &BigInt::from(0), + NumOrStr::Num(num) => num != &BigInt::from(0), NumOrStr::Str(str) => { // Edge case: `-` followed by nothing is truthy if str == "-" { From 21c041fa79b64d9f55b8672c4a74e22dd941fd96 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sun, 3 Dec 2023 22:27:13 +0000 Subject: [PATCH 05/27] Fix lint issues in expr --- src/uu/expr/src/syntax_tree.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index a4cb99a83..4f447e60f 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -201,39 +201,39 @@ pub enum NumOrStr { } impl From for NumOrStr { - fn from(num: usize) -> NumOrStr { - NumOrStr::Num(BigInt::from(num)) + fn from(num: usize) -> Self { + Self::Num(BigInt::from(num)) } } impl From for NumOrStr { - fn from(num: BigInt) -> NumOrStr { - NumOrStr::Num(num) + fn from(num: BigInt) -> Self { + Self::Num(num) } } impl From for NumOrStr { - fn from(str: String) -> NumOrStr { - NumOrStr::Str(str) + fn from(str: String) -> Self { + Self::Str(str) } } impl NumOrStr { - pub fn to_usize(self: Self) -> Option { + pub fn to_usize(self) -> Option { match self.to_bigint() { Ok(num) => num.to_usize(), Err(_) => None, } } - pub fn to_string(self: Self) -> String { + pub fn to_string(self) -> String { match self { Self::Num(num) => num.to_string(), Self::Str(str) => str.to_string(), } } - pub fn to_bigint(self: Self) -> ExprResult { + pub fn to_bigint(self) -> ExprResult { match self { Self::Num(num) => Ok(num), Self::Str(str) => str @@ -242,7 +242,7 @@ impl NumOrStr { } } - pub fn coerce_bigint(self: &Self) -> Result { + pub fn coerce_bigint(&self) -> Result { match self { Self::Num(num) => Ok(num.clone()), Self::Str(str) => str.parse::(), From 9ecd6a296e06b6f20a5bc29f876a546cdafd020d Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Sun, 3 Dec 2023 23:32:51 +0000 Subject: [PATCH 06/27] Refactoring for lint issues --- src/uu/expr/src/expr.rs | 2 +- src/uu/expr/src/syntax_tree.rs | 53 ++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index b46034f84..1a9bb07de 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -108,7 +108,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.into_iter().map(|s| s.as_ref()).collect::>()) .unwrap_or_default(); - let res = AstNode::parse(&token_strings)?.eval()?.to_string(); + let res: String = AstNode::parse(&token_strings)?.eval()?.into(); println!("{res}"); if !is_truthy(&NumOrStr::from(res)) { return Err(1.into()); diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 4f447e60f..7677b5e7e 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -59,7 +59,7 @@ impl RelationOp { fn eval(&self, a: &AstNode, b: &AstNode) -> ExprResult { let a = a.eval()?; let b = b.eval()?; - let b = if let (Ok(a), Ok(b)) = (&a.coerce_bigint(), &b.coerce_bigint()) { + let b = if let (Ok(a), Ok(b)) = (&a.to_bigint(), &b.to_bigint()) { match self { Self::Lt => a < b, Self::Leq => a <= b, @@ -89,8 +89,8 @@ impl RelationOp { impl NumericOp { fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { - let a = left.eval()?.to_bigint()?; - let b = right.eval()?.to_bigint()?; + let a = >>::into(left.eval()?)?; + let b = >>::into(right.eval()?)?; Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, @@ -135,9 +135,9 @@ impl StringOp { Ok(left) } Self::Match => { - let left = left.eval()?; - let right = right.eval()?; - let re_string = format!("^{}", right.to_string()); + let left: String = left.eval()?.into(); + let right: String = right.eval()?.into(); + let re_string = format!("^{}", right); let re = Regex::with_options( &re_string, RegexOptions::REGEX_OPTION_NONE, @@ -145,18 +145,18 @@ impl StringOp { ) .map_err(|_| ExprError::InvalidRegexExpression)?; Ok(NumOrStr::from(if re.captures_len() > 0 { - re.captures(&left.to_string()) + re.captures(&left) .map(|captures| captures.at(1).unwrap()) .unwrap_or("") .to_string() } else { - re.find(&left.to_string()) + re.find(&left) .map_or("0".to_string(), |(start, end)| (end - start).to_string()) })) } Self::Index => { - let left = left.eval()?.to_string(); - let right = right.eval()?.to_string(); + let left: String = left.eval()?.into(); + let right: String = right.eval()?.into(); for (current_idx, ch_h) in left.chars().enumerate() { for ch_n in right.to_string().chars() { if ch_n == ch_h { @@ -218,22 +218,26 @@ impl From for NumOrStr { } } -impl NumOrStr { - pub fn to_usize(self) -> Option { - match self.to_bigint() { +impl Into> for NumOrStr { + fn into(self) -> Option { + match self.into() { Ok(num) => num.to_usize(), Err(_) => None, } } +} - pub fn to_string(self) -> String { +impl Into for NumOrStr { + fn into(self) -> String { match self { Self::Num(num) => num.to_string(), Self::Str(str) => str.to_string(), } } +} - pub fn to_bigint(self) -> ExprResult { +impl Into> for NumOrStr { + fn into(self) -> ExprResult { match self { Self::Num(num) => Ok(num), Self::Str(str) => str @@ -241,8 +245,10 @@ impl NumOrStr { .map_err(|_| ExprError::NonIntegerArgument), } } +} - pub fn coerce_bigint(&self) -> Result { +impl NumOrStr { + pub fn to_bigint(&self) -> Result { match self { Self::Num(num) => Ok(num.clone()), Self::Str(str) => str.parse::(), @@ -288,7 +294,7 @@ impl AstNode { pos, length, } => { - let string = string.eval()?.to_string(); + let string: String = string.eval()?.into(); // The GNU docs say: // @@ -297,8 +303,9 @@ impl AstNode { // // So we coerce errors into 0 to make that the only case we // have to care about. - let pos: usize = pos.eval()?.to_usize().unwrap_or(0); - let length: usize = length.eval()?.to_usize().unwrap_or(0); + let pos: usize = >>::into(pos.eval()?).unwrap_or(0); + let length: usize = + >>::into(length.eval()?).unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { return Ok(NumOrStr::from(String::new())); @@ -308,9 +315,11 @@ impl AstNode { string.chars().skip(pos).take(length).collect::(), )) } - Self::Length { string } => { - Ok(NumOrStr::from(string.eval()?.to_string().chars().count())) - } + Self::Length { string } => Ok(NumOrStr::from( + >::into(string.eval()?) + .chars() + .count(), + )), } } } From 4d2ae8485cd65429e64606119acac3156158ea2b Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Mon, 4 Dec 2023 22:44:18 +0000 Subject: [PATCH 07/27] impl from trait instead of into --- src/uu/expr/src/syntax_tree.rs | 43 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 7677b5e7e..ae2a44e52 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -89,8 +89,8 @@ impl RelationOp { impl NumericOp { fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { - let a = >>::into(left.eval()?)?; - let b = >>::into(right.eval()?)?; + let a = ExprResult::::from(left.eval()?)?; + let b = ExprResult::::from(right.eval()?)?; Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, @@ -218,29 +218,29 @@ impl From for NumOrStr { } } -impl Into> for NumOrStr { - fn into(self) -> Option { - match self.into() { +impl From for Option { + fn from(s: NumOrStr) -> Self { + match s.into() { Ok(num) => num.to_usize(), Err(_) => None, } } } -impl Into for NumOrStr { - fn into(self) -> String { - match self { - Self::Num(num) => num.to_string(), - Self::Str(str) => str.to_string(), +impl From for String { + fn from(s: NumOrStr) -> Self { + match s { + NumOrStr::Num(num) => num.to_string(), + NumOrStr::Str(str) => str.to_string(), } } } -impl Into> for NumOrStr { - fn into(self) -> ExprResult { - match self { - Self::Num(num) => Ok(num), - Self::Str(str) => str +impl From for ExprResult { + fn from(s: NumOrStr) -> Self { + match s { + NumOrStr::Num(num) => Ok(num), + NumOrStr::Str(str) => str .parse::() .map_err(|_| ExprError::NonIntegerArgument), } @@ -303,9 +303,8 @@ impl AstNode { // // So we coerce errors into 0 to make that the only case we // have to care about. - let pos: usize = >>::into(pos.eval()?).unwrap_or(0); - let length: usize = - >>::into(length.eval()?).unwrap_or(0); + let pos: usize = Option::::from(pos.eval()?).unwrap_or(0); + let length: usize = Option::::from(length.eval()?).unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { return Ok(NumOrStr::from(String::new())); @@ -315,11 +314,9 @@ impl AstNode { string.chars().skip(pos).take(length).collect::(), )) } - Self::Length { string } => Ok(NumOrStr::from( - >::into(string.eval()?) - .chars() - .count(), - )), + Self::Length { string } => { + Ok(NumOrStr::from(String::from(string.eval()?).chars().count())) + } } } } From fa0c64ddde2d08103c8e682815ec9f5924a716a5 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Mon, 11 Dec 2023 02:05:55 +0000 Subject: [PATCH 08/27] review fixes --- src/uu/expr/src/expr.rs | 6 +-- src/uu/expr/src/syntax_tree.rs | 88 +++++++++++++++++----------------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index 1a9bb07de..6adedd9ec 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -13,7 +13,7 @@ use uucore::{ format_usage, help_about, help_section, help_usage, }; -use crate::syntax_tree::{is_truthy, NumOrStr}; +use crate::syntax_tree::is_truthy; mod syntax_tree; @@ -108,9 +108,9 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { .map(|v| v.into_iter().map(|s| s.as_ref()).collect::>()) .unwrap_or_default(); - let res: String = AstNode::parse(&token_strings)?.eval()?.into(); + let res: String = AstNode::parse(&token_strings)?.eval()?.eval_as_string(); println!("{res}"); - if !is_truthy(&NumOrStr::from(res)) { + if !is_truthy(&res.into()) { return Err(1.into()); } Ok(()) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index ae2a44e52..4514b2a67 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -80,17 +80,17 @@ impl RelationOp { } }; if b { - Ok(NumOrStr::from(1)) + Ok(1.into()) } else { - Ok(NumOrStr::from(0)) + Ok(0.into()) } } } impl NumericOp { fn eval(&self, left: &AstNode, right: &AstNode) -> ExprResult { - let a = ExprResult::::from(left.eval()?)?; - let b = ExprResult::::from(right.eval()?)?; + let a = left.eval()?.eval_as_bigint()?; + let b = right.eval()?.eval_as_bigint()?; Ok(NumOrStr::Num(match self { Self::Add => a + b, Self::Sub => a - b, @@ -121,22 +121,22 @@ impl StringOp { if is_truthy(&right) { return Ok(right); } - Ok(NumOrStr::from(0)) + Ok(0.into()) } Self::And => { let left = left.eval()?; if !is_truthy(&left) { - return Ok(NumOrStr::from(0)); + return Ok(0.into()); } let right = right.eval()?; if !is_truthy(&right) { - return Ok(NumOrStr::from(0)); + return Ok(0.into()); } Ok(left) } Self::Match => { - let left: String = left.eval()?.into(); - let right: String = right.eval()?.into(); + let left = left.eval()?.eval_as_string(); + let right = right.eval()?.eval_as_string(); let re_string = format!("^{}", right); let re = Regex::with_options( &re_string, @@ -144,7 +144,7 @@ impl StringOp { Syntax::grep(), ) .map_err(|_| ExprError::InvalidRegexExpression)?; - Ok(NumOrStr::from(if re.captures_len() > 0 { + Ok(if re.captures_len() > 0 { re.captures(&left) .map(|captures| captures.at(1).unwrap()) .unwrap_or("") @@ -152,19 +152,20 @@ impl StringOp { } else { re.find(&left) .map_or("0".to_string(), |(start, end)| (end - start).to_string()) - })) + } + .into()) } Self::Index => { - let left: String = left.eval()?.into(); - let right: String = right.eval()?.into(); + let left = left.eval()?.eval_as_string(); + let right = right.eval()?.eval_as_string(); for (current_idx, ch_h) in left.chars().enumerate() { for ch_n in right.to_string().chars() { if ch_n == ch_h { - return Ok(NumOrStr::from(current_idx + 1)); + return Ok((current_idx + 1).into()); } } } - Ok(NumOrStr::from(0)) + Ok(0.into()) } } } @@ -220,33 +221,13 @@ impl From for NumOrStr { impl From for Option { fn from(s: NumOrStr) -> Self { - match s.into() { + match s.eval_as_bigint() { Ok(num) => num.to_usize(), Err(_) => None, } } } -impl From for String { - fn from(s: NumOrStr) -> Self { - match s { - NumOrStr::Num(num) => num.to_string(), - NumOrStr::Str(str) => str.to_string(), - } - } -} - -impl From for ExprResult { - fn from(s: NumOrStr) -> Self { - match s { - NumOrStr::Num(num) => Ok(num), - NumOrStr::Str(str) => str - .parse::() - .map_err(|_| ExprError::NonIntegerArgument), - } - } -} - impl NumOrStr { pub fn to_bigint(&self) -> Result { match self { @@ -254,6 +235,22 @@ impl NumOrStr { Self::Str(str) => str.parse::(), } } + + pub fn eval_as_bigint(self) -> ExprResult { + match self { + NumOrStr::Num(num) => Ok(num), + NumOrStr::Str(str) => str + .parse::() + .map_err(|_| ExprError::NonIntegerArgument), + } + } + + pub fn eval_as_string(self) -> String { + match self { + NumOrStr::Num(num) => num.to_string(), + NumOrStr::Str(str) => str, + } + } } #[derive(Debug, PartialEq, Eq)] @@ -283,7 +280,7 @@ impl AstNode { pub fn eval(&self) -> ExprResult { match self { - Self::Leaf { value } => Ok(NumOrStr::from(value.to_string())), + Self::Leaf { value } => Ok(value.to_string().into()), Self::BinOp { op_type, left, @@ -294,7 +291,7 @@ impl AstNode { pos, length, } => { - let string: String = string.eval()?.into(); + let string: String = string.eval()?.eval_as_string(); // The GNU docs say: // @@ -307,16 +304,17 @@ impl AstNode { let length: usize = Option::::from(length.eval()?).unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { - return Ok(NumOrStr::from(String::new())); + return Ok(String::new().into()); }; - Ok(NumOrStr::from( - string.chars().skip(pos).take(length).collect::(), - )) - } - Self::Length { string } => { - Ok(NumOrStr::from(String::from(string.eval()?).chars().count())) + Ok(string + .chars() + .skip(pos) + .take(length) + .collect::() + .into()) } + Self::Length { string } => Ok(string.eval()?.eval_as_string().chars().count().into()), } } } From 824371d8841f1652de5a8b4d865a175af2a91d5b Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Mon, 11 Dec 2023 02:12:24 +0000 Subject: [PATCH 09/27] style lint fixes --- src/uu/expr/src/syntax_tree.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 4514b2a67..820911cd3 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -238,8 +238,8 @@ impl NumOrStr { pub fn eval_as_bigint(self) -> ExprResult { match self { - NumOrStr::Num(num) => Ok(num), - NumOrStr::Str(str) => str + Self::Num(num) => Ok(num), + Self::Str(str) => str .parse::() .map_err(|_| ExprError::NonIntegerArgument), } @@ -247,8 +247,8 @@ impl NumOrStr { pub fn eval_as_string(self) -> String { match self { - NumOrStr::Num(num) => num.to_string(), - NumOrStr::Str(str) => str, + Self::Num(num) => num.to_string(), + Self::Str(str) => str, } } } From 2faab59aa4abce17e04158fc2a74e1daf8f8d9f1 Mon Sep 17 00:00:00 2001 From: Laurent Cheylus Date: Mon, 11 Dec 2023 12:45:16 +0100 Subject: [PATCH 10/27] tests/hostname: disable failing test_hostname::test_hostname_ip on OpenBSD - On OpenBSD, test_hostname::test_hostname_ip fails with "failed to lookup address information: Name does not resolve" error Signed-off-by: Laurent Cheylus --- tests/by-util/test_hostname.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/by-util/test_hostname.rs b/tests/by-util/test_hostname.rs index 84cb73e2e..972ec4aab 100644 --- a/tests/by-util/test_hostname.rs +++ b/tests/by-util/test_hostname.rs @@ -14,8 +14,8 @@ fn test_hostname() { assert!(ls_default_res.stdout().len() >= ls_domain_res.stdout().len()); } -// FixME: fails for "MacOS" and "freebsd" "failed to lookup address information: Name does not resolve" -#[cfg(not(any(target_os = "macos", target_os = "freebsd")))] +// FixME: fails for "MacOS", "freebsd" and "openbsd" "failed to lookup address information: Name does not resolve" +#[cfg(not(any(target_os = "macos", target_os = "freebsd", target_os = "openbsd")))] #[test] fn test_hostname_ip() { let result = new_ucmd!().arg("-i").succeeds(); From 6711dd569480c63ed1c6acb9de59b360a665a84c Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 11 Dec 2023 16:38:55 +0100 Subject: [PATCH 11/27] ls: make --block-size and --human-readable/--si override each other --- src/uu/ls/src/ls.rs | 6 +++-- tests/by-util/test_ls.rs | 50 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index a5fe3d624..2aa4bad06 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1552,7 +1552,7 @@ pub fn uu_app() -> Command { .short('h') .long(options::size::HUMAN_READABLE) .help("Print human readable file sizes (e.g. 1K 234M 56G).") - .overrides_with(options::size::SI) + .overrides_with_all([options::size::BLOCK_SIZE, options::size::SI]) .action(ArgAction::SetTrue), ) .arg( @@ -1569,6 +1569,7 @@ pub fn uu_app() -> Command { Arg::new(options::size::SI) .long(options::size::SI) .help("Print human readable file sizes using powers of 1000 instead of 1024.") + .overrides_with_all([options::size::BLOCK_SIZE, options::size::HUMAN_READABLE]) .action(ArgAction::SetTrue), ) .arg( @@ -1576,7 +1577,8 @@ pub fn uu_app() -> Command { .long(options::size::BLOCK_SIZE) .require_equals(true) .value_name("BLOCK_SIZE") - .help("scale sizes by BLOCK_SIZE when printing them"), + .help("scale sizes by BLOCK_SIZE when printing them") + .overrides_with_all([options::size::SI, options::size::HUMAN_READABLE]), ) .arg( Arg::new(options::INODE) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index c9f43028c..179941e78 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3874,6 +3874,56 @@ fn test_ls_invalid_block_size() { .stderr_is("ls: invalid --block-size argument 'invalid'\n"); } +#[cfg(all(unix, feature = "dd"))] +#[test] +fn test_ls_block_size_override() { + let scene = TestScenario::new(util_name!()); + + scene + .ccmd("dd") + .arg("if=/dev/zero") + .arg("of=file") + .arg("bs=1024") + .arg("count=1") + .succeeds(); + + // --si "wins" + scene + .ucmd() + .arg("-s") + .arg("--block-size=512") + .arg("--si") + .succeeds() + .stdout_contains_line("total 4.1k"); + + // --block-size "wins" + scene + .ucmd() + .arg("-s") + .arg("--si") + .arg("--block-size=512") + .succeeds() + .stdout_contains_line("total 8"); + + // --human-readable "wins" + scene + .ucmd() + .arg("-s") + .arg("--block-size=512") + .arg("--human-readable") + .succeeds() + .stdout_contains_line("total 4.0K"); + + // --block-size "wins" + scene + .ucmd() + .arg("-s") + .arg("--human-readable") + .arg("--block-size=512") + .succeeds() + .stdout_contains_line("total 8"); +} + #[test] fn test_ls_hyperlink() { let scene = TestScenario::new(util_name!()); From 3bf966df56a435a99e05e8802a85be16f42bf100 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Mon, 11 Dec 2023 20:47:36 +0000 Subject: [PATCH 12/27] remove from trait for NumOrStr --- src/uu/expr/src/syntax_tree.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 820911cd3..7817b1721 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -219,15 +219,6 @@ impl From for NumOrStr { } } -impl From for Option { - fn from(s: NumOrStr) -> Self { - match s.eval_as_bigint() { - Ok(num) => num.to_usize(), - Err(_) => None, - } - } -} - impl NumOrStr { pub fn to_bigint(&self) -> Result { match self { @@ -300,8 +291,16 @@ impl AstNode { // // So we coerce errors into 0 to make that the only case we // have to care about. - let pos: usize = Option::::from(pos.eval()?).unwrap_or(0); - let length: usize = Option::::from(length.eval()?).unwrap_or(0); + let pos = pos + .eval()? + .eval_as_bigint() + .map_or(0.into(), |n| n.to_usize()) + .unwrap_or(0); + let length = length + .eval()? + .eval_as_bigint() + .map_or(0.into(), |n| n.to_usize()) + .unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { return Ok(String::new().into()); From 1919b3ba1702f9836fb38bc2490b418981e4faae Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 11 Dec 2023 10:08:02 -0700 Subject: [PATCH 13/27] Add Redox OS CI --- .github/workflows/CICD.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 8c96ce693..f52ead1f6 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -473,6 +473,7 @@ jobs: - { os: ubuntu-latest , target: i686-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } - { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , features: feat_os_unix , use-cross: use-cross } - { os: ubuntu-latest , target: x86_64-unknown-linux-musl , features: feat_os_unix_musl , use-cross: use-cross } + - { os: ubuntu-latest , target: x86_64-unknown-redox , features: feat_os_unix_redox , use-cross: redoxer , skip-tests: true } - { os: macos-latest , target: aarch64-apple-darwin , features: feat_os_macos , use-cross: use-cross, skip-tests: true} # Hopefully github provides free M1 runners soon... - { os: macos-latest , target: x86_64-apple-darwin , features: feat_os_macos } - { os: windows-latest , target: i686-pc-windows-msvc , features: feat_os_windows } @@ -525,7 +526,7 @@ jobs: i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac; - unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; esac; + unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; *-redox*) TARGET_OS=redox ;; esac; outputs TARGET_ARCH TARGET_OS # package name PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac; @@ -560,8 +561,11 @@ jobs: if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi outputs CARGO_FEATURES_OPTION # * CARGO_CMD - CARGO_CMD='cross' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) CARGO_CMD='cargo' ;; esac; + CARGO_CMD='cross' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) CARGO_CMD='cargo' ;; redoxer) CARGO_CMD='redoxer' ;; esac; outputs CARGO_CMD + # * CARGO_CMD_OPTIONS + CARGO_CMD_OPTIONS='+${{ env.RUST_MIN_SRV }}' ; case '${{ matrix.job.target }}' in *-redox*) CARGO_CMD_OPTIONS="" ;; esac; + outputs CARGO_CMD_OPTIONS # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then printf "[build.env]\npassthrough = [\"CI\", \"RUST_BACKTRACE\", \"CARGO_TERM_COLOR\"]\n" > Cross.toml @@ -595,6 +599,7 @@ jobs: case '${{ matrix.job.target }}' in arm-unknown-linux-gnueabihf) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;; aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;; + *-redox*) sudo apt-get -y update ; sudo apt-get -y install fuse3 libfuse-dev ;; esac case '${{ matrix.job.os }}' in macos-latest) brew install coreutils ;; # needed for testing @@ -614,6 +619,10 @@ jobs: echo "foo" > /home/runner/.plan ;; esac + - uses: taiki-e/install-action@v2 + if: steps.vars.outputs.CARGO_CMD == 'redoxer' + with: + tool: redoxer@0.2.37 - name: Initialize toolchain-dependent workflow variables id: dep_vars shell: bash @@ -652,14 +661,14 @@ jobs: shell: bash run: | ## Build - ${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} build --release \ + ${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} build --release \ --target=${{ matrix.job.target }} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} - name: Test if: matrix.job.skip-tests != true shell: bash run: | ## Test - ${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \ + ${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} test --target=${{ matrix.job.target }} \ ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.vars.outputs.CARGO_FEATURES_OPTION }} env: RUST_BACKTRACE: "1" @@ -668,7 +677,7 @@ jobs: shell: bash run: | ## Test individual utilities - ${{ steps.vars.outputs.CARGO_CMD }} +${{ env.RUST_MIN_SRV }} test --target=${{ matrix.job.target }} \ + ${{ steps.vars.outputs.CARGO_CMD }} ${{ steps.vars.outputs.CARGO_CMD_OPTIONS }} test --target=${{ matrix.job.target }} \ ${{ steps.vars.outputs.CARGO_TEST_OPTIONS}} ${{ matrix.job.cargo-options }} ${{ steps.dep_vars.outputs.CARGO_UTILITY_LIST_OPTIONS }} env: RUST_BACKTRACE: "1" From 42558344f155f085acdc7b3b18e5a97fb479beb7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Tue, 12 Dec 2023 14:23:51 +0100 Subject: [PATCH 14/27] ls: enable "args override self" --- src/uu/ls/src/ls.rs | 1 + tests/by-util/test_ls.rs | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index 2aa4bad06..1fceefe17 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -1070,6 +1070,7 @@ pub fn uu_app() -> Command { .about(ABOUT) .infer_long_args(true) .disable_help_flag(true) + .args_override_self(true) .arg( Arg::new(options::HELP) .long(options::HELP) diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 179941e78..c3460633a 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -3924,6 +3924,21 @@ fn test_ls_block_size_override() { .stdout_contains_line("total 8"); } +#[test] +fn test_ls_block_size_override_self() { + new_ucmd!() + .arg("--block-size=512") + .arg("--block-size=512") + .succeeds(); + + new_ucmd!() + .arg("--human-readable") + .arg("--human-readable") + .succeeds(); + + new_ucmd!().arg("--si").arg("--si").succeeds(); +} + #[test] fn test_ls_hyperlink() { let scene = TestScenario::new(util_name!()); From c32fb25b1faac8bd38bd3474d89ebb30e708eab7 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 11 Dec 2023 10:55:37 +0100 Subject: [PATCH 15/27] Bump xattr from 1.1.1 to 1.1.3 --- Cargo.lock | 98 +++++++++++++++++++++++++++++++++++++++++++++--------- Cargo.toml | 2 +- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c943a2611..446b17247 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -781,12 +781,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1215,9 +1215,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -1600,7 +1600,7 @@ dependencies = [ "hex", "lazy_static", "procfs-core", - "rustix 0.38.21", + "rustix 0.38.28", ] [[package]] @@ -1842,15 +1842,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] @@ -2063,7 +2063,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall 0.4.0", - "rustix 0.38.21", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -2083,7 +2083,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -3403,6 +3403,15 @@ dependencies = [ "windows-targets 0.48.0", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -3433,6 +3442,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -3445,6 +3469,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -3457,6 +3487,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -3469,6 +3505,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -3481,6 +3523,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -3493,6 +3541,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -3505,6 +3559,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -3518,12 +3578,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] -name = "xattr" -version = "1.1.1" +name = "windows_x86_64_msvc" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc6ab6ec1907d1a901cdbcd2bd4cb9e7d64ce5c9739cbb97d3c391acd8c7fae" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "xattr" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dae5072fe1f8db8f8d29059189ac175196e410e40ba42d5d4684ae2f750995" dependencies = [ "libc", + "linux-raw-sys 0.4.12", + "rustix 0.38.28", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 53e5ce32e..332131bbe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -331,7 +331,7 @@ utf-8 = "0.7.6" walkdir = "2.4" winapi-util = "0.1.6" windows-sys = { version = "0.48.0", default-features = false } -xattr = "1.1.1" +xattr = "1.1.3" zip = { version = "0.6.6", default-features = false, features = ["deflate"] } hex = "0.4.3" From 116245b8eff208c2540fb7a9477d8f3c9842ebc1 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Mon, 11 Dec 2023 11:02:22 +0100 Subject: [PATCH 16/27] deny.toml: allow three versions of windows-sys --- deny.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/deny.toml b/deny.toml index 03301ad7c..df970c2c6 100644 --- a/deny.toml +++ b/deny.toml @@ -64,8 +64,12 @@ skip = [ { name = "rustix", version = "0.37.26" }, # various crates { name = "windows-sys", version = "0.45.0" }, + # various crates + { name = "windows-sys", version = "0.48.0" }, # windows-sys { name = "windows-targets", version = "0.42.2" }, + # windows-sys + { name = "windows-targets", version = "0.48.0" }, # windows-targets { name = "windows_aarch64_gnullvm", version = "0.42.2" }, # windows-targets @@ -80,6 +84,20 @@ skip = [ { name = "windows_x86_64_gnullvm", version = "0.42.2" }, # windows-targets { name = "windows_x86_64_msvc", version = "0.42.2" }, + # windows-targets + { name = "windows_aarch64_gnullvm", version = "0.48.0" }, + # windows-targets + { name = "windows_aarch64_msvc", version = "0.48.0" }, + # windows-targets + { name = "windows_i686_gnu", version = "0.48.0" }, + # windows-targets + { name = "windows_i686_msvc", version = "0.48.0" }, + # windows-targets + { name = "windows_x86_64_gnu", version = "0.48.0" }, + # windows-targets + { name = "windows_x86_64_gnullvm", version = "0.48.0" }, + # windows-targets + { name = "windows_x86_64_msvc", version = "0.48.0" }, # various crates { name = "syn", version = "1.0.109" }, # various crates From 5d57fdc7f8cf9195c5bbe94ac6cb092087c168f7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 09:25:44 +0000 Subject: [PATCH 17/27] chore(deps): update dawidd6/action-download-artifact action to v3 --- .github/workflows/CICD.yml | 4 ++-- .github/workflows/GnuTests.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 8c96ce693..7629725ee 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -395,14 +395,14 @@ jobs: --arg multisize "$SIZE_MULTI" \ '{($date): { sha: $sha, size: $size, multisize: $multisize, }}' > size-result.json - name: Download the previous individual size result - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v3 with: workflow: CICD.yml name: individual-size-result repo: uutils/coreutils path: dl - name: Download the previous size result - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v3 with: workflow: CICD.yml name: size-result diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index 87e4373ed..f889e5a85 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -77,7 +77,7 @@ jobs: ref: ${{ steps.vars.outputs.repo_GNU_ref }} submodules: recursive - name: Retrieve reference artifacts - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v3 # ref: continue-on-error: true ## don't break the build for missing reference artifacts (may be expired or just not generated yet) with: From 6fb3bbb8a0051b4ef091a781599a1347cdc57705 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Wed, 13 Dec 2023 14:27:19 +0100 Subject: [PATCH 18/27] mv: rename two tests --- tests/by-util/test_mv.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index 571de7691..3fb002dc3 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -10,10 +10,20 @@ use std::thread::sleep; use std::time::Duration; #[test] -fn test_invalid_arg() { +fn test_mv_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails().code_is(1); } +#[test] +fn test_mv_missing_dest() { + let (at, mut ucmd) = at_and_ucmd!(); + let dir = "dir"; + + at.mkdir(dir); + + ucmd.arg(dir).fails(); +} + #[test] fn test_mv_rename_dir() { let (at, mut ucmd) = at_and_ucmd!(); @@ -27,16 +37,6 @@ fn test_mv_rename_dir() { assert!(at.dir_exists(dir2)); } -#[test] -fn test_mv_fail() { - let (at, mut ucmd) = at_and_ucmd!(); - let dir1 = "test_mv_rename_dir"; - - at.mkdir(dir1); - - ucmd.arg(dir1).fails(); -} - #[test] fn test_mv_rename_file() { let (at, mut ucmd) = at_and_ucmd!(); From ebe5c51cee2f9a221df1c3dcd3881c39d6f503d2 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Wed, 13 Dec 2023 08:47:16 -0700 Subject: [PATCH 19/27] Format case statements --- .github/workflows/CICD.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index f52ead1f6..dc25e58b6 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -526,7 +526,13 @@ jobs: i686-*) TARGET_ARCH=i686 ;; x86_64-*) TARGET_ARCH=x86_64 ;; esac; - unset TARGET_OS ; case '${{ matrix.job.target }}' in *-linux-*) TARGET_OS=linux ;; *-apple-*) TARGET_OS=macos ;; *-windows-*) TARGET_OS=windows ;; *-redox*) TARGET_OS=redox ;; esac; + unset TARGET_OS + case '${{ matrix.job.target }}' in + *-linux-*) TARGET_OS=linux ;; + *-apple-*) TARGET_OS=macos ;; + *-windows-*) TARGET_OS=windows ;; + *-redox*) TARGET_OS=redox ;; + esac outputs TARGET_ARCH TARGET_OS # package name PKG_suffix=".tar.gz" ; case '${{ matrix.job.target }}' in *-pc-windows-*) PKG_suffix=".zip" ;; esac; @@ -561,10 +567,18 @@ jobs: if [ -n "${{ matrix.job.features }}" ]; then CARGO_FEATURES_OPTION='--features=${{ matrix.job.features }}' ; fi outputs CARGO_FEATURES_OPTION # * CARGO_CMD - CARGO_CMD='cross' ; case '${{ matrix.job.use-cross }}' in ''|0|f|false|n|no) CARGO_CMD='cargo' ;; redoxer) CARGO_CMD='redoxer' ;; esac; + CARGO_CMD='cross' + CARGO_CMD_OPTIONS='+${{ env.RUST_MIN_SRV }}' + case '${{ matrix.job.use-cross }}' in + ''|0|f|false|n|no) + CARGO_CMD='cargo' + ;; + redoxer) + CARGO_CMD='redoxer' + CARGO_CMD_OPTIONS='' + ;; + esac outputs CARGO_CMD - # * CARGO_CMD_OPTIONS - CARGO_CMD_OPTIONS='+${{ env.RUST_MIN_SRV }}' ; case '${{ matrix.job.target }}' in *-redox*) CARGO_CMD_OPTIONS="" ;; esac; outputs CARGO_CMD_OPTIONS # ** pass needed environment into `cross` container (iff `cross` not already configured via "Cross.toml") if [ "${CARGO_CMD}" = 'cross' ] && [ ! -e "Cross.toml" ] ; then From 7f23faf8999069b283a370991f1f3220619304ba Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Thu, 14 Dec 2023 16:35:56 +0100 Subject: [PATCH 20/27] expr: clean up conversion from bigint to usize --- src/uu/expr/src/syntax_tree.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/uu/expr/src/syntax_tree.rs b/src/uu/expr/src/syntax_tree.rs index 7817b1721..28e4ff0bd 100644 --- a/src/uu/expr/src/syntax_tree.rs +++ b/src/uu/expr/src/syntax_tree.rs @@ -294,12 +294,14 @@ impl AstNode { let pos = pos .eval()? .eval_as_bigint() - .map_or(0.into(), |n| n.to_usize()) + .ok() + .and_then(|n| n.to_usize()) .unwrap_or(0); let length = length .eval()? .eval_as_bigint() - .map_or(0.into(), |n| n.to_usize()) + .ok() + .and_then(|n| n.to_usize()) .unwrap_or(0); let (Some(pos), Some(_)) = (pos.checked_sub(1), length.checked_sub(1)) else { From 97857d5be08d4901508cf5f6bdecf09399b4e8bc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 14 Dec 2023 17:51:36 +0000 Subject: [PATCH 21/27] chore(deps): update actions/upload-artifact action to v4 --- .github/workflows/CICD.yml | 18 +++++++++--------- .github/workflows/GnuTests.yml | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 7629725ee..965e26062 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -439,12 +439,12 @@ jobs: previous_multisize=$(cat dl/size-result.json | jq -r '.[] | .multisize') check 'multicall binary' "$multisize" "$previous_multisize" 'size-result.json' - name: Upload the individual size result - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: individual-size-result path: individual-size-result.json - name: Upload the size result - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: size-result path: size-result.json @@ -673,7 +673,7 @@ jobs: env: RUST_BACKTRACE: "1" - name: Archive executable artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ env.PROJECT_NAME }}-${{ matrix.job.target }} path: target/${{ matrix.job.target }}/release/${{ env.PROJECT_NAME }}${{ steps.vars.outputs.EXE_suffix }} @@ -784,17 +784,17 @@ jobs: HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) echo "HASH=${HASH}" >> $GITHUB_OUTPUT - name: Reserve SHA1/ID of 'test-summary' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: "${{ steps.summary.outputs.HASH }}" path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Reserve test results summary - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-summary path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Upload json results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: busybox-result.json path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }} @@ -872,17 +872,17 @@ jobs: HASH=$(sha1sum '${{ steps.vars.outputs.TEST_SUMMARY_FILE }}' | cut --delim=" " -f 1) echo "HASH=${HASH}" >> $GITHUB_OUTPUT - name: Reserve SHA1/ID of 'test-summary' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: "${{ steps.summary.outputs.HASH }}" path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Reserve test results summary - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-summary path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Upload json results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: toybox-result.json path: ${{ steps.vars.outputs.TEST_SUMMARY_FILE }} diff --git a/.github/workflows/GnuTests.yml b/.github/workflows/GnuTests.yml index f889e5a85..5215ab24f 100644 --- a/.github/workflows/GnuTests.yml +++ b/.github/workflows/GnuTests.yml @@ -179,22 +179,22 @@ jobs: # Compress logs before upload (fails otherwise) gzip ${{ steps.vars.outputs.TEST_LOGS_GLOB }} - name: Reserve SHA1/ID of 'test-summary' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: "${{ steps.summary.outputs.HASH }}" path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Reserve test results summary - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-summary path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Reserve test logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: test-logs path: "${{ steps.vars.outputs.TEST_LOGS_GLOB }}" - name: Upload full json results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: gnu-full-result.json path: ${{ steps.vars.outputs.TEST_FULL_SUMMARY_FILE }} @@ -288,7 +288,7 @@ jobs: if test -n "${have_new_failures}" ; then exit -1 ; fi - name: Upload comparison log (for GnuComment workflow) if: success() || failure() # run regardless of prior step success/failure - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: comment path: ${{ steps.vars.outputs.path_reference }}/comment/ From 3a7a3bf63941492c7885ba0287c78854a6950c12 Mon Sep 17 00:00:00 2001 From: Arpit Bhadauria Date: Fri, 15 Dec 2023 16:44:31 +0530 Subject: [PATCH 22/27] fmt: remove crash! macro (#5589) * fmt: remove crash! macro * Fix styling in fmt * Revert "Fix styling in fmt" This reverts commit 002e02f50c5bfebfc69fb1acb86d39a36d96d97d. * Revert "fmt: remove crash! macro" This reverts commit d65a3f85a1840d0c1d2e32f927e951a62258370f. * Replace crash! with unreachable! macro * Remove crash! import * Remove unreachable! from fmt * keep the helpful comment * Fix lint and format issues * review fixes --- src/uu/fmt/src/linebreak.rs | 40 +++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/uu/fmt/src/linebreak.rs b/src/uu/fmt/src/linebreak.rs index 306c15f36..7393589d0 100644 --- a/src/uu/fmt/src/linebreak.rs +++ b/src/uu/fmt/src/linebreak.rs @@ -8,8 +8,6 @@ use std::io::{BufWriter, Stdout, Write}; use std::{cmp, i64, mem}; -use uucore::crash; - use crate::parasplit::{ParaWords, Paragraph, WordInfo}; use crate::FmtOptions; @@ -363,28 +361,26 @@ fn find_kp_breakpoints<'a, T: Iterator>>( } fn build_best_path<'a>(paths: &[LineBreak<'a>], active: &[usize]) -> Vec<(&'a WordInfo<'a>, bool)> { - let mut breakwords = vec![]; // of the active paths, we select the one with the fewest demerits - let mut best_idx = match active.iter().min_by_key(|&&a| paths[a].demerits) { - None => crash!( - 1, - "Failed to find a k-p linebreak solution. This should never happen." - ), - Some(&s) => s, - }; - - // now, chase the pointers back through the break list, recording - // the words at which we should break - loop { - let next_best = &paths[best_idx]; - match next_best.linebreak { - None => return breakwords, - Some(prev) => { - breakwords.push((prev, next_best.break_before)); - best_idx = next_best.prev; + active + .iter() + .min_by_key(|&&a| paths[a].demerits) + .map(|&(mut best_idx)| { + let mut breakwords = vec![]; + // now, chase the pointers back through the break list, recording + // the words at which we should break + loop { + let next_best = &paths[best_idx]; + match next_best.linebreak { + None => return breakwords, + Some(prev) => { + breakwords.push((prev, next_best.break_before)); + best_idx = next_best.prev; + } + } } - } - } + }) + .unwrap_or_default() } // "infinite" badness is more like (1+BAD_INFTY)^2 because of how demerits are computed From c32e730a1f0f0625158571dd528cde7519515f81 Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 15 Dec 2023 14:38:27 +0100 Subject: [PATCH 23/27] all: remove collect_{lossy,ignore} calls where possible --- src/uu/base32/src/base_common.rs | 3 +-- src/uu/cat/src/cat.rs | 2 -- src/uu/chroot/src/chroot.rs | 2 -- src/uu/cksum/src/cksum.rs | 2 -- src/uu/comm/src/comm.rs | 2 -- src/uu/csplit/src/csplit.rs | 2 -- src/uu/dd/src/dd.rs | 2 -- src/uu/dircolors/src/dircolors.rs | 2 -- src/uu/dirname/src/dirname.rs | 2 -- src/uu/du/src/du.rs | 2 -- src/uu/echo/src/echo.rs | 1 - src/uu/expr/src/expr.rs | 2 -- src/uu/logname/src/logname.rs | 2 -- src/uu/mkfifo/src/mkfifo.rs | 2 -- src/uu/mknod/src/mknod.rs | 1 - src/uu/mktemp/src/mktemp.rs | 6 +++--- src/uu/more/src/more.rs | 1 - src/uu/nl/src/nl.rs | 2 -- src/uu/nohup/src/nohup.rs | 2 -- src/uu/pathchk/src/pathchk.rs | 2 -- src/uu/pinky/src/pinky.rs | 2 -- src/uu/printf/src/printf.rs | 1 - src/uu/ptx/src/ptx.rs | 2 -- src/uu/shred/src/shred.rs | 2 -- src/uu/shuf/src/shuf.rs | 2 -- src/uu/sort/src/sort.rs | 1 - src/uu/stdbuf/src/stdbuf.rs | 2 -- src/uu/stty/src/stty.rs | 2 -- src/uu/sum/src/sum.rs | 2 -- src/uu/tac/src/tac.rs | 2 -- src/uu/timeout/src/timeout.rs | 2 -- src/uu/tr/src/tr.rs | 2 -- src/uu/tsort/src/tsort.rs | 2 -- src/uu/who/src/who.rs | 2 -- 34 files changed, 4 insertions(+), 64 deletions(-) diff --git a/src/uu/base32/src/base_common.rs b/src/uu/base32/src/base_common.rs index 74c3dc808..2112a40ea 100644 --- a/src/uu/base32/src/base_common.rs +++ b/src/uu/base32/src/base_common.rs @@ -87,8 +87,7 @@ pub fn parse_base_cmd_args( usage: &str, ) -> UResult { let command = base_app(about, usage); - let arg_list = args.collect_lossy(); - Config::from(&command.try_get_matches_from(arg_list)?) + Config::from(&command.try_get_matches_from(args)?) } pub fn base_app(about: &'static str, usage: &str) -> Command { diff --git a/src/uu/cat/src/cat.rs b/src/uu/cat/src/cat.rs index 34eb26512..8aaecb8c1 100644 --- a/src/uu/cat/src/cat.rs +++ b/src/uu/cat/src/cat.rs @@ -174,8 +174,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let number_mode = if matches.get_flag(options::NUMBER_NONBLANK) { diff --git a/src/uu/chroot/src/chroot.rs b/src/uu/chroot/src/chroot.rs index 6366775c3..9ea861d46 100644 --- a/src/uu/chroot/src/chroot.rs +++ b/src/uu/chroot/src/chroot.rs @@ -33,8 +33,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?; let default_shell: &'static str = "/bin/sh"; diff --git a/src/uu/cksum/src/cksum.rs b/src/uu/cksum/src/cksum.rs index 629bb457f..245760409 100644 --- a/src/uu/cksum/src/cksum.rs +++ b/src/uu/cksum/src/cksum.rs @@ -221,8 +221,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let algo_name: &str = match matches.get_one::(options::ALGORITHM) { diff --git a/src/uu/comm/src/comm.rs b/src/uu/comm/src/comm.rs index e6977142e..dd49ef53b 100644 --- a/src/uu/comm/src/comm.rs +++ b/src/uu/comm/src/comm.rs @@ -145,8 +145,6 @@ fn open_file(name: &str, line_ending: LineEnding) -> io::Result { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO_TERMINATED)); let filename1 = matches.get_one::(options::FILE_1).unwrap(); diff --git a/src/uu/csplit/src/csplit.rs b/src/uu/csplit/src/csplit.rs index d33be1a5d..00bebbf4d 100644 --- a/src/uu/csplit/src/csplit.rs +++ b/src/uu/csplit/src/csplit.rs @@ -552,8 +552,6 @@ where #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; // get the file to split diff --git a/src/uu/dd/src/dd.rs b/src/uu/dd/src/dd.rs index b721d1d72..e849fcd2a 100644 --- a/src/uu/dd/src/dd.rs +++ b/src/uu/dd/src/dd.rs @@ -1267,8 +1267,6 @@ fn is_fifo(filename: &str) -> bool { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let settings: Settings = Parser::new().parse( diff --git a/src/uu/dircolors/src/dircolors.rs b/src/uu/dircolors/src/dircolors.rs index ecca9d160..531c3ee47 100644 --- a/src/uu/dircolors/src/dircolors.rs +++ b/src/uu/dircolors/src/dircolors.rs @@ -129,8 +129,6 @@ fn generate_ls_colors(fmt: &OutputFmt, sep: &str) -> String { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let files = matches diff --git a/src/uu/dirname/src/dirname.rs b/src/uu/dirname/src/dirname.rs index 51935cb7f..a645b05fd 100644 --- a/src/uu/dirname/src/dirname.rs +++ b/src/uu/dirname/src/dirname.rs @@ -21,8 +21,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 7114ccc26..1213e004f 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -590,8 +590,6 @@ pub fn div_ceil(a: u64, b: u64) -> u64 { #[uucore::main] #[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let summarize = matches.get_flag(options::SUMMARIZE); diff --git a/src/uu/echo/src/echo.rs b/src/uu/echo/src/echo.rs index b3707b6f8..522cb0c94 100644 --- a/src/uu/echo/src/echo.rs +++ b/src/uu/echo/src/echo.rs @@ -118,7 +118,6 @@ fn print_escaped(input: &str, mut output: impl Write) -> io::Result UResult<()> { - let args = args.collect_lossy(); let matches = uu_app().get_matches_from(args); let no_newline = matches.get_flag(options::NO_NEWLINE); diff --git a/src/uu/expr/src/expr.rs b/src/uu/expr/src/expr.rs index c271f0935..1e19b6e12 100644 --- a/src/uu/expr/src/expr.rs +++ b/src/uu/expr/src/expr.rs @@ -98,8 +98,6 @@ pub fn uu_app() -> Command { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - // For expr utility we do not want getopts. // The following usage should work without escaping hyphens: `expr -15 = 1 + 2 \* \( 3 - -4 \)` let matches = uu_app().try_get_matches_from(args)?; diff --git a/src/uu/logname/src/logname.rs b/src/uu/logname/src/logname.rs index 55d4fec75..02a78cf4c 100644 --- a/src/uu/logname/src/logname.rs +++ b/src/uu/logname/src/logname.rs @@ -30,8 +30,6 @@ const USAGE: &str = help_usage!("logname.md"); #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let _ = uu_app().try_get_matches_from(args)?; match get_userlogin() { diff --git a/src/uu/mkfifo/src/mkfifo.rs b/src/uu/mkfifo/src/mkfifo.rs index 39d112739..9320f76ed 100644 --- a/src/uu/mkfifo/src/mkfifo.rs +++ b/src/uu/mkfifo/src/mkfifo.rs @@ -22,8 +22,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; if matches.contains_id(options::CONTEXT) { diff --git a/src/uu/mknod/src/mknod.rs b/src/uu/mknod/src/mknod.rs index ceafd235b..15a0fdacd 100644 --- a/src/uu/mknod/src/mknod.rs +++ b/src/uu/mknod/src/mknod.rs @@ -68,7 +68,6 @@ fn _mknod(file_name: &str, mode: mode_t, dev: dev_t) -> i32 { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); // Linux-specific options, not implemented // opts.optflag("Z", "", "set the SELinux security context to default type"); // opts.optopt("", "context", "like -Z, or if CTX is specified then set the SELinux or SMACK security context to CTX"); diff --git a/src/uu/mktemp/src/mktemp.rs b/src/uu/mktemp/src/mktemp.rs index d52351a89..ae44225c9 100644 --- a/src/uu/mktemp/src/mktemp.rs +++ b/src/uu/mktemp/src/mktemp.rs @@ -12,6 +12,7 @@ use uucore::{format_usage, help_about, help_usage}; use std::env; use std::error::Error; +use std::ffi::OsStr; use std::fmt::Display; use std::io::ErrorKind; use std::iter; @@ -308,8 +309,7 @@ impl Params { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - + let args: Vec<_> = args.collect(); let matches = match uu_app().try_get_matches_from(&args) { Ok(m) => m, Err(e) => { @@ -333,7 +333,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // If POSIXLY_CORRECT was set, template MUST be the last argument. if matches.contains_id(ARG_TEMPLATE) { // Template argument was provided, check if was the last one. - if args.last().unwrap() != &options.template { + if args.last().unwrap() != OsStr::new(&options.template) { return Err(Box::new(MkTempError::TooManyTemplates)); } } diff --git a/src/uu/more/src/more.rs b/src/uu/more/src/more.rs index b21b2ab1f..f651a033b 100644 --- a/src/uu/more/src/more.rs +++ b/src/uu/more/src/more.rs @@ -87,7 +87,6 @@ impl Options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); let matches = match uu_app().try_get_matches_from(args) { Ok(m) => m, Err(e) => return Err(e.into()), diff --git a/src/uu/nl/src/nl.rs b/src/uu/nl/src/nl.rs index eaf27f3b6..7d7688650 100644 --- a/src/uu/nl/src/nl.rs +++ b/src/uu/nl/src/nl.rs @@ -178,8 +178,6 @@ pub mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let mut settings = Settings::default(); diff --git a/src/uu/nohup/src/nohup.rs b/src/uu/nohup/src/nohup.rs index c64f7bf71..602cb7ca7 100644 --- a/src/uu/nohup/src/nohup.rs +++ b/src/uu/nohup/src/nohup.rs @@ -74,8 +74,6 @@ impl Display for NohupError { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?; replace_fds()?; diff --git a/src/uu/pathchk/src/pathchk.rs b/src/uu/pathchk/src/pathchk.rs index 81c352088..ffb214e2e 100644 --- a/src/uu/pathchk/src/pathchk.rs +++ b/src/uu/pathchk/src/pathchk.rs @@ -36,8 +36,6 @@ const POSIX_NAME_MAX: usize = 14; #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; // set working mode diff --git a/src/uu/pinky/src/pinky.rs b/src/uu/pinky/src/pinky.rs index 8ac8f6c84..02161cb36 100644 --- a/src/uu/pinky/src/pinky.rs +++ b/src/uu/pinky/src/pinky.rs @@ -47,8 +47,6 @@ fn get_long_usage() -> String { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app() .after_help(get_long_usage()) .try_get_matches_from(args)?; diff --git a/src/uu/printf/src/printf.rs b/src/uu/printf/src/printf.rs index 663411b89..ad42e3894 100644 --- a/src/uu/printf/src/printf.rs +++ b/src/uu/printf/src/printf.rs @@ -27,7 +27,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); let matches = uu_app().get_matches_from(args); let format_string = matches diff --git a/src/uu/ptx/src/ptx.rs b/src/uu/ptx/src/ptx.rs index 6dd2b2992..7caa8f4a5 100644 --- a/src/uu/ptx/src/ptx.rs +++ b/src/uu/ptx/src/ptx.rs @@ -715,8 +715,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let mut input_files: Vec = match &matches.get_many::(options::FILE) { diff --git a/src/uu/shred/src/shred.rs b/src/uu/shred/src/shred.rs index 711fd0485..d4209aa3a 100644 --- a/src/uu/shred/src/shred.rs +++ b/src/uu/shred/src/shred.rs @@ -200,8 +200,6 @@ impl BytesWriter { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; if !matches.contains_id(options::FILE) { diff --git a/src/uu/shuf/src/shuf.rs b/src/uu/shuf/src/shuf.rs index 8c636f1cb..de302435c 100644 --- a/src/uu/shuf/src/shuf.rs +++ b/src/uu/shuf/src/shuf.rs @@ -47,8 +47,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let mode = if let Some(args) = matches.get_many::(options::ECHO) { diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 4e6e84187..bc331915b 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -1029,7 +1029,6 @@ fn make_sort_mode_arg(mode: &'static str, short: char, help: &'static str) -> Ar #[uucore::main] #[allow(clippy::cognitive_complexity)] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); let mut settings = GlobalSettings::default(); let matches = match uu_app().try_get_matches_from(args) { diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 38c4451ca..2436274e7 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -141,8 +141,6 @@ fn get_preload_env(tmp_dir: &TempDir) -> UResult<(String, PathBuf)> { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app().try_get_matches_from(args)?; let options = ProgramOptions::try_from(&matches).map_err(|e| UUsageError::new(125, e.0))?; diff --git a/src/uu/stty/src/stty.rs b/src/uu/stty/src/stty.rs index 669285750..5a5c31f5e 100644 --- a/src/uu/stty/src/stty.rs +++ b/src/uu/stty/src/stty.rs @@ -176,8 +176,6 @@ ioctl_write_ptr_bad!( #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let opts = Options::from(&matches)?; diff --git a/src/uu/sum/src/sum.rs b/src/uu/sum/src/sum.rs index 38ad3964e..d1f383351 100644 --- a/src/uu/sum/src/sum.rs +++ b/src/uu/sum/src/sum.rs @@ -102,8 +102,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let files: Vec = match matches.get_many::(options::FILE) { diff --git a/src/uu/tac/src/tac.rs b/src/uu/tac/src/tac.rs index b8cb61029..3865c61ae 100644 --- a/src/uu/tac/src/tac.rs +++ b/src/uu/tac/src/tac.rs @@ -33,8 +33,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let before = matches.get_flag(options::BEFORE); diff --git a/src/uu/timeout/src/timeout.rs b/src/uu/timeout/src/timeout.rs index 5e73fe2ab..958bc647e 100644 --- a/src/uu/timeout/src/timeout.rs +++ b/src/uu/timeout/src/timeout.rs @@ -107,8 +107,6 @@ impl Config { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args).with_exit_code(125)?; let config = Config::from(&matches)?; diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index 9c6e7a7da..010228260 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -33,8 +33,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().after_help(AFTER_HELP).try_get_matches_from(args)?; let delete_flag = matches.get_flag(options::DELETE); diff --git a/src/uu/tsort/src/tsort.rs b/src/uu/tsort/src/tsort.rs index e71710847..3ae4f4f97 100644 --- a/src/uu/tsort/src/tsort.rs +++ b/src/uu/tsort/src/tsort.rs @@ -20,8 +20,6 @@ mod options { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_lossy(); - let matches = uu_app().try_get_matches_from(args)?; let input = matches diff --git a/src/uu/who/src/who.rs b/src/uu/who/src/who.rs index 5d952efff..788368aaf 100644 --- a/src/uu/who/src/who.rs +++ b/src/uu/who/src/who.rs @@ -54,8 +54,6 @@ fn get_long_usage() -> String { #[uucore::main] pub fn uumain(args: impl uucore::Args) -> UResult<()> { - let args = args.collect_ignore(); - let matches = uu_app() .after_help(get_long_usage()) .try_get_matches_from(args)?; From 92692c815dc1d44f8af548589cec98eccf91527e Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 15 Dec 2023 15:02:46 +0100 Subject: [PATCH 24/27] docs: add winget installer (#5648) * docs: add winget installer * docs: add "winget" to spell-checker:ignore --------- Co-authored-by: Daniel Hofstetter --- docs/src/installation.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 54b1e23f3..9eba96b55 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -1,4 +1,4 @@ - + # Installation @@ -131,6 +131,12 @@ pkg install rust-coreutils ## Windows +### Winget + +```shell +winget install uutils.coreutils +``` + ### Scoop [![Scoop package](https://repology.org/badge/version-for-repo/scoop/uutils-coreutils.svg)](https://scoop.sh/#/apps?q=uutils-coreutils&s=0&d=1&o=true) From 8ce6fdc1950d0be2e59f23f46d987912f655e779 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 15 Dec 2023 15:35:22 +0100 Subject: [PATCH 25/27] docs: remove scoop badge, adapt links to repos --- docs/src/installation.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/src/installation.md b/docs/src/installation.md index 9eba96b55..dadc6e58e 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -12,7 +12,7 @@ You can also [build uutils from source](build.md). ## Cargo -[![crates.io package](https://repology.org/badge/version-for-repo/crates_io/uutils-coreutils.svg)](https://repology.org/project/uutils-coreutils/versions) +[![crates.io package](https://repology.org/badge/version-for-repo/crates_io/uutils-coreutils.svg)](https://crates.io/crates/coreutils) ```shell # Linux @@ -65,9 +65,9 @@ emerge -pv sys-apps/uutils-coreutils ### Manjaro -![Manjaro Stable package](https://repology.org/badge/version-for-repo/manjaro_stable/uutils-coreutils.svg) -[![Manjaro Testing package](https://repology.org/badge/version-for-repo/manjaro_testing/uutils-coreutils.svg)](https://repology.org/project/uutils-coreutils/versions) -[![Manjaro Unstable package](https://repology.org/badge/version-for-repo/manjaro_unstable/uutils-coreutils.svg)](https://repology.org/project/uutils-coreutils/versions) +[![Manjaro Stable package](https://repology.org/badge/version-for-repo/manjaro_stable/uutils-coreutils.svg)](https://packages.manjaro.org/?query=uutils-coreutils) +[![Manjaro Testing package](https://repology.org/badge/version-for-repo/manjaro_testing/uutils-coreutils.svg)](https://packages.manjaro.org/?query=uutils-coreutils) +[![Manjaro Unstable package](https://repology.org/badge/version-for-repo/manjaro_unstable/uutils-coreutils.svg)](https://packages.manjaro.org/?query=uutils-coreutils) ```shell pacman -S uutils-coreutils @@ -77,7 +77,7 @@ pamac install uutils-coreutils ### NixOS -[![nixpkgs unstable package](https://repology.org/badge/version-for-repo/nix_unstable/uutils-coreutils.svg)](https://repology.org/project/uutils-coreutils/versions) +[![nixpkgs unstable package](https://repology.org/badge/version-for-repo/nix_unstable/uutils-coreutils.svg)](https://search.nixos.org/packages?query=uutils-coreutils) ```shell nix-env -iA nixos.uutils-coreutils @@ -139,7 +139,7 @@ winget install uutils.coreutils ### Scoop -[![Scoop package](https://repology.org/badge/version-for-repo/scoop/uutils-coreutils.svg)](https://scoop.sh/#/apps?q=uutils-coreutils&s=0&d=1&o=true) +[Scoop package](https://scoop.sh/#/apps?q=uutils-coreutils&s=0&d=1&o=true) ```shell scoop install uutils-coreutils @@ -152,7 +152,7 @@ scoop install uutils-coreutils [Conda package](https://anaconda.org/conda-forge/uutils-coreutils) ``` -conda install -c conda-forge uutils-coreutils +conda install -c conda-forge uutils-coreutils ``` ## Non-standard packages From 30c27c143c988b947cb00111b3d09e97ef4ae74d Mon Sep 17 00:00:00 2001 From: Terts Diepraam Date: Fri, 15 Dec 2023 15:56:41 +0100 Subject: [PATCH 26/27] mknod: remove parsemode.rs This file was entirely unused, so it's probably safe to remove it --- src/uu/mknod/src/parsemode.rs | 57 ----------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 src/uu/mknod/src/parsemode.rs diff --git a/src/uu/mknod/src/parsemode.rs b/src/uu/mknod/src/parsemode.rs deleted file mode 100644 index c38800bcb..000000000 --- a/src/uu/mknod/src/parsemode.rs +++ /dev/null @@ -1,57 +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 (path) osrelease - -use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR}; - -use uucore::mode; - -pub const MODE_RW_UGO: mode_t = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - -pub fn parse_mode(mode: &str) -> Result { - let result = if mode.chars().any(|c| c.is_ascii_digit()) { - mode::parse_numeric(MODE_RW_UGO as u32, mode) - } else { - mode::parse_symbolic(MODE_RW_UGO as u32, mode, true) - }; - result.map(|mode| mode as mode_t) -} - -#[cfg(test)] -mod test { - /// Test if the program is running under WSL - // ref: @@ - // ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy - pub fn is_wsl() -> bool { - #[cfg(target_os = "linux")] - { - if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") { - if let Ok(s) = std::str::from_utf8(&b) { - let a = s.to_ascii_lowercase(); - return a.contains("microsoft") || a.contains("wsl"); - } - } - } - false - } - - #[test] - fn symbolic_modes() { - assert_eq!(super::parse_mode("u+x").unwrap(), 0o766); - assert_eq!( - super::parse_mode("+x").unwrap(), - if is_wsl() { 0o776 } else { 0o777 } - ); - assert_eq!(super::parse_mode("a-w").unwrap(), 0o444); - assert_eq!(super::parse_mode("g-r").unwrap(), 0o626); - } - - #[test] - fn numeric_modes() { - assert_eq!(super::parse_mode("644").unwrap(), 0o644); - assert_eq!(super::parse_mode("+100").unwrap(), 0o766); - assert_eq!(super::parse_mode("-4").unwrap(), 0o662); - } -} From c2276f4f6b62ffc2a21c6156bb299b5ceae9c5cb Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Fri, 15 Dec 2023 17:10:24 +0100 Subject: [PATCH 27/27] ci: rename test summary names for busybox & toybox --- .github/workflows/CICD.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index 965e26062..4e0179908 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -791,7 +791,7 @@ jobs: - name: Reserve test results summary uses: actions/upload-artifact@v4 with: - name: test-summary + name: busybox-test-summary path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Upload json results uses: actions/upload-artifact@v4 @@ -879,7 +879,7 @@ jobs: - name: Reserve test results summary uses: actions/upload-artifact@v4 with: - name: test-summary + name: toybox-test-summary path: "${{ steps.vars.outputs.TEST_SUMMARY_FILE }}" - name: Upload json results uses: actions/upload-artifact@v4