Remove ApprovalCategory and ApprovalCategoryValue
These can be completely specified in the project config hierarchy and the database tables are no longer required. Also remove the size limit on patch_set_approvals.category_id, so new PatchSetApprovals can refer to label names rather than IDs. Migrate existing labels into project.config in All-Projects. When migrating, also convert existing PatchSetApprovals to refer to label names rather than IDs. Label IDs are still written to PatchSetApprovals and still supported in project.config. As of this change, update all code to match PatchSetApproval's categoryId on either label ID or name. This allows for the possibility of database migration without downtime (e.g. for gerrit-review.googlesource.com). The default schema migration code, however, does not include label IDs in project.config, since this schema migration is only intended to run offline. Change-Id: I5df6f0c5665d0ae4ee6b5e2944f5954fa2f96b5c
This commit is contained in:
@@ -1,45 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.common.data;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** Summarizes the approvals (or negative approvals) for a patch set.
|
|
||||||
* This will typically contain zero or one approvals for each
|
|
||||||
* category, with all of the approvals coming from a single patch set.
|
|
||||||
*/
|
|
||||||
public class ApprovalSummary {
|
|
||||||
protected Map<String, PatchSetApproval> approvals;
|
|
||||||
|
|
||||||
protected ApprovalSummary() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalSummary(final Iterable<PatchSetApproval> list) {
|
|
||||||
approvals = new HashMap<String, PatchSetApproval>();
|
|
||||||
for (final PatchSetApproval a : list) {
|
|
||||||
approvals.put(a.getCategoryId().get(), a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Convert keys to label names.
|
|
||||||
/** @return a map of approvals keyed by ID string. */
|
|
||||||
public Map<String, PatchSetApproval> getApprovalMap() {
|
|
||||||
return Collections.unmodifiableMap(approvals);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,49 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.common.data;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/** Contains a set of ApprovalSummary objects, keyed by the change id
|
|
||||||
* from which they were derived.
|
|
||||||
*/
|
|
||||||
public class ApprovalSummarySet {
|
|
||||||
protected AccountInfoCache accounts;
|
|
||||||
|
|
||||||
protected Map<Change.Id, ApprovalSummary> summaries;
|
|
||||||
|
|
||||||
protected ApprovalSummarySet() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalSummarySet(final AccountInfoCache accts,
|
|
||||||
final Map<Change.Id, ApprovalSummary> map) {
|
|
||||||
accounts = accts;
|
|
||||||
|
|
||||||
summaries = new HashMap<Change.Id, ApprovalSummary>();
|
|
||||||
summaries.putAll(map);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AccountInfoCache getAccountInfoCache() {
|
|
||||||
return accounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<Change.Id, ApprovalSummary> getSummaryMap() {
|
|
||||||
return Collections.unmodifiableMap(summaries);
|
|
||||||
}
|
|
||||||
}
|
|
@@ -14,9 +14,8 @@
|
|||||||
|
|
||||||
package com.google.gerrit.common.data;
|
package com.google.gerrit.common.data;
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -26,39 +25,29 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class LabelType {
|
public class LabelType {
|
||||||
public static LabelType fromApprovalCategory(ApprovalCategory ac,
|
public static LabelType withDefaultValues(String name) {
|
||||||
List<ApprovalCategoryValue> acvs) {
|
|
||||||
List<LabelValue> values = new ArrayList<LabelValue>(acvs.size());
|
|
||||||
for (ApprovalCategoryValue acv : acvs) {
|
|
||||||
values.add(
|
|
||||||
new LabelValue(acv.getValue(), acv.getName()));
|
|
||||||
}
|
|
||||||
LabelType lt = new LabelType(ac.getId().get(), ac.getLabelName(), values);
|
|
||||||
lt.setAbbreviatedName(ac.getAbbreviatedName());
|
|
||||||
lt.setFunctionName(ac.getFunctionName());
|
|
||||||
lt.setCopyMinScore(ac.isCopyMinScore());
|
|
||||||
lt.setCanOverride(true);
|
|
||||||
return lt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LabelType withDefaultValues(String id, String name) {
|
|
||||||
checkId(id);
|
|
||||||
checkName(name);
|
checkName(name);
|
||||||
List<LabelValue> values = new ArrayList<LabelValue>(2);
|
List<LabelValue> values = new ArrayList<LabelValue>(2);
|
||||||
values.add(new LabelValue((short) 0, "Rejected"));
|
values.add(new LabelValue((short) 0, "Rejected"));
|
||||||
values.add(new LabelValue((short) 1, "Approved"));
|
values.add(new LabelValue((short) 1, "Approved"));
|
||||||
return new LabelType(id, name, values);
|
return new LabelType(name, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String checkId(String id) {
|
private static String checkId(String id) {
|
||||||
if (id == null || id.length() > 4) {
|
if ("SUBM".equals(id)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("Reserved label ID \"" + id + "\"");
|
||||||
"Illegal label ID \"" + id + "\"");
|
}
|
||||||
|
if (id != null && id.length() > 4) {
|
||||||
|
throw new IllegalArgumentException("Illegal label ID \"" + id + "\"");
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String checkName(String name) {
|
private static String checkName(String name) {
|
||||||
|
if ("SUBM".equals(name)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Reserved label name \"" + name + "\"");
|
||||||
|
}
|
||||||
for (int i = 0; i < name.length(); i++) {
|
for (int i = 0; i < name.length(); i++) {
|
||||||
char c = name.charAt(i);
|
char c = name.charAt(i);
|
||||||
if (!((c >= 'a' && c <= 'z') ||
|
if (!((c >= 'a' && c <= 'z') ||
|
||||||
@@ -72,7 +61,7 @@ public class LabelType {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String defaultAbbreviation(String name) {
|
public static String defaultAbbreviation(String name) {
|
||||||
StringBuilder abbr = new StringBuilder();
|
StringBuilder abbr = new StringBuilder();
|
||||||
for (int i = 0; i < name.length(); i++) {
|
for (int i = 0; i < name.length(); i++) {
|
||||||
char c = name.charAt(i);
|
char c = name.charAt(i);
|
||||||
@@ -87,8 +76,8 @@ public class LabelType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String name;
|
protected String name;
|
||||||
|
|
||||||
protected String id;
|
protected String id;
|
||||||
|
|
||||||
protected String abbreviatedName;
|
protected String abbreviatedName;
|
||||||
protected String functionName;
|
protected String functionName;
|
||||||
protected boolean copyMinScore;
|
protected boolean copyMinScore;
|
||||||
@@ -104,8 +93,7 @@ public class LabelType {
|
|||||||
protected LabelType() {
|
protected LabelType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabelType(String id, String name, List<LabelValue> valueList) {
|
public LabelType(String name, List<LabelValue> valueList) {
|
||||||
this.id = checkId(id);
|
|
||||||
this.name = checkName(name);
|
this.name = checkName(name);
|
||||||
canOverride = true;
|
canOverride = true;
|
||||||
values = new ArrayList<LabelValue>(valueList);
|
values = new ArrayList<LabelValue>(valueList);
|
||||||
@@ -134,10 +122,23 @@ public class LabelType {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public String getId() {
|
public String getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = checkId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(PatchSetApproval psa) {
|
||||||
|
if (id != null && psa.getLabelId().get().equals(id)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return psa.getLabelId().get().equalsIgnoreCase(name);
|
||||||
|
}
|
||||||
|
|
||||||
public String getAbbreviatedName() {
|
public String getAbbreviatedName() {
|
||||||
return abbreviatedName;
|
return abbreviatedName;
|
||||||
}
|
}
|
||||||
@@ -228,14 +229,8 @@ public class LabelType {
|
|||||||
return intList;
|
return intList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
public LabelId getLabelId() {
|
||||||
public ApprovalCategoryValue.Id getApprovalCategoryValueId(short value) {
|
return new LabelId(id != null ? id : name);
|
||||||
return new ApprovalCategoryValue.Id(getApprovalCategoryId(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Deprecated
|
|
||||||
public ApprovalCategory.Id getApprovalCategoryId() {
|
|
||||||
return new ApprovalCategory.Id(getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -243,12 +238,6 @@ public class LabelType {
|
|||||||
StringBuilder sb = new StringBuilder(name).append('[');
|
StringBuilder sb = new StringBuilder(name).append('[');
|
||||||
LabelValue min = getMin();
|
LabelValue min = getMin();
|
||||||
LabelValue max = getMax();
|
LabelValue max = getMax();
|
||||||
if (id != null) {
|
|
||||||
sb.append(id);
|
|
||||||
if (min != null || max != null) {
|
|
||||||
sb.append(", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (min != null && max != null) {
|
if (min != null && max != null) {
|
||||||
sb.append(new PermissionRange(Permission.forLabel(name), min.getValue(),
|
sb.append(new PermissionRange(Permission.forLabel(name), min.getValue(),
|
||||||
max.getValue()).toString().trim());
|
max.getValue()).toString().trim());
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
|
|
||||||
package com.google.gerrit.common.data;
|
package com.google.gerrit.common.data;
|
||||||
|
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -21,36 +25,25 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class LabelTypes {
|
public class LabelTypes {
|
||||||
protected List<LabelType> labelTypes;
|
protected List<LabelType> labelTypes;
|
||||||
private transient Map<String, LabelType> byId;
|
|
||||||
private transient Map<String, LabelType> byLabel;
|
private transient Map<String, LabelType> byLabel;
|
||||||
|
private transient Map<String, LabelType> byId;
|
||||||
private transient Map<String, Integer> positions;
|
private transient Map<String, Integer> positions;
|
||||||
|
|
||||||
protected LabelTypes() {
|
protected LabelTypes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabelTypes(final List<LabelType> approvals) {
|
public LabelTypes(final List<? extends LabelType> approvals) {
|
||||||
labelTypes = approvals;
|
labelTypes =
|
||||||
byId();
|
Collections.unmodifiableList(new ArrayList<LabelType>(approvals));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LabelType> getLabelTypes() {
|
public List<LabelType> getLabelTypes() {
|
||||||
return labelTypes;
|
return labelTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabelType byId(String id) {
|
public LabelType byLabel(LabelId labelId) {
|
||||||
return byId().get(id);
|
LabelType t = byId().get(labelId.get());
|
||||||
}
|
return t != null ? t : byLabel().get(labelId.get().toLowerCase());
|
||||||
|
|
||||||
private Map<String, LabelType> byId() {
|
|
||||||
if (byId == null) {
|
|
||||||
byId = new HashMap<String, LabelType>();
|
|
||||||
if (labelTypes != null) {
|
|
||||||
for (final LabelType t : labelTypes) {
|
|
||||||
byId.put(t.getId(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return byId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LabelType byLabel(String labelName) {
|
public LabelType byLabel(String labelName) {
|
||||||
@@ -69,6 +62,20 @@ public class LabelTypes {
|
|||||||
return byLabel;
|
return byLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, LabelType> byId() {
|
||||||
|
if (byId == null) {
|
||||||
|
byId = new HashMap<String, LabelType>();
|
||||||
|
if (labelTypes != null) {
|
||||||
|
for (LabelType t : labelTypes) {
|
||||||
|
if (t.getId() != null) {
|
||||||
|
byId.put(t.getId(), t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return byId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return labelTypes.toString();
|
return labelTypes.toString();
|
||||||
|
@@ -14,14 +14,7 @@
|
|||||||
|
|
||||||
package com.google.gerrit.common.data;
|
package com.google.gerrit.common.data;
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
|
||||||
|
|
||||||
public class LabelValue {
|
public class LabelValue {
|
||||||
@Deprecated
|
|
||||||
public static LabelValue fromApprovalCategoryValue(ApprovalCategoryValue acv) {
|
|
||||||
return new LabelValue(acv.getValue(), acv.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String formatValue(short value) {
|
public static String formatValue(short value) {
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
return Short.toString(value);
|
return Short.toString(value);
|
||||||
|
@@ -1,154 +0,0 @@
|
|||||||
// Copyright (C) 2008 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.reviewdb.client;
|
|
||||||
|
|
||||||
import com.google.gwtorm.client.Column;
|
|
||||||
import com.google.gwtorm.client.Key;
|
|
||||||
import com.google.gwtorm.client.StringKey;
|
|
||||||
|
|
||||||
/** Types of approvals that can be associated with a {@link Change}. */
|
|
||||||
public final class ApprovalCategory {
|
|
||||||
/** Id of the special "Submit" action (and category). */
|
|
||||||
public static final String SUBMIT_ID = "SUBM";
|
|
||||||
|
|
||||||
public static boolean isSubmit(PatchSetApproval a) {
|
|
||||||
return SUBMIT_ID.equals(a.getCategoryId().get());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Id extends StringKey<Key<?>> {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Column(id = 1, length = 4)
|
|
||||||
protected String id;
|
|
||||||
|
|
||||||
protected Id() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public Id(final String a) {
|
|
||||||
id = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String get() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void set(String newValue) {
|
|
||||||
id = newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Internal short unique identifier for this category. */
|
|
||||||
@Column(id = 1)
|
|
||||||
protected Id categoryId;
|
|
||||||
|
|
||||||
/** Unique name for this category, shown in the web interface to users. */
|
|
||||||
@Column(id = 2, length = 20)
|
|
||||||
protected String name;
|
|
||||||
|
|
||||||
/** Abbreviated form of {@link #name} for display in very wide tables. */
|
|
||||||
@Column(id = 3, length = 4, notNull = false)
|
|
||||||
protected String abbreviatedName;
|
|
||||||
|
|
||||||
/** Order of this category within the Approvals table when presented. */
|
|
||||||
@Column(id = 4)
|
|
||||||
protected short position;
|
|
||||||
|
|
||||||
/** Identity of the function used to aggregate the category's value. */
|
|
||||||
@Column(id = 5)
|
|
||||||
protected String functionName;
|
|
||||||
|
|
||||||
/** If set, the minimum score is copied during patch set replacement. */
|
|
||||||
@Column(id = 6)
|
|
||||||
protected boolean copyMinScore;
|
|
||||||
|
|
||||||
/** Computed name derived from {@link #name}. */
|
|
||||||
protected String labelName;
|
|
||||||
|
|
||||||
protected ApprovalCategory() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalCategory(final ApprovalCategory.Id id, final String name) {
|
|
||||||
this.categoryId = id;
|
|
||||||
this.name = name;
|
|
||||||
this.functionName = "MaxWithBlock";
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalCategory.Id getId() {
|
|
||||||
return categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(final String n) {
|
|
||||||
name = n;
|
|
||||||
labelName = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clean version of {@link #getName()}, e.g. "Code Review" is "Code-Review". */
|
|
||||||
public String getLabelName() {
|
|
||||||
if (labelName == null) {
|
|
||||||
StringBuilder r = new StringBuilder();
|
|
||||||
for (int i = 0; i < name.length(); i++) {
|
|
||||||
char c = name.charAt(i);
|
|
||||||
if (('0' <= c && c <= '9') //
|
|
||||||
|| ('a' <= c && c <= 'z') //
|
|
||||||
|| ('A' <= c && c <= 'Z') //
|
|
||||||
|| (c == '-')) {
|
|
||||||
r.append(c);
|
|
||||||
} else if (c == ' ') {
|
|
||||||
r.append('-');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
labelName = r.toString();
|
|
||||||
}
|
|
||||||
return labelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAbbreviatedName() {
|
|
||||||
return abbreviatedName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAbbreviatedName(final String n) {
|
|
||||||
abbreviatedName = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPosition(final short p) {
|
|
||||||
position = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getFunctionName() {
|
|
||||||
return functionName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFunctionName(final String name) {
|
|
||||||
functionName = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCopyMinScore() {
|
|
||||||
return copyMinScore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCopyMinScore(final boolean copy) {
|
|
||||||
copyMinScore = copy;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,90 +0,0 @@
|
|||||||
// Copyright (C) 2008 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.reviewdb.client;
|
|
||||||
|
|
||||||
import com.google.gwtorm.client.Column;
|
|
||||||
import com.google.gwtorm.client.ShortKey;
|
|
||||||
|
|
||||||
/** Valid value for a {@link ApprovalCategory}. */
|
|
||||||
public final class ApprovalCategoryValue {
|
|
||||||
public static class Id extends ShortKey<ApprovalCategory.Id> {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
@Column(id = 1)
|
|
||||||
protected ApprovalCategory.Id categoryId;
|
|
||||||
|
|
||||||
@Column(id = 2)
|
|
||||||
protected short value;
|
|
||||||
|
|
||||||
protected Id() {
|
|
||||||
categoryId = new ApprovalCategory.Id();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Id(final ApprovalCategory.Id cat, final short v) {
|
|
||||||
categoryId = cat;
|
|
||||||
value = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApprovalCategory.Id getParentKey() {
|
|
||||||
return categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public short get() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void set(short newValue) {
|
|
||||||
value = newValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Column(id = 1, name = Column.NONE)
|
|
||||||
protected Id key;
|
|
||||||
|
|
||||||
@Column(id = 2, length = 50)
|
|
||||||
protected String name;
|
|
||||||
|
|
||||||
protected ApprovalCategoryValue() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalCategoryValue(final ApprovalCategoryValue.Id id,
|
|
||||||
final String name) {
|
|
||||||
this.key = id;
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalCategoryValue.Id getId() {
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApprovalCategory.Id getCategoryId() {
|
|
||||||
return key.categoryId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getValue() {
|
|
||||||
return key.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(final String n) {
|
|
||||||
name = n;
|
|
||||||
}
|
|
||||||
}
|
|
@@ -16,11 +16,52 @@ package com.google.gerrit.reviewdb.client;
|
|||||||
|
|
||||||
import com.google.gwtorm.client.Column;
|
import com.google.gwtorm.client.Column;
|
||||||
import com.google.gwtorm.client.CompoundKey;
|
import com.google.gwtorm.client.CompoundKey;
|
||||||
|
import com.google.gwtorm.client.StringKey;
|
||||||
|
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
|
||||||
/** An approval (or negative approval) on a patch set. */
|
/** An approval (or negative approval) on a patch set. */
|
||||||
public final class PatchSetApproval {
|
public final class PatchSetApproval {
|
||||||
|
public static class LabelId extends
|
||||||
|
StringKey<com.google.gwtorm.client.Key<?>> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public static final LabelId SUBMIT = new LabelId("SUBM");
|
||||||
|
|
||||||
|
@Column(id = 1)
|
||||||
|
protected String id;
|
||||||
|
|
||||||
|
protected LabelId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LabelId(final String n) {
|
||||||
|
id = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void set(String newValue) {
|
||||||
|
id = newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return get().hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object b) {
|
||||||
|
if (b instanceof LabelId) {
|
||||||
|
return get().equals(((LabelId) b).get());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class Key extends CompoundKey<PatchSet.Id> {
|
public static class Key extends CompoundKey<PatchSet.Id> {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@@ -31,16 +72,16 @@ public final class PatchSetApproval {
|
|||||||
protected Account.Id accountId;
|
protected Account.Id accountId;
|
||||||
|
|
||||||
@Column(id = 3)
|
@Column(id = 3)
|
||||||
protected ApprovalCategory.Id categoryId;
|
protected LabelId categoryId;
|
||||||
|
|
||||||
protected Key() {
|
protected Key() {
|
||||||
patchSetId = new PatchSet.Id();
|
patchSetId = new PatchSet.Id();
|
||||||
accountId = new Account.Id();
|
accountId = new Account.Id();
|
||||||
categoryId = new ApprovalCategory.Id();
|
categoryId = new LabelId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Key(final PatchSet.Id ps, final Account.Id a,
|
public Key(final PatchSet.Id ps, final Account.Id a,
|
||||||
final ApprovalCategory.Id c) {
|
final LabelId c) {
|
||||||
this.patchSetId = ps;
|
this.patchSetId = ps;
|
||||||
this.accountId = a;
|
this.accountId = a;
|
||||||
this.categoryId = c;
|
this.categoryId = c;
|
||||||
@@ -55,7 +96,7 @@ public final class PatchSetApproval {
|
|||||||
return accountId;
|
return accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApprovalCategory.Id getCategoryId() {
|
public LabelId getLabelId() {
|
||||||
return categoryId;
|
return categoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +152,7 @@ public final class PatchSetApproval {
|
|||||||
|
|
||||||
public PatchSetApproval(final PatchSet.Id psId, final PatchSetApproval src) {
|
public PatchSetApproval(final PatchSet.Id psId, final PatchSetApproval src) {
|
||||||
key =
|
key =
|
||||||
new PatchSetApproval.Key(psId, src.getAccountId(), src.getCategoryId());
|
new PatchSetApproval.Key(psId, src.getAccountId(), src.getLabelId());
|
||||||
changeOpen = true;
|
changeOpen = true;
|
||||||
value = src.getValue();
|
value = src.getValue();
|
||||||
granted = src.granted;
|
granted = src.granted;
|
||||||
@@ -129,7 +170,7 @@ public final class PatchSetApproval {
|
|||||||
return key.accountId;
|
return key.accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ApprovalCategory.Id getCategoryId() {
|
public LabelId getLabelId() {
|
||||||
return key.categoryId;
|
return key.categoryId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,6 +207,10 @@ public final class PatchSetApproval {
|
|||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSubmit() {
|
||||||
|
return LabelId.SUBMIT.get().equals(getLabelId().get());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new StringBuilder().append('[').append(key).append(": ")
|
return new StringBuilder().append('[').append(key).append(": ")
|
||||||
|
@@ -1,31 +0,0 @@
|
|||||||
// Copyright (C) 2008 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.reviewdb.server;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gwtorm.server.Access;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
|
||||||
import com.google.gwtorm.server.PrimaryKey;
|
|
||||||
import com.google.gwtorm.server.Query;
|
|
||||||
import com.google.gwtorm.server.ResultSet;
|
|
||||||
|
|
||||||
public interface ApprovalCategoryAccess extends
|
|
||||||
Access<ApprovalCategory, ApprovalCategory.Id> {
|
|
||||||
@PrimaryKey("categoryId")
|
|
||||||
ApprovalCategory get(ApprovalCategory.Id id) throws OrmException;
|
|
||||||
|
|
||||||
@Query("ORDER BY position, name")
|
|
||||||
ResultSet<ApprovalCategory> all() throws OrmException;
|
|
||||||
}
|
|
@@ -1,33 +0,0 @@
|
|||||||
// Copyright (C) 2008 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.reviewdb.server;
|
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
|
||||||
import com.google.gwtorm.server.Access;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
|
||||||
import com.google.gwtorm.server.PrimaryKey;
|
|
||||||
import com.google.gwtorm.server.Query;
|
|
||||||
import com.google.gwtorm.server.ResultSet;
|
|
||||||
|
|
||||||
public interface ApprovalCategoryValueAccess extends
|
|
||||||
Access<ApprovalCategoryValue, ApprovalCategoryValue.Id> {
|
|
||||||
@PrimaryKey("key")
|
|
||||||
ApprovalCategoryValue get(ApprovalCategoryValue.Id key) throws OrmException;
|
|
||||||
|
|
||||||
@Query("WHERE key.categoryId = ? ORDER BY key.value")
|
|
||||||
ResultSet<ApprovalCategoryValue> byCategory(ApprovalCategory.Id id)
|
|
||||||
throws OrmException;
|
|
||||||
}
|
|
@@ -43,11 +43,9 @@ public interface ReviewDb extends Schema {
|
|||||||
@Relation(id = 2)
|
@Relation(id = 2)
|
||||||
SystemConfigAccess systemConfig();
|
SystemConfigAccess systemConfig();
|
||||||
|
|
||||||
@Relation(id = 3)
|
// Deleted @Relation(id = 3)
|
||||||
ApprovalCategoryAccess approvalCategories();
|
|
||||||
|
|
||||||
@Relation(id = 4)
|
// Deleted @Relation(id = 4)
|
||||||
ApprovalCategoryValueAccess approvalCategoryValues();
|
|
||||||
|
|
||||||
@Relation(id = 6)
|
@Relation(id = 6)
|
||||||
AccountAccess accounts();
|
AccountAccess accounts();
|
||||||
|
@@ -416,7 +416,7 @@ public class ChangeHookRunner implements ChangeHooks, LifecycleListener {
|
|||||||
for (Map.Entry<String, Short> approval : approvals.entrySet()) {
|
for (Map.Entry<String, Short> approval : approvals.entrySet()) {
|
||||||
LabelType lt = labelTypes.byLabel(approval.getKey());
|
LabelType lt = labelTypes.byLabel(approval.getKey());
|
||||||
if (lt != null) {
|
if (lt != null) {
|
||||||
addArg(args, "--" + lt.getId(), Short.toString(approval.getValue()));
|
addArg(args, "--" + lt.getName(), Short.toString(approval.getValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,10 +21,10 @@ import com.google.gerrit.common.data.LabelType;
|
|||||||
import com.google.gerrit.common.data.LabelTypes;
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.Account.Id;
|
import com.google.gerrit.reviewdb.client.Account.Id;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
import com.google.gerrit.reviewdb.client.PatchSetInfo;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
@@ -86,7 +86,7 @@ public class ApprovalsUtil {
|
|||||||
List<PatchSetApproval> patchSetApprovals =
|
List<PatchSetApproval> patchSetApprovals =
|
||||||
db.patchSetApprovals().byChange(dest.getParentKey()).toList();
|
db.patchSetApprovals().byChange(dest.getParentKey()).toList();
|
||||||
for (PatchSetApproval a : patchSetApprovals) {
|
for (PatchSetApproval a : patchSetApprovals) {
|
||||||
LabelType type = labelTypes.byId(a.getCategoryId().get());
|
LabelType type = labelTypes.byLabel(a.getLabelId());
|
||||||
if (type != null && a.getPatchSetId().equals(source) &&
|
if (type != null && a.getPatchSetId().equals(source) &&
|
||||||
type.isCopyMinScore() &&
|
type.isCopyMinScore() &&
|
||||||
type.isMaxNegative(a)) {
|
type.isMaxNegative(a)) {
|
||||||
@@ -123,11 +123,10 @@ public class ApprovalsUtil {
|
|||||||
need.removeAll(existingReviewers);
|
need.removeAll(existingReviewers);
|
||||||
|
|
||||||
List<PatchSetApproval> cells = Lists.newArrayListWithCapacity(need.size());
|
List<PatchSetApproval> cells = Lists.newArrayListWithCapacity(need.size());
|
||||||
ApprovalCategory.Id catId =
|
LabelId labelId = Iterables.getLast(allTypes).getLabelId();
|
||||||
Iterables.getLast(allTypes).getApprovalCategoryId();
|
|
||||||
for (Account.Id account : need) {
|
for (Account.Id account : need) {
|
||||||
PatchSetApproval psa = new PatchSetApproval(
|
PatchSetApproval psa = new PatchSetApproval(
|
||||||
new PatchSetApproval.Key(ps.getId(), account, catId),
|
new PatchSetApproval.Key(ps.getId(), account, labelId),
|
||||||
(short) 0);
|
(short) 0);
|
||||||
psa.cache(change);
|
psa.cache(change);
|
||||||
cells.add(psa);
|
cells.add(psa);
|
||||||
|
@@ -45,7 +45,6 @@ import com.google.gerrit.extensions.restapi.Url;
|
|||||||
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.Change.Status;
|
import com.google.gerrit.reviewdb.client.Change.Status;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||||
import com.google.gerrit.reviewdb.client.Patch;
|
import com.google.gerrit.reviewdb.client.Patch;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
@@ -403,8 +402,7 @@ public class ChangeJson {
|
|||||||
|
|
||||||
for (PatchSetApproval psa : cd.currentApprovals(db)) {
|
for (PatchSetApproval psa : cd.currentApprovals(db)) {
|
||||||
short val = psa.getValue();
|
short val = psa.getValue();
|
||||||
if (val != 0 && min < val && val < max
|
if (val != 0 && min < val && val < max && type.matches(psa)) {
|
||||||
&& psa.getCategoryId().get().equals(type.getId())) {
|
|
||||||
if (0 < val) {
|
if (0 < val) {
|
||||||
label.recommended = accountLoader.get(psa.getAccountId());
|
label.recommended = accountLoader.get(psa.getAccountId());
|
||||||
label.value = val != 1 ? val : null;
|
label.value = val != 1 ? val : null;
|
||||||
@@ -447,7 +445,7 @@ public class ChangeJson {
|
|||||||
}
|
}
|
||||||
for (PatchSetApproval psa : current.get(accountId)) {
|
for (PatchSetApproval psa : current.get(accountId)) {
|
||||||
// TODO Support arbitrary labels placed by a reviewer.
|
// TODO Support arbitrary labels placed by a reviewer.
|
||||||
LabelType lt = ctl.getLabelTypes().byId(psa.getCategoryId().get());
|
LabelType lt = ctl.getLabelTypes().byLabel(psa.getLabelId());
|
||||||
if (lt == null) {
|
if (lt == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -471,11 +469,12 @@ public class ChangeJson {
|
|||||||
allUsers.add(psa.getAccountId());
|
allUsers.add(psa.getAccountId());
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<ApprovalCategory.Id> categories = Sets.newHashSet();
|
Set<String> labelNames = Sets.newHashSet();
|
||||||
Multimap<Account.Id, PatchSetApproval> current = HashMultimap.create();
|
Multimap<Account.Id, PatchSetApproval> current = HashMultimap.create();
|
||||||
for (PatchSetApproval a : cd.currentApprovals(db)) {
|
for (PatchSetApproval a : cd.currentApprovals(db)) {
|
||||||
if (a.getValue() != 0) {
|
LabelType type = labelTypes.byLabel(a.getLabelId());
|
||||||
categories.add(a.getCategoryId());
|
if (type != null && a.getValue() != 0) {
|
||||||
|
labelNames.add(type.getName());
|
||||||
current.put(a.getAccountId(), a);
|
current.put(a.getAccountId(), a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -486,15 +485,13 @@ public class ChangeJson {
|
|||||||
// Don't use Maps.newTreeMap(Comparator) due to OpenJDK bug 100167.
|
// Don't use Maps.newTreeMap(Comparator) due to OpenJDK bug 100167.
|
||||||
Map<String, LabelInfo> labels =
|
Map<String, LabelInfo> labels =
|
||||||
new TreeMap<String, LabelInfo>(labelTypes.nameComparator());
|
new TreeMap<String, LabelInfo>(labelTypes.nameComparator());
|
||||||
for (ApprovalCategory.Id id : categories) {
|
for (String name : labelNames) {
|
||||||
LabelType type = labelTypes.byId(id.get());
|
LabelType type = labelTypes.byLabel(name);
|
||||||
if (type != null) {
|
LabelInfo li = new LabelInfo();
|
||||||
LabelInfo li = new LabelInfo();
|
if (detailed) {
|
||||||
if (detailed) {
|
setLabelValues(type, li);
|
||||||
setLabelValues(type, li);
|
|
||||||
}
|
|
||||||
labels.put(type.getName(), li);
|
|
||||||
}
|
}
|
||||||
|
labels.put(type.getName(), li);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Account.Id accountId : allUsers) {
|
for (Account.Id accountId : allUsers) {
|
||||||
@@ -509,7 +506,7 @@ public class ChangeJson {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (PatchSetApproval psa : current.get(accountId)) {
|
for (PatchSetApproval psa : current.get(accountId)) {
|
||||||
LabelType type = labelTypes.byId(psa.getCategoryId().get());
|
LabelType type = labelTypes.byLabel(psa.getLabelId());
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -28,7 +28,6 @@ import com.google.gerrit.extensions.restapi.BadRequestException;
|
|||||||
import com.google.gerrit.extensions.restapi.DefaultInput;
|
import com.google.gerrit.extensions.restapi.DefaultInput;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
import com.google.gerrit.extensions.restapi.Url;
|
import com.google.gerrit.extensions.restapi.Url;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
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;
|
||||||
import com.google.gerrit.reviewdb.client.Patch;
|
import com.google.gerrit.reviewdb.client.Patch;
|
||||||
@@ -180,8 +179,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
|
|||||||
if (lt == null) {
|
if (lt == null) {
|
||||||
if (strict) {
|
if (strict) {
|
||||||
throw new BadRequestException(String.format(
|
throw new BadRequestException(String.format(
|
||||||
"label \"%s\" is not a configured ApprovalCategory",
|
"label \"%s\" is not a configured label", ent.getKey()));
|
||||||
ent.getKey()));
|
|
||||||
} else {
|
} else {
|
||||||
itr.remove();
|
itr.remove();
|
||||||
continue;
|
continue;
|
||||||
@@ -371,7 +369,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
|
|||||||
c = new PatchSetApproval(new PatchSetApproval.Key(
|
c = new PatchSetApproval(new PatchSetApproval.Key(
|
||||||
rsrc.getPatchSet().getId(),
|
rsrc.getPatchSet().getId(),
|
||||||
rsrc.getAccountId(),
|
rsrc.getAccountId(),
|
||||||
lt.getApprovalCategoryId()),
|
lt.getLabelId()),
|
||||||
ent.getValue());
|
ent.getValue());
|
||||||
c.setGranted(timestamp);
|
c.setGranted(timestamp);
|
||||||
c.cache(change);
|
c.cache(change);
|
||||||
@@ -400,7 +398,7 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
|
|||||||
rsrc.getPatchSet().getId(),
|
rsrc.getPatchSet().getId(),
|
||||||
rsrc.getAccountId(),
|
rsrc.getAccountId(),
|
||||||
rsrc.getControl().getLabelTypes().getLabelTypes().get(0)
|
rsrc.getControl().getLabelTypes().getLabelTypes().get(0)
|
||||||
.getApprovalCategoryId()),
|
.getLabelId()),
|
||||||
(short) 0);
|
(short) 0);
|
||||||
c.setGranted(timestamp);
|
c.setGranted(timestamp);
|
||||||
c.cache(change);
|
c.cache(change);
|
||||||
@@ -424,11 +422,11 @@ public class PostReview implements RestModifyView<RevisionResource, Input> {
|
|||||||
Map<String, PatchSetApproval> current = Maps.newHashMap();
|
Map<String, PatchSetApproval> current = Maps.newHashMap();
|
||||||
for (PatchSetApproval a : db.patchSetApprovals().byPatchSetUser(
|
for (PatchSetApproval a : db.patchSetApprovals().byPatchSetUser(
|
||||||
rsrc.getPatchSet().getId(), rsrc.getAccountId())) {
|
rsrc.getPatchSet().getId(), rsrc.getAccountId())) {
|
||||||
if (ApprovalCategory.SUBMIT_ID.equals(a.getCategoryId().get())) {
|
if (a.isSubmit()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelType lt = labelTypes.byId(a.getCategoryId().get());
|
LabelType lt = labelTypes.byLabel(a.getLabelId());
|
||||||
if (lt != null) {
|
if (lt != null) {
|
||||||
current.put(lt.getName(), a);
|
current.put(lt.getName(), a);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -32,10 +32,10 @@ import com.google.gerrit.extensions.restapi.RestModifyView;
|
|||||||
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.account.AccountCache;
|
import com.google.gerrit.server.account.AccountCache;
|
||||||
@@ -274,8 +274,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, Input> {
|
|||||||
|
|
||||||
private PatchSetApproval dummyApproval(ChangeControl ctl,
|
private PatchSetApproval dummyApproval(ChangeControl ctl,
|
||||||
PatchSet.Id patchSetId, Account.Id reviewerId) {
|
PatchSet.Id patchSetId, Account.Id reviewerId) {
|
||||||
ApprovalCategory.Id id = new ApprovalCategory.Id(
|
LabelId id =
|
||||||
Iterables.getLast(ctl.getLabelTypes().getLabelTypes()).getId());
|
Iterables.getLast(ctl.getLabelTypes().getLabelTypes()).getLabelId();
|
||||||
PatchSetApproval dummyApproval = new PatchSetApproval(
|
PatchSetApproval dummyApproval = new PatchSetApproval(
|
||||||
new PatchSetApproval.Key(patchSetId, reviewerId, id), (short) 0);
|
new PatchSetApproval.Key(patchSetId, reviewerId, id), (short) 0);
|
||||||
dummyApproval.cache(ctl.getChange());
|
dummyApproval.cache(ctl.getChange());
|
||||||
|
@@ -93,7 +93,7 @@ public class ReviewerJson {
|
|||||||
for (PermissionRange pr : ctl.getLabelRanges()) {
|
for (PermissionRange pr : ctl.getLabelRanges()) {
|
||||||
if (!pr.isEmpty()) {
|
if (!pr.isEmpty()) {
|
||||||
// TODO: Support arbitrary labels.
|
// TODO: Support arbitrary labels.
|
||||||
LabelType at = labelTypes.byId(ca.getCategoryId().get());
|
LabelType at = labelTypes.byLabel(ca.getLabelId());
|
||||||
if (at != null) {
|
if (at != null) {
|
||||||
out.approvals.put(at.getName(), formatValue(ca.getValue())); }
|
out.approvals.put(at.getName(), formatValue(ca.getValue())); }
|
||||||
}
|
}
|
||||||
|
@@ -24,11 +24,11 @@ import com.google.gerrit.common.data.SubmitRecord;
|
|||||||
import com.google.gerrit.extensions.restapi.AuthException;
|
import com.google.gerrit.extensions.restapi.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
import com.google.gerrit.extensions.restapi.RestModifyView;
|
import com.google.gerrit.extensions.restapi.RestModifyView;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
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;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.ChangeUtil;
|
import com.google.gerrit.server.ChangeUtil;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -187,7 +187,7 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
|||||||
new Predicate<PatchSetApproval>() {
|
new Predicate<PatchSetApproval>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(PatchSetApproval input) {
|
public boolean apply(PatchSetApproval input) {
|
||||||
return ApprovalCategory.SUBMIT_ID.equals(input.getCategoryId().get());
|
return input.isSubmit();
|
||||||
}
|
}
|
||||||
}), null);
|
}), null);
|
||||||
if (submit == null) {
|
if (submit == null) {
|
||||||
@@ -195,7 +195,7 @@ public class Submit implements RestModifyView<RevisionResource, Input> {
|
|||||||
new PatchSetApproval.Key(
|
new PatchSetApproval.Key(
|
||||||
rev.getId(),
|
rev.getId(),
|
||||||
caller.getAccountId(),
|
caller.getAccountId(),
|
||||||
new ApprovalCategory.Id(ApprovalCategory.SUBMIT_ID)),
|
LabelId.SUBMIT),
|
||||||
(short) 1);
|
(short) 1);
|
||||||
}
|
}
|
||||||
submit.setValue((short) 1);
|
submit.setValue((short) 1);
|
||||||
|
@@ -19,7 +19,6 @@ import static com.google.inject.Scopes.SINGLETON;
|
|||||||
import com.google.common.cache.Cache;
|
import com.google.common.cache.Cache;
|
||||||
import com.google.gerrit.audit.AuditModule;
|
import com.google.gerrit.audit.AuditModule;
|
||||||
import com.google.gerrit.common.ChangeListener;
|
import com.google.gerrit.common.ChangeListener;
|
||||||
import com.google.gerrit.common.data.LabelTypes;
|
|
||||||
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
|
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
|
||||||
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
|
import com.google.gerrit.extensions.events.NewProjectCreatedListener;
|
||||||
import com.google.gerrit.extensions.registration.DynamicItem;
|
import com.google.gerrit.extensions.registration.DynamicItem;
|
||||||
@@ -142,8 +141,6 @@ public class GerritGlobalModule extends FactoryModule {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(LabelTypes.class).toProvider(LabelTypesProvider.class).in(
|
|
||||||
SINGLETON);
|
|
||||||
bind(EmailExpander.class).toProvider(EmailExpanderProvider.class).in(
|
bind(EmailExpander.class).toProvider(EmailExpanderProvider.class).in(
|
||||||
SINGLETON);
|
SINGLETON);
|
||||||
|
|
||||||
|
@@ -1,61 +0,0 @@
|
|||||||
// Copyright (C) 2009 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.server.config;
|
|
||||||
|
|
||||||
import com.google.gerrit.common.data.LabelType;
|
|
||||||
import com.google.gerrit.common.data.LabelTypes;
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
|
||||||
import com.google.gwtorm.server.OrmException;
|
|
||||||
import com.google.gwtorm.server.SchemaFactory;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provider;
|
|
||||||
import com.google.inject.ProvisionException;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class LabelTypesProvider implements Provider<LabelTypes> {
|
|
||||||
private final SchemaFactory<ReviewDb> schema;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
LabelTypesProvider(final SchemaFactory<ReviewDb> sf) {
|
|
||||||
schema = sf;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public LabelTypes get() {
|
|
||||||
List<LabelType> types = new ArrayList<LabelType>(2);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final ReviewDb db = schema.open();
|
|
||||||
try {
|
|
||||||
for (final ApprovalCategory c : db.approvalCategories().all()) {
|
|
||||||
final List<ApprovalCategoryValue> values =
|
|
||||||
db.approvalCategoryValues().byCategory(c.getId()).toList();
|
|
||||||
types.add(LabelType.fromApprovalCategory(c, values));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
db.close();
|
|
||||||
}
|
|
||||||
} catch (OrmException e) {
|
|
||||||
throw new ProvisionException("Cannot query label categories", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new LabelTypes(Collections.unmodifiableList(types));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -456,12 +456,12 @@ public class EventFactory {
|
|||||||
public ApprovalAttribute asApprovalAttribute(PatchSetApproval approval,
|
public ApprovalAttribute asApprovalAttribute(PatchSetApproval approval,
|
||||||
LabelTypes labelTypes) {
|
LabelTypes labelTypes) {
|
||||||
ApprovalAttribute a = new ApprovalAttribute();
|
ApprovalAttribute a = new ApprovalAttribute();
|
||||||
a.type = approval.getCategoryId().get();
|
a.type = approval.getLabelId().get();
|
||||||
a.value = Short.toString(approval.getValue());
|
a.value = Short.toString(approval.getValue());
|
||||||
a.by = asAccountAttribute(approval.getAccountId());
|
a.by = asAccountAttribute(approval.getAccountId());
|
||||||
a.grantedOn = approval.getGranted().getTime() / 1000L;
|
a.grantedOn = approval.getGranted().getTime() / 1000L;
|
||||||
|
|
||||||
LabelType lt = labelTypes.byId(approval.getCategoryId().get());
|
LabelType lt = labelTypes.byLabel(approval.getLabelId());
|
||||||
if (lt != null) {
|
if (lt != null) {
|
||||||
a.description = lt.getName();
|
a.description = lt.getName();
|
||||||
}
|
}
|
||||||
|
@@ -16,10 +16,10 @@ package com.google.gerrit.server.git;
|
|||||||
|
|
||||||
import static com.google.gerrit.server.git.MergeUtil.getSubmitter;
|
import static com.google.gerrit.server.git.MergeUtil.getSubmitter;
|
||||||
|
|
||||||
|
import static java.util.concurrent.TimeUnit.DAYS;
|
||||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||||
import static java.util.concurrent.TimeUnit.MINUTES;
|
import static java.util.concurrent.TimeUnit.MINUTES;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||||
import static java.util.concurrent.TimeUnit.DAYS;
|
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
import com.google.common.collect.ArrayListMultimap;
|
||||||
@@ -31,7 +31,6 @@ import com.google.gerrit.common.data.LabelType;
|
|||||||
import com.google.gerrit.common.data.LabelTypes;
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
import com.google.gerrit.common.data.SubmitTypeRecord;
|
import com.google.gerrit.common.data.SubmitTypeRecord;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.Branch;
|
import com.google.gerrit.reviewdb.client.Branch;
|
||||||
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;
|
||||||
@@ -938,8 +937,7 @@ public class MergeOp {
|
|||||||
CategoryFunction.forType(lt).run(lt, fs);
|
CategoryFunction.forType(lt).run(lt, fs);
|
||||||
}
|
}
|
||||||
for (PatchSetApproval a : approvals) {
|
for (PatchSetApproval a : approvals) {
|
||||||
if (a.getValue() > 0
|
if (a.getValue() > 0 && a.isSubmit()
|
||||||
&& ApprovalCategory.SUBMIT_ID.equals(a.getCategoryId().get())
|
|
||||||
&& a.getPatchSetId().equals(merged)) {
|
&& a.getPatchSetId().equals(merged)) {
|
||||||
if (submitter == null
|
if (submitter == null
|
||||||
|| a.getGranted().compareTo(submitter.getGranted()) > 0) {
|
|| a.getGranted().compareTo(submitter.getGranted()) > 0) {
|
||||||
|
@@ -16,10 +16,10 @@ package com.google.gerrit.server.git;
|
|||||||
|
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.Branch;
|
import com.google.gerrit.reviewdb.client.Branch;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
import com.google.gerrit.server.config.CanonicalWebUrl;
|
import com.google.gerrit.server.config.CanonicalWebUrl;
|
||||||
@@ -82,9 +82,6 @@ public class MergeUtil {
|
|||||||
private static final String R_HEADS_MASTER =
|
private static final String R_HEADS_MASTER =
|
||||||
Constants.R_HEADS + Constants.MASTER;
|
Constants.R_HEADS + Constants.MASTER;
|
||||||
|
|
||||||
private static final String CRVW = "CRVW";
|
|
||||||
private static final String VRIF = "VRIF";
|
|
||||||
|
|
||||||
private static final FooterKey REVIEWED_ON = new FooterKey("Reviewed-on");
|
private static final FooterKey REVIEWED_ON = new FooterKey("Reviewed-on");
|
||||||
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
|
private static final FooterKey CHANGE_ID = new FooterKey("Change-Id");
|
||||||
|
|
||||||
@@ -171,7 +168,7 @@ public class MergeUtil {
|
|||||||
final List<PatchSetApproval> approvals =
|
final List<PatchSetApproval> approvals =
|
||||||
reviewDb.patchSetApprovals().byPatchSet(c).toList();
|
reviewDb.patchSetApprovals().byPatchSet(c).toList();
|
||||||
for (PatchSetApproval a : approvals) {
|
for (PatchSetApproval a : approvals) {
|
||||||
if (a.getValue() > 0 && ApprovalCategory.isSubmit(a)) {
|
if (a.getValue() > 0 && a.isSubmit()) {
|
||||||
if (submitter == null
|
if (submitter == null
|
||||||
|| a.getGranted().compareTo(submitter.getGranted()) > 0) {
|
|| a.getGranted().compareTo(submitter.getGranted()) > 0) {
|
||||||
submitter = a;
|
submitter = a;
|
||||||
@@ -257,7 +254,7 @@ public class MergeUtil {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ApprovalCategory.isSubmit(a)) {
|
if (a.isSubmit()) {
|
||||||
// Submit is treated specially, below (becomes committer)
|
// Submit is treated specially, below (becomes committer)
|
||||||
//
|
//
|
||||||
if (submitAudit == null
|
if (submitAudit == null
|
||||||
@@ -294,13 +291,12 @@ public class MergeUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String tag;
|
final String tag;
|
||||||
if (CRVW.equals(a.getCategoryId().get())) {
|
if (isCodeReview(a.getLabelId())) {
|
||||||
tag = "Reviewed-by";
|
tag = "Reviewed-by";
|
||||||
} else if (VRIF.equals(a.getCategoryId().get())) {
|
} else if (isVerified(a.getLabelId())) {
|
||||||
tag = "Tested-by";
|
tag = "Tested-by";
|
||||||
} else {
|
} else {
|
||||||
final LabelType lt =
|
final LabelType lt = project.getLabelTypes().byLabel(a.getLabelId());
|
||||||
project.getLabelTypes().byId(a.getCategoryId().get());
|
|
||||||
if (lt == null) {
|
if (lt == null) {
|
||||||
// TODO: Support arbitrary labels.
|
// TODO: Support arbitrary labels.
|
||||||
continue;
|
continue;
|
||||||
@@ -319,6 +315,14 @@ public class MergeUtil {
|
|||||||
return msgbuf.toString();
|
return msgbuf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isCodeReview(LabelId id) {
|
||||||
|
return "CRVW".equals(id.get()) || "Code-Review".equalsIgnoreCase(id.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isVerified(LabelId id) {
|
||||||
|
return "VRIF".equals(id.get()) || "Verified".equalsIgnoreCase(id.get());
|
||||||
|
}
|
||||||
|
|
||||||
public List<PatchSetApproval> getApprovalsForCommit(final CodeReviewCommit n) {
|
public List<PatchSetApproval> getApprovalsForCommit(final CodeReviewCommit n) {
|
||||||
try {
|
try {
|
||||||
List<PatchSetApproval> approvalList =
|
List<PatchSetApproval> approvalList =
|
||||||
|
@@ -22,6 +22,7 @@ import com.google.common.base.Splitter;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.primitives.Shorts;
|
import com.google.common.primitives.Shorts;
|
||||||
import com.google.gerrit.common.data.AccessSection;
|
import com.google.gerrit.common.data.AccessSection;
|
||||||
import com.google.gerrit.common.data.ContributorAgreement;
|
import com.google.gerrit.common.data.ContributorAgreement;
|
||||||
@@ -225,8 +226,8 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
return notifySections.values();
|
return notifySections.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<LabelType> getLabelSections() {
|
public Map<String, LabelType> getLabelSections() {
|
||||||
return labelSections.values();
|
return labelSections;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupReference resolve(AccountGroup group) {
|
public GroupReference resolve(AccountGroup group) {
|
||||||
@@ -545,21 +546,14 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LabelType label;
|
LabelType label;
|
||||||
String id = rc.getString(LABEL, name, KEY_ID);
|
|
||||||
if (id == null || id.length() > 4) {
|
|
||||||
error(new ValidationError(PROJECT_CONFIG, String.format(
|
|
||||||
"Invalid label ID \"%s\" for label \"%s\": "
|
|
||||||
+ "Label ID may have at most 4 characters", id, name)));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
label = new LabelType(id, name, values);
|
label = new LabelType(name, values);
|
||||||
} catch (IllegalArgumentException badName) {
|
} catch (IllegalArgumentException badName) {
|
||||||
error(new ValidationError(PROJECT_CONFIG, String.format(
|
error(new ValidationError(PROJECT_CONFIG, String.format(
|
||||||
"Invalid label \"%s\"", name)));
|
"Invalid label \"%s\"", name)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
label.setId(rc.getString(LABEL, name, KEY_ID));
|
||||||
String abbr = rc.getString(LABEL, name, KEY_ABBREVIATION);
|
String abbr = rc.getString(LABEL, name, KEY_ABBREVIATION);
|
||||||
if (abbr != null) {
|
if (abbr != null) {
|
||||||
label.setAbbreviatedName(abbr);
|
label.setAbbreviatedName(abbr);
|
||||||
@@ -645,6 +639,7 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
saveAccessSections(rc, keepGroups);
|
saveAccessSections(rc, keepGroups);
|
||||||
saveNotifySections(rc, keepGroups);
|
saveNotifySections(rc, keepGroups);
|
||||||
groupsByUUID.keySet().retainAll(keepGroups);
|
groupsByUUID.keySet().retainAll(keepGroups);
|
||||||
|
saveLabelSections(rc);
|
||||||
|
|
||||||
saveConfig(PROJECT_CONFIG, rc);
|
saveConfig(PROJECT_CONFIG, rc);
|
||||||
saveGroupList();
|
saveGroupList();
|
||||||
@@ -814,6 +809,53 @@ public class ProjectConfig extends VersionedMetaData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saveLabelSections(Config rc) {
|
||||||
|
List<String> existing = Lists.newArrayList(rc.getSubsections(LABEL));
|
||||||
|
if (!Lists.newArrayList(labelSections.keySet()).equals(existing)) {
|
||||||
|
// Order of sections changed, remove and rewrite them all.
|
||||||
|
for (String name : existing) {
|
||||||
|
rc.unsetSection(LABEL, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> toUnset = Sets.newHashSet(existing);
|
||||||
|
for (Map.Entry<String, LabelType> e : labelSections.entrySet()) {
|
||||||
|
String name = e.getKey();
|
||||||
|
LabelType label = e.getValue();
|
||||||
|
toUnset.remove(name);
|
||||||
|
rc.setString(LABEL, name, KEY_FUNCTION, label.getFunctionName());
|
||||||
|
|
||||||
|
if (!LabelType.defaultAbbreviation(name)
|
||||||
|
.equals(label.getAbbreviatedName())) {
|
||||||
|
rc.setString(
|
||||||
|
LABEL, name, KEY_ABBREVIATION, label.getAbbreviatedName());
|
||||||
|
} else {
|
||||||
|
rc.unset(LABEL, name, KEY_ABBREVIATION);
|
||||||
|
}
|
||||||
|
if (label.isCopyMinScore()) {
|
||||||
|
rc.setBoolean(LABEL, name, KEY_COPY_MIN_SCORE, true);
|
||||||
|
} else {
|
||||||
|
rc.unset(LABEL, name, KEY_COPY_MIN_SCORE);
|
||||||
|
}
|
||||||
|
if (!label.canOverride()) {
|
||||||
|
rc.setBoolean(LABEL, name, KEY_CAN_OVERRIDE, false);
|
||||||
|
} else {
|
||||||
|
rc.unset(LABEL, name, KEY_CAN_OVERRIDE);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> values =
|
||||||
|
Lists.newArrayListWithCapacity(label.getValues().size());
|
||||||
|
for (LabelValue value : label.getValues()) {
|
||||||
|
values.add(value.format());
|
||||||
|
}
|
||||||
|
rc.setStringList(LABEL, name, KEY_VALUE, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String name : toUnset) {
|
||||||
|
rc.unsetSection(LABEL, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void saveGroupList() throws IOException {
|
private void saveGroupList() throws IOException {
|
||||||
if (groupsByUUID.isEmpty()) {
|
if (groupsByUUID.isEmpty()) {
|
||||||
saveFile(GROUP_LIST, null);
|
saveFile(GROUP_LIST, null);
|
||||||
|
@@ -63,7 +63,7 @@ public class MergedSender extends ReplyToChangeSender {
|
|||||||
Table<Account.Id, String, PatchSetApproval> neg = HashBasedTable.create();
|
Table<Account.Id, String, PatchSetApproval> neg = HashBasedTable.create();
|
||||||
for (PatchSetApproval ca : args.db.get().patchSetApprovals()
|
for (PatchSetApproval ca : args.db.get().patchSetApprovals()
|
||||||
.byPatchSet(patchSet.getId())) {
|
.byPatchSet(patchSet.getId())) {
|
||||||
LabelType lt = labelTypes.byId(ca.getCategoryId().get());
|
LabelType lt = labelTypes.byLabel(ca.getLabelId());
|
||||||
if (lt == null) {
|
if (lt == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -69,7 +69,6 @@ public class ProjectState {
|
|||||||
private final PrologEnvironment.Factory envFactory;
|
private final PrologEnvironment.Factory envFactory;
|
||||||
private final GitRepositoryManager gitMgr;
|
private final GitRepositoryManager gitMgr;
|
||||||
private final RulesCache rulesCache;
|
private final RulesCache rulesCache;
|
||||||
private final LabelTypes dbLabelTypes;
|
|
||||||
|
|
||||||
private final ProjectConfig config;
|
private final ProjectConfig config;
|
||||||
private final Set<AccountGroup.UUID> localOwners;
|
private final Set<AccountGroup.UUID> localOwners;
|
||||||
@@ -94,7 +93,6 @@ public class ProjectState {
|
|||||||
final PrologEnvironment.Factory envFactory,
|
final PrologEnvironment.Factory envFactory,
|
||||||
final GitRepositoryManager gitMgr,
|
final GitRepositoryManager gitMgr,
|
||||||
final RulesCache rulesCache,
|
final RulesCache rulesCache,
|
||||||
final LabelTypes labelTypes,
|
|
||||||
@Assisted final ProjectConfig config) {
|
@Assisted final ProjectConfig config) {
|
||||||
this.projectCache = projectCache;
|
this.projectCache = projectCache;
|
||||||
this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName);
|
this.isAllProjects = config.getProject().getNameKey().equals(allProjectsName);
|
||||||
@@ -107,7 +105,6 @@ public class ProjectState {
|
|||||||
this.capabilities = isAllProjects
|
this.capabilities = isAllProjects
|
||||||
? new CapabilityCollection(config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES))
|
? new CapabilityCollection(config.getAccessSection(AccessSection.GLOBAL_CAPABILITIES))
|
||||||
: null;
|
: null;
|
||||||
this.dbLabelTypes = labelTypes;
|
|
||||||
|
|
||||||
if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) {
|
if (isAllProjects && !Permission.canBeOnAllProjects(AccessSection.ALL, Permission.OWNER)) {
|
||||||
localOwners = Collections.emptySet();
|
localOwners = Collections.emptySet();
|
||||||
@@ -344,23 +341,16 @@ public class ProjectState {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void putLabelType(Map<String, LabelType> types, LabelType type) {
|
|
||||||
LabelType old = types.get(type.getName());
|
|
||||||
if (old == null || old.canOverride()) {
|
|
||||||
types.put(type.getName(), type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelTypes getLabelTypes() {
|
public LabelTypes getLabelTypes() {
|
||||||
Map<String, LabelType> types = Maps.newLinkedHashMap();
|
Map<String, LabelType> types = Maps.newLinkedHashMap();
|
||||||
for (LabelType type : dbLabelTypes.getLabelTypes()) {
|
|
||||||
putLabelType(types, type);
|
|
||||||
}
|
|
||||||
List<ProjectState> projects = Lists.newArrayList(tree());
|
List<ProjectState> projects = Lists.newArrayList(tree());
|
||||||
Collections.reverse(projects);
|
Collections.reverse(projects);
|
||||||
for (ProjectState s : projects) {
|
for (ProjectState s : projects) {
|
||||||
for (LabelType type : s.getConfig().getLabelSections()) {
|
for (LabelType type : s.getConfig().getLabelSections().values()) {
|
||||||
putLabelType(types, type);
|
LabelType old = types.get(type.getName());
|
||||||
|
if (old == null || !old.canOverride()) {
|
||||||
|
types.put(type.getName(), type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
|
List<LabelType> all = Lists.newArrayListWithCapacity(types.size());
|
||||||
|
@@ -64,10 +64,6 @@ class LabelPredicate extends OperatorPredicate<ChangeData> {
|
|||||||
return types.byLabel(toFind);
|
return types.byLabel(toFind);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (types.byId(toFind) != null) {
|
|
||||||
return types.byId(toFind);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (LabelType lt : types.getLabelTypes()) {
|
for (LabelType lt : types.getLabelTypes()) {
|
||||||
if (toFind.equalsIgnoreCase(lt.getName())) {
|
if (toFind.equalsIgnoreCase(lt.getName())) {
|
||||||
return lt;
|
return lt;
|
||||||
@@ -80,7 +76,7 @@ class LabelPredicate extends OperatorPredicate<ChangeData> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LabelType.withDefaultValues(toFind.substring(0, 4), toFind);
|
return LabelType.withDefaultValues(toFind);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Test op(String op) {
|
private static Test op(String op) {
|
||||||
@@ -162,7 +158,7 @@ class LabelPredicate extends OperatorPredicate<ChangeData> {
|
|||||||
final Set<Account.Id> approversThatVotedInCategory = new HashSet<Account.Id>();
|
final Set<Account.Id> approversThatVotedInCategory = new HashSet<Account.Id>();
|
||||||
for (PatchSetApproval p : object.currentApprovals(dbProvider)) {
|
for (PatchSetApproval p : object.currentApprovals(dbProvider)) {
|
||||||
allApprovers.add(p.getAccountId());
|
allApprovers.add(p.getAccountId());
|
||||||
if (p.getCategoryId().get().equals(labelType.getId())) {
|
if (labelType.matches(p)) {
|
||||||
approversThatVotedInCategory.add(p.getAccountId());
|
approversThatVotedInCategory.add(p.getAccountId());
|
||||||
if (match(c, p.getValue(), p.getAccountId(), labelType)) {
|
if (match(c, p.getValue(), p.getAccountId(), labelType)) {
|
||||||
return true;
|
return true;
|
||||||
|
@@ -14,15 +14,16 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.schema;
|
package com.google.gerrit.server.schema;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gerrit.common.Version;
|
import com.google.gerrit.common.Version;
|
||||||
import com.google.gerrit.common.data.AccessSection;
|
import com.google.gerrit.common.data.AccessSection;
|
||||||
import com.google.gerrit.common.data.GlobalCapability;
|
import com.google.gerrit.common.data.GlobalCapability;
|
||||||
|
import com.google.gerrit.common.data.LabelType;
|
||||||
|
import com.google.gerrit.common.data.LabelValue;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.common.data.PermissionRule;
|
import com.google.gerrit.common.data.PermissionRule;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
import com.google.gerrit.reviewdb.client.AccountGroupName;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
|
||||||
import com.google.gerrit.reviewdb.client.CurrentSchemaVersion;
|
import com.google.gerrit.reviewdb.client.CurrentSchemaVersion;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
|
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
|
||||||
@@ -51,7 +52,6 @@ import org.eclipse.jgit.lib.Repository;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
/** Creates the current database schema and populates initial code rows. */
|
/** Creates the current database schema and populates initial code rows. */
|
||||||
@@ -109,15 +109,8 @@ public class SchemaCreator {
|
|||||||
sVer.versionNbr = versionNbr;
|
sVer.versionNbr = versionNbr;
|
||||||
db.schemaVersion().insert(Collections.singleton(sVer));
|
db.schemaVersion().insert(Collections.singleton(sVer));
|
||||||
|
|
||||||
final SystemConfig sConfig = initSystemConfig(db);
|
initSystemConfig(db);
|
||||||
initVerifiedCategory(db);
|
initWildCardProject();
|
||||||
initCodeReviewCategory(db, sConfig);
|
|
||||||
|
|
||||||
if (mgr != null) {
|
|
||||||
// TODO This should never be null when initializing a site.
|
|
||||||
initWildCardProject();
|
|
||||||
}
|
|
||||||
|
|
||||||
dataSourceType.getIndexScript().run(db);
|
dataSourceType.getIndexScript().run(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,6 +234,9 @@ public class SchemaCreator {
|
|||||||
metaReadPermission.setExclusiveGroup(true);
|
metaReadPermission.setExclusiveGroup(true);
|
||||||
metaReadPermission.add(rule(config, owners));
|
metaReadPermission.add(rule(config, owners));
|
||||||
|
|
||||||
|
initVerifiedCategory(config);
|
||||||
|
initCodeReviewCategory(config);
|
||||||
|
|
||||||
md.setMessage("Initialized Gerrit Code Review " + Version.getVersion());
|
md.setMessage("Initialized Gerrit Code Review " + Version.getVersion());
|
||||||
config.commit(md);
|
config.commit(md);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -252,43 +248,23 @@ public class SchemaCreator {
|
|||||||
return new PermissionRule(config.resolve(group));
|
return new PermissionRule(config.resolve(group));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initVerifiedCategory(final ReviewDb c) throws OrmException {
|
private void initVerifiedCategory(ProjectConfig c) {
|
||||||
final ApprovalCategory cat;
|
LabelType type = new LabelType("Verified", ImmutableList.of(
|
||||||
final ArrayList<ApprovalCategoryValue> vals;
|
new LabelValue((short) 1, "Verified"),
|
||||||
|
new LabelValue((short) 0, "No score"),
|
||||||
cat = new ApprovalCategory(new ApprovalCategory.Id("VRIF"), "Verified");
|
new LabelValue((short) -1, "Fails")));
|
||||||
cat.setPosition((short) 0);
|
c.getLabelSections().put(type.getName(), type);
|
||||||
cat.setAbbreviatedName("V");
|
|
||||||
vals = new ArrayList<ApprovalCategoryValue>();
|
|
||||||
vals.add(value(cat, 1, "Verified"));
|
|
||||||
vals.add(value(cat, 0, "No score"));
|
|
||||||
vals.add(value(cat, -1, "Fails"));
|
|
||||||
c.approvalCategories().insert(Collections.singleton(cat));
|
|
||||||
c.approvalCategoryValues().insert(vals);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initCodeReviewCategory(final ReviewDb c,
|
private void initCodeReviewCategory(ProjectConfig c) {
|
||||||
final SystemConfig sConfig) throws OrmException {
|
LabelType type = new LabelType("Code-Review", ImmutableList.of(
|
||||||
final ApprovalCategory cat;
|
new LabelValue((short) 2, "Looks good to me, approved"),
|
||||||
final ArrayList<ApprovalCategoryValue> vals;
|
new LabelValue((short) 1, "Looks good to me, but someone else must approve"),
|
||||||
|
new LabelValue((short) 0, "No score"),
|
||||||
cat = new ApprovalCategory(new ApprovalCategory.Id("CRVW"), "Code Review");
|
new LabelValue((short) -1, "I would prefer that you didn't submit this"),
|
||||||
cat.setPosition((short) 1);
|
new LabelValue((short) -2, "Do not submit")));
|
||||||
cat.setAbbreviatedName("R");
|
type.setAbbreviatedName("CR");
|
||||||
cat.setCopyMinScore(true);
|
type.setCopyMinScore(true);
|
||||||
vals = new ArrayList<ApprovalCategoryValue>();
|
c.getLabelSections().put(type.getName(), type);
|
||||||
vals.add(value(cat, 2, "Looks good to me, approved"));
|
|
||||||
vals.add(value(cat, 1, "Looks good to me, but someone else must approve"));
|
|
||||||
vals.add(value(cat, 0, "No score"));
|
|
||||||
vals.add(value(cat, -1, "I would prefer that you didn't submit this"));
|
|
||||||
vals.add(value(cat, -2, "Do not submit"));
|
|
||||||
c.approvalCategories().insert(Collections.singleton(cat));
|
|
||||||
c.approvalCategoryValues().insert(vals);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ApprovalCategoryValue value(final ApprovalCategory cat,
|
|
||||||
final int value, final String name) {
|
|
||||||
return new ApprovalCategoryValue(new ApprovalCategoryValue.Id(cat.getId(),
|
|
||||||
(short) value), name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ import java.util.List;
|
|||||||
/** A version of the database schema. */
|
/** A version of the database schema. */
|
||||||
public abstract class SchemaVersion {
|
public abstract class SchemaVersion {
|
||||||
/** The current schema version. */
|
/** The current schema version. */
|
||||||
public static final Class<Schema_76> C = Schema_76.class;
|
public static final Class<Schema_77> C = Schema_77.class;
|
||||||
|
|
||||||
public static class Module extends AbstractModule {
|
public static class Module extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
|
@@ -28,10 +28,12 @@ import static com.google.gerrit.common.data.Permission.SUBMIT;
|
|||||||
|
|
||||||
import com.google.gerrit.common.data.AccessSection;
|
import com.google.gerrit.common.data.AccessSection;
|
||||||
import com.google.gerrit.common.data.GroupReference;
|
import com.google.gerrit.common.data.GroupReference;
|
||||||
|
import com.google.gerrit.common.data.LabelType;
|
||||||
|
import com.google.gerrit.common.data.LabelTypes;
|
||||||
import com.google.gerrit.common.data.Permission;
|
import com.google.gerrit.common.data.Permission;
|
||||||
import com.google.gerrit.common.data.PermissionRule;
|
import com.google.gerrit.common.data.PermissionRule;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
import com.google.gerrit.reviewdb.client.AccountGroup;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval.LabelId;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
|
import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
|
||||||
import com.google.gerrit.reviewdb.client.SystemConfig;
|
import com.google.gerrit.reviewdb.client.SystemConfig;
|
||||||
@@ -68,7 +70,7 @@ class Schema_53 extends SchemaVersion {
|
|||||||
|
|
||||||
private SystemConfig systemConfig;
|
private SystemConfig systemConfig;
|
||||||
private Map<AccountGroup.Id, GroupReference> groupMap;
|
private Map<AccountGroup.Id, GroupReference> groupMap;
|
||||||
private Map<ApprovalCategory.Id, ApprovalCategory> categoryMap;
|
private LabelTypes labelTypes;
|
||||||
private GroupReference projectOwners;
|
private GroupReference projectOwners;
|
||||||
|
|
||||||
private Map<Project.NameKey, Project.NameKey> parentsByProject;
|
private Map<Project.NameKey, Project.NameKey> parentsByProject;
|
||||||
@@ -93,7 +95,7 @@ class Schema_53 extends SchemaVersion {
|
|||||||
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
|
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException,
|
||||||
SQLException {
|
SQLException {
|
||||||
systemConfig = db.systemConfig().get(new SystemConfig.Key());
|
systemConfig = db.systemConfig().get(new SystemConfig.Key());
|
||||||
categoryMap = db.approvalCategories().toMap(db.approvalCategories().all());
|
labelTypes = Schema_77.getLegacyTypes(db);
|
||||||
|
|
||||||
assignGroupUUIDs(db);
|
assignGroupUUIDs(db);
|
||||||
readOldRefRights(db);
|
readOldRefRights(db);
|
||||||
@@ -104,13 +106,17 @@ class Schema_53 extends SchemaVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void deleteActionCategories(ReviewDb db) throws OrmException {
|
private void deleteActionCategories(ReviewDb db) throws OrmException {
|
||||||
List<ApprovalCategory> delete = new ArrayList<ApprovalCategory>();
|
try {
|
||||||
for (ApprovalCategory category : categoryMap.values()) {
|
Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
|
||||||
if (category.getPosition() < 0) {
|
try {
|
||||||
delete.add(category);
|
stmt.executeUpdate(
|
||||||
|
"DELETE FROM approval_categories WHERE position < 0");
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
}
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new OrmException(e);
|
||||||
}
|
}
|
||||||
db.approvalCategories().delete(delete);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assignGroupUUIDs(ReviewDb db) throws OrmException {
|
private void assignGroupUUIDs(ReviewDb db) throws OrmException {
|
||||||
@@ -365,8 +371,7 @@ class Schema_53 extends SchemaVersion {
|
|||||||
|
|
||||||
if (3 <= old.max_value) {
|
if (3 <= old.max_value) {
|
||||||
add(section, FORGE_SERVER, old.exclusive, rule(group));
|
add(section, FORGE_SERVER, old.exclusive, rule(group));
|
||||||
} else if (3 <= inheritedMax(config, old)) {
|
} else if (3 <= inheritedMax(config, old)) { add(section, FORGE_SERVER, old.exclusive, deny(group));
|
||||||
add(section, FORGE_SERVER, old.exclusive, deny(group));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -375,7 +380,9 @@ class Schema_53 extends SchemaVersion {
|
|||||||
if (old.min_value == 0 && old.max_value == 0) {
|
if (old.min_value == 0 && old.max_value == 0) {
|
||||||
rule.setDeny();
|
rule.setDeny();
|
||||||
}
|
}
|
||||||
add(section, LABEL + varNameOf(old.category), old.exclusive, rule);
|
LabelType type = labelTypes.byLabel(new LabelId(old.category));
|
||||||
|
String name = type != null ? type.getName() : old.category;
|
||||||
|
add(section, LABEL + name, old.exclusive, rule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -443,14 +450,6 @@ class Schema_53 extends SchemaVersion {
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String varNameOf(String id) {
|
|
||||||
ApprovalCategory category = categoryMap.get(new ApprovalCategory.Id(id));
|
|
||||||
if (category == null) {
|
|
||||||
category = new ApprovalCategory(new ApprovalCategory.Id(id), id);
|
|
||||||
}
|
|
||||||
return category.getLabelName();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void add(AccessSection section, String name,
|
private static void add(AccessSection section, String name,
|
||||||
boolean exclusive, PermissionRule rule) {
|
boolean exclusive, PermissionRule rule) {
|
||||||
Permission p = section.getPermission(name, true);
|
Permission p = section.getPermission(name, true);
|
||||||
|
@@ -0,0 +1,219 @@
|
|||||||
|
// Copyright (C) 2013 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.server.schema;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
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.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.GerritPersonIdent;
|
||||||
|
import com.google.gerrit.server.config.AllProjectsName;
|
||||||
|
import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
|
||||||
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
|
import com.google.gerrit.server.git.MetaDataUpdate;
|
||||||
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
|
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||||
|
import com.google.gwtorm.schema.sql.DialectH2;
|
||||||
|
import com.google.gwtorm.schema.sql.DialectMySQL;
|
||||||
|
import com.google.gwtorm.schema.sql.DialectPostgreSQL;
|
||||||
|
import com.google.gwtorm.schema.sql.SqlDialect;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provider;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||||
|
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||||
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class Schema_77 extends SchemaVersion {
|
||||||
|
private final GitRepositoryManager mgr;
|
||||||
|
private final AllProjectsName allProjects;
|
||||||
|
private final PersonIdent serverUser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Schema_77(Provider<Schema_76> prior, AllProjectsName allProjects,
|
||||||
|
GitRepositoryManager mgr, @GerritPersonIdent PersonIdent serverUser) {
|
||||||
|
super(prior);
|
||||||
|
this.allProjects = allProjects;
|
||||||
|
this.mgr = mgr;
|
||||||
|
this.serverUser = serverUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException {
|
||||||
|
try {
|
||||||
|
LabelTypes labelTypes = getLegacyTypes(db);
|
||||||
|
SqlDialect dialect = ((JdbcSchema) db).getDialect();
|
||||||
|
if (dialect instanceof DialectH2) {
|
||||||
|
alterTable(db, "ALTER TABLE %s ALTER COLUMN %s varchar(255)");
|
||||||
|
} else if (dialect instanceof DialectPostgreSQL) {
|
||||||
|
alterTable(db, "ALTER TABLE %s ALTER %s TYPE varchar(255)");
|
||||||
|
} else if (dialect instanceof DialectMySQL) {
|
||||||
|
alterTable(db, "ALTER TABLE %s MODIFY %s varchar(255) BINARY");
|
||||||
|
} else {
|
||||||
|
alterTable(db, "ALTER TABLE %s MODIFY %s varchar(255)");
|
||||||
|
}
|
||||||
|
migratePatchSetApprovals(db, labelTypes);
|
||||||
|
migrateLabelsToAllProjects(db, labelTypes);
|
||||||
|
} catch (RepositoryNotFoundException e) {
|
||||||
|
throw new OrmException(e);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new OrmException(e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new OrmException(e);
|
||||||
|
} catch (ConfigInvalidException e) {
|
||||||
|
throw new OrmException(e);
|
||||||
|
}
|
||||||
|
ui.message(
|
||||||
|
"Migrated label types from database to All-Projects project.config");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void alterTable(ReviewDb db, String sqlFormat) throws SQLException {
|
||||||
|
Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
|
||||||
|
try {
|
||||||
|
stmt.executeUpdate(
|
||||||
|
String.format(sqlFormat, "patch_set_approvals", "category_id"));
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void migrateLabelsToAllProjects(ReviewDb db, LabelTypes labelTypes)
|
||||||
|
throws SQLException, RepositoryNotFoundException, IOException,
|
||||||
|
ConfigInvalidException {
|
||||||
|
Repository git = mgr.openRepository(allProjects);
|
||||||
|
|
||||||
|
try {
|
||||||
|
MetaDataUpdate md =
|
||||||
|
new MetaDataUpdate(GitReferenceUpdated.DISABLED, allProjects, git);
|
||||||
|
md.getCommitBuilder().setAuthor(serverUser);
|
||||||
|
md.getCommitBuilder().setCommitter(serverUser);
|
||||||
|
|
||||||
|
ProjectConfig config = ProjectConfig.read(md);
|
||||||
|
Map<String, LabelType> configTypes = config.getLabelSections();
|
||||||
|
List<LabelType> newTypes = Lists.newArrayList();
|
||||||
|
for (LabelType type : labelTypes.getLabelTypes()) {
|
||||||
|
// Don't include IDs for this migration, since we are also updating all
|
||||||
|
// existing PatchSetApprovals.
|
||||||
|
type.setId(null);
|
||||||
|
if (!configTypes.containsKey(type.getName())) {
|
||||||
|
newTypes.add(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newTypes.addAll(configTypes.values());
|
||||||
|
configTypes.clear();
|
||||||
|
for (LabelType type : newTypes) {
|
||||||
|
configTypes.put(type.getName(), type);
|
||||||
|
}
|
||||||
|
md.setMessage("Upgrade to Gerrit Code Review schema 77\n");
|
||||||
|
config.commit(md);
|
||||||
|
} finally {
|
||||||
|
git.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void migratePatchSetApprovals(ReviewDb db, LabelTypes labelTypes)
|
||||||
|
throws SQLException {
|
||||||
|
PreparedStatement stmt = ((JdbcSchema) db).getConnection().prepareStatement(
|
||||||
|
"UPDATE patch_set_approvals SET category_id = ? WHERE category_id = ?");
|
||||||
|
try {
|
||||||
|
for (LabelType type : labelTypes.getLabelTypes()) {
|
||||||
|
stmt.setString(1, type.getName());
|
||||||
|
stmt.setString(2, type.getId());
|
||||||
|
stmt.addBatch();
|
||||||
|
}
|
||||||
|
stmt.executeBatch();
|
||||||
|
} finally {
|
||||||
|
stmt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static LabelTypes getLegacyTypes(ReviewDb db) throws SQLException {
|
||||||
|
List<LabelType> types = Lists.newArrayListWithCapacity(2);
|
||||||
|
Statement catStmt = null;
|
||||||
|
PreparedStatement valStmt = null;
|
||||||
|
ResultSet catRs = null;
|
||||||
|
try {
|
||||||
|
catStmt = ((JdbcSchema) db).getConnection().createStatement();
|
||||||
|
catRs = catStmt.executeQuery(
|
||||||
|
"SELECT category_id, name, abbreviated_name, function_name, "
|
||||||
|
+ " copy_min_score"
|
||||||
|
+ " FROM approval_categories"
|
||||||
|
+ " ORDER BY position, name");
|
||||||
|
valStmt = ((JdbcSchema) db).getConnection().prepareStatement(
|
||||||
|
"SELECT value, name"
|
||||||
|
+ " FROM approval_category_values"
|
||||||
|
+ " WHERE category_id = ?");
|
||||||
|
while (catRs.next()) {
|
||||||
|
String id = catRs.getString("category_id");
|
||||||
|
valStmt.setString(1, id);
|
||||||
|
List<LabelValue> values = Lists.newArrayListWithCapacity(5);
|
||||||
|
ResultSet valRs = valStmt.executeQuery();
|
||||||
|
try {
|
||||||
|
while (valRs.next()) {
|
||||||
|
values.add(new LabelValue(
|
||||||
|
valRs.getShort("value"), valRs.getString("name")));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
valRs.close();
|
||||||
|
}
|
||||||
|
LabelType type =
|
||||||
|
new LabelType(getLabelName(catRs.getString("name")), values);
|
||||||
|
type.setId(id);
|
||||||
|
type.setAbbreviatedName(catRs.getString("abbreviated_name"));
|
||||||
|
type.setFunctionName(catRs.getString("function_name"));
|
||||||
|
type.setCopyMinScore("Y".equals(catRs.getString("copy_min_score")));
|
||||||
|
types.add(type);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (valStmt != null) {
|
||||||
|
valStmt.close();
|
||||||
|
}
|
||||||
|
if (catRs != null) {
|
||||||
|
catRs.close();
|
||||||
|
}
|
||||||
|
if (catStmt != null) {
|
||||||
|
catStmt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new LabelTypes(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLabelName(String name) {
|
||||||
|
StringBuilder r = new StringBuilder();
|
||||||
|
for (int i = 0; i < name.length(); i++) {
|
||||||
|
char c = name.charAt(i);
|
||||||
|
if (('0' <= c && c <= '9') //
|
||||||
|
|| ('a' <= c && c <= 'z') //
|
||||||
|
|| ('A' <= c && c <= 'Z') //
|
||||||
|
|| (c == '-')) {
|
||||||
|
r.append(c);
|
||||||
|
} else if (c == ' ') {
|
||||||
|
r.append('-');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r.toString();
|
||||||
|
}
|
||||||
|
}
|
@@ -15,7 +15,6 @@
|
|||||||
package com.google.gerrit.server.workflow;
|
package com.google.gerrit.server.workflow;
|
||||||
|
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -48,18 +47,6 @@ public abstract class CategoryFunction {
|
|||||||
return r != null ? r : new NoOpFunction();
|
return r != null ? r : new NoOpFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Locate a function by category.
|
|
||||||
*
|
|
||||||
* @param category the category the function is for.
|
|
||||||
* @return the function implementation; {@link NoOpFunction} if the function
|
|
||||||
* is not known to Gerrit and thus cannot be executed.
|
|
||||||
*/
|
|
||||||
public static CategoryFunction forCategory(final ApprovalCategory category) {
|
|
||||||
final CategoryFunction r = all.get(category.getFunctionName());
|
|
||||||
return r != null ? r : new NoOpFunction();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize ChangeApprovals and set the valid flag for this category.
|
* Normalize ChangeApprovals and set the valid flag for this category.
|
||||||
* <p>
|
* <p>
|
||||||
|
@@ -60,15 +60,14 @@ public class FunctionState {
|
|||||||
|
|
||||||
for (final PatchSetApproval ca : all) {
|
for (final PatchSetApproval ca : all) {
|
||||||
if (psId.equals(ca.getPatchSetId())) {
|
if (psId.equals(ca.getPatchSetId())) {
|
||||||
Collection<PatchSetApproval> l =
|
LabelType lt = c.getLabelTypes().byLabel(ca.getLabelId());
|
||||||
approvals.get(ca.getCategoryId().get());
|
if (lt == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Collection<PatchSetApproval> l = approvals.get(lt.getName());
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
l = new ArrayList<PatchSetApproval>();
|
l = new ArrayList<PatchSetApproval>();
|
||||||
LabelType lt = c.getLabelTypes().byId(ca.getCategoryId().get());
|
approvals.put(lt.getName(), l);
|
||||||
if (lt != null) {
|
|
||||||
// TODO: Support arbitrary labels
|
|
||||||
approvals.put(lt.getName(), l);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
l.add(ca);
|
l.add(ca);
|
||||||
}
|
}
|
||||||
@@ -84,7 +83,7 @@ public class FunctionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void valid(final LabelType lt, final boolean v) {
|
public void valid(final LabelType lt, final boolean v) {
|
||||||
valid.put(id(lt), v);
|
valid.put(lt.getName(), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isValid(final LabelType lt) {
|
public boolean isValid(final LabelType lt) {
|
||||||
@@ -148,8 +147,4 @@ public class FunctionState {
|
|||||||
applyTypeFloor(lt, ca);
|
applyTypeFloor(lt, ca);
|
||||||
applyRightFloor(lt, ca);
|
applyRightFloor(lt, ca);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String id(final LabelType lt) {
|
|
||||||
return lt.getId();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
package com.google.gerrit.server.workflow;
|
package com.google.gerrit.server.workflow;
|
||||||
|
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
package com.google.gerrit.server.workflow;
|
package com.google.gerrit.server.workflow;
|
||||||
|
|
||||||
import com.google.gerrit.common.data.LabelType;
|
import com.google.gerrit.common.data.LabelType;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -59,7 +59,7 @@ class PRED__load_commit_labels_1 extends Predicate.P1 {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelType t = types.byId(a.getCategoryId().get());
|
LabelType t = types.byLabel(a.getLabelId());
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -35,11 +35,10 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* Obtain a list of label types from the server configuration.
|
* Obtain a list of label types from the server configuration.
|
||||||
* <p>
|
* <p>
|
||||||
* Unifies to a Prolog list of: {@code label_type(Label, Id, Fun, Min, Max)}
|
* Unifies to a Prolog list of: {@code label_type(Label, Fun, Min, Max)}
|
||||||
* where:
|
* where:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@code Label} - the newer style label name</li>
|
* <li>{@code Label} - the newer style label name</li>
|
||||||
* <li>{@code Id} - the legacy LabelCategory.Id from the database</li>
|
|
||||||
* <li>{@code Fun} - legacy function name</li>
|
* <li>{@code Fun} - legacy function name</li>
|
||||||
* <li>{@code Min, Max} - the smallest and largest configured values.</li>
|
* <li>{@code Min, Max} - the smallest and largest configured values.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
@@ -74,12 +73,11 @@ class PRED_get_legacy_label_types_1 extends Predicate.P1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final SymbolTerm symLabelType = SymbolTerm.intern(
|
static final SymbolTerm symLabelType = SymbolTerm.intern(
|
||||||
"label_type", 5);
|
"label_type", 4);
|
||||||
|
|
||||||
static Term export(LabelType type) {
|
static Term export(LabelType type) {
|
||||||
return new StructureTerm(symLabelType,
|
return new StructureTerm(symLabelType,
|
||||||
SymbolTerm.intern(type.getName()),
|
SymbolTerm.intern(type.getName()),
|
||||||
SymbolTerm.intern(type.getId()),
|
|
||||||
SymbolTerm.intern(type.getFunctionName()),
|
SymbolTerm.intern(type.getFunctionName()),
|
||||||
new IntegerTerm(type.getMin().getValue()),
|
new IntegerTerm(type.getMin().getValue()),
|
||||||
new IntegerTerm(type.getMax().getValue()));
|
new IntegerTerm(type.getMax().getValue()));
|
||||||
|
@@ -228,8 +228,8 @@ default_submit(LabelTypes, P) :-
|
|||||||
|
|
||||||
default_submit([], Out, Out).
|
default_submit([], Out, Out).
|
||||||
default_submit([Type | Types], Tmp, Out) :-
|
default_submit([Type | Types], Tmp, Out) :-
|
||||||
label_type(Label, Id, Fun, Min, Max) = Type,
|
label_type(Label, Fun, Min, Max) = Type,
|
||||||
legacy_submit_rule(Fun, Label, Id, Min, Max, Status),
|
legacy_submit_rule(Fun, Label, Min, Max, Status),
|
||||||
R = label(Label, Status),
|
R = label(Label, Status),
|
||||||
default_submit(Types, [R | Tmp], Out).
|
default_submit(Types, [R | Tmp], Out).
|
||||||
|
|
||||||
@@ -238,11 +238,11 @@ default_submit([Type | Types], Tmp, Out) :-
|
|||||||
%%
|
%%
|
||||||
%% Apply the old -2..+2 style logic.
|
%% Apply the old -2..+2 style logic.
|
||||||
%%
|
%%
|
||||||
legacy_submit_rule('MaxWithBlock', Label, Id, Min, Max, T) :- !, max_with_block(Label, Min, Max, T).
|
legacy_submit_rule('MaxWithBlock', Label, Min, Max, T) :- !, max_with_block(Label, Min, Max, T).
|
||||||
legacy_submit_rule('MaxNoBlock', Label, Id, Min, Max, T) :- !, max_no_block(Label, Max, T).
|
legacy_submit_rule('MaxNoBlock', Label, Min, Max, T) :- !, max_no_block(Label, Max, T).
|
||||||
legacy_submit_rule('NoBlock', Label, Id, Min, Max, T) :- !, T = may(_).
|
legacy_submit_rule('NoBlock', Label, Min, Max, T) :- !, T = may(_).
|
||||||
legacy_submit_rule('NoOp', Label, Id, Min, Max, T) :- !, T = may(_).
|
legacy_submit_rule('NoOp', Label, Min, Max, T) :- !, T = may(_).
|
||||||
legacy_submit_rule(Fun, Label, Id, Min, Max, T) :- T = impossible(unsupported(Fun)).
|
legacy_submit_rule(Fun, Label, Min, Max, T) :- T = impossible(unsupported(Fun)).
|
||||||
|
|
||||||
%% max_with_block:
|
%% max_with_block:
|
||||||
%%
|
%%
|
||||||
|
@@ -38,13 +38,13 @@ public class GerritCommonTest extends PrologTestCase {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
projects = new Projects(new LabelTypes(Arrays.asList(
|
projects = new Projects(new LabelTypes(Arrays.asList(
|
||||||
category("CRVW", "Code-Review",
|
category("Code-Review",
|
||||||
value(2, "Looks good to me, approved"),
|
value(2, "Looks good to me, approved"),
|
||||||
value(1, "Looks good to me, but someone else must approve"),
|
value(1, "Looks good to me, but someone else must approve"),
|
||||||
value(0, "No score"),
|
value(0, "No score"),
|
||||||
value(-1, "I would prefer that you didn't submit this"),
|
value(-1, "I would prefer that you didn't submit this"),
|
||||||
value(-2, "Do not submit")),
|
value(-2, "Do not submit")),
|
||||||
category("VRIF", "Verified", value(1, "Verified"),
|
category("Verified", value(1, "Verified"),
|
||||||
value(0, "No score"), value(-1, "Fails")))));
|
value(0, "No score"), value(-1, "Fails")))));
|
||||||
load("gerrit", "gerrit_common_test.pl", new AbstractModule() {
|
load("gerrit", "gerrit_common_test.pl", new AbstractModule() {
|
||||||
@Override
|
@Override
|
||||||
@@ -65,15 +65,8 @@ public class GerritCommonTest extends PrologTestCase {
|
|||||||
return new LabelValue((short) value, text);
|
return new LabelValue((short) value, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ProjectConfig config(String name) {
|
private static LabelType category(String name, LabelValue... values) {
|
||||||
ProjectConfig config = new ProjectConfig(new Project.NameKey(name));
|
return new LabelType(name, Arrays.asList(values));
|
||||||
config.createInMemory();
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static LabelType category(String id, String name,
|
|
||||||
LabelValue... values) {
|
|
||||||
return new LabelType(id, name, Arrays.asList(values));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Projects implements ProjectCache {
|
private static class Projects implements ProjectCache {
|
||||||
@@ -82,8 +75,13 @@ public class GerritCommonTest extends PrologTestCase {
|
|||||||
|
|
||||||
private Projects(LabelTypes labelTypes) {
|
private Projects(LabelTypes labelTypes) {
|
||||||
allProjectsName = new AllProjectsName("All-Projects");
|
allProjectsName = new AllProjectsName("All-Projects");
|
||||||
|
ProjectConfig config = new ProjectConfig(allProjectsName);
|
||||||
|
config.createInMemory();
|
||||||
|
for (LabelType label : labelTypes.getLabelTypes()) {
|
||||||
|
config.getLabelSections().put(label.getName(), label);
|
||||||
|
}
|
||||||
allProjects = new ProjectState(this, allProjectsName, null,
|
allProjects = new ProjectState(this, allProjectsName, null,
|
||||||
null, null, null, labelTypes, config(allProjectsName.get()));
|
null, null, null, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -541,10 +541,10 @@ public class RefControlTest extends TestCase {
|
|||||||
RulesCache rulesCache = null;
|
RulesCache rulesCache = null;
|
||||||
all.put(local.getProject().getNameKey(), new ProjectState(
|
all.put(local.getProject().getNameKey(), new ProjectState(
|
||||||
projectCache, allProjectsName, projectControlFactory,
|
projectCache, allProjectsName, projectControlFactory,
|
||||||
envFactory, mgr, rulesCache, null, local));
|
envFactory, mgr, rulesCache, local));
|
||||||
all.put(parent.getProject().getNameKey(), new ProjectState(
|
all.put(parent.getProject().getNameKey(), new ProjectState(
|
||||||
projectCache, allProjectsName, projectControlFactory,
|
projectCache, allProjectsName, projectControlFactory,
|
||||||
envFactory, mgr, rulesCache, null, parent));
|
envFactory, mgr, rulesCache, parent));
|
||||||
return all.get(local.getProject().getNameKey());
|
return all.get(local.getProject().getNameKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,23 +14,31 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.schema;
|
package com.google.gerrit.server.schema;
|
||||||
|
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategory;
|
import com.google.common.base.Strings;
|
||||||
import com.google.gerrit.reviewdb.client.ApprovalCategoryValue;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.common.collect.Lists;
|
||||||
|
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.server.config.AllProjectsName;
|
||||||
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
|
import com.google.gerrit.server.git.ProjectConfig;
|
||||||
import com.google.gerrit.testutil.InMemoryDatabase;
|
import com.google.gerrit.testutil.InMemoryDatabase;
|
||||||
import com.google.gwtorm.jdbc.JdbcSchema;
|
import com.google.gwtorm.jdbc.JdbcSchema;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashSet;
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class SchemaCreatorTest extends TestCase {
|
public class SchemaCreatorTest extends TestCase {
|
||||||
private ApprovalCategory.Id codeReview = new ApprovalCategory.Id("CRVW");
|
|
||||||
private InMemoryDatabase db;
|
private InMemoryDatabase db;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,53 +87,56 @@ public class SchemaCreatorTest extends TestCase {
|
|||||||
assertEquals(sitePath.getCanonicalPath(), db.getSystemConfig().sitePath);
|
assertEquals(sitePath.getCanonicalPath(), db.getSystemConfig().sitePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCreateSchema_ApprovalCategory_CodeReview()
|
private LabelTypes getLabelTypes() throws Exception {
|
||||||
throws OrmException {
|
db.create();
|
||||||
final ReviewDb c = db.create().open();
|
AllProjectsName allProjects = db.getInstance(AllProjectsName.class);
|
||||||
|
ProjectConfig c = new ProjectConfig(allProjects);
|
||||||
|
Repository repo = db.getInstance(GitRepositoryManager.class)
|
||||||
|
.openRepository(allProjects);
|
||||||
try {
|
try {
|
||||||
final ApprovalCategory cat;
|
c.load(repo);
|
||||||
|
return new LabelTypes(
|
||||||
cat = c.approvalCategories().get(codeReview);
|
ImmutableList.copyOf(c.getLabelSections().values()));
|
||||||
assertNotNull(cat);
|
|
||||||
assertEquals(codeReview, cat.getId());
|
|
||||||
assertEquals("Code Review", cat.getName());
|
|
||||||
assertEquals("R", cat.getAbbreviatedName());
|
|
||||||
assertEquals("MaxWithBlock", cat.getFunctionName());
|
|
||||||
assertTrue(cat.isCopyMinScore());
|
|
||||||
assertTrue(0 <= cat.getPosition());
|
|
||||||
} finally {
|
} finally {
|
||||||
c.close();
|
repo.close();
|
||||||
}
|
}
|
||||||
assertValueRange(codeReview, -2, -1, 0, 1, 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertValueRange(ApprovalCategory.Id cat, int... range)
|
public void testCreateSchema_LabelTypes() throws Exception {
|
||||||
throws OrmException {
|
List<String> labels = Lists.newArrayList();
|
||||||
final HashSet<ApprovalCategoryValue.Id> act =
|
for (LabelType label : getLabelTypes().getLabelTypes()) {
|
||||||
new HashSet<ApprovalCategoryValue.Id>();
|
labels.add(label.getName());
|
||||||
final ReviewDb c = db.open();
|
|
||||||
try {
|
|
||||||
for (ApprovalCategoryValue v : c.approvalCategoryValues().byCategory(cat)) {
|
|
||||||
assertNotNull(v.getId());
|
|
||||||
assertNotNull(v.getName());
|
|
||||||
assertEquals(cat, v.getCategoryId());
|
|
||||||
assertFalse(v.getName().isEmpty());
|
|
||||||
|
|
||||||
act.add(v.getId());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
c.close();
|
|
||||||
}
|
}
|
||||||
|
assertEquals(ImmutableList.of("Verified", "Code-Review"), labels);
|
||||||
|
}
|
||||||
|
|
||||||
for (int value : range) {
|
public void testCreateSchema_Label_Verified() throws Exception {
|
||||||
final ApprovalCategoryValue.Id exp =
|
LabelType verified = getLabelTypes().byLabel("Verified");
|
||||||
new ApprovalCategoryValue.Id(cat, (short) value);
|
assertNotNull(verified);
|
||||||
if (!act.remove(exp)) {
|
assertEquals("Verified", verified.getName());
|
||||||
fail("Category " + cat + " lacks value " + value);
|
assertEquals("V", verified.getAbbreviatedName());
|
||||||
}
|
assertEquals("MaxWithBlock", verified.getFunctionName());
|
||||||
}
|
assertFalse(verified.isCopyMinScore());
|
||||||
if (!act.isEmpty()) {
|
assertValueRange(verified, 1, 0, -1);
|
||||||
fail("Category " + cat + " has additional values: " + act);
|
}
|
||||||
|
|
||||||
|
public void testCreateSchema_Label_CodeReview() throws Exception {
|
||||||
|
LabelType codeReview = getLabelTypes().byLabel("Code-Review");
|
||||||
|
assertNotNull(codeReview);
|
||||||
|
assertEquals("Code-Review", codeReview.getName());
|
||||||
|
assertEquals("CR", codeReview.getAbbreviatedName());
|
||||||
|
assertEquals("MaxWithBlock", codeReview.getFunctionName());
|
||||||
|
assertTrue(codeReview.isCopyMinScore());
|
||||||
|
assertValueRange(codeReview, 2, 1, 0, -1, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertValueRange(LabelType label, Integer... range) {
|
||||||
|
assertEquals(Arrays.asList(range), label.getValuesAsList());
|
||||||
|
assertEquals(range[0], Integer.valueOf(label.getMax().getValue()));
|
||||||
|
assertEquals(range[range.length - 1],
|
||||||
|
Integer.valueOf(label.getMin().getValue()));
|
||||||
|
for (LabelValue v : label.getValues()) {
|
||||||
|
assertFalse(Strings.isNullOrEmpty(v.getText()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -27,8 +27,8 @@ test(not_same_success) :-
|
|||||||
test(get_legacy_label_types) :-
|
test(get_legacy_label_types) :-
|
||||||
get_legacy_label_types(T),
|
get_legacy_label_types(T),
|
||||||
T = [C, V],
|
T = [C, V],
|
||||||
C = label_type('Code-Review', 'CRVW', 'MaxWithBlock', -2, 2),
|
C = label_type('Code-Review', 'MaxWithBlock', -2, 2),
|
||||||
V = label_type('Verified', 'VRIF', 'MaxWithBlock', -1, 1).
|
V = label_type('Verified', 'MaxWithBlock', -1, 1).
|
||||||
|
|
||||||
|
|
||||||
%% commit_label
|
%% commit_label
|
||||||
|
Reference in New Issue
Block a user