Skip to content

Commit 8f1bd52

Browse files
committed
fix(nl): allow repeated flags to match GNU behavior
• Enable args_override_self(true) for repeated flags • Remove unnecessary ArgAction::Append calls • Fix tests to verify last value wins, not just succeeds • Update test output validation for repeated flags Fixes #9132
1 parent 8f7afa7 commit 8f1bd52

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

src/uu/nl/src/nl.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ pub fn uu_app() -> Command {
245245
.after_help(translate!("nl-after-help"))
246246
.infer_long_args(true)
247247
.disable_help_flag(true)
248+
.args_override_self(true)
248249
.arg(
249250
Arg::new(options::HELP)
250251
.long(options::HELP)

tests/by-util/test_nl.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,3 +800,104 @@ fn test_file_with_non_utf8_content() {
800800
String::from_utf8_lossy(invalid_utf8)
801801
));
802802
}
803+
804+
// Regression tests for issue #9132: repeated flags should use last value
805+
#[test]
806+
fn test_repeated_body_numbering_flag() {
807+
// -ba -bt should use -bt (t=nonempty)
808+
new_ucmd!()
809+
.args(&["-ba", "-bt"])
810+
.pipe_in("a\n\nb\n\nc")
811+
.succeeds()
812+
.stdout_is(" 1\ta\n \n 2\tb\n \n 3\tc\n");
813+
}
814+
815+
#[test]
816+
fn test_repeated_header_numbering_flag() {
817+
// -ha -ht should use -ht (t=nonempty in header)
818+
new_ucmd!()
819+
.args(&["-ha", "-ht"])
820+
.pipe_in(r"\:::\na\nb\nc")
821+
.succeeds()
822+
.stdout_contains(" 1\t\\:::");
823+
}
824+
825+
#[test]
826+
fn test_repeated_footer_numbering_flag() {
827+
// -fa -ft should use -ft (t=nonempty in footer)
828+
new_ucmd!()
829+
.args(&["-fa", "-ft"])
830+
.pipe_in(r"\:\na\nb\nc")
831+
.succeeds()
832+
.stdout_contains(r" 1 \:");
833+
}
834+
835+
#[test]
836+
fn test_repeated_number_format_flag() {
837+
// -n ln -n rn should use -n rn (rn=right aligned)
838+
new_ucmd!()
839+
.args(&["-n", "ln", "-n", "rn"])
840+
.pipe_in("a\nb\nc")
841+
.succeeds()
842+
.stdout_is(" 1\ta\n 2\tb\n 3\tc\n");
843+
}
844+
845+
#[test]
846+
fn test_repeated_number_separator_flag() {
847+
// -s ':' -s '|' should use -s '|'
848+
new_ucmd!()
849+
.args(&["-s", ":", "-s", "|"])
850+
.pipe_in("a\nb\nc")
851+
.succeeds()
852+
.stdout_is(" 1|a\n 2|b\n 3|c\n");
853+
}
854+
855+
#[test]
856+
fn test_repeated_number_width_flag() {
857+
// -w 3 -w 8 should use -w 8
858+
new_ucmd!()
859+
.args(&["-w", "3", "-w", "8"])
860+
.pipe_in("a\nb\nc")
861+
.succeeds()
862+
.stdout_is(" 1\ta\n 2\tb\n 3\tc\n");
863+
}
864+
865+
#[test]
866+
fn test_repeated_line_increment_flag() {
867+
// -i 1 -i 5 should use -i 5
868+
new_ucmd!()
869+
.args(&["-i", "1", "-i", "5"])
870+
.pipe_in("a\nb\nc")
871+
.succeeds()
872+
.stdout_is(" 1\ta\n 6\tb\n 11\tc\n");
873+
}
874+
875+
#[test]
876+
fn test_repeated_starting_line_number_flag() {
877+
// -v 1 -v 10 should use -v 10
878+
new_ucmd!()
879+
.args(&["-v", "1", "-v", "10"])
880+
.pipe_in("a\nb\nc")
881+
.succeeds()
882+
.stdout_is(" 10\ta\n 11\tb\n 12\tc\n");
883+
}
884+
885+
#[test]
886+
fn test_repeated_join_blank_lines_flag() {
887+
// -l 1 -l 2 should use -l 2
888+
new_ucmd!()
889+
.args(&["-l", "1", "-l", "2"])
890+
.pipe_in("a\n\n\nb")
891+
.succeeds()
892+
.stdout_is(" 1\ta\n \n \n 2\tb\n");
893+
}
894+
895+
#[test]
896+
fn test_repeated_section_delimiter_flag() {
897+
// -d ':' -d '|' should use -d '|'
898+
new_ucmd!()
899+
.args(&["-d", ":", "-d", "|"])
900+
.pipe_in("a\nb\nc")
901+
.succeeds()
902+
.stdout_is(" 1\ta\n 2\tb\n 3\tc\n");
903+
}

0 commit comments

Comments
 (0)