use of com.google.gerrit.server.project.RuleEvalException 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.google.gerrit.server.project.RuleEvalException 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.google.gerrit.server.project.RuleEvalException 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.google.gerrit.server.project.RuleEvalException in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method getPrologEnvironment.
private PrologEnvironment getPrologEnvironment() throws RuleEvalException {
PrologEnvironment env;
try {
PrologMachineCopy pmc;
if (opts.rule().isPresent()) {
pmc = rulesCache.loadMachine("stdin", new StringReader(opts.rule().get()));
} else {
pmc = rulesCache.loadMachine(projectState.getNameKey(), projectState.getConfig().getRulesId().orElse(null));
}
env = envFactory.create(pmc);
} catch (CompileException err) {
String msg;
if (opts.rule().isPresent()) {
msg = err.getMessage();
} else {
msg = String.format("Cannot load rules.pl for %s: %s", projectState.getName(), err.getMessage());
}
throw new RuleEvalException(msg, err);
}
env.set(StoredValues.ACCOUNTS, accounts);
env.set(StoredValues.ACCOUNT_CACHE, accountCache);
env.set(StoredValues.EMAILS, emails);
env.set(StoredValues.CHANGE_DATA, cd);
env.set(StoredValues.PROJECT_STATE, projectState);
return env;
}
use of com.google.gerrit.server.project.RuleEvalException in project gerrit by GerritCodeReview.
the class PrologRuleEvaluator method getSubmitType.
/**
* Evaluate the submit type rules to get the submit type.
*
* @return record from the evaluated rules.
*/
public SubmitTypeRecord getSubmitType() {
try {
if (projectState == null) {
throw new NoSuchProjectException(cd.project());
}
} catch (NoSuchProjectException e) {
return typeError("Error looking up change " + cd.getId(), e);
}
List<Term> results;
try {
results = evaluateImpl("locate_submit_type", "get_submit_type", "locate_submit_type_filter", "filter_submit_type_results");
} catch (RuleEvalException e) {
return typeError(e.getMessage(), e);
}
if (results.isEmpty()) {
// Should never occur for a well written rule
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + projectState.getName() + " has no solution.");
}
Term typeTerm = results.get(0);
if (!(typeTerm instanceof SymbolTerm)) {
return typeError("Submit rule '" + getSubmitRuleName() + "' for change " + cd.getId() + " of " + projectState.getName() + " did not return a symbol.");
}
String typeName = typeTerm.name();
try {
return SubmitTypeRecord.OK(SubmitType.valueOf(typeName.toUpperCase()));
} catch (IllegalArgumentException e) {
return typeError("Submit type rule " + getSubmitRule() + " for change " + cd.getId() + " of " + projectState.getName() + " output invalid result: " + typeName);
}
}
Aggregations