use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method evaluateImpl.
private List<Term> evaluateImpl(String userRuleLocatorName, String userRuleWrapperName, String filterRuleLocatorName, String filterRuleWrapperName) throws RuleEvalException {
PrologEnvironment env = getPrologEnvironment();
try {
Term sr = env.once("gerrit", userRuleLocatorName, new VariableTerm());
List<Term> results = new ArrayList<>();
try {
for (Term[] template : env.all("gerrit", userRuleWrapperName, sr, new VariableTerm())) {
results.add(template[1]);
}
} catch (ReductionLimitException err) {
throw new RuleEvalException(String.format("%s on change %d of %s", err.getMessage(), cd.getId().get(), projectState.getName()));
} catch (RuntimeException err) {
throw new RuleEvalException(String.format("Exception calling %s on change %d of %s", sr, cd.getId().get(), projectState.getName()), err);
}
Term resultsTerm = toListTerm(results);
if (!opts.skipFilters()) {
resultsTerm = runSubmitFilters(resultsTerm, env, filterRuleLocatorName, filterRuleWrapperName);
}
List<Term> r;
if (resultsTerm instanceof ListTerm) {
r = new ArrayList<>();
for (Term t = resultsTerm; t instanceof ListTerm; ) {
ListTerm l = (ListTerm) t;
r.add(l.car().dereference());
t = l.cdr().dereference();
}
} else {
r = Collections.emptyList();
}
submitRule = sr;
return r;
} finally {
env.close();
}
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method evaluate.
/**
* Evaluate the submit rules.
*
* @return {@link SubmitRecord} returned from the evaluated rules. Can include errors.
*/
public SubmitRecord evaluate() {
Change change;
try {
change = cd.change();
if (change == null) {
throw new StorageException("No change found");
}
if (projectState == null) {
throw new NoSuchProjectException(cd.project());
}
} catch (StorageException | NoSuchProjectException e) {
return ruleError("Error looking up change " + cd.getId(), e);
}
logger.atFine().log("input approvals: %s", cd.approvals());
List<Term> results;
try {
results = evaluateImpl("locate_submit_rule", "can_submit", "locate_submit_filter", "filter_submit_results");
} catch (RuleEvalException e) {
return ruleError(e.getMessage(), e);
}
if (results.isEmpty()) {
// whether or not that is actually possible given the permissions.
return ruleError(String.format("Submit rule '%s' for change %s of %s has no solution.", getSubmitRuleName(), cd.getId(), projectState.getName()));
}
SubmitRecord submitRecord = resultsToSubmitRecord(getSubmitRule(), results);
logger.atFine().log("submit record: %s", submitRecord);
return submitRecord;
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method runSubmitFilters.
private Term runSubmitFilters(Term results, PrologEnvironment env, String filterRuleLocatorName, String filterRuleWrapperName) throws RuleEvalException {
PrologEnvironment childEnv = env;
ChangeData cd = env.get(StoredValues.CHANGE_DATA);
ProjectState projectState = env.get(StoredValues.PROJECT_STATE);
for (ProjectState parentState : projectState.parents()) {
PrologEnvironment parentEnv;
try {
parentEnv = envFactory.create(rulesCache.loadMachine(parentState.getNameKey(), parentState.getConfig().getRulesId().orElse(null)));
} catch (CompileException err) {
throw new RuleEvalException("Cannot consult rules.pl for " + parentState.getName(), err);
}
parentEnv.copyStoredValues(childEnv);
Term filterRule = parentEnv.once("gerrit", filterRuleLocatorName, new VariableTerm());
try {
Term[] template = parentEnv.once("gerrit", filterRuleWrapperName, filterRule, results, new VariableTerm());
results = template[2];
} catch (ReductionLimitException err) {
throw new RuleEvalException(String.format("%s on change %d of %s", err.getMessage(), cd.getId().get(), parentState.getName()));
} catch (RuntimeException err) {
throw new RuleEvalException(String.format("Exception calling %s on change %d of %s", filterRule, cd.getId().get(), parentState.getName()), err);
}
childEnv = parentEnv;
}
return results;
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class RulesCache method prettyProlog.
private static String prettyProlog(Term at) {
StringBuilder b = new StringBuilder();
for (Object o : ((ListTerm) at).toJava()) {
if (o instanceof Term) {
Term t = (Term) o;
if (!(t instanceof StructureTerm)) {
b.append(t.toString()).append(' ');
continue;
}
switch(t.name()) {
case "atom":
SymbolTerm atom = (SymbolTerm) t.arg(0);
b.append(atom.toString());
break;
case "var":
b.append(t.arg(0).toString());
break;
}
} else {
b.append(o);
}
}
return b.toString().trim();
}
use of com.googlecode.prolog_cafe.lang.Term in project gerrit by GerritCodeReview.
the class PRED_commit_edits_2 method exec.
@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);
Map<String, FileDiffOutput> modifiedFiles = StoredValues.DIFF_LIST.get(engine);
FileDiffOutput firstDiff = Iterables.getFirst(modifiedFiles.values(), /* defaultValue= */
null);
if (firstDiff == null) {
// No available diffs. We cannot identify old and new commit IDs.
engine.fail();
}
Repository repo = StoredValues.REPOSITORY.get(engine);
try (ObjectReader reader = repo.newObjectReader();
RevWalk rw = new RevWalk(reader)) {
final RevTree aTree = firstDiff.oldCommitId().equals(ObjectId.zeroId()) ? null : rw.parseTree(firstDiff.oldCommitId());
final RevTree bTree = rw.parseCommit(firstDiff.newCommitId()).getTree();
for (FileDiffOutput entry : modifiedFiles.values()) {
String newName = FilePathAdapter.getNewPath(entry.oldPath(), entry.newPath(), entry.changeType());
String oldName = FilePathAdapter.getOldPath(entry.oldPath(), entry.changeType());
if (Patch.isMagic(newName)) {
continue;
}
if (fileRegex.matcher(newName).find() || (oldName != null && fileRegex.matcher(oldName).find())) {
List<Edit> edits = entry.edits().stream().map(TaggedEdit::jgitEdit).collect(Collectors.toList());
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();
}
Aggregations