Merge "Add pure_revert Prolog fact"
This commit is contained in:
commit
9797e3850b
@ -58,6 +58,10 @@ of them we must use a qualified name like `gerrit:change_branch(X)`.
|
|||||||
|`current_user(user(peer_daemon)).`
|
|`current_user(user(peer_daemon)).`
|
||||||
|`current_user(user(replication)).`
|
|`current_user(user(replication)).`
|
||||||
|
|
||||||
|
|`pure_revert/1` |`pure_revert(1).`
|
||||||
|
|link:rest-api-changes.html#get-pure-revert[Pure revert] as integer atom (1 if
|
||||||
|
the change is a pure revert, 0 otherwise)
|
||||||
|
|
||||||
|`uploader/1` |`uploader(user(1000000)).`
|
|`uploader/1` |`uploader(user(1000000)).`
|
||||||
|Uploader as `user(ID)` term. ID is the numeric account ID
|
|Uploader as `user(ID)` term. ID is the numeric account ID
|
||||||
|
|
||||||
|
@ -1048,6 +1048,56 @@ It's only used to show `'Needs All-Comments-Resolved'` in the UI to clearly
|
|||||||
indicate to the user that all the comments have to be resolved for the
|
indicate to the user that all the comments have to be resolved for the
|
||||||
change to become submittable.
|
change to become submittable.
|
||||||
|
|
||||||
|
=== Example 17: Make change submittable if it is a pure revert
|
||||||
|
In this example we will use the `pure_revert` fact about a
|
||||||
|
change. Our goal is to block the submission of any change that is not a
|
||||||
|
pure revert. Basically, it can be achieved by the following rules:
|
||||||
|
|
||||||
|
`rules.pl`
|
||||||
|
[source,prolog]
|
||||||
|
----
|
||||||
|
submit_rule(submit(R)) :-
|
||||||
|
gerrit:pure_revert(1),
|
||||||
|
!,
|
||||||
|
gerrit:commit_author(A),
|
||||||
|
R = label('Is-Pure-Revert', ok(A)).
|
||||||
|
|
||||||
|
submit_rule(submit(R)) :-
|
||||||
|
gerrit:pure_revert(U),
|
||||||
|
U /= 1,
|
||||||
|
R = label('Is-Pure-Revert', need(_)).
|
||||||
|
----
|
||||||
|
|
||||||
|
Suppose currently a change is submittable if it gets `+2` for `Code-Review`
|
||||||
|
and `+1` for `Verified`. It can be extended to support the above rules as
|
||||||
|
follows:
|
||||||
|
|
||||||
|
`rules.pl`
|
||||||
|
[source,prolog]
|
||||||
|
----
|
||||||
|
submit_rule(submit(CR, V, R)) :-
|
||||||
|
base(CR, V),
|
||||||
|
gerrit:pure_revert(1),
|
||||||
|
!,
|
||||||
|
gerrit:commit_author(A),
|
||||||
|
R = label('Is-Pure-Revert', ok(A)).
|
||||||
|
|
||||||
|
submit_rule(submit(CR, V, R)) :-
|
||||||
|
base(CR, V),
|
||||||
|
gerrit:pure_revert(U),
|
||||||
|
U /= 1,
|
||||||
|
R = label('Is-Pure-Revert', need(_)).
|
||||||
|
|
||||||
|
base(CR, V) :-
|
||||||
|
gerrit:max_with_block(-2, 2, 'Code-Review', CR),
|
||||||
|
gerrit:max_with_block(-1, 1, 'Verified', V).
|
||||||
|
----
|
||||||
|
|
||||||
|
Note that a new label as `Is-Pure-Revert` should not be configured.
|
||||||
|
It's only used to show `'Needs Is-Pure-Revert'` in the UI to clearly
|
||||||
|
indicate to the user that all the comments have to be resolved for the
|
||||||
|
change to become submittable.
|
||||||
|
|
||||||
== Examples - Submit Type
|
== Examples - Submit Type
|
||||||
The following examples show how to implement own submit type rules.
|
The following examples show how to implement own submit type rules.
|
||||||
|
|
||||||
|
@ -63,7 +63,6 @@ import com.google.gerrit.acceptance.GerritConfig;
|
|||||||
import com.google.gerrit.acceptance.GitUtil;
|
import com.google.gerrit.acceptance.GitUtil;
|
||||||
import com.google.gerrit.acceptance.NoHttpd;
|
import com.google.gerrit.acceptance.NoHttpd;
|
||||||
import com.google.gerrit.acceptance.PushOneCommit;
|
import com.google.gerrit.acceptance.PushOneCommit;
|
||||||
import com.google.gerrit.acceptance.Sandboxed;
|
|
||||||
import com.google.gerrit.acceptance.TestAccount;
|
import com.google.gerrit.acceptance.TestAccount;
|
||||||
import com.google.gerrit.acceptance.TestProjectInput;
|
import com.google.gerrit.acceptance.TestProjectInput;
|
||||||
import com.google.gerrit.common.FooterConstants;
|
import com.google.gerrit.common.FooterConstants;
|
||||||
@ -2963,19 +2962,9 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
assertThat(approval.permittedVotingRange).isNull();
|
assertThat(approval.permittedVotingRange).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sandboxed
|
|
||||||
@Test
|
@Test
|
||||||
public void unresolvedCommentsBlocked() throws Exception {
|
public void unresolvedCommentsBlocked() throws Exception {
|
||||||
RevCommit oldHead = getRemoteHead();
|
modifySubmitRules(
|
||||||
GitUtil.fetch(testRepo, RefNames.REFS_CONFIG + ":config");
|
|
||||||
testRepo.reset("config");
|
|
||||||
PushOneCommit push =
|
|
||||||
pushFactory.create(
|
|
||||||
db,
|
|
||||||
admin.getIdent(),
|
|
||||||
testRepo,
|
|
||||||
"Configure",
|
|
||||||
"rules.pl",
|
|
||||||
"submit_rule(submit(R)) :- \n"
|
"submit_rule(submit(R)) :- \n"
|
||||||
+ "gerrit:unresolved_comments_count(0), \n"
|
+ "gerrit:unresolved_comments_count(0), \n"
|
||||||
+ "!,"
|
+ "!,"
|
||||||
@ -2986,10 +2975,7 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
+ "U > 0,"
|
+ "U > 0,"
|
||||||
+ "R = label('All-Comments-Resolved', need(_)). \n\n");
|
+ "R = label('All-Comments-Resolved', need(_)). \n\n");
|
||||||
|
|
||||||
push.to(RefNames.REFS_CONFIG);
|
String oldHead = getRemoteHead().name();
|
||||||
testRepo.reset(oldHead);
|
|
||||||
|
|
||||||
oldHead = getRemoteHead();
|
|
||||||
PushOneCommit.Result result1 =
|
PushOneCommit.Result result1 =
|
||||||
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
|
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
|
||||||
testRepo.reset(oldHead);
|
testRepo.reset(oldHead);
|
||||||
@ -3002,12 +2988,60 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
gApi.changes().id(result1.getChangeId()).current().submit();
|
gApi.changes().id(result1.getChangeId()).current().submit();
|
||||||
|
|
||||||
exception.expect(ResourceConflictException.class);
|
exception.expect(ResourceConflictException.class);
|
||||||
exception.expectMessage(
|
exception.expectMessage("Failed to submit 1 change due to the following problems");
|
||||||
"Failed to submit 1 change due to the following problems:\n"
|
exception.expectMessage("needs All-Comments-Resolved");
|
||||||
+ "Change 2: needs All-Comments-Resolved");
|
|
||||||
gApi.changes().id(result2.getChangeId()).current().submit();
|
gApi.changes().id(result2.getChangeId()).current().submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pureRevertFactBlocksSubmissionOfNonReverts() throws Exception {
|
||||||
|
addPureRevertSubmitRule();
|
||||||
|
|
||||||
|
// Create a change that is not a revert of another change
|
||||||
|
PushOneCommit.Result r1 =
|
||||||
|
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
|
||||||
|
approve(r1.getChangeId());
|
||||||
|
|
||||||
|
exception.expect(ResourceConflictException.class);
|
||||||
|
exception.expectMessage("Failed to submit 1 change due to the following problems");
|
||||||
|
exception.expectMessage("needs Is-Pure-Revert");
|
||||||
|
gApi.changes().id(r1.getChangeId()).current().submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pureRevertFactBlocksSubmissionOfNonPureReverts() throws Exception {
|
||||||
|
PushOneCommit.Result r1 =
|
||||||
|
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
|
||||||
|
merge(r1);
|
||||||
|
|
||||||
|
addPureRevertSubmitRule();
|
||||||
|
|
||||||
|
// Create a revert and push a content change
|
||||||
|
String revertId = gApi.changes().id(r1.getChangeId()).revert().get().changeId;
|
||||||
|
amendChange(revertId);
|
||||||
|
approve(revertId);
|
||||||
|
|
||||||
|
exception.expect(ResourceConflictException.class);
|
||||||
|
exception.expectMessage("Failed to submit 1 change due to the following problems");
|
||||||
|
exception.expectMessage("needs Is-Pure-Revert");
|
||||||
|
gApi.changes().id(revertId).current().submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void pureRevertFactAllowsSubmissionOfPureReverts() throws Exception {
|
||||||
|
// Create a change that we can later revert
|
||||||
|
PushOneCommit.Result r1 =
|
||||||
|
pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
|
||||||
|
merge(r1);
|
||||||
|
|
||||||
|
addPureRevertSubmitRule();
|
||||||
|
|
||||||
|
// Create a revert and submit it
|
||||||
|
String revertId = gApi.changes().id(r1.getChangeId()).revert().get().changeId;
|
||||||
|
approve(revertId);
|
||||||
|
gApi.changes().id(revertId).current().submit();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void changeCommitMessage() throws Exception {
|
public void changeCommitMessage() throws Exception {
|
||||||
// Tests mutating the commit message as both the owner of the change and a regular user with
|
// Tests mutating the commit message as both the owner of the change and a regular user with
|
||||||
@ -3330,6 +3364,33 @@ public class ChangeIT extends AbstractDaemonTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addPureRevertSubmitRule() throws Exception {
|
||||||
|
modifySubmitRules(
|
||||||
|
"submit_rule(submit(R)) :- \n"
|
||||||
|
+ "gerrit:pure_revert(1), \n"
|
||||||
|
+ "!,"
|
||||||
|
+ "gerrit:commit_author(A), \n"
|
||||||
|
+ "R = label('Is-Pure-Revert', ok(A)).\n"
|
||||||
|
+ "submit_rule(submit(R)) :- \n"
|
||||||
|
+ "gerrit:pure_revert(U), \n"
|
||||||
|
+ "U \\= 1,"
|
||||||
|
+ "R = label('Is-Pure-Revert', need(_)). \n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifySubmitRules(String newContent) throws Exception {
|
||||||
|
try (Repository repo = repoManager.openRepository(project)) {
|
||||||
|
TestRepository testRepo = new TestRepository<>((InMemoryRepository) repo);
|
||||||
|
testRepo
|
||||||
|
.branch(RefNames.REFS_CONFIG)
|
||||||
|
.commit()
|
||||||
|
.author(admin.getIdent())
|
||||||
|
.committer(admin.getIdent())
|
||||||
|
.add("rules.pl", newContent)
|
||||||
|
.message("Modify rules.pl")
|
||||||
|
.create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@GerritConfig(name = "trackingid.jira-bug.footer", value = "Bug:")
|
@GerritConfig(name = "trackingid.jira-bug.footer", value = "Bug:")
|
||||||
@GerritConfig(name = "trackingid.jira-bug.match", value = "JRA\\d{2,8}")
|
@GerritConfig(name = "trackingid.jira-bug.match", value = "JRA\\d{2,8}")
|
||||||
|
@ -93,20 +93,30 @@ public class GetPureRevert implements RestReadView<ChangeResource> {
|
|||||||
.isPatchVisible(currentPatchSet, dbProvider.get())) {
|
.isPatchVisible(currentPatchSet, dbProvider.get())) {
|
||||||
throw new AuthException("current revision not accessible");
|
throw new AuthException("current revision not accessible");
|
||||||
}
|
}
|
||||||
|
return getPureRevert(rsrc.getNotes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public PureRevertInfo getPureRevert(ChangeNotes notes)
|
||||||
|
throws OrmException, IOException, BadRequestException, AuthException,
|
||||||
|
ResourceConflictException {
|
||||||
|
PatchSet currentPatchSet = psUtil.current(dbProvider.get(), notes);
|
||||||
|
if (currentPatchSet == null) {
|
||||||
|
throw new ResourceConflictException("current revision is missing");
|
||||||
|
}
|
||||||
|
|
||||||
if (claimedOriginal == null) {
|
if (claimedOriginal == null) {
|
||||||
if (rsrc.getChange().getRevertOf() == null) {
|
if (notes.getChange().getRevertOf() == null) {
|
||||||
throw new BadRequestException("no ID was provided and change isn't a revert");
|
throw new BadRequestException("no ID was provided and change isn't a revert");
|
||||||
}
|
}
|
||||||
PatchSet ps =
|
PatchSet ps =
|
||||||
psUtil.current(
|
psUtil.current(
|
||||||
dbProvider.get(),
|
dbProvider.get(),
|
||||||
notesFactory.createChecked(
|
notesFactory.createChecked(
|
||||||
dbProvider.get(), rsrc.getProject(), rsrc.getChange().getRevertOf()));
|
dbProvider.get(), notes.getProjectName(), notes.getChange().getRevertOf()));
|
||||||
claimedOriginal = ps.getRevision().get();
|
claimedOriginal = ps.getRevision().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
try (Repository repo = repoManager.openRepository(rsrc.getProject());
|
try (Repository repo = repoManager.openRepository(notes.getProjectName());
|
||||||
ObjectInserter oi = repo.newObjectInserter();
|
ObjectInserter oi = repo.newObjectInserter();
|
||||||
RevWalk rw = new RevWalk(repo)) {
|
RevWalk rw = new RevWalk(repo)) {
|
||||||
RevCommit claimedOriginalCommit;
|
RevCommit claimedOriginalCommit;
|
||||||
@ -126,7 +136,7 @@ public class GetPureRevert implements RestReadView<ChangeResource> {
|
|||||||
// Rebase claimed revert onto claimed original
|
// Rebase claimed revert onto claimed original
|
||||||
ThreeWayMerger merger =
|
ThreeWayMerger merger =
|
||||||
mergeUtilFactory
|
mergeUtilFactory
|
||||||
.create(projectCache.checkedGet(rsrc.getProject()))
|
.create(projectCache.checkedGet(notes.getProjectName()))
|
||||||
.newThreeWayMerger(oi, repo.getConfig());
|
.newThreeWayMerger(oi, repo.getConfig());
|
||||||
merger.setBase(claimedRevertCommit.getParent(0));
|
merger.setBase(claimedRevertCommit.getParent(0));
|
||||||
merger.merge(claimedRevertCommit, claimedOriginalCommit);
|
merger.merge(claimedRevertCommit, claimedOriginalCommit);
|
||||||
|
@ -35,6 +35,9 @@ import com.google.gerrit.common.Nullable;
|
|||||||
import com.google.gerrit.common.data.LabelTypes;
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
import com.google.gerrit.common.data.SubmitRecord;
|
import com.google.gerrit.common.data.SubmitRecord;
|
||||||
import com.google.gerrit.common.data.SubmitTypeRecord;
|
import com.google.gerrit.common.data.SubmitTypeRecord;
|
||||||
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||||
@ -61,6 +64,7 @@ import com.google.gerrit.server.account.AccountCache;
|
|||||||
import com.google.gerrit.server.account.Accounts;
|
import com.google.gerrit.server.account.Accounts;
|
||||||
import com.google.gerrit.server.account.Emails;
|
import com.google.gerrit.server.account.Emails;
|
||||||
import com.google.gerrit.server.change.ChangeResource;
|
import com.google.gerrit.server.change.ChangeResource;
|
||||||
|
import com.google.gerrit.server.change.GetPureRevert;
|
||||||
import com.google.gerrit.server.change.MergeabilityCache;
|
import com.google.gerrit.server.change.MergeabilityCache;
|
||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
import com.google.gerrit.server.config.TrackingFooters;
|
import com.google.gerrit.server.config.TrackingFooters;
|
||||||
@ -349,7 +353,7 @@ public class ChangeData {
|
|||||||
ChangeData cd =
|
ChangeData cd =
|
||||||
new ChangeData(
|
new ChangeData(
|
||||||
null, null, null, null, null, null, null, null, null, null, null, null, null, null,
|
null, null, null, null, null, null, null, null, null, null, null, null, null, null,
|
||||||
null, null, null, null, null, null, project, id, null, null, null);
|
null, null, null, null, null, null, null, project, id, null, null, null);
|
||||||
cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId));
|
cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId));
|
||||||
return cd;
|
return cd;
|
||||||
}
|
}
|
||||||
@ -374,6 +378,7 @@ public class ChangeData {
|
|||||||
private final PatchSetUtil psUtil;
|
private final PatchSetUtil psUtil;
|
||||||
private final ProjectCache projectCache;
|
private final ProjectCache projectCache;
|
||||||
private final TrackingFooters trackingFooters;
|
private final TrackingFooters trackingFooters;
|
||||||
|
private final GetPureRevert pureRevert;
|
||||||
|
|
||||||
// Required assisted injected fields.
|
// Required assisted injected fields.
|
||||||
private final ReviewDb db;
|
private final ReviewDb db;
|
||||||
@ -445,6 +450,7 @@ public class ChangeData {
|
|||||||
PatchSetUtil psUtil,
|
PatchSetUtil psUtil,
|
||||||
ProjectCache projectCache,
|
ProjectCache projectCache,
|
||||||
TrackingFooters trackingFooters,
|
TrackingFooters trackingFooters,
|
||||||
|
GetPureRevert pureRevert,
|
||||||
@Assisted ReviewDb db,
|
@Assisted ReviewDb db,
|
||||||
@Assisted Project.NameKey project,
|
@Assisted Project.NameKey project,
|
||||||
@Assisted Change.Id id,
|
@Assisted Change.Id id,
|
||||||
@ -470,6 +476,7 @@ public class ChangeData {
|
|||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
this.starredChangesUtil = starredChangesUtil;
|
this.starredChangesUtil = starredChangesUtil;
|
||||||
this.trackingFooters = trackingFooters;
|
this.trackingFooters = trackingFooters;
|
||||||
|
this.pureRevert = pureRevert;
|
||||||
|
|
||||||
// May be null in tests when created via createForTest above, in which case lazy-loading will
|
// May be null in tests when created via createForTest above, in which case lazy-loading will
|
||||||
// intentionally fail with NPE. Still not marked @Nullable in the constructor, to force callers
|
// intentionally fail with NPE. Still not marked @Nullable in the constructor, to force callers
|
||||||
@ -1270,6 +1277,22 @@ public class ChangeData {
|
|||||||
return starsOf.stars();
|
return starsOf.stars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code null} if {@code revertOf} is {@code null}; true if the change is a pure revert;
|
||||||
|
* false otherwise.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public Boolean isPureRevert() throws OrmException {
|
||||||
|
if (change().getRevertOf() == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return pureRevert.getPureRevert(notes()).isPureRevert;
|
||||||
|
} catch (IOException | BadRequestException | AuthException | ResourceConflictException e) {
|
||||||
|
throw new OrmException("could not compute pure revert", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
MoreObjects.ToStringHelper h = MoreObjects.toStringHelper(this);
|
MoreObjects.ToStringHelper h = MoreObjects.toStringHelper(this);
|
||||||
|
50
gerrit-server/src/main/java/gerrit/PRED_pure_revert_1.java
Normal file
50
gerrit-server/src/main/java/gerrit/PRED_pure_revert_1.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 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;
|
||||||
|
|
||||||
|
/** Checks if change is a pure revert of the change it references in 'revertOf'. */
|
||||||
|
public class PRED_pure_revert_1 extends Predicate.P1 {
|
||||||
|
public PRED_pure_revert_1(Term a1, Operation n) {
|
||||||
|
arg1 = a1;
|
||||||
|
cont = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operation exec(Prolog engine) throws PrologException {
|
||||||
|
engine.setB0();
|
||||||
|
Term a1 = arg1.dereference();
|
||||||
|
|
||||||
|
Boolean isPureRevert;
|
||||||
|
try {
|
||||||
|
isPureRevert = StoredValues.CHANGE_DATA.get(engine).isPureRevert();
|
||||||
|
} catch (OrmException e) {
|
||||||
|
throw new JavaException(this, 1, e);
|
||||||
|
}
|
||||||
|
if (!a1.unify(new IntegerTerm(Boolean.TRUE.equals(isPureRevert) ? 1 : 0), engine.trail)) {
|
||||||
|
return engine.fail();
|
||||||
|
}
|
||||||
|
return cont;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user