Add exclude tags/tag query option#361
Open
awgymer wants to merge 10 commits into
Open
Conversation
Adds an excludeTags field and two-list constructor. The isExcluded() helper mirrors the existing recursive include logic so exclusion is case-insensitive, name-based, and hierarchical. Exclusion is evaluated before inclusion so --exclude-tag always wins. Removes the varargs constructor which conflated include tags into a single ambiguous list and would become misleading as TagQuery gains more structure (upcoming AND-logic feature).
Mirrors the existing --tag option: comma-separated, multi-value, case-insensitive. Wires the new excludeTags list into TagQuery construction so the resolver applies exclusion automatically.
Migrates existing varargs TagQuery call sites to List.of() following removal of the varargs constructor. Adds four new tests covering exclude by tag, exclude by suite-level tag, exclude by name, and combined include+exclude.
Introduces TagExpression interface and four implementations: - TagNode: leaf node that matches a tag against a test's name, tags, and parent tags (case-insensitive, hierarchical) - NotNode: negates its operand - AndNode: short-circuiting logical AND of two expressions - OrNode: short-circuiting logical OR of two expressions Lays the groundwork for boolean tag query expressions such as (!foo && bar) || baz.
Recursive descent parser for boolean tag query expressions supporting:
- Unquoted tags (letters, digits, underscores, hyphens)
- Quoted tags with single or double quotes (allows whitespace)
- Logical operators: ! (NOT), && (AND), || (OR), with () grouping
- Operator precedence: ! > && > ||
Parse errors are reported as TagQueryParseException which includes the
original query and a caret pointer to the exact position of the problem:
Invalid tag query: foo & bar
^
Expected '&&' but got '&' — did you mean '&&'?
Tests cover: - AST shape: operator precedence, parenthesis grouping, nesting - Evaluation: single tag, name matching, case-insensitivity, NOT/AND/OR, complex expressions, parent tag inheritance, quoted multi-word tags (both single and double quotes) - Errors: empty input, unmatched parens, unterminated strings, single & and |, trailing operators — all verified to throw TagQueryParseException at the correct position
Allows TagQuery to delegate matching to a TagExpression AST rather than the internal include/exclude tag lists. When an expression is set, matches() evaluates it directly, bypassing the list-based logic.
Accepts a boolean tag expression string (e.g. '(!tag1 && tag2) || tag3') parsed by TagQueryParser. Cannot be combined with --tag or --exclude-tag. Parse errors are reported with a caret pointer to the problem position and return exit code 1 without a stack trace.
84b28c8 to
254fe33
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Started as
--exclude-tagbut I noticed that there had been some outstanding work on adding complex tag queries.I implemented a simple query grammar:
!: NOT&&: AND||: ORFor now I left the
--tagand--exclude-tagas mutually exclusive to the new query system but in theory they could be easily dropped and the new--tag-queryoption used to cover those cases (grammar would just need to be extended to see,as||I think).Would supersede #283
Closes #180
Closes #255
Closes #260