Skip to content

Commit cb7c0f1

Browse files
oech3sylvestre
authored andcommitted
cksum family: New errors for --binary, --text and --tag
1 parent e0694a5 commit cb7c0f1

File tree

6 files changed

+40
-86
lines changed

6 files changed

+40
-86
lines changed

src/uu/checksum_common/src/cli.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ impl ChecksumCommand for Command {
131131
.long(options::BINARY)
132132
.short('b')
133133
.hide(true)
134+
.overrides_with(options::TEXT)
134135
.action(ArgAction::SetTrue),
135136
)
136137
}
@@ -169,6 +170,7 @@ impl ChecksumCommand for Command {
169170
Arg::new(options::UNTAGGED)
170171
.long(options::UNTAGGED)
171172
.help(translate!("ck-common-help-untagged"))
173+
.overrides_with(options::TAG)
172174
.action(ArgAction::SetTrue),
173175
)
174176
}

src/uu/checksum_common/src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ pub fn standalone_with_length_main(
7474
.transpose()?
7575
.flatten();
7676

77-
let format = OutputFormat::from_standalone(std::env::args_os());
77+
//todo: deduplicate matches.get_flag
78+
let text = !matches.get_flag(options::BINARY);
79+
let tag = matches.get_flag(options::TAG);
80+
let format = OutputFormat::from_standalone(text, tag);
7881

7982
checksum_main(algo, length, matches, format?)
8083
}
@@ -83,8 +86,10 @@ pub fn standalone_with_length_main(
8386
pub fn standalone_main(algo: AlgoKind, cmd: Command, args: impl uucore::Args) -> UResult<()> {
8487
let matches = uucore::clap_localization::handle_clap_result(cmd, args)?;
8588
let algo = Some(algo);
86-
87-
let format = OutputFormat::from_standalone(std::env::args_os());
89+
//todo: deduplicate matches.get_flag
90+
let text = !matches.get_flag(options::BINARY);
91+
let tag = matches.get_flag(options::TAG);
92+
let format = OutputFormat::from_standalone(text, tag);
8893

8994
checksum_main(algo, None, matches, format?)
9095
}
@@ -155,24 +160,30 @@ pub fn checksum_main(
155160
let quiet = check_flag("quiet")?;
156161
let strict = check_flag("strict")?;
157162
let status = check_flag("status")?;
163+
let text_flag = matches.get_flag(options::TEXT);
164+
let binary_flag = matches.get_flag(options::BINARY);
165+
let tag = matches.get_flag(options::TAG);
158166

159167
// clap provides the default value -. So we unwrap() safety.
160168
let files = matches
161169
.get_many::<OsString>(options::FILE)
162170
.unwrap()
163171
.map(Borrow::borrow);
164172

173+
if text_flag && tag {
174+
return Err(ChecksumError::TextAfterTag.into());
175+
}
176+
165177
if check {
166178
// cksum does not support '--check'ing legacy algorithms
167179
if algo.is_some_and(AlgoKind::is_legacy) {
168180
return Err(ChecksumError::AlgorithmNotSupportedWithCheck.into());
169181
}
170-
171-
let text_flag = matches.get_flag(options::TEXT);
172-
let binary_flag = matches.get_flag(options::BINARY);
173-
let tag = matches.get_flag(options::TAG);
174-
175-
if tag || binary_flag || text_flag {
182+
// Maybe, we should just use clap
183+
if tag {
184+
return Err(ChecksumError::TagCheck.into());
185+
}
186+
if binary_flag || text_flag {
176187
return Err(ChecksumError::BinaryTextConflict.into());
177188
}
178189

src/uu/cksum/src/cksum.rs

Lines changed: 7 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
// spell-checker:ignore (ToDO) fname, algo, bitlen
77

8-
use std::ffi::OsStr;
98
use std::io::{Write, stderr};
109

1110
use clap::Command;
@@ -44,48 +43,6 @@ fn print_cpu_debug_info() {
4443
}
4544
}
4645

47-
/// cksum has a bunch of legacy behavior. We handle this in this function to
48-
/// make sure they are self contained and "easier" to understand.
49-
///
50-
/// Returns a pair of boolean. The first one indicates if we should use tagged
51-
/// output format, the second one indicates if we should use the binary flag in
52-
/// the untagged case.
53-
fn handle_tag_text_binary_flags<S: AsRef<OsStr>>(
54-
args: impl Iterator<Item = S>,
55-
) -> UResult<(bool, bool)> {
56-
let mut tag = true;
57-
let mut binary = false;
58-
let mut text = false;
59-
60-
// --binary, --tag and --untagged are tight together: none of them
61-
// conflicts with each other but --tag will reset "binary" and "text" and
62-
// set "tag".
63-
64-
for arg in args {
65-
let arg = arg.as_ref();
66-
if arg == "-b" || arg == "--binary" {
67-
text = false;
68-
binary = true;
69-
} else if arg == "--text" {
70-
text = true;
71-
binary = false;
72-
} else if arg == "--tag" {
73-
tag = true;
74-
binary = false;
75-
text = false;
76-
} else if arg == "--untagged" {
77-
tag = false;
78-
}
79-
}
80-
81-
// Specifying --text without ever mentioning --untagged fails.
82-
if text && tag {
83-
return Err(ChecksumError::TextWithoutUntagged.into());
84-
}
85-
86-
Ok((tag, binary))
87-
}
88-
8946
/// Sanitize the `--length` argument depending on `--algorithm` and `--length`.
9047
fn maybe_sanitize_length(
9148
algo_cli: Option<AlgoKind>,
@@ -134,8 +91,14 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
13491
.map(String::as_str);
13592

13693
let length = maybe_sanitize_length(algo_cli, input_length)?;
94+
let tag = !matches.get_flag(options::UNTAGGED);
95+
let binary = matches.get_flag(options::BINARY);
96+
let text = matches.get_flag(options::TEXT);
13797

138-
let (tag, binary) = handle_tag_text_binary_flags(std::env::args_os())?;
98+
//Specifying --text without ever mentioning --untagged fails.
99+
if text && tag {
100+
return Err(ChecksumError::TextWithoutUntagged.into());
101+
}
139102

140103
let output_format = OutputFormat::from_cksum(
141104
algo_cli.unwrap_or(AlgoKind::Crc),

src/uucore/src/lib/features/checksum/compute.rs

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
// spell-checker:ignore bitlen
77

8-
use std::ffi::{OsStr, OsString};
8+
use std::ffi::OsStr;
99
use std::fs::File;
1010
use std::io::{self, BufReader, Read, Write};
1111
use std::path::Path;
@@ -115,27 +115,8 @@ impl OutputFormat {
115115
///
116116
/// Since standalone utils can't use the Raw or Legacy output format, it is
117117
/// decided only using the --tag, --binary and --text arguments.
118-
pub fn from_standalone(args: impl Iterator<Item = OsString>) -> UResult<Self> {
119-
let mut text = true;
120-
let mut tag = false;
121-
122-
for arg in args {
123-
if arg == "--" {
124-
break;
125-
} else if arg == "--tag" {
126-
tag = true;
127-
text = false;
128-
} else if arg == "--binary" || arg == "-b" {
129-
text = false;
130-
} else if arg == "--text" || arg == "-t" {
131-
// Finding a `--text` after `--tag` is an error.
132-
if tag {
133-
return Err(ChecksumError::TextAfterTag.into());
134-
}
135-
text = true;
136-
}
137-
}
138-
118+
#[allow(clippy::unnecessary_wraps)]
119+
pub fn from_standalone(text: bool, tag: bool) -> UResult<Self> {
139120
if tag {
140121
Ok(Self::Tagged(DigestFormat::Hexadecimal))
141122
} else {

src/uucore/src/lib/features/checksum/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,8 @@ pub enum ChecksumError {
403403
BinaryTextConflict,
404404
#[error("--text mode is only supported with --untagged")]
405405
TextWithoutUntagged,
406+
#[error("the --tag option is meaningless when verifying checksums")]
407+
TagCheck,
406408
#[error("--tag does not support --text mode")]
407409
TextAfterTag,
408410
#[error("--check is not supported with --algorithm={{bsd,sysv,crc,crc32b}}")]

tests/by-util/test_cksum.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,13 +1012,13 @@ fn test_reset_binary() {
10121012

10131013
scene
10141014
.ucmd()
1015-
.arg("--binary") // should disappear because of the following option
1015+
.arg("--binary")
10161016
.arg("--tag")
10171017
.arg("--untagged")
10181018
.arg("--algorithm=md5")
10191019
.arg(at.subdir.join("f"))
10201020
.succeeds()
1021-
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e ");
1021+
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e *");
10221022
}
10231023

10241024
#[test]
@@ -1040,7 +1040,6 @@ fn test_reset_binary_but_set() {
10401040
.stdout_contains("d41d8cd98f00b204e9800998ecf8427e *");
10411041
}
10421042

1043-
/// Test legacy behaviors with --tag, --untagged, --binary and --text
10441043
mod output_format {
10451044
use super::*;
10461045

@@ -1049,13 +1048,11 @@ mod output_format {
10491048
let (at, mut ucmd) = at_and_ucmd!();
10501049
at.touch("f");
10511050

1052-
ucmd.arg("--text") // should disappear because of the following option
1051+
ucmd.arg("--text")
10531052
.arg("--tag")
10541053
.args(&["-a", "md5"])
10551054
.arg(at.subdir.join("f"))
1056-
.succeeds()
1057-
// Tagged output is used
1058-
.stdout_contains("f) = d41d8cd98f00b204e9800998ecf8427e");
1055+
.fails();
10591056
}
10601057

10611058
#[test]
@@ -1181,7 +1178,7 @@ fn test_binary_file() {
11811178
.arg("--untagged")
11821179
.arg("lorem_ipsum.txt")
11831180
.succeeds()
1184-
.stdout_is("cd724690f7dc61775dfac400a71f2caa lorem_ipsum.txt\n");
1181+
.stdout_is("cd724690f7dc61775dfac400a71f2caa *lorem_ipsum.txt\n");
11851182
}
11861183

11871184
#[test]
@@ -1229,9 +1226,7 @@ fn test_conflicting_options() {
12291226
.arg("md5")
12301227
.fails_with_code(1)
12311228
.no_stdout()
1232-
.stderr_contains(
1233-
"cksum: the --binary and --text options are meaningless when verifying checksums",
1234-
);
1229+
.stderr_contains("cksum: the --tag option is meaningless when verifying checksums");
12351230
}
12361231

12371232
#[test]

0 commit comments

Comments
 (0)