Skip to content

feat: allow repeated --filter flags for exports - #443

Open
jacalata wants to merge 1 commit into
developmentfrom
jac/filter-repeatable
Open

feat: allow repeated --filter flags for exports#443
jacalata wants to merge 1 commit into
developmentfrom
jac/filter-repeatable

Conversation

@jacalata

@jacalata jacalata commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Motivation

--filter previously accepted one value and required multi-pair filters
to be joined with &. That parsing scheme prevents literal & inside a
value (e.g. Product Name=AT&T gets split). Making --filter
repeatable removes the need for callers to encode delimiters.

Related to #442, which handles the same problem when the filter comes in
via URL syntax rather than the flag.

Behavior change

For users: --filter is now repeatable. Each flag carries exactly
one COLUMN=VALUE pair.

--filter "Region=West&Product=Widget"                # still works (back-compat)
--filter "Region=West" --filter "Product=Widget"     # preferred
--filter "Product=AT&T"                              # new: repeated form allows '&' in value

Back-compat: when only one --filter is present, the value is still
split on &. This means a single flag carrying one filter with & in
its value (e.g. --filter "Product=AT&T" alone) is still ambiguous.
Workaround: pass the filter in the URL query string instead of via
--filter. #442 landed the URL-path handling for literal &, so
tabcmd get "views/View/Sheet.csv?Product%20Name=AT&T%20841000%20Phone"
works correctly (space must be encoded as %20; & may be literal).

Test plan

  • pytest tests/commands/test_datasources_and_workbooks_command.py tests/parsers/test_parser_export.py — 34 passed
  • Manual e2e: repeated --filter with & in the value returns the
    expected row
  • Manual e2e: single-flag &-joined form still parses and filters
    correctly

🤖 Generated with Claude Code

Previously `--filter` accepted only one value, and multi-pair filtering
required joining pairs with '&' (e.g. `--filter "A=1&B=2"`). That
parsing scheme conflicts with values that legitimately contain '&'
(e.g. `Product Name=AT&T ...`).

Make `--filter` repeatable via argparse action="append". Each flag now
carries exactly one COLUMN=VALUE pair — no '&' splitting — so literal
'&' in a value passes through untouched.

Back-compat: when only one --filter flag is present, the value is still
split on '&' so existing scripts keep working. Users who need '&' in a
value should switch to the repeated-flag form.

Adds parser tests for the new syntax and unit tests for
apply_filters_from_args covering both forms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jacalata
jacalata changed the base branch from main to development July 30, 2026 21:57
@jacalata
jacalata requested a lite review from Copilot August 6, 2026 21:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for repeating --filter on the export command while preserving backward-compatible parsing of legacy &-joined filter pairs.

Changes:

  • Update export CLI arg parsing to accept multiple --filter flags (action="append").
  • Implement back-compat filter splitting when a single --filter contains &.
  • Add/extend tests for parser behavior and filter application; update help text to document new usage.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
tests/parsers/test_parser_export.py Adds tests validating --filter repeatability and default behavior.
tests/commands/test_datasources_and_workbooks_command.py Adds unit tests for applying parsed filters into TSC request options, including back-compat.
tabcmd/locales/en/tabcmd_messages_en.properties Expands the --filter help text to document the new repeatable flag semantics and back-compat.
tabcmd/commands/datasources_and_workbooks/export_command.py Changes --filter arg to append and updates filter parsing logic accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +147 to +159
if not args.filter:
return
logger.debug("filter = {}".format(args.filter))
# Back-compat: a single --filter flag historically joined multiple pairs
# with '&' (e.g. `--filter "a=1&b=2"`), so that one case still splits on '&'.
# Repeated --filter flags each carry exactly one pair — no split — so a
# literal '&' or '=' in a value is passed through untouched.
if len(args.filter) == 1:
values = args.filter[0].split("&")
else:
values = args.filter
for value in values:
ExportCommand.apply_filter_value(logger, request_options, value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants