Expose the commit to Prolog

Expose the commit to allow for more granular control over what needs to
be loaded by Gerrit, and keep the parsed commit in memory. This allows
removal of the PATCH_SET_INFO and COMMIT_MESSAGE StoredValues.

Change-Id: I81649c9b976ca8750f28cb39c58051594b781c9a
This commit is contained in:
Maxime Guerreiro 2018-06-27 13:11:53 +00:00
parent bbb1765ebd
commit 20282d6879
9 changed files with 49 additions and 44 deletions

View File

@ -214,14 +214,13 @@ public class PatchSetUtil {
return false;
}
/** Returns the full commit message for the given project at the given patchset revision */
public String getFullCommitMessage(Project.NameKey project, PatchSet patchSet)
throws IOException {
/** Returns the commit for the given project at the given patchset revision */
public RevCommit getRevCommit(Project.NameKey project, PatchSet patchSet) throws IOException {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = new RevWalk(repo)) {
RevCommit src = rw.parseCommit(ObjectId.fromString(patchSet.getRevision().get()));
rw.parseBody(src);
return src.getFullMessage();
return src;
}
}
}

View File

@ -18,6 +18,7 @@ import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.AnonymousUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.patch.PatchListCache;
@ -176,6 +177,7 @@ public class PrologEnvironment extends BufferingPrologControl {
private final int reductionLimit;
private final int compileLimit;
private final PatchSetUtil patchsetUtil;
private Emails emails;
@Inject
Args(
@ -187,7 +189,8 @@ public class PrologEnvironment extends BufferingPrologControl {
IdentifiedUser.GenericFactory userFactory,
Provider<AnonymousUser> anonymousUser,
@GerritServerConfig Config config,
PatchSetUtil patchsetUtil) {
PatchSetUtil patchsetUtil,
Emails emails) {
this.projectCache = projectCache;
this.permissionBackend = permissionBackend;
this.repositoryManager = repositoryManager;
@ -196,6 +199,7 @@ public class PrologEnvironment extends BufferingPrologControl {
this.userFactory = userFactory;
this.anonymousUser = anonymousUser;
this.patchsetUtil = patchsetUtil;
this.emails = emails;
int limit = config.getInt("rules", null, "reductionLimit", 100000);
reductionLimit = limit <= 0 ? Integer.MAX_VALUE : limit;
@ -247,5 +251,9 @@ public class PrologEnvironment extends BufferingPrologControl {
public PatchSetUtil getPatchsetUtil() {
return patchsetUtil;
}
public Emails getEmails() {
return emails;
}
}
}

View File

@ -20,7 +20,6 @@ import com.google.gerrit.extensions.client.DiffPreferencesInfo.Whitespace;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.AnonymousUser;
@ -34,8 +33,6 @@ import com.google.gerrit.server.patch.PatchList;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.patch.PatchListKey;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectState;
import com.google.gerrit.server.query.change.ChangeData;
@ -47,6 +44,7 @@ import java.util.HashMap;
import java.util.Map;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
public final class StoredValues {
public static final StoredValue<Accounts> ACCOUNTS = create(Accounts.class);
@ -74,32 +72,16 @@ public final class StoredValues {
}
}
public static final StoredValue<PatchSetInfo> PATCH_SET_INFO =
new StoredValue<PatchSetInfo>() {
public static final StoredValue<RevCommit> COMMIT =
new StoredValue<RevCommit>() {
@Override
public PatchSetInfo createValue(Prolog engine) {
Change change = getChange(engine);
PatchSet ps = getPatchSet(engine);
PrologEnvironment env = (PrologEnvironment) engine.control;
PatchSetInfoFactory patchInfoFactory = env.getArgs().getPatchSetInfoFactory();
try {
return patchInfoFactory.get(change.getProject(), ps);
} catch (PatchSetInfoNotAvailableException e) {
throw new SystemException(e.getMessage());
}
}
};
public static final StoredValue<String> COMMIT_MESSAGE =
new StoredValue<String>() {
@Override
public String createValue(Prolog engine) {
public RevCommit createValue(Prolog engine) {
Change change = getChange(engine);
PatchSet ps = getPatchSet(engine);
PrologEnvironment env = (PrologEnvironment) engine.control;
PatchSetUtil patchSetUtil = env.getArgs().getPatchsetUtil();
try {
return patchSetUtil.getFullCommitMessage(change.getProject(), ps);
return patchSetUtil.getRevCommit(change.getProject(), ps);
} catch (IOException e) {
throw new SystemException(e.getMessage());
}

View File

@ -14,9 +14,13 @@
package gerrit;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.server.account.Emails;
import com.google.gerrit.server.rules.PrologEnvironment;
import com.google.gwtorm.server.OrmException;
import com.googlecode.prolog_cafe.exceptions.PrologException;
import com.googlecode.prolog_cafe.exceptions.SystemException;
import com.googlecode.prolog_cafe.lang.IntegerTerm;
import com.googlecode.prolog_cafe.lang.Operation;
import com.googlecode.prolog_cafe.lang.Predicate;
@ -24,6 +28,8 @@ 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.io.IOException;
import org.eclipse.jgit.lib.PersonIdent;
abstract class AbstractCommitUserIdentityPredicate extends Predicate.P3 {
private static final SymbolTerm user = SymbolTerm.intern("user", 1);
@ -36,7 +42,7 @@ abstract class AbstractCommitUserIdentityPredicate extends Predicate.P3 {
cont = n;
}
protected Operation exec(Prolog engine, UserIdentity userId) throws PrologException {
protected Operation exec(Prolog engine, PersonIdent userId) throws PrologException {
engine.setB0();
Term a1 = arg1.dereference();
Term a2 = arg2.dereference();
@ -46,7 +52,18 @@ abstract class AbstractCommitUserIdentityPredicate extends Predicate.P3 {
Term nameTerm = Prolog.Nil;
Term emailTerm = Prolog.Nil;
Account.Id id = userId.getAccount();
PrologEnvironment env = (PrologEnvironment) engine.control;
Emails emails = env.getArgs().getEmails();
Account.Id id = null;
try {
ImmutableSet<Account.Id> ids = emails.getAccountFor(userId.getEmailAddress());
if (ids.size() == 1) {
id = ids.iterator().next();
}
} catch (IOException | OrmException e) {
throw new SystemException(e.getMessage());
}
if (id == null) {
idTerm = anonymous;
} else {
@ -58,7 +75,7 @@ abstract class AbstractCommitUserIdentityPredicate extends Predicate.P3 {
nameTerm = SymbolTerm.create(name);
}
String email = userId.getEmail();
String email = userId.getEmailAddress();
if (email != null && !email.equals("")) {
emailTerm = SymbolTerm.create(email);
}

View File

@ -11,5 +11,6 @@ java_library(
"//lib/flogger:api",
"//lib/jgit/org.eclipse.jgit:jgit",
"//lib/prolog:runtime",
"@guava//jar",
],
)

View File

@ -14,13 +14,12 @@
package gerrit;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.server.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;
import org.eclipse.jgit.revwalk.RevCommit;
public class PRED_commit_author_3 extends AbstractCommitUserIdentityPredicate {
public PRED_commit_author_3(Term a1, Term a2, Term a3, Operation n) {
@ -29,8 +28,7 @@ public class PRED_commit_author_3 extends AbstractCommitUserIdentityPredicate {
@Override
public Operation exec(Prolog engine) throws PrologException {
PatchSetInfo psInfo = StoredValues.PATCH_SET_INFO.get(engine);
UserIdentity author = psInfo.getAuthor();
return exec(engine, author);
RevCommit revCommit = StoredValues.COMMIT.get(engine);
return exec(engine, revCommit.getAuthorIdent());
}
}

View File

@ -14,13 +14,12 @@
package gerrit;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.UserIdentity;
import com.google.gerrit.server.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;
import org.eclipse.jgit.revwalk.RevCommit;
public class PRED_commit_committer_3 extends AbstractCommitUserIdentityPredicate {
public PRED_commit_committer_3(Term a1, Term a2, Term a3, Operation n) {
@ -29,8 +28,7 @@ public class PRED_commit_committer_3 extends AbstractCommitUserIdentityPredicate
@Override
public Operation exec(Prolog engine) throws PrologException {
PatchSetInfo psInfo = StoredValues.PATCH_SET_INFO.get(engine);
UserIdentity committer = psInfo.getCommitter();
return exec(engine, committer);
RevCommit revCommit = StoredValues.COMMIT.get(engine);
return exec(engine, revCommit.getCommitterIdent());
}
}

View File

@ -21,6 +21,7 @@ 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 org.eclipse.jgit.revwalk.RevCommit;
/**
* Returns the commit message as a symbol
@ -40,7 +41,8 @@ public class PRED_commit_message_1 extends Predicate.P1 {
engine.setB0();
Term a1 = arg1.dereference();
String commitMessage = StoredValues.COMMIT_MESSAGE.get(engine);
RevCommit revCommit = StoredValues.COMMIT.get(engine);
String commitMessage = revCommit.getFullMessage();
SymbolTerm msg = SymbolTerm.create(commitMessage);
if (!a1.unify(msg, engine.trail)) {

View File

@ -49,7 +49,7 @@ public class GerritCommonTest extends PrologTestCase {
bind(PrologEnvironment.Args.class)
.toInstance(
new PrologEnvironment.Args(
null, null, null, null, null, null, null, cfg, null));
null, null, null, null, null, null, null, cfg, null, null));
}
});
}