Extract prolog predicates from gerrit-server:server rule

Change-Id: I52a22035f7b0189c6d1e21cf05c85901c5235853
This commit is contained in:
David Ostrovsky
2017-08-22 09:11:42 +02:00
committed by Dave Borowitz
parent 36daeea48a
commit 3d6cf9b6cc
20 changed files with 16 additions and 1 deletions

View File

@@ -0,0 +1,77 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
abstract class AbstractCommitUserIdentityPredicate extends Predicate.P3 {
private static final SymbolTerm user = SymbolTerm.intern("user", 1);
private static final SymbolTerm anonymous = SymbolTerm.intern("anonymous");
AbstractCommitUserIdentityPredicate(Term a1, Term a2, Term a3, Operation n) {
arg1 = a1;
arg2 = a2;
arg3 = a3;
cont = n;
}
protected Operation exec(Prolog engine, UserIdentity userId) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
Term a3 = arg3.dereference();
Term idTerm;
Term nameTerm = Prolog.Nil;
Term emailTerm = Prolog.Nil;
Account.Id id = userId.getAccount();
if (id == null) {
idTerm = anonymous;
} else {
idTerm = new IntegerTerm(id.get());
}
String name = userId.getName();
if (name != null && !name.equals("")) {
nameTerm = SymbolTerm.create(name);
}
String email = userId.getEmail();
if (email != null && !email.equals("")) {
emailTerm = SymbolTerm.create(email);
}
if (!a1.unify(new StructureTerm(user, idTerm), engine.trail)) {
return engine.fail();
}
if (!a2.unify(nameTerm, engine.trail)) {
return engine.fail();
}
if (!a3.unify(emailTerm, engine.trail)) {
return engine.fail();
}
return cont;
}
}

15
java/gerrit/BUILD Normal file
View File

@@ -0,0 +1,15 @@
java_library(
name = "prolog-predicates",
srcs = glob(["**/*.java"]),
visibility = ["//visibility:public"],
deps = [
"//gerrit-server:server",
"//java/com/google/gerrit/common:server",
"//java/com/google/gerrit/extensions:api",
"//java/com/google/gerrit/reviewdb:server",
"//lib:gwtorm",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/log:api",
"//lib/prolog:runtime",
],
)

View File

@@ -0,0 +1,67 @@
// Copyright 2011 Google Inc. All Rights Reserved.
package gerrit;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
import com.googlecode.prolog_cafe.exceptions.JavaException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
/** Exports list of {@code commit_label( label('Code-Review', 2), user(12345789) )}. */
class PRED__load_commit_labels_1 extends Predicate.P1 {
private static final SymbolTerm sym_commit_label = SymbolTerm.intern("commit_label", 2);
private static final SymbolTerm sym_label = SymbolTerm.intern("label", 2);
private static final SymbolTerm sym_user = SymbolTerm.intern("user", 1);
PRED__load_commit_labels_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term listHead = Prolog.Nil;
try {
ChangeData cd = StoredValues.CHANGE_DATA.get(engine);
LabelTypes types = cd.getLabelTypes();
for (PatchSetApproval a : cd.currentApprovals()) {
LabelType t = types.byLabel(a.getLabelId());
if (t == null) {
continue;
}
StructureTerm labelTerm =
new StructureTerm(
sym_label, SymbolTerm.intern(t.getName()), new IntegerTerm(a.getValue()));
StructureTerm userTerm =
new StructureTerm(sym_user, new IntegerTerm(a.getAccountId().get()));
listHead = new ListTerm(new StructureTerm(sym_commit_label, labelTerm, userTerm), listHead);
}
} catch (OrmException err) {
throw new JavaException(this, 1, err);
}
if (!a1.unify(listHead, engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_change_branch_1 extends Predicate.P1 {
public PRED_change_branch_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Branch.NameKey name = StoredValues.getChange(engine).getDest();
if (!a1.unify(SymbolTerm.create(name.get()), engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_change_owner_1 extends Predicate.P1 {
private static final SymbolTerm user = SymbolTerm.intern("user", 1);
public PRED_change_owner_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Account.Id ownerId = StoredValues.getChange(engine).getOwner();
if (!a1.unify(new StructureTerm(user, new IntegerTerm(ownerId.get())), engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,44 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_change_project_1 extends Predicate.P1 {
public PRED_change_project_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Project.NameKey name = StoredValues.getChange(engine).getProject();
if (!a1.unify(SymbolTerm.create(name.get()), engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,49 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_change_topic_1 extends Predicate.P1 {
public PRED_change_topic_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term topicTerm = Prolog.Nil;
Change change = StoredValues.getChange(engine);
String topic = change.getTopic();
if (topic != null) {
topicTerm = SymbolTerm.create(topic);
}
if (!a1.unify(topicTerm, engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_commit_author_3 extends AbstractCommitUserIdentityPredicate {
public PRED_commit_author_3(Term a1, Term a2, Term a3, Operation n) {
super(a1, a2, a3, n);
}
@Override
public Operation exec(Prolog engine) throws PrologException {
PatchSetInfo psInfo = StoredValues.PATCH_SET_INFO.get(engine);
UserIdentity author = psInfo.getAuthor();
return exec(engine, author);
}
}

View File

@@ -0,0 +1,36 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_commit_committer_3 extends AbstractCommitUserIdentityPredicate {
public PRED_commit_committer_3(Term a1, Term a2, Term a3, Operation n) {
super(a1, a2, a3, n);
}
@Override
public Operation exec(Prolog engine) throws PrologException {
PatchSetInfo psInfo = StoredValues.PATCH_SET_INFO.get(engine);
UserIdentity committer = psInfo.getCommitter();
return exec(engine, committer);
}
}

View File

@@ -0,0 +1,172 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListEntry;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import com.googlecode.prolog_cafe.lang.VariableTerm;
import java.util.Iterator;
import java.util.regex.Pattern;
/**
* Given a regular expression, checks it against the file list in the most recent patchset of a
* change. For all files that match the regex, returns the (new) path of the file, the change type,
* and the old path of the file if applicable (if the file was copied or renamed).
*
* <pre>
* 'commit_delta'(+Regex, -ChangeType, -NewPath, -OldPath)
* </pre>
*/
public class PRED_commit_delta_4 extends Predicate.P4 {
private static final SymbolTerm add = SymbolTerm.intern("add");
private static final SymbolTerm modify = SymbolTerm.intern("modify");
private static final SymbolTerm delete = SymbolTerm.intern("delete");
private static final SymbolTerm rename = SymbolTerm.intern("rename");
private static final SymbolTerm copy = SymbolTerm.intern("copy");
static final Operation commit_delta_check = new PRED_commit_delta_check();
static final Operation commit_delta_next = new PRED_commit_delta_next();
static final Operation commit_delta_empty = new PRED_commit_delta_empty();
public PRED_commit_delta_4(Term a1, Term a2, Term a3, Term a4, Operation n) {
arg1 = a1;
arg2 = a2;
arg3 = a3;
arg4 = a4;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.cont = cont;
engine.setB0();
Term a1 = arg1.dereference();
if (a1 instanceof VariableTerm) {
throw new PInstantiationException(this, 1);
}
if (!(a1 instanceof SymbolTerm)) {
throw new IllegalTypeException(this, 1, "symbol", a1);
}
Pattern regex = Pattern.compile(a1.name());
engine.r1 = new JavaObjectTerm(regex);
engine.r2 = arg2;
engine.r3 = arg3;
engine.r4 = arg4;
PatchList pl = StoredValues.PATCH_LIST.get(engine);
Iterator<PatchListEntry> iter = pl.getPatches().iterator();
engine.r5 = new JavaObjectTerm(iter);
return engine.jtry5(commit_delta_check, commit_delta_next);
}
private static final class PRED_commit_delta_check extends Operation {
@Override
public Operation exec(Prolog engine) {
Term a1 = engine.r1;
Term a2 = engine.r2;
Term a3 = engine.r3;
Term a4 = engine.r4;
Term a5 = engine.r5;
Pattern regex = (Pattern) ((JavaObjectTerm) a1).object();
@SuppressWarnings("unchecked")
Iterator<PatchListEntry> iter = (Iterator<PatchListEntry>) ((JavaObjectTerm) a5).object();
while (iter.hasNext()) {
PatchListEntry patch = iter.next();
String newName = patch.getNewName();
String oldName = patch.getOldName();
Patch.ChangeType changeType = patch.getChangeType();
if (newName.equals("/COMMIT_MSG")) {
continue;
}
if (regex.matcher(newName).find() || (oldName != null && regex.matcher(oldName).find())) {
SymbolTerm changeSym = getTypeSymbol(changeType);
SymbolTerm newSym = SymbolTerm.create(newName);
SymbolTerm oldSym = Prolog.Nil;
if (oldName != null) {
oldSym = SymbolTerm.create(oldName);
}
if (!a2.unify(changeSym, engine.trail)) {
continue;
}
if (!a3.unify(newSym, engine.trail)) {
continue;
}
if (!a4.unify(oldSym, engine.trail)) {
continue;
}
return engine.cont;
}
}
return engine.fail();
}
}
private static final class PRED_commit_delta_next extends Operation {
@Override
public Operation exec(Prolog engine) {
return engine.trust(commit_delta_empty);
}
}
private static final class PRED_commit_delta_empty extends Operation {
@Override
public Operation exec(Prolog engine) {
Term a5 = engine.r5;
@SuppressWarnings("unchecked")
Iterator<PatchListEntry> iter = (Iterator<PatchListEntry>) ((JavaObjectTerm) a5).object();
if (!iter.hasNext()) {
return engine.fail();
}
return engine.jtry5(commit_delta_check, commit_delta_next);
}
}
private static SymbolTerm getTypeSymbol(Patch.ChangeType type) {
switch (type) {
case ADDED:
return add;
case MODIFIED:
return modify;
case DELETED:
return delete;
case RENAMED:
return rename;
case COPIED:
return copy;
case REWRITE:
break;
}
throw new IllegalArgumentException("ChangeType not recognized");
}
}

View File

@@ -0,0 +1,159 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListEntry;
import com.google.gerrit.server.patch.Text;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.JavaException;
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import com.googlecode.prolog_cafe.lang.VariableTerm;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.jgit.diff.Edit;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
/**
* Returns true if any of the files that match FileNameRegex have edited lines that match EditRegex
*
* <pre>
* 'commit_edits'(+FileNameRegex, +EditRegex)
* </pre>
*/
public class PRED_commit_edits_2 extends Predicate.P2 {
public PRED_commit_edits_2(Term a1, Term a2, Operation n) {
arg1 = a1;
arg2 = a2;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
Pattern fileRegex = getRegexParameter(a1);
Pattern editRegex = getRegexParameter(a2);
PatchList pl = StoredValues.PATCH_LIST.get(engine);
Repository repo = StoredValues.REPOSITORY.get(engine);
try (ObjectReader reader = repo.newObjectReader();
RevWalk rw = new RevWalk(reader)) {
final RevTree aTree;
final RevTree bTree;
final RevCommit bCommit = rw.parseCommit(pl.getNewId());
if (pl.getOldId() != null) {
aTree = rw.parseTree(pl.getOldId());
} else {
// Octopus merge with unknown automatic merge result, since the
// web UI returns no files to match against, just fail.
return engine.fail();
}
bTree = bCommit.getTree();
for (PatchListEntry entry : pl.getPatches()) {
String newName = entry.getNewName();
String oldName = entry.getOldName();
if (newName.equals("/COMMIT_MSG")) {
continue;
}
if (fileRegex.matcher(newName).find()
|| (oldName != null && fileRegex.matcher(oldName).find())) {
List<Edit> edits = entry.getEdits();
if (edits.isEmpty()) {
continue;
}
Text tA;
if (oldName != null) {
tA = load(aTree, oldName, reader);
} else {
tA = load(aTree, newName, reader);
}
Text tB = load(bTree, newName, reader);
for (Edit edit : edits) {
if (tA != Text.EMPTY) {
String aDiff = tA.getString(edit.getBeginA(), edit.getEndA(), true);
if (editRegex.matcher(aDiff).find()) {
return cont;
}
}
if (tB != Text.EMPTY) {
String bDiff = tB.getString(edit.getBeginB(), edit.getEndB(), true);
if (editRegex.matcher(bDiff).find()) {
return cont;
}
}
}
}
}
} catch (IOException err) {
throw new JavaException(this, 1, err);
}
return engine.fail();
}
private Pattern getRegexParameter(Term term) {
if (term instanceof VariableTerm) {
throw new PInstantiationException(this, 1);
}
if (!(term instanceof SymbolTerm)) {
throw new IllegalTypeException(this, 1, "symbol", term);
}
return Pattern.compile(term.name(), Pattern.MULTILINE);
}
private Text load(ObjectId tree, String path, ObjectReader reader)
throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
IOException {
if (path == null) {
return Text.EMPTY;
}
final TreeWalk tw = TreeWalk.forPath(reader, path, tree);
if (tw == null) {
return Text.EMPTY;
}
if (tw.getFileMode(0).getObjectType() != Constants.OBJ_BLOB) {
return Text.EMPTY;
}
return new Text(reader.open(tw.getObjectId(0), Constants.OBJ_BLOB));
}
}

View File

@@ -0,0 +1,52 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
/**
* Returns the commit message as a symbol
*
* <pre>
* 'commit_message'(-Msg)
* </pre>
*/
public class PRED_commit_message_1 extends Predicate.P1 {
public PRED_commit_message_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
PatchSetInfo psInfo = StoredValues.PATCH_SET_INFO.get(engine);
SymbolTerm msg = SymbolTerm.create(psInfo.getMessage());
if (!a1.unify(msg, engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,76 @@
// Copyright (C) 2012 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 gerrit;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListEntry;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.Term;
import java.util.List;
/**
* Exports basic commit statistics.
*
* <pre>
* 'commit_stats'(-Files, -Insertions, -Deletions)
* </pre>
*/
public class PRED_commit_stats_3 extends Predicate.P3 {
public PRED_commit_stats_3(Term a1, Term a2, Term a3, Operation n) {
arg1 = a1;
arg2 = a2;
arg3 = a3;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
Term a3 = arg3.dereference();
PatchList pl = StoredValues.PATCH_LIST.get(engine);
// Account for magic files
if (!a1.unify(
new IntegerTerm(pl.getPatches().size() - countMagicFiles(pl.getPatches())), engine.trail)) {
return engine.fail();
}
if (!a2.unify(new IntegerTerm(pl.getInsertions()), engine.trail)) {
return engine.fail();
}
if (!a3.unify(new IntegerTerm(pl.getDeletions()), engine.trail)) {
return engine.fail();
}
return cont;
}
private int countMagicFiles(List<PatchListEntry> entries) {
int count = 0;
for (PatchListEntry e : entries) {
if (Patch.isMagic(e.getNewName())) {
count++;
}
}
return count;
}
}

View File

@@ -0,0 +1,69 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.PeerDaemonUser;
import com.googlecode.prolog_cafe.exceptions.EvaluationException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_current_user_1 extends Predicate.P1 {
private static final SymbolTerm user = SymbolTerm.intern("user", 1);
private static final SymbolTerm anonymous = SymbolTerm.intern("anonymous");
private static final SymbolTerm peerDaemon = SymbolTerm.intern("peer_daemon");
public PRED_current_user_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
CurrentUser curUser = StoredValues.CURRENT_USER.getOrNull(engine);
if (curUser == null) {
throw new EvaluationException("Current user not available in this rule type");
}
Term resultTerm;
if (curUser.isIdentifiedUser()) {
Account.Id id = curUser.getAccountId();
resultTerm = new IntegerTerm(id.get());
} else if (curUser instanceof AnonymousUser) {
resultTerm = anonymous;
} else if (curUser instanceof PeerDaemonUser) {
resultTerm = peerDaemon;
} else {
throw new EvaluationException("Unknown user type");
}
if (!a1.unify(new StructureTerm(user, resultTerm), engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,108 @@
// Copyright (C) 2011 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 gerrit;
import static com.googlecode.prolog_cafe.lang.SymbolTerm.intern;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.rules.PrologEnvironment;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;
import com.googlecode.prolog_cafe.exceptions.PInstantiationException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.JavaObjectTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import com.googlecode.prolog_cafe.lang.VariableTerm;
import java.util.Map;
/**
* Loads a CurrentUser object for a user identity.
*
* <p>Values are cached in the hash {@code current_user}, avoiding recreation during a single
* evaluation.
*
* <pre>
* current_user(user(+AccountId), -CurrentUser).
* </pre>
*/
class PRED_current_user_2 extends Predicate.P2 {
private static final SymbolTerm user = intern("user", 1);
private static final SymbolTerm anonymous = intern("anonymous");
PRED_current_user_2(Term a1, Term a2, Operation n) {
arg1 = a1;
arg2 = a2;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
if (a1 instanceof VariableTerm) {
throw new PInstantiationException(this, 1);
}
if (!a2.unify(createUser(engine, a1), engine.trail)) {
return engine.fail();
}
return cont;
}
public Term createUser(Prolog engine, Term key) {
if (!(key instanceof StructureTerm)
|| key.arity() != 1
|| !((StructureTerm) key).functor().equals(user)) {
throw new IllegalTypeException(this, 1, "user(int)", key);
}
Term idTerm = key.arg(0);
CurrentUser user;
if (idTerm instanceof IntegerTerm) {
Map<Account.Id, IdentifiedUser> cache = StoredValues.USERS.get(engine);
Account.Id accountId = new Account.Id(((IntegerTerm) idTerm).intValue());
user = cache.get(accountId);
if (user == null) {
IdentifiedUser.GenericFactory userFactory = userFactory(engine);
IdentifiedUser who = userFactory.create(accountId);
cache.put(accountId, who);
user = who;
}
} else if (idTerm.equals(anonymous)) {
user = StoredValues.ANONYMOUS_USER.get(engine);
} else {
throw new IllegalTypeException(this, 1, "user(int)", key);
}
return new JavaObjectTerm(user);
}
private static IdentifiedUser.GenericFactory userFactory(Prolog engine) {
return ((PrologEnvironment) engine.control).getArgs().getUserFactory();
}
}

View File

@@ -0,0 +1,85 @@
// Copyright (C) 2011 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 gerrit;
import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.rules.StoredValues;
import com.google.gwtorm.server.OrmException;
import com.googlecode.prolog_cafe.exceptions.JavaException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.ListTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import java.util.List;
/**
* Obtain a list of label types from the server configuration.
*
* <p>Unifies to a Prolog list of: {@code label_type(Label, Fun, Min, Max)} where:
*
* <ul>
* <li>{@code Label} - the newer style label name
* <li>{@code Fun} - legacy function name
* <li>{@code Min, Max} - the smallest and largest configured values.
* </ul>
*/
class PRED_get_legacy_label_types_1 extends Predicate.P1 {
private static final SymbolTerm NONE = SymbolTerm.intern("none");
PRED_get_legacy_label_types_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
List<LabelType> list;
try {
list = StoredValues.CHANGE_DATA.get(engine).getLabelTypes().getLabelTypes();
} catch (OrmException err) {
throw new JavaException(this, 1, err);
}
Term head = Prolog.Nil;
for (int idx = list.size() - 1; 0 <= idx; idx--) {
head = new ListTerm(export(list.get(idx)), head);
}
if (!a1.unify(head, engine.trail)) {
return engine.fail();
}
return cont;
}
static final SymbolTerm symLabelType = SymbolTerm.intern("label_type", 4);
static Term export(LabelType type) {
LabelValue min = type.getMin();
LabelValue max = type.getMax();
return new StructureTerm(
symLabelType,
SymbolTerm.intern(type.getName()),
SymbolTerm.intern(type.getFunction().getFunctionName()),
min != null ? new IntegerTerm(min.getValue()) : NONE,
max != null ? new IntegerTerm(max.getValue()) : NONE);
}
}

View File

@@ -0,0 +1,56 @@
// Copyright (C) 2012 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 gerrit;
import com.google.gerrit.extensions.client.SubmitType;
import com.google.gerrit.rules.StoredValues;
import com.google.gerrit.server.project.ProjectState;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_project_default_submit_type_1 extends Predicate.P1 {
private static final SymbolTerm[] term;
static {
SubmitType[] val = SubmitType.values();
term = new SymbolTerm[val.length];
for (int i = 0; i < val.length; i++) {
term[i] = SymbolTerm.create(val[i].name());
}
}
public PRED_project_default_submit_type_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
ProjectState projectState = StoredValues.PROJECT_STATE.get(engine);
SubmitType submitType = projectState.getProject().getSubmitType();
if (!a1.unify(term[submitType.ordinal()], engine.trail)) {
return engine.fail();
}
return cont;
}
}

View File

@@ -0,0 +1,48 @@
// Copyright (C) 2017 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 gerrit;
import com.google.gerrit.rules.StoredValues;
import com.google.gwtorm.server.OrmException;
import com.googlecode.prolog_cafe.exceptions.JavaException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.Term;
public class PRED_unresolved_comments_count_1 extends Predicate.P1 {
public PRED_unresolved_comments_count_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
try {
Integer count = StoredValues.CHANGE_DATA.get(engine).unresolvedCommentCount();
if (!a1.unify(new IntegerTerm(count != null ? count : 0), engine.trail)) {
return engine.fail();
}
} catch (OrmException err) {
throw new JavaException(this, 1, err);
}
return cont;
}
}

View File

@@ -0,0 +1,61 @@
// Copyright (C) 2016 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 gerrit;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.rules.StoredValues;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
import com.googlecode.prolog_cafe.lang.Prolog;
import com.googlecode.prolog_cafe.lang.StructureTerm;
import com.googlecode.prolog_cafe.lang.SymbolTerm;
import com.googlecode.prolog_cafe.lang.Term;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PRED_uploader_1 extends Predicate.P1 {
private static final Logger log = LoggerFactory.getLogger(PRED_uploader_1.class);
private static final SymbolTerm user = SymbolTerm.intern("user", 1);
public PRED_uploader_1(Term a1, Operation n) {
arg1 = a1;
cont = n;
}
@Override
public Operation exec(Prolog engine) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
PatchSet patchSet = StoredValues.getPatchSet(engine);
if (patchSet == null) {
log.error(
"Failed to load current patch set of change "
+ StoredValues.getChange(engine).getChangeId());
return engine.fail();
}
Account.Id uploaderId = patchSet.getUploader();
if (!a1.unify(new StructureTerm(user, new IntegerTerm(uploaderId.get())), engine.trail)) {
return engine.fail();
}
return cont;
}
}