From c896d16e8f5e7d3ca12ccea8ccd61395ce148d5a Mon Sep 17 00:00:00 2001 From: Jan Riemer <2428387-janriemer@users.noreply.gitlab.com> Date: Sun, 5 Nov 2023 16:27:24 +0100 Subject: [PATCH 1/3] `diff`: `no-headers-result` -> `no-headers-output` We want to be consistent with the rest of qsv. --- src/cmd/diff.rs | 8 ++++---- tests/test_diff.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cmd/diff.rs b/src/cmd/diff.rs index 1f36470d2..2858cac87 100644 --- a/src/cmd/diff.rs +++ b/src/cmd/diff.rs @@ -24,7 +24,7 @@ sort the result by the first and second column: qsv diff -k 0,1 --sort-columns 0,1 left.csv right.csv Find the difference between two CSVs, but do not output headers in the result: - qsv diff --no-headers-result left.csv right.csv + qsv diff --no-headers-output left.csv right.csv Find the difference between two CSVs. Both CSVs have no headers, but the result should have headers, so generic headers will be used in the form of: _col_1, _col_2, etc.: @@ -45,7 +45,7 @@ diff options: the right CSV to diff. (When not set, the first row is the header row and will be skipped during the diff. It will always appear in the output.) - --no-headers-result When set, the diff result won't have a header row in + --no-headers-output When set, the diff result won't have a header row in it's output. If not set and both CSVs have no headers, headers in the result will be: _col_1,_col_2, etc. --delimiter-left The field delimiter for reading CSV data on the left. @@ -96,7 +96,7 @@ struct Args { flag_no_headers_right: bool, flag_delimiter_left: Option, flag_delimiter_right: Option, - flag_no_headers_result: bool, + flag_no_headers_output: bool, flag_key: Option, flag_sort_columns: Option, } @@ -166,7 +166,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> { }, } - let mut csv_diff_writer = CsvDiffWriter::new(wtr, args.flag_no_headers_result); + let mut csv_diff_writer = CsvDiffWriter::new(wtr, args.flag_no_headers_output); Ok(csv_diff_writer.write_diff_byte_records(diff_byte_records)?) } diff --git a/tests/test_diff.rs b/tests/test_diff.rs index d45c782ae..db4f244fa 100644 --- a/tests/test_diff.rs +++ b/tests/test_diff.rs @@ -227,7 +227,7 @@ fn diff_with_no_headers_in_result() { wrk.create("right.csv", right); let mut cmd = wrk.command("diff"); - cmd.args(["left.csv", "right.csv", "--no-headers-result"]); + cmd.args(["left.csv", "right.csv", "--no-headers-output"]); let got: Vec> = wrk.read_stdout(&mut cmd); let expected = vec![ @@ -249,7 +249,7 @@ fn diff_no_diff_with_no_headers_in_result() { wrk.create("right.csv", right); let mut cmd = wrk.command("diff"); - cmd.args(["left.csv", "right.csv", "--no-headers-result"]); + cmd.args(["left.csv", "right.csv", "--no-headers-output"]); let got: Vec> = wrk.read_stdout(&mut cmd); let expected: Vec> = vec![]; @@ -347,7 +347,7 @@ fn diff_with_no_left_no_right_and_no_headers_in_result() { "right.csv", "--no-headers-left", "--no-headers-right", - "--no-headers-result", + "--no-headers-output", ]); let got: Vec> = wrk.read_stdout(&mut cmd); From dbe5c70d8c28cf6807fe9dafdbc4896d2d42d1ee Mon Sep 17 00:00:00 2001 From: Jan Riemer <2428387-janriemer@users.noreply.gitlab.com> Date: Sun, 5 Nov 2023 17:15:26 +0100 Subject: [PATCH 2/3] `diff`: add option/flag `--delimiter-output` This adds an option to specify, which delimiter to use for the resulting diff output. By default, it uses ',' as the delimiter. Example: csv_left.csv col1,col2,col3 1,foo,bar csv_right.csv col1,col2,col3 1,foo,baz qsv diff --delimiter-output ';' csv_left.csv csv_right.csv Output: diffresult;col1;col2;col3 -;1;foo;bar +;1;foo;baz --- src/cmd/diff.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/cmd/diff.rs b/src/cmd/diff.rs index 2858cac87..2233a9f34 100644 --- a/src/cmd/diff.rs +++ b/src/cmd/diff.rs @@ -16,6 +16,12 @@ Find the difference between two CSVs. The left CSV uses a tab as the delimiter: # or ';' as the delimiter qsv diff --delimiter-left ';' left.csv right-semicolon.csv +Find the difference between two CSVs. The output CSV uses a tab as the delimiter +and is written to a file: + qsv diff -o diff-tab.tsv --delimiter-output '\t' left.csv right.csv + # or ';' as the delimiter + qsv diff -o diff-semicolon.csv --delimiter-output ';' left.csv right.csv + Find the difference between two CSVs, but only for the first two columns: qsv diff --key 0,1 left.csv right.csv @@ -52,6 +58,8 @@ diff options: Must be a single character. (default: ,) --delimiter-right The field delimiter for reading CSV data on the right. Must be a single character. (default: ,) + --delimiter-output The field delimiter for writing the CSV diff result. + Must be a single character. (default: ,) -k, --key The column indices that uniquely identify a record as a comma separated list of indices, e.g. 0,1,2. (default: 0) @@ -94,9 +102,10 @@ struct Args { flag_jobs: Option, flag_no_headers_left: bool, flag_no_headers_right: bool, + flag_no_headers_output: bool, flag_delimiter_left: Option, flag_delimiter_right: Option, - flag_no_headers_output: bool, + flag_delimiter_output: Option, flag_key: Option, flag_sort_columns: Option, } @@ -137,7 +146,9 @@ pub fn run(argv: &[&str]) -> CliResult<()> { }) .transpose()?; - let wtr = Config::new(&args.flag_output).writer()?; + let wtr = Config::new(&args.flag_output) + .delimiter(args.flag_delimiter_output) + .writer()?; let csv_rdr_left = rconfig_left.reader()?; let csv_rdr_right = rconfig_right.reader()?; From f934fb1acfc5ee59ffa5a36df53fdd726255a6c3 Mon Sep 17 00:00:00 2001 From: Jan Riemer <2428387-janriemer@users.noreply.gitlab.com> Date: Sun, 5 Nov 2023 17:20:28 +0100 Subject: [PATCH 3/3] `diff`: add tests for `--delimiter-output` --- tests/test_diff.rs | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test_diff.rs b/tests/test_diff.rs index db4f244fa..a6c3dd1ba 100644 --- a/tests/test_diff.rs +++ b/tests/test_diff.rs @@ -425,6 +425,48 @@ fn diff_left_has_one_column_right_has_none_headers_in_result() { assert_eq!(got, expected); } +#[test] +fn diff_with_default_delimiter_in_result() { + let wrk = Workdir::new("diff_with_default_delimiter_in_result"); + + let left = vec![svec!["h1", "h2", "h3"], svec!["1", "foo", "bar"]]; + wrk.create("left.csv", left); + + let right = vec![svec!["h1", "h2", "h3"], svec!["1", "foo_changed", "bar"]]; + wrk.create("right.csv", right); + + let mut cmd = wrk.command("diff"); + cmd.args(["left.csv", "right.csv"]); + + let got: String = wrk.stdout(&mut cmd); + let expected = "\ +diffresult,h1,h2,h3 +-,1,foo,bar ++,1,foo_changed,bar"; + assert_eq!(got.as_str(), expected); +} + +#[test] +fn diff_with_different_delimiter_in_result() { + let wrk = Workdir::new("diff_with_different_delimiter_in_result"); + + let left = vec![svec!["h1", "h2", "h3"], svec!["1", "foo", "bar"]]; + wrk.create("left.csv", left); + + let right = vec![svec!["h1", "h2", "h3"], svec!["1", "foo_changed", "bar"]]; + wrk.create("right.csv", right); + + let mut cmd = wrk.command("diff"); + cmd.args(["left.csv", "right.csv", "--delimiter-output", ";"]); + + let got: String = wrk.stdout(&mut cmd); + let expected = "\ +diffresult;h1;h2;h3 +-;1;foo;bar ++;1;foo_changed;bar"; + assert_eq!(got.as_str(), expected); +} + fn create_file_with_delim(wrk: &Workdir, file_path_new: &str, file_path: &str, delimiter: u8) { let mut select_cmd = wrk.command("select"); select_cmd.args(["1-", file_path]);