Submit requirements: Inability to express “non-matching file paths” (negative path predicate)

16 views
Skip to first unread message

David Horton

unread,
2:34 AM (14 hours ago) 2:34 AM
to Repo and Gerrit Discussion

Hi all,

I’ve run into a limitation in Gerrit submit requirements when trying to express path-dependent validation rules and wanted to check whether this is expected and/or if there’s interest in improving it.

Use case

We have a single repository with a subdirectory (aviary/) that has its own CI pipeline and verification requirements, separate from the rest of the repo.

We would like to express the following behaviour via submit requirements:

  • Changes affecting only aviary/** → require Aviary checks only

  • Changes affecting only non-aviary/** paths → require non-Aviary checks only

  • Changes affecting both → require both sets of checks

The positive case works fine: applicableIf = file:^aviary/.*

Problem

There does not appear to be a way to express:

“there exists a changed file that is not under aviary/”

The natural regex form would be:

file:^(?!aviary/).*

However, this fails during submit-requirement validation:

no viable alternative at character '?'

This appears to be because the expression is first parsed by Gerrit’s query parser, which rejects the ? before the file:operator sees the pattern.

I also tried:

  • quoting: file:"^(?!aviary/).*"

  • brace grouping: file:{^(?!aviary/).*}

These are accepted syntactically in some contexts, but do not behave correctly for applicability.  I also tried variations of double and higher escaping.

NOTE:

This is semantically different from negating the existing file: predicate.

NOT file:^aviary/.*

means:
      "no changed file is under aviary/"

whereas:

fileNot:^aviary/.*

means:
      "there exists at least one changed file not under aviary/"

These differ for mixed changes (touching both aviary and non-aviary paths), which is exactly the case we need to support.


Current workaround

The only viable workaround seems to be moving this logic into CI orchestration (e.g. an aggregator build that decides which labels to apply), rather than expressing it in submit requirements. This works, but loses the declarative nature of submit requirements and introduces ordering/race concerns.

Proposal

It would be very useful to have a first-class way to express the negative case, for example:

fileNot:^aviary/.*

or

pathNot:^aviary/.*

with semantics:

  • file:^aviary/.* → at least one changed path matches

  • fileNot:^aviary/.* → at least one changed path does not match

This would allow clean expression of mixed-path requirements without relying on regex lookahead or CI-side logic.

Why a new operator?

While it might be possible to extend the query parser to support more complex regex constructs, this would require changes to the parser and could introduce unintended compatibility issues.

A dedicated operator seems:

  • clearer to users

  • easier to document

  • safer from a backward-compatibility perspective

Questions
  • Is there an existing way to express this that I’ve missed?

  • Would a fileNot: / pathNot: predicate be acceptable?

  • If so, I’m happy to work on this.  I’ve attached a draft patch to illustrate the approach — happy to revise or rework this based on feedback.

Thanks!

David


gerrit_submit_requirements_fileNot.patch
gerrit_submit_requirements_fileNot.msg
Reply all
Reply to author
Forward
0 new messages