Support searching changes that touch directories by regular expressions
Signed-off-by: Edwin Kempin <ekempin@google.com> Change-Id: I8865dbf9b6dd7bd3b83f2227206f00c8690ddefb
This commit is contained in:
		@@ -317,6 +317,10 @@ E.g. a change that touches a file in the directory 'a/b/c' matches for 'a/b/c',
 | 
			
		||||
+
 | 
			
		||||
Slash ('/') is used path separator. Leading and trailing slashes are allowed
 | 
			
		||||
but are not mandatory.
 | 
			
		||||
+
 | 
			
		||||
If 'DIR' starts with `^` it matches directories and directory segments by
 | 
			
		||||
regular expression. The link:http://www.brics.dk/automaton/[dk.brics.automaton
 | 
			
		||||
library] is used for evaluation of such patterns.
 | 
			
		||||
 | 
			
		||||
[[footer]]
 | 
			
		||||
footer:'FOOTER'::
 | 
			
		||||
 
 | 
			
		||||
@@ -781,6 +781,10 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
 | 
			
		||||
  @Operator
 | 
			
		||||
  public Predicate<ChangeData> directory(String directory) throws QueryParseException {
 | 
			
		||||
    if (args.getSchema().hasField(ChangeField.DIRECTORY)) {
 | 
			
		||||
      if (directory.startsWith("^")) {
 | 
			
		||||
        return new RegexDirectoryPredicate(directory);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return new DirectoryPredicate(directory);
 | 
			
		||||
    }
 | 
			
		||||
    throw new QueryParseException("'directory' operator is not supported by change index version");
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,48 @@
 | 
			
		||||
// Copyright (C) 2019 The Android Open Source Project
 | 
			
		||||
//
 | 
			
		||||
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
// you may not use this file except in compliance with the License.
 | 
			
		||||
// You may obtain a copy of the License at
 | 
			
		||||
//
 | 
			
		||||
// http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
//
 | 
			
		||||
// Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
// See the License for the specific language governing permissions and
 | 
			
		||||
// limitations under the License.
 | 
			
		||||
 | 
			
		||||
package com.google.gerrit.server.query.change;
 | 
			
		||||
 | 
			
		||||
import com.google.gerrit.server.index.change.ChangeField;
 | 
			
		||||
import com.google.gwtorm.server.OrmException;
 | 
			
		||||
import dk.brics.automaton.RegExp;
 | 
			
		||||
import dk.brics.automaton.RunAutomaton;
 | 
			
		||||
 | 
			
		||||
public class RegexDirectoryPredicate extends ChangeRegexPredicate {
 | 
			
		||||
  protected final RunAutomaton pattern;
 | 
			
		||||
 | 
			
		||||
  public RegexDirectoryPredicate(String re) {
 | 
			
		||||
    super(ChangeField.DIRECTORY, re);
 | 
			
		||||
 | 
			
		||||
    if (re.startsWith("^")) {
 | 
			
		||||
      re = re.substring(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (re.endsWith("$") && !re.endsWith("\\$")) {
 | 
			
		||||
      re = re.substring(0, re.length() - 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.pattern = new RunAutomaton(new RegExp(re).toAutomaton());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public boolean match(ChangeData cd) throws OrmException {
 | 
			
		||||
    return ChangeField.getDirectories(cd).stream().anyMatch(pattern::run);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public int getCost() {
 | 
			
		||||
    return 1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1581,6 +1581,11 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
 | 
			
		||||
    assertQuery("directory:/b/c", change5);
 | 
			
		||||
    assertQuery("directory:/b/c/", change5);
 | 
			
		||||
    assertQuery("directory:b/c/", change5);
 | 
			
		||||
 | 
			
		||||
    // match by regexp
 | 
			
		||||
    assertQuery("directory:^.*va.*", change2);
 | 
			
		||||
    assertQuery("directory:^documentation/.*/slides", change3);
 | 
			
		||||
    assertQuery("directory:^train.*", change3);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user