From 594157d1e0e2bdffb29d92d27570835f7c1dcb91 Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Sat, 22 Jan 2022 11:35:42 -0500 Subject: [PATCH 1/2] join: fix default check order behaviour If neither --nocheck-order or --check-order are specified, only fail on unsorted inputs if either file contains unpaired lines. --- src/uu/join/src/join.rs | 44 +++++++++++++++++++++++++++----------- tests/by-util/test_join.rs | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/uu/join/src/join.rs b/src/uu/join/src/join.rs index 691d374b4..70efc58c3 100644 --- a/src/uu/join/src/join.rs +++ b/src/uu/join/src/join.rs @@ -273,6 +273,7 @@ struct State<'a> { seq: Vec, line_num: usize, has_failed: bool, + has_unpaired: bool, } impl<'a> State<'a> { @@ -302,6 +303,7 @@ impl<'a> State<'a> { seq: Vec::new(), line_num: 0, has_failed: false, + has_unpaired: false, } } @@ -415,11 +417,18 @@ impl<'a> State<'a> { } fn finalize(&mut self, input: &Input, repr: &Repr) -> Result<(), std::io::Error> { - if self.has_line() && self.print_unpaired { - self.print_first_line(repr)?; + if self.has_line() { + if self.print_unpaired { + self.print_first_line(repr)?; + } - while let Some(line) = self.next_line(input) { - self.print_line(&line, repr)?; + let mut next_line = self.next_line(input); + while let Some(line) = &next_line { + if self.print_unpaired { + self.print_line(line, repr)?; + } + self.reset(next_line); + next_line = self.next_line(input); } } @@ -444,20 +453,21 @@ impl<'a> State<'a> { let diff = input.compare(self.get_current_key(), line.get_field(self.key)); if diff == Ordering::Greater { - eprintln!( - "{}: {}:{}: is not sorted: {}", - uucore::execution_phrase(), - self.file_name.maybe_quote(), - self.line_num, - String::from_utf8_lossy(&line.string) - ); + if input.check_order == CheckOrder::Enabled || (self.has_unpaired && !self.has_failed) { + eprintln!( + "{}: {}:{}: is not sorted: {}", + uucore::execution_phrase(), + self.file_name.maybe_quote(), + self.line_num, + String::from_utf8_lossy(&line.string) + ); + self.has_failed = true; + } // This is fatal if the check is enabled. if input.check_order == CheckOrder::Enabled { std::process::exit(1); } - - self.has_failed = true; } Some(line) @@ -760,9 +770,13 @@ fn exec(file1: &str, file2: &str, settings: Settings) -> Result<(), std::io::Err match diff { Ordering::Less => { state1.skip_line(&input, &repr)?; + state1.has_unpaired = true; + state2.has_unpaired = true; } Ordering::Greater => { state2.skip_line(&input, &repr)?; + state1.has_unpaired = true; + state2.has_unpaired = true; } Ordering::Equal => { let next_line1 = state1.extend(&input); @@ -782,6 +796,10 @@ fn exec(file1: &str, file2: &str, settings: Settings) -> Result<(), std::io::Err state2.finalize(&input, &repr)?; if state1.has_failed || state2.has_failed { + eprintln!( + "{}: input is not in sorted order", + uucore::execution_phrase() + ); set_exit_code(1); } Ok(()) diff --git a/tests/by-util/test_join.rs b/tests/by-util/test_join.rs index ea081da22..3bf296290 100644 --- a/tests/by-util/test_join.rs +++ b/tests/by-util/test_join.rs @@ -289,7 +289,7 @@ fn wrong_line_order() { .arg("fields_4.txt") .fails() .stderr_is(&format!( - "{} {}: fields_4.txt:5: is not sorted: 11 g 5 gh", + "{0} {1}: fields_4.txt:5: is not sorted: 11 g 5 gh\n{0} {1}: input is not in sorted order", ts.bin_path.to_string_lossy(), ts.util_name )); From c8f9ea5b151f485d8bda9cd3cbb0a5c2235a69f5 Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Sat, 22 Jan 2022 17:50:13 -0500 Subject: [PATCH 2/2] tests/join: test default check order behaviour --- tests/by-util/test_join.rs | 16 +++++++++++++++- tests/fixtures/join/fields_5.txt | 6 ++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/join/fields_5.txt diff --git a/tests/by-util/test_join.rs b/tests/by-util/test_join.rs index 3bf296290..743eda512 100644 --- a/tests/by-util/test_join.rs +++ b/tests/by-util/test_join.rs @@ -289,7 +289,21 @@ fn wrong_line_order() { .arg("fields_4.txt") .fails() .stderr_is(&format!( - "{0} {1}: fields_4.txt:5: is not sorted: 11 g 5 gh\n{0} {1}: input is not in sorted order", + "{0} {1}: fields_4.txt:5: is not sorted: 11 g 5 gh\n{0} {1}: input is not in sorted order", + ts.bin_path.to_string_lossy(), + ts.util_name + )); +} + +#[test] +fn both_files_wrong_line_order() { + let ts = TestScenario::new(util_name!()); + new_ucmd!() + .arg("fields_4.txt") + .arg("fields_5.txt") + .fails() + .stderr_is(&format!( + "{0} {1}: fields_5.txt:4: is not sorted: 3\n{0} {1}: fields_4.txt:5: is not sorted: 11 g 5 gh\n{0} {1}: input is not in sorted order", ts.bin_path.to_string_lossy(), ts.util_name )); diff --git a/tests/fixtures/join/fields_5.txt b/tests/fixtures/join/fields_5.txt new file mode 100644 index 000000000..13b9b0736 --- /dev/null +++ b/tests/fixtures/join/fields_5.txt @@ -0,0 +1,6 @@ +1 +2 +5 +3 +6 +4