Search in sources :

Example 1 with RuleEvalException

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();
    }
}
Also used : ListTerm(com.googlecode.prolog_cafe.lang.ListTerm) ArrayList(java.util.ArrayList) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ReductionLimitException(com.googlecode.prolog_cafe.exceptions.ReductionLimitException) RuleEvalException(com.google.gerrit.server.project.RuleEvalException) Term(com.googlecode.prolog_cafe.lang.Term) IntegerTerm(com.googlecode.prolog_cafe.lang.IntegerTerm) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ListTerm(com.googlecode.prolog_cafe.lang.ListTerm) StructureTerm(com.googlecode.prolog_cafe.lang.StructureTerm)

Example 2 with RuleEvalException

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;
}
Also used : SubmitRecord(com.google.gerrit.entities.SubmitRecord) NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) RuleEvalException(com.google.gerrit.server.project.RuleEvalException) Change(com.google.gerrit.entities.Change) Term(com.googlecode.prolog_cafe.lang.Term) IntegerTerm(com.googlecode.prolog_cafe.lang.IntegerTerm) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ListTerm(com.googlecode.prolog_cafe.lang.ListTerm) StructureTerm(com.googlecode.prolog_cafe.lang.StructureTerm) StorageException(com.google.gerrit.exceptions.StorageException)

Example 3 with RuleEvalException

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;
}
Also used : CompileException(com.googlecode.prolog_cafe.exceptions.CompileException) ProjectState(com.google.gerrit.server.project.ProjectState) RuleEvalException(com.google.gerrit.server.project.RuleEvalException) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ReductionLimitException(com.googlecode.prolog_cafe.exceptions.ReductionLimitException) Term(com.googlecode.prolog_cafe.lang.Term) IntegerTerm(com.googlecode.prolog_cafe.lang.IntegerTerm) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ListTerm(com.googlecode.prolog_cafe.lang.ListTerm) StructureTerm(com.googlecode.prolog_cafe.lang.StructureTerm) ChangeData(com.google.gerrit.server.query.change.ChangeData)

Example 4 with RuleEvalException

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;
}
Also used : StringReader(java.io.StringReader) CompileException(com.googlecode.prolog_cafe.exceptions.CompileException) RuleEvalException(com.google.gerrit.server.project.RuleEvalException) PrologMachineCopy(com.googlecode.prolog_cafe.lang.PrologMachineCopy)

Example 5 with RuleEvalException

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);
    }
}
Also used : NoSuchProjectException(com.google.gerrit.server.project.NoSuchProjectException) RuleEvalException(com.google.gerrit.server.project.RuleEvalException) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) Term(com.googlecode.prolog_cafe.lang.Term) IntegerTerm(com.googlecode.prolog_cafe.lang.IntegerTerm) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) ListTerm(com.googlecode.prolog_cafe.lang.ListTerm) StructureTerm(com.googlecode.prolog_cafe.lang.StructureTerm)

Aggregations

RuleEvalException (com.google.gerrit.server.project.RuleEvalException)5 IntegerTerm (com.googlecode.prolog_cafe.lang.IntegerTerm)4 ListTerm (com.googlecode.prolog_cafe.lang.ListTerm)4 StructureTerm (com.googlecode.prolog_cafe.lang.StructureTerm)4 SymbolTerm (com.googlecode.prolog_cafe.lang.SymbolTerm)4 Term (com.googlecode.prolog_cafe.lang.Term)4 VariableTerm (com.googlecode.prolog_cafe.lang.VariableTerm)4 NoSuchProjectException (com.google.gerrit.server.project.NoSuchProjectException)2 CompileException (com.googlecode.prolog_cafe.exceptions.CompileException)2 ReductionLimitException (com.googlecode.prolog_cafe.exceptions.ReductionLimitException)2 Change (com.google.gerrit.entities.Change)1 SubmitRecord (com.google.gerrit.entities.SubmitRecord)1 StorageException (com.google.gerrit.exceptions.StorageException)1 ProjectState (com.google.gerrit.server.project.ProjectState)1 ChangeData (com.google.gerrit.server.query.change.ChangeData)1 PrologMachineCopy (com.googlecode.prolog_cafe.lang.PrologMachineCopy)1 StringReader (java.io.StringReader)1 ArrayList (java.util.ArrayList)1