Add has_depends-on:<query> operator This operator matches changes that have "Depends-on" change dependencies defined in their comments matched by the given sub query. Change-Id: Ieb9a5e7da22a4f44e546cbcf5a5a2e9e9715e403
diff --git a/src/main/java/com/googlesource/gerrit/plugins/depends/on/DependsOnOperator.java b/src/main/java/com/googlesource/gerrit/plugins/depends/on/DependsOnOperator.java new file mode 100644 index 0000000..5761248 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/depends/on/DependsOnOperator.java
@@ -0,0 +1,79 @@ +// Copyright (C) 2022 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.googlesource.gerrit.plugins.depends.on; + +import com.google.gerrit.index.query.PostFilterPredicate; +import com.google.gerrit.index.query.Predicate; +import com.google.gerrit.index.query.QueryParseException; +import com.google.gerrit.server.notedb.ChangeNotes; +import com.google.gerrit.server.query.change.ChangeData; +import com.google.gerrit.server.query.change.ChangeQueryBuilder; +import com.google.gerrit.server.query.change.ChangeQueryBuilder.ChangeOperatorFactory; +import com.google.inject.Inject; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class DependsOnOperator implements ChangeOperatorFactory { + public static final String FIELD = "has"; + + public class DependsOnPredicate extends PostFilterPredicate<ChangeData> { + private Predicate<ChangeData> subQuery; + + public DependsOnPredicate(Predicate<ChangeData> subQuery) { + super(FIELD, subQuery.toString()); + this.subQuery = subQuery; + } + + @Override + public boolean match(ChangeData change) { + Set<DependsOn> dependOns = changeMessageStore.load(change.getId()); + List<ChangeNotes> changeNotes = + changeNotesFactory.createUsingIndexLookup( + dependOns.stream() + .filter(d -> d.isResolved()) + .map(DependsOn::id) + .collect(Collectors.toList())); + return changeNotes.stream() + .anyMatch( + note -> subQuery.asMatchable().match(changeDataFactory.create(note.getChange()))); + } + + @Override + public int getCost() { + return 2; + } + } + + protected final ChangeMessageStore changeMessageStore; + protected final ChangeNotes.Factory changeNotesFactory; + protected final ChangeData.Factory changeDataFactory; + + @Inject + public DependsOnOperator( + ChangeMessageStore changeMessageStore, + ChangeNotes.Factory changeNotesFactory, + ChangeData.Factory changeDataFactory) { + this.changeMessageStore = changeMessageStore; + this.changeNotesFactory = changeNotesFactory; + this.changeDataFactory = changeDataFactory; + } + + @Override + public Predicate<ChangeData> create(ChangeQueryBuilder builder, String value) + throws QueryParseException { + return new DependsOnPredicate(builder.parse(value)); + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/depends/on/Module.java b/src/main/java/com/googlesource/gerrit/plugins/depends/on/Module.java index 0a51e2b..2b40b88 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/depends/on/Module.java +++ b/src/main/java/com/googlesource/gerrit/plugins/depends/on/Module.java
@@ -45,6 +45,9 @@ bind(ChangeOperatorFactory.class) .annotatedWith(Exports.named(InDependsOnOperator.FIELD)) .to(InDependsOnOperator.class); + bind(ChangeOperatorFactory.class) + .annotatedWith(Exports.named(DependsOnOperator.FIELD)) + .to(DependsOnOperator.class); bind(ChangeHasOperandFactory.class) .annotatedWith(Exports.named(HasDependsOnOperator.FIELD)) .to(HasDependsOnOperator.class);
diff --git a/src/main/resources/Documentation/change-search-operators.md b/src/main/resources/Documentation/change-search-operators.md index dc7585d..c16c514 100644 --- a/src/main/resources/Documentation/change-search-operators.md +++ b/src/main/resources/Documentation/change-search-operators.md
@@ -5,6 +5,10 @@ : Changes that are listed as "Depends-on" change dependencies defined in the comments of the provided change. +**has_@PLUGIN@:<query>** + +: Changes that have "Depends-on" change dependencies defined in their comments which match the given sub query. + **has:a_@PLUGIN@** : Changes that have at least one "Depends-on" change dependencies defined in their comments.
diff --git a/test/docker/gerrit/start.sh b/test/docker/gerrit/start.sh index 09bac64..cf48b39 100755 --- a/test/docker/gerrit/start.sh +++ b/test/docker/gerrit/start.sh
@@ -3,6 +3,8 @@ git config -f "$GERRIT_SITE/etc/gerrit.config" \ operator-alias.change.independson "in_depends-on" git config -f "$GERRIT_SITE/etc/gerrit.config" \ + operator-alias.change.hasdependson "has_depends-on" +git config -f "$GERRIT_SITE/etc/gerrit.config" \ sendemail.enable "false" echo "Initializing Gerrit site ..."
diff --git a/test/test_dependson_operators.sh b/test/test_dependson_operators.sh index 1c861a1..03c31c3 100755 --- a/test/test_dependson_operators.sh +++ b/test/test_dependson_operators.sh
@@ -1,13 +1,12 @@ #!/usr/bin/env bash -# This test relies on change operator aliasing for "in_depends-on" operator -# since query parser is not able to parse dash(-) in depends-on -# operator. -# This test assumes that change operator aliasing for "in_depends-on" operator -# is configured as follows : +# This test relies on change operator aliasing since query parser +# cannot parse hyphens(-) in field names. Following alias have to be +# configured: # # [operator-alias "change"] # independson = in_depends-on +# hasdependson = has_depends-on # run a gerrit ssh command gssh() { ssh -x -p "$PORT" "$SERVER" "$@" ; 2>&1 ; } # [args]... @@ -145,4 +144,13 @@ ACTUAL="$(query "change:$CHANGE_2 has:a_depends-on" | jq --raw-output '.number')" result_out "has:a_depends-on operator (empty Depends-On)" "null" "$ACTUAL" +# ------------------------- hasdependson:<query> Tests --------------------------- +CHANGE_1=$(create_change "$SRC_REF_BRANCH" "$FILE_A") || \ + die "Failed to create change on project: $PROJECT branch: $SRC_REF_BRANCH" +CHANGE_2=$(create_change "$SRC_REF_BRANCH" "$FILE_A") || \ + die "Failed to create change on project: $PROJECT branch: $SRC_REF_BRANCH" +gssh gerrit review --message \'"Depends-on: $CHANGE_1"\' "$CHANGE_2",1 +ACTUAL="$(query "change:$CHANGE_2 hasdependson:\"change:$CHANGE_1\"" | jq --raw-output '.number')" +result_out "hasdependson operator" "$CHANGE_2" "$ACTUAL" + exit $RESULT