Merge "Expose the submit requirements in the Change API"

This commit is contained in:
Maxime Guerreiro
2018-04-18 09:03:13 +00:00
committed by Gerrit Code Review
5 changed files with 182 additions and 0 deletions

View File

@@ -5642,6 +5642,9 @@ AccountInfo] entity.
Actions the caller might be able to perform on this revision. The
information is a map of view name to link:#action-info[ActionInfo]
entities.
|`requirements` |optional|
List of the link:rest-api-changes.html#requirement[requirements] to be met before this change
can be submitted.
|`labels` |optional|
The labels of the change as a map that maps the label names to
link:#label-info[LabelInfo] entries. +
@@ -6591,6 +6594,32 @@ describing the related changes. Sorted by git commit order, newest to
oldest. Empty if there are no related changes.
|===========================
[[requirement]]
=== Requirement
The `Requirement` entity contains information about a requirement relative to a change.
type:: Alphanumerical (plus hyphens or underscores) string to identify what the requirement is and
why it was triggered. Can be seen as a class: requirements sharing the same type were created for a
similar reason, and the data structure will follow one set of rules.
data:: (Optional) Additional key-value data linked to this requirement. This is used in templates to
render rich status messages.
[options="header",cols="1,^1,5"]
|===========================
|Field Name | |Description
|`status` | | Status of the requirement. Can be either `OK`, `NOT_READY` or `RULE_ERROR`.
|`fallbackText` | | A human readable reason
|`type` | |
Alphanumerical (plus hyphens or underscores) string to identify what the requirement is and why it
was triggered. Can be seen as a class: requirements sharing the same type were created for a similar
reason, and the data structure will follow one set of rules.
|`data` |optional|
Holds custom key-value strings, used in templates to render richer status messages
|===========================
[[restore-input]]
=== RestoreInput
The `RestoreInput` entity contains information for restoring a change.

View File

@@ -70,4 +70,5 @@ public class ChangeInfo {
public List<ProblemInfo> problems;
public List<PluginDefinedInfo> plugins;
public Collection<TrackingIdInfo> trackingIds;
public Collection<SubmitRequirementInfo> requirements;
}

View File

@@ -0,0 +1,53 @@
// Copyright (C) 2018 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 com.google.gerrit.extensions.common;
import java.util.Map;
import java.util.Objects;
public class SubmitRequirementInfo {
public final String status;
public final String fallbackText;
public final String type;
public final Map<String, String> data;
public SubmitRequirementInfo(
String status, String fallbackText, String type, Map<String, String> data) {
this.status = status;
this.fallbackText = fallbackText;
this.type = type;
this.data = data;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof SubmitRequirementInfo)) {
return false;
}
SubmitRequirementInfo that = (SubmitRequirementInfo) o;
return Objects.equals(status, that.status)
&& Objects.equals(fallbackText, that.fallbackText)
&& Objects.equals(type, that.type)
&& Objects.equals(data, that.data);
}
@Override
public int hashCode() {
return Objects.hash(status, fallbackText, type, data);
}
}

View File

@@ -63,6 +63,8 @@ import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.LabelTypes;
import com.google.gerrit.common.data.LabelValue;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.common.data.SubmitRecord.Status;
import com.google.gerrit.common.data.SubmitRequirement;
import com.google.gerrit.common.data.SubmitTypeRecord;
import com.google.gerrit.extensions.api.changes.FixInput;
import com.google.gerrit.extensions.client.ListChangesOption;
@@ -78,6 +80,7 @@ import com.google.gerrit.extensions.common.ProblemInfo;
import com.google.gerrit.extensions.common.PushCertificateInfo;
import com.google.gerrit.extensions.common.ReviewerUpdateInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
import com.google.gerrit.extensions.common.SubmitRequirementInfo;
import com.google.gerrit.extensions.common.TrackingIdInfo;
import com.google.gerrit.extensions.common.VotingRangeInfo;
import com.google.gerrit.extensions.common.WebLinkInfo;
@@ -435,6 +438,23 @@ public class ChangeJson {
return out;
}
private static Collection<SubmitRequirementInfo> requirementsFor(ChangeData cd) {
Collection<SubmitRequirementInfo> reqInfos = new ArrayList<>();
for (SubmitRecord submitRecord : cd.submitRecords(SUBMIT_RULE_OPTIONS_STRICT)) {
if (submitRecord.requirements == null) {
continue;
}
for (SubmitRequirement requirement : submitRecord.requirements) {
reqInfos.add(requirementToInfo(requirement, submitRecord.status));
}
}
return reqInfos;
}
private static SubmitRequirementInfo requirementToInfo(SubmitRequirement req, Status status) {
return new SubmitRequirementInfo(status.name(), req.fallbackText(), req.type(), req.data());
}
private void ensureLoaded(Iterable<ChangeData> all) throws OrmException {
if (lazyLoad) {
ChangeData.ensureChangeLoaded(all);
@@ -613,6 +633,7 @@ public class ChangeJson {
}
out.labels = labelsFor(cd, has(LABELS), has(DETAILED_LABELS));
out.requirements = requirementsFor(cd);
if (out.labels != null && has(DETAILED_LABELS)) {
// If limited to specific patch sets but not the current patch set, don't

View File

@@ -0,0 +1,78 @@
// Copyright (C) 2018 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 com.google.gerrit.acceptance.api.change;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.common.data.SubmitRecord;
import com.google.gerrit.common.data.SubmitRequirement;
import com.google.gerrit.extensions.annotations.Exports;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.SubmitRequirementInfo;
import com.google.gerrit.extensions.config.FactoryModule;
import com.google.gerrit.server.project.SubmitRuleOptions;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.rules.SubmitRule;
import com.google.inject.Module;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
public class ChangeSubmitRequirementIT extends AbstractDaemonTest {
private static final SubmitRequirement req =
SubmitRequirement.builder()
.setType("custom_rule")
.setFallbackText("Fallback text")
.addCustomValue("key", "value")
.build();
private static final SubmitRequirementInfo reqInfo =
new SubmitRequirementInfo(
"NOT_READY", "Fallback text", "custom_rule", ImmutableMap.of("key", "value"));
@Override
public Module createModule() {
return new FactoryModule() {
@Override
public void configure() {
bind(SubmitRule.class)
.annotatedWith(Exports.named("CustomSubmitRule"))
.to(CustomSubmitRule.class);
}
};
}
@Test
public void checkSubmitRequirementIsPropagated() throws Exception {
PushOneCommit.Result r = createChange();
ChangeInfo result = gApi.changes().id(r.getChangeId()).get();
assertThat(result.requirements).containsExactly(reqInfo);
}
private static class CustomSubmitRule implements SubmitRule {
@Override
public Collection<SubmitRecord> evaluate(ChangeData changeData, SubmitRuleOptions options) {
SubmitRecord record = new SubmitRecord();
record.labels = new ArrayList<>();
record.status = SubmitRecord.Status.NOT_READY;
record.requirements = ImmutableList.of(req);
return ImmutableList.of(record);
}
}
}