From 77040128cde31845bf8a3222fb23dba0cd18194a Mon Sep 17 00:00:00 2001 From: Yun Zheng Hu Date: Mon, 16 Feb 2026 22:38:36 +0100 Subject: [PATCH 1/4] Allow spaces in -F/--fields and -X/--exclude values --- flow/record/tools/rdump.py | 4 ++-- tests/tools/test_rdump.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/flow/record/tools/rdump.py b/flow/record/tools/rdump.py index 974cbf6..4d382e6 100644 --- a/flow/record/tools/rdump.py +++ b/flow/record/tools/rdump.py @@ -321,8 +321,8 @@ def main(argv: list[str] | None = None) -> int: root_logger.handlers.clear() root_logger.addHandler(handler) - fields_to_exclude = args.exclude.split(",") if args.exclude else [] - fields = args.fields.split(",") if args.fields else [] + fields_to_exclude = [x.strip() for x in args.exclude.split(",")] if args.exclude else [] + fields = [x.strip() for x in args.fields.split(",")] if args.fields else [] if args.list_adapters: list_adapters() diff --git a/tests/tools/test_rdump.py b/tests/tools/test_rdump.py index 6a364bd..465a94a 100644 --- a/tests/tools/test_rdump.py +++ b/tests/tools/test_rdump.py @@ -904,3 +904,30 @@ def test_rdump_print_error_notes( rdump.main([str(path), "-vvv"]) capsys.readouterr() + + +def test_rdump_fields_with_spaces(tmp_path: Path) -> None: + """Test if rdump handles spaces in field names gracefully.""" + TestRecord = RecordDescriptor( + "test/record", + [ + ("varint", "count"), + ("string", "foo"), + ("string", "bar"), + ], + ) + + path = tmp_path / "test.records" + out_path = tmp_path / "out.records" + with RecordWriter(path) as writer: + writer.write(TestRecord(count=0, foo="bar", bar="baz")) + + rdump.main([str(path), "--fields", "foo, count ", "-w", str(out_path)]) + with RecordReader(out_path) as reader: + for record in reader: + assert list(record._desc.fields.keys()) == ["foo", "count"] + + rdump.main([str(path), "--exclude", " foo, bar ", "-w", str(out_path)]) + with RecordReader(out_path) as reader: + for record in reader: + assert list(record._desc.fields.keys()) == ["count"] From 703d5709f1396b1b91275caf37cb06f5752f46ba Mon Sep 17 00:00:00 2001 From: Yun Zheng Hu Date: Tue, 17 Feb 2026 09:57:44 +0000 Subject: [PATCH 2/4] Pass fields+exclude args via kwargs instead of uri --- flow/record/tools/rdump.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/flow/record/tools/rdump.py b/flow/record/tools/rdump.py index 4d382e6..d2dec0d 100644 --- a/flow/record/tools/rdump.py +++ b/flow/record/tools/rdump.py @@ -324,6 +324,12 @@ def main(argv: list[str] | None = None) -> int: fields_to_exclude = [x.strip() for x in args.exclude.split(",")] if args.exclude else [] fields = [x.strip() for x in args.fields.split(",")] if args.fields else [] + writer_options = {} + if fields: + writer_options["fields"] = fields + if fields_to_exclude: + writer_options["exclude"] = fields_to_exclude + if args.list_adapters: list_adapters() return 0 @@ -340,8 +346,6 @@ def main(argv: list[str] | None = None) -> int: } uri = mode_to_uri.get(args.mode, uri) qparams = { - "fields": args.fields, - "exclude": args.exclude, "format_spec": args.format, } query = urlencode({k: v for k, v in qparams.items() if v}) @@ -393,7 +397,7 @@ def main(argv: list[str] | None = None) -> int: ret = 0 try: - with RecordWriter(uri) as record_writer: + with RecordWriter(uri, **writer_options) as record_writer: for count, rec in enumerate(record_iterator, start=1): # noqa: B007 if args.record_source is not None: rec._source = args.record_source From 1784e0b0ad8bae1b73d75eedce3350e5fbf51c7d Mon Sep 17 00:00:00 2001 From: Yun Zheng Hu Date: Tue, 17 Feb 2026 10:01:00 +0000 Subject: [PATCH 3/4] Fix test to be more robust --- tests/tools/test_rdump.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/tools/test_rdump.py b/tests/tools/test_rdump.py index 465a94a..ef13c76 100644 --- a/tests/tools/test_rdump.py +++ b/tests/tools/test_rdump.py @@ -924,10 +924,12 @@ def test_rdump_fields_with_spaces(tmp_path: Path) -> None: rdump.main([str(path), "--fields", "foo, count ", "-w", str(out_path)]) with RecordReader(out_path) as reader: - for record in reader: - assert list(record._desc.fields.keys()) == ["foo", "count"] + records = list(reader) + assert len(records) == 1 + assert list(records[0]._desc.fields.keys()) == ["foo", "count"] rdump.main([str(path), "--exclude", " foo, bar ", "-w", str(out_path)]) with RecordReader(out_path) as reader: - for record in reader: - assert list(record._desc.fields.keys()) == ["count"] + records = list(reader) + assert len(records) == 1 + assert list(records[0]._desc.fields.keys()) == ["count"] From dc7ab005fdff84d23a2d7e3c4eaf241d25d810b6 Mon Sep 17 00:00:00 2001 From: Yun Zheng Hu Date: Tue, 17 Feb 2026 11:50:30 +0000 Subject: [PATCH 4/4] Apply copilot suggestions --- flow/record/tools/rdump.py | 4 ++-- tests/tools/test_rdump.py | 10 +++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/flow/record/tools/rdump.py b/flow/record/tools/rdump.py index d2dec0d..3ec4c40 100644 --- a/flow/record/tools/rdump.py +++ b/flow/record/tools/rdump.py @@ -321,8 +321,8 @@ def main(argv: list[str] | None = None) -> int: root_logger.handlers.clear() root_logger.addHandler(handler) - fields_to_exclude = [x.strip() for x in args.exclude.split(",")] if args.exclude else [] - fields = [x.strip() for x in args.fields.split(",")] if args.fields else [] + fields_to_exclude = list(filter(None, map(str.strip, args.exclude.split(",")))) if args.exclude else [] + fields = list(filter(None, map(str.strip, args.fields.split(",")))) if args.fields else [] writer_options = {} if fields: diff --git a/tests/tools/test_rdump.py b/tests/tools/test_rdump.py index ef13c76..6e06726 100644 --- a/tests/tools/test_rdump.py +++ b/tests/tools/test_rdump.py @@ -906,7 +906,7 @@ def test_rdump_print_error_notes( capsys.readouterr() -def test_rdump_fields_with_spaces(tmp_path: Path) -> None: +def test_rdump_fields_with_spaces(tmp_path: Path, capsysbinary: pytest.CaptureFixture) -> None: """Test if rdump handles spaces in field names gracefully.""" TestRecord = RecordDescriptor( "test/record", @@ -922,14 +922,22 @@ def test_rdump_fields_with_spaces(tmp_path: Path) -> None: with RecordWriter(path) as writer: writer.write(TestRecord(count=0, foo="bar", bar="baz")) + # test if fields works with spaces in the name rdump.main([str(path), "--fields", "foo, count ", "-w", str(out_path)]) with RecordReader(out_path) as reader: records = list(reader) assert len(records) == 1 assert list(records[0]._desc.fields.keys()) == ["foo", "count"] + # test if exclude works with spaces in the field names rdump.main([str(path), "--exclude", " foo, bar ", "-w", str(out_path)]) with RecordReader(out_path) as reader: records = list(reader) assert len(records) == 1 assert list(records[0]._desc.fields.keys()) == ["count"] + + # also test an adapter + rdump.main([str(path), "--exclude", " foo, bar ", "--csv"]) + captured = capsysbinary.readouterr() + assert captured.err == b"" + assert b"count,_source,_classification,_generated,_version\r\n" in captured.out