Merge "Ignoring vi swap file"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 527e4de..0b7eaeb 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1909,6 +1909,12 @@
If the file doesn't exist or can't be read the default robots.txt file
bundled with the .war will be used instead.
+[[httpd.registerMBeans]]httpd.registerMBeans::
++
+Enable (or disable) registration of Jetty MBeans for Java JMX.
++
+By default, false.
+
[[index]]
=== Section index
diff --git a/Documentation/config-labels.txt b/Documentation/config-labels.txt
index fc25f22..0fe12ca 100644
--- a/Documentation/config-labels.txt
+++ b/Documentation/config-labels.txt
@@ -169,6 +169,20 @@
optional leading `+`.
+[[label_defaultValue]]
+=== `label.Label-Name.defaultValue`
+
+The default value (or score) for the label. The defaultValue must be
+within the range of valid label values. It is an optional label setting,
+if not defined the defaultValue for the label will be 0. When a
+defaultValue is defined, that value will get set in the Reply dialog
+by default.
+
+A defaultValue can be set to a score that is outside of the permissible
+range for a user. In that case the score that will get set in the Reply
+box will be either the lowest or highest score in the permissible range.
+
+
[[label_abbreviation]]
=== `label.Label-Name.abbreviation`
@@ -297,6 +311,32 @@
copyright` will block submit, while `+1 Copyright clear` is required to
enable submit.
+=== Default Value Example
+
+This example attempts to describe how a label default value works with the
+user permissions. Assume the configuration below.
+
+====
+ [access "refs/heads/*"]
+ label-Snarky-Review = -3..+3 group Administrators
+ label-Snarky-Review = -2..+2 group Project Owners
+ label-Snarky-Review = -1..+1 group Registered Users
+ [label "Snarky-Review"]
+ value = -3 Ohh, hell no!
+ value = -2 Hmm, I'm not a fan
+ value = -1 I'm not sure I like this
+ value = 0 No score
+ value = +1 I like, but need another to like it as well
+ value = +2 Hmm, this is pretty nice
+ value = +3 Ohh, hell yes!
+ defaultValue = -3
+====
+
+Upon clicking the Reply button:
+* Administrators have all scores (-3..+3) available, -3 is set as the default.
+* Project Owners have limited scores (-2..+2) available, -2 is set as the default.
+* Registered Users have limited scores (-1..+1) available, -1 is set as the default.
+
GERRIT
------
Part of link:index.html[Gerrit Code Review]
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt
index 2fb256f..64fa9c4 100644
--- a/Documentation/config-project-config.txt
+++ b/Documentation/config-project-config.txt
@@ -171,6 +171,21 @@
documentation for a full list of available access rights.
+[[mimetype-section]]
+=== MIME Types section
+
+The +mimetype+ section may be configured to force the web code
+reviewer to return certain MIME types by file path. MIME types
+may be used to activate syntax highlighting.
+
+----
+[mimetype "text/x-c"]
+ path = *.pkt
+[mimetype "text/x-java"]
+ path = api/current.txt
+----
+
+
[[capability-section]]
=== Capability section
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 8f6b8a4..c172781 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -3093,6 +3093,8 @@
|`value` |optional|The voting value of the user who
recommended/disliked this label on the change if it is not
"`+1`"/"`-1`".
+|`default_value`|optional|The default voting value for the label.
+This value may be outside the range specified in permitted_labels.
|===========================
==== Fields set by `DETAILED_LABELS`
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
index f3db988..7240036 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/server/project/LabelTypeIT.java
@@ -69,6 +69,7 @@
codeReview.setCopyMaxScore(false);
codeReview.setCopyAllScoresOnTrivialRebase(false);
codeReview.setCopyAllScoresIfNoCodeChange(false);
+ codeReview.setDefaultValue((short)-1);
saveProjectConfig(cfg);
}
@@ -264,6 +265,7 @@
// through JSON instead of querying the DB directly.
ChangeInfo c = get(r.getChangeId());
LabelInfo cr = c.labels.get("Code-Review");
+ assertEquals(-1, (int) cr.defaultValue);
assertEquals(1, cr.all.size());
assertEquals("Administrator", cr.all.get(0).name);
assertEquals(expected, cr.all.get(0).value.intValue());
diff --git a/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java b/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
index d4f5b7b..28629b9 100644
--- a/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
+++ b/gerrit-common/src/main/java/com/google/gerrit/common/data/LabelType.java
@@ -27,10 +27,6 @@
public class LabelType {
public static LabelType withDefaultValues(String name) {
checkName(name);
- return withDefaultValuesDoNotCheckName(name);
- }
-
- public static LabelType withDefaultValuesDoNotCheckName(String name) {
List<LabelValue> values = new ArrayList<>(2);
values.add(new LabelValue((short) 0, "Rejected"));
values.add(new LabelValue((short) 1, "Approved"));
@@ -112,6 +108,7 @@
protected boolean copyMaxScore;
protected boolean copyAllScoresOnTrivialRebase;
protected boolean copyAllScoresIfNoCodeChange;
+ protected short defaultValue;
protected List<LabelValue> values;
protected short maxNegative;
@@ -129,6 +126,7 @@
this.name = checkName(name);
canOverride = true;
values = sortValues(valueList);
+ defaultValue = 0;
abbreviation = defaultAbbreviation(name);
functionName = "MaxWithBlock";
@@ -204,6 +202,14 @@
return v.getValue() > 0 ? v : null;
}
+ public short getDefaultValue() {
+ return defaultValue;
+ }
+
+ public void setDefaultValue(short defaultValue) {
+ this.defaultValue = defaultValue;
+ }
+
public boolean isCopyMinScore() {
return copyMinScore;
}
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/LabelInfo.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/LabelInfo.java
index fd6008f..1e4edcd 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/LabelInfo.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/common/LabelInfo.java
@@ -25,6 +25,7 @@
public List<ApprovalInfo> all;
public Map<String, String> values;
public Short value;
+ public Short defaultValue;
public Boolean optional;
public Boolean blocking;
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
index 2f646b7..f42bc75 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.java
@@ -139,8 +139,7 @@
@UiField InlineHyperlink ownerLink;
@UiField Element statusText;
@UiField Image projectSettings;
- @UiField Image projectDashboard;
- @UiField InlineHyperlink projectLink;
+ @UiField InlineHyperlink projectDashboard;
@UiField InlineHyperlink branchLink;
@UiField Element strategy;
@UiField Element submitActionText;
@@ -357,13 +356,6 @@
}
private void initProjectLinks(final ChangeInfo info) {
- projectDashboard.addDomHandler(new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- Gerrit.display(
- PageLinks.toProjectDefaultDashboard(info.project_name_key()));
- }
- }, ClickEvent.getType());
projectSettings.addDomHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
@@ -371,12 +363,9 @@
PageLinks.toProject(info.project_name_key()));
}
}, ClickEvent.getType());
- projectLink.setText(info.project());
- projectLink.setTargetHistoryToken(
- PageLinks.toChangeQuery(
- PageLinks.projectQuery(
- info.project_name_key(),
- info.status())));
+ projectDashboard.setText(info.project());
+ projectDashboard.setTargetHistoryToken(
+ PageLinks.toProjectDefaultDashboard(info.project_name_key()));
}
private void initBranchLink(ChangeInfo info) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.ui.xml
index 79bd162..f475ab1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ChangeScreen2.ui.xml
@@ -166,11 +166,6 @@
cursor: pointer;
}
- .projectDashboard {
- float: right;
- cursor: pointer;
- }
-
.infoColumn {
width: 440px;
padding-left: 17px;
@@ -387,8 +382,8 @@
</tr>
<tr>
<th><ui:msg>Project</ui:msg></th>
- <td><x:InlineHyperlink ui:field='projectLink'
- title='Search for changes on this project'>
+ <td><x:InlineHyperlink ui:field='projectDashboard'
+ title='Go to project dashboard'>
<ui:attribute name='title'/>
</x:InlineHyperlink>
<g:Image
@@ -398,13 +393,6 @@
title='Go to project settings'>
<ui:attribute name='title'/>
</g:Image>
- <g:Image
- ui:field='projectDashboard'
- resource='{ico.dashboard}'
- styleName='{style.projectDashboard}'
- title='Go to project dashboard'>
- <ui:attribute name='title'/>
- </g:Image>
</td>
</tr>
<tr>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
index dc6d710..4e77041 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/change/ReplyBox.java
@@ -322,10 +322,23 @@
}
}
+ private Short normalizeDefaultValue(Short defaultValue, Set<Short> permittedValues) {
+ Short pmin = Collections.min(permittedValues);
+ Short pmax = Collections.max(permittedValues);
+ Short dv = defaultValue;
+ if (dv > pmax) {
+ dv = pmax;
+ } else if (dv < pmin) {
+ dv = pmin;
+ }
+ return dv;
+ }
+
private void renderRadio(int row,
List<Short> columns,
LabelAndValues lv) {
String id = lv.info.name();
+ Short dv = normalizeDefaultValue(lv.info.defaultValue(), lv.permitted);
labelHelpColumn = 1 + columns.size();
labelsTable.setText(row, 0, id);
@@ -345,9 +358,10 @@
if (lv.permitted.contains(v)) {
String text = lv.info.value_text(LabelValue.formatValue(v));
LabelRadioButton b = new LabelRadioButton(group, text, v);
- if ((self != null && v == self.value()) || (self == null && v == 0)) {
+ if ((self != null && v == self.value()) || (self == null && v.equals(dv))) {
b.setValue(true);
group.select(b);
+ in.label(group.label, v);
labelsTable.setText(row, labelHelpColumn, b.text);
}
group.buttons.add(b);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
index b23403b..f2c97c1 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeDetailCache.java
@@ -84,7 +84,7 @@
r.setCanRebase(can(rev.actions(), "rebase"));
r.setCanRestore(can(info.actions(), "restore"));
r.setCanRevert(can(info.actions(), "revert"));
- r.setCanDeleteDraft(can(rev.actions(), "/"));
+ r.setCanDeleteDraft(can(info.actions(), "/"));
r.setCanEditTopicName(can(info.actions(), "topic"));
r.setCanSubmit(can(rev.actions(), "submit"));
r.setCanEdit(true);
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
index a627725..ed6f046 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeInfo.java
@@ -161,6 +161,7 @@
public final native boolean optional() /*-{ return this.optional ? true : false; }-*/;
public final native boolean blocking() /*-{ return this.blocking ? true : false; }-*/;
+ public final native short defaultValue() /*-{ return this.default_value; }-*/;
final native short _value()
/*-{
if (this.value) return this.value;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CustomDashboardScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CustomDashboardScreen.java
index 840ebaa..320976e 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CustomDashboardScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/CustomDashboardScreen.java
@@ -26,12 +26,7 @@
@Override
protected void onInitUI() {
- table = new DashboardTable(params) {
- @Override
- protected void onLoad() {
- super.onLoad();
- }
-
+ table = new DashboardTable(this, params) {
@Override
public void finishDisplay() {
super.finishDisplay();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
index ac68722..978d4e5 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/DashboardTable.java
@@ -18,10 +18,13 @@
import com.google.gerrit.client.rpc.GerritCallback;
import com.google.gerrit.client.rpc.Natives;
import com.google.gerrit.client.ui.InlineHyperlink;
+import com.google.gerrit.client.ui.Screen;
import com.google.gerrit.common.PageLinks;
import com.google.gerrit.extensions.common.ListChangesOption;
import com.google.gwt.core.client.JsArray;
+import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.http.client.URL;
+import com.google.gwtexpui.globalkey.client.KeyCommand;
import java.util.ArrayList;
import java.util.EnumSet;
@@ -34,7 +37,7 @@
private List<String> titles;
private List<String> queries;
- public DashboardTable(String params) {
+ public DashboardTable(final Screen screen, String params) {
titles = new ArrayList<>();
queries = new ArrayList<>();
String foreach = null;
@@ -72,6 +75,13 @@
addSection(s);
sections.add(s);
}
+
+ keysNavigation.add(new KeyCommand(0, 'R', Util.C.keyReloadSearch()) {
+ @Override
+ public void onKeyPress(KeyPressEvent event) {
+ Gerrit.display(screen.getToken());
+ }
+ });
}
private String removeLimit(String query) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ProjectDashboardScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ProjectDashboardScreen.java
index 899e86b..d2eec27 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ProjectDashboardScreen.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ProjectDashboardScreen.java
@@ -32,12 +32,7 @@
@Override
protected void onInitUI() {
- table = new DashboardTable(params) {
- @Override
- protected void onLoad() {
- super.onLoad();
- }
-
+ table = new DashboardTable(this, params) {
@Override
public void finishDisplay() {
super.finishDisplay();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
index ed7c3b6..0ef5272 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.java
@@ -32,6 +32,8 @@
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Theme;
import com.google.gerrit.reviewdb.client.AccountDiffPreference.Whitespace;
import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyDownEvent;
@@ -52,6 +54,12 @@
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ToggleButton;
+import net.codemirror.lib.ModeInjector;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
/** Displays current diff preferences. */
class PreferencesBox extends Composite {
interface Binder extends UiBinder<HTMLPanel, PreferencesBox> {}
@@ -83,6 +91,7 @@
@UiField ToggleButton expandAllComments;
@UiField ToggleButton renderEntireFile;
@UiField ListBox theme;
+ @UiField ListBox mode;
@UiField Button apply;
@UiField Button save;
@@ -92,6 +101,7 @@
initWidget(uiBinder.createAndBindUi(this));
initIgnoreWhitespace();
initTheme();
+ initMode();
}
@Override
@@ -114,6 +124,16 @@
if (prefs.context() == WHOLE_FILE_CONTEXT) {
contextEntireFile.setValue(true);
}
+ if (view.canEnableRenderEntireFile(prefs)) {
+ renderEntireFile.setEnabled(true);
+ } else {
+ if (prefs.renderEntireFile()) {
+ prefs.renderEntireFile(false);
+ renderEntireFile.setValue(false);
+ view.updateRenderEntireFile();
+ }
+ renderEntireFile.setEnabled(false);
+ }
view.setContext(prefs.context());
}
};
@@ -133,8 +153,14 @@
manualReview.setValue(prefs.manualReview());
expandAllComments.setValue(prefs.expandAllComments());
renderEntireFile.setValue(prefs.renderEntireFile());
+ renderEntireFile.setEnabled(view.canEnableRenderEntireFile(prefs));
setTheme(prefs.theme());
+ mode.setEnabled(prefs.syntaxHighlighting());
+ if (prefs.syntaxHighlighting()) {
+ setMode(view.getContentType());
+ }
+
switch (view.getIntraLineStatus()) {
case OFF:
case OK:
@@ -277,9 +303,35 @@
@UiHandler("syntaxHighlighting")
void onSyntaxHighlighting(ValueChangeEvent<Boolean> e) {
prefs.syntaxHighlighting(e.getValue());
+ mode.setEnabled(prefs.syntaxHighlighting());
+ if (prefs.syntaxHighlighting()) {
+ setMode(view.getContentType());
+ }
view.setSyntaxHighlighting(prefs.syntaxHighlighting());
}
+ @UiHandler("mode")
+ void onMode(ChangeEvent e) {
+ final String m = mode.getValue(mode.getSelectedIndex());
+ prefs.syntaxHighlighting(true);
+ syntaxHighlighting.setValue(true, false);
+ Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
+ @Override
+ public boolean execute() {
+ if (prefs.syntaxHighlighting() && view.isAttached()) {
+ view.operation(new Runnable() {
+ @Override
+ public void run() {
+ view.getCmFromSide(DisplaySide.A).setOption("mode", m);
+ view.getCmFromSide(DisplaySide.B).setOption("mode", m);
+ }
+ });
+ }
+ return false;
+ }
+ }, 50);
+ }
+
@UiHandler("whitespaceErrors")
void onWhitespaceErrors(ValueChangeEvent<Boolean> e) {
prefs.showWhitespaceErrors(e.getValue());
@@ -374,6 +426,51 @@
IGNORE_ALL_SPACE.name());
}
+ private static final Map<String, String> NAME_TO_MODE;
+ private static final Map<String, String> NORMALIZED_MODES;
+ static {
+ NAME_TO_MODE = new TreeMap<String, String>();
+ NORMALIZED_MODES = new HashMap<String, String>();
+ for (String type : ModeInjector.getKnownMimeTypes()) {
+ String name = type;
+ if (name.startsWith("text/x-")) {
+ name = name.substring("text/x-".length());
+ } else if (name.startsWith("text/")) {
+ name = name.substring("text/".length());
+ } else if (name.startsWith("application/")) {
+ name = name.substring("application/".length());
+ }
+
+ String normalized = NAME_TO_MODE.get(name);
+ if (normalized == null) {
+ normalized = type;
+ NAME_TO_MODE.put(name, normalized);
+ }
+ NORMALIZED_MODES.put(type, normalized);
+ }
+ }
+
+ private void initMode() {
+ for (Map.Entry<String, String> e : NAME_TO_MODE.entrySet()) {
+ mode.addItem(e.getKey(), e.getValue());
+ }
+ }
+
+ private void setMode(String modeType) {
+ if (modeType != null && !modeType.isEmpty()) {
+ if (NORMALIZED_MODES.containsKey(modeType)) {
+ modeType =NORMALIZED_MODES.get(modeType);
+ }
+ for (int i = 0; i < mode.getItemCount(); i++) {
+ if (mode.getValue(i).equals(modeType)) {
+ mode.setSelectedIndex(i);
+ return;
+ }
+ }
+ }
+ mode.setSelectedIndex(0);
+ }
+
private void setTheme(Theme v) {
String name = v != null ? v.name() : Theme.DEFAULT.name();
for (int i = 0; i < theme.getItemCount(); i++) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
index d940590..b3ec067 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/PreferencesBox.ui.xml
@@ -204,6 +204,10 @@
</g:ToggleButton></td>
</tr>
<tr>
+ <th><ui:msg>Language</ui:msg></th>
+ <td><g:ListBox ui:field='mode'/></td>
+ </tr>
+ <tr>
<th><ui:msg>Whitespace Errors</ui:msg></th>
<td><g:ToggleButton ui:field='whitespaceErrors'>
<g:upFace><ui:msg>Hide</ui:msg></g:upFace>
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
index ddf3978..db8c402 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/diff/SideBySide2.java
@@ -14,6 +14,7 @@
package com.google.gerrit.client.diff;
+import static com.google.gerrit.reviewdb.client.AccountDiffPreference.WHOLE_FILE_CONTEXT;
import static java.lang.Double.POSITIVE_INFINITY;
import com.google.gerrit.client.Gerrit;
@@ -24,6 +25,7 @@
import com.google.gerrit.client.changes.ChangeInfo;
import com.google.gerrit.client.changes.ChangeInfo.RevisionInfo;
import com.google.gerrit.client.changes.ChangeList;
+import com.google.gerrit.client.diff.DiffInfo.FileMeta;
import com.google.gerrit.client.diff.LineMapper.LineOnOtherInfo;
import com.google.gerrit.client.patches.PatchUtil;
import com.google.gerrit.client.projects.ConfigInfoCache;
@@ -83,6 +85,18 @@
interface Binder extends UiBinder<FlowPanel, SideBySide2> {}
private static final Binder uiBinder = GWT.create(Binder.class);
+ enum FileSize {
+ SMALL(0),
+ LARGE(500),
+ HUGE(4000);
+
+ final int lines;
+
+ FileSize(int n) {
+ this.lines = n;
+ }
+ }
+
@UiField(provided = true)
Header header;
@@ -103,7 +117,7 @@
private Element columnMarginB;
private HandlerRegistration resizeHandler;
private DiffInfo diff;
- private boolean largeFile;
+ private FileSize fileSize;
private ChunkManager chunkManager;
private CommentManager commentManager;
private SkipManager skipManager;
@@ -163,8 +177,8 @@
public void onSuccess(DiffInfo diffInfo) {
diff = diffInfo;
if (prefs.syntaxHighlighting()) {
- largeFile = isLargeFile(diffInfo);
- if (largeFile) {
+ fileSize = bucketFileSize(diffInfo);
+ if (fileSize.compareTo(FileSize.SMALL) > 0) {
modeInjectorCb.onSuccess(null);
} else {
injectMode(diffInfo, modeInjectorCb);
@@ -505,6 +519,11 @@
cmA.getMoverElement().appendChild(columnMarginA);
cmB.getMoverElement().appendChild(columnMarginB);
+ if (prefs.renderEntireFile() && !canEnableRenderEntireFile(prefs)) {
+ // CodeMirror is too slow to layout an entire huge file.
+ prefs.renderEntireFile(false);
+ }
+
operation(new Runnable() {
public void run() {
// Estimate initial CM3 height, fixed up in onShowView.
@@ -526,7 +545,7 @@
prefsAction = new PreferencesAction(this, prefs);
header.init(prefsAction);
- if (largeFile && prefs.syntaxHighlighting()) {
+ if (prefs.syntaxHighlighting() && fileSize.compareTo(FileSize.SMALL) > 0) {
Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
@Override
public boolean execute() {
@@ -544,13 +563,16 @@
String contents,
DisplaySide side,
Element parent) {
+ String mode = fileSize == FileSize.SMALL
+ ? getContentType(meta)
+ : null;
return CodeMirror.create(side, parent, Configuration.create()
.set("readOnly", true)
.set("cursorBlinkRate", 0)
.set("cursorHeight", 0.85)
.set("lineNumbers", prefs.showLineNumbers())
.set("tabSize", prefs.tabSize())
- .set("mode", largeFile ? null : getContentType(meta))
+ .set("mode", mode)
.set("lineWrapping", false)
.set("styleSelectedText", true)
.set("showTrailingSpace", prefs.showWhitespaceErrors())
@@ -564,6 +586,15 @@
return diff.intraline_status();
}
+ boolean canEnableRenderEntireFile(DiffPreferences prefs) {
+ return fileSize.compareTo(FileSize.HUGE) < 0
+ || (prefs.context() != WHOLE_FILE_CONTEXT && prefs.context() < 100);
+ }
+
+ String getContentType() {
+ return getContentType(diff.meta_b());
+ }
+
void setThemeStyles(boolean d) {
if (d) {
diffTable.addStyleName(DiffTable.style.dark());
@@ -934,8 +965,17 @@
});
}
- private static boolean isLargeFile(DiffInfo diffInfo) {
- return (diffInfo.meta_a() != null && diffInfo.meta_a().lines() > 500)
- || (diffInfo.meta_b() != null && diffInfo.meta_b().lines() > 500);
+ private static FileSize bucketFileSize(DiffInfo diff) {
+ FileMeta a = diff.meta_a();
+ FileMeta b = diff.meta_b();
+ FileSize[] sizes = FileSize.values();
+ for (int i = sizes.length - 1; 0 <= i; i--) {
+ FileSize s = sizes[i];
+ if ((a != null && s.lines <= a.lines())
+ || (b != null && s.lines <= b.lines())) {
+ return s;
+ }
+ }
+ return FileSize.SMALL;
}
}
diff --git a/gerrit-gwtui/src/main/java/net/codemirror/lib/ModeInjector.java b/gerrit-gwtui/src/main/java/net/codemirror/lib/ModeInjector.java
index 02faccb..3d77d09 100644
--- a/gerrit-gwtui/src/main/java/net/codemirror/lib/ModeInjector.java
+++ b/gerrit-gwtui/src/main/java/net/codemirror/lib/ModeInjector.java
@@ -21,6 +21,7 @@
import net.codemirror.mode.Modes;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -94,6 +95,10 @@
return real != null ? real : mode;
}
+ public static Collection<String> getKnownMimeTypes() {
+ return mimeModes.keySet();
+ }
+
private static native boolean isModeLoaded(String n)
/*-{ return $wnd.CodeMirror.modes.hasOwnProperty(n); }-*/;
diff --git a/gerrit-pgm/BUCK b/gerrit-pgm/BUCK
index d1c468f..f76fa4c 100644
--- a/gerrit-pgm/BUCK
+++ b/gerrit-pgm/BUCK
@@ -115,6 +115,7 @@
'//lib/guice:guice-servlet',
'//lib/jetty:server',
'//lib/jetty:servlet',
+ '//lib/jetty:jmx',
'//lib/jgit:jgit',
'//lib/log:api',
'//lib/log:log4j',
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
index 067eeab..60b5144 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/http/jetty/JettyServer.java
@@ -39,6 +39,7 @@
import com.google.inject.servlet.GuiceServletContextListener;
import org.eclipse.jetty.http.HttpScheme;
+import org.eclipse.jetty.jmx.MBeanContainer;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.ForwardedRequestCustomizer;
import org.eclipse.jetty.server.Handler;
@@ -58,6 +59,7 @@
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.BlockingArrayQueue;
+import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
@@ -75,6 +77,7 @@
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.PrintWriter;
+import java.lang.management.ManagementFactory;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -171,6 +174,13 @@
handler.setHandler(app);
app = handler;
}
+ if (cfg.getBoolean("httpd", "registerMBeans", false)) {
+ MBeanContainer mbean =
+ new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
+ httpd.addEventListener(mbean);
+ httpd.addBean(Log.getRootLogger());
+ httpd.addBean(mbean);
+ }
httpd.setHandler(app);
httpd.setStopAtShutdown(false);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
index 9d813fc..b82328c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeInfoMapper.java
@@ -116,6 +116,7 @@
lo.recommended = fromAcountInfo(li.recommended);
lo.disliked = fromAcountInfo(li.disliked);
lo.value = li.value;
+ lo.defaultValue = li.defaultValue;
lo.optional = li.optional;
lo.blocking = li.blocking;
lo.values = li.values;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
index 5955fde..5321acd 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/ChangeJson.java
@@ -631,6 +631,7 @@
}
private void setLabelValues(LabelType type, LabelInfo label) {
+ label.defaultValue = type.getDefaultValue();
label.values = Maps.newLinkedHashMap();
for (LabelValue v : type.getValues()) {
label.values.put(v.formatValue(), v.getText());
@@ -1007,6 +1008,7 @@
public Map<String, String> values;
public Short value;
+ public Short defaultValue;
public Boolean optional;
public Boolean blocking;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
index 7267f7d..3386e38 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/GetDiff.java
@@ -33,9 +33,11 @@
import com.google.gerrit.reviewdb.client.AccountDiffPreference;
import com.google.gerrit.reviewdb.client.Patch.ChangeType;
import com.google.gerrit.reviewdb.client.PatchSet;
+import com.google.gerrit.server.git.LargeObjectException;
import com.google.gerrit.server.patch.PatchScriptFactory;
import com.google.gerrit.server.project.NoSuchChangeException;
-import com.google.gerrit.server.git.LargeObjectException;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectState;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -55,6 +57,7 @@
import java.util.concurrent.TimeUnit;
public class GetDiff implements RestReadView<FileResource> {
+ private final ProjectCache projectCache;
private final PatchScriptFactory.Factory patchScriptFactoryFactory;
private final Provider<Revisions> revisions;
@@ -71,8 +74,10 @@
boolean intraline;
@Inject
- GetDiff(PatchScriptFactory.Factory patchScriptFactoryFactory,
+ GetDiff(ProjectCache projectCache,
+ PatchScriptFactory.Factory patchScriptFactoryFactory,
Provider<Revisions> revisions) {
+ this.projectCache = projectCache;
this.patchScriptFactoryFactory = patchScriptFactoryFactory;
this.revisions = revisions;
}
@@ -127,18 +132,21 @@
}
content.addCommon(ps.getA().size());
+ ProjectState state =
+ projectCache.get(resource.getRevision().getChange().getProject());
+
Result result = new Result();
if (ps.getDisplayMethodA() != DisplayMethod.NONE) {
result.metaA = new FileMeta();
result.metaA.name = Objects.firstNonNull(ps.getOldName(), ps.getNewName());
- result.metaA.setContentType(ps.getFileModeA(), ps.getMimeTypeA());
+ setContentType(result.metaA, state, ps.getFileModeA(), ps.getMimeTypeA());
result.metaA.lines = ps.getA().size();
}
if (ps.getDisplayMethodB() != DisplayMethod.NONE) {
result.metaB = new FileMeta();
result.metaB.name = ps.getNewName();
- result.metaB.setContentType(ps.getFileModeB(), ps.getMimeTypeB());
+ setContentType(result.metaB, state, ps.getFileModeB(), ps.getMimeTypeB());
result.metaB.lines = ps.getB().size();
}
@@ -182,21 +190,31 @@
String name;
String contentType;
Integer lines;
+ }
- void setContentType(FileMode fileMode, String mimeType) {
- switch (fileMode) {
- case FILE:
- contentType = mimeType;
- break;
- case GITLINK:
- contentType = "x-git/gitlink";
- break;
- case SYMLINK:
- contentType = "x-git/symlink";
- break;
- default:
- throw new IllegalStateException("file mode: " + fileMode);
- }
+ private void setContentType(FileMeta meta, ProjectState project,
+ FileMode fileMode, String mimeType) {
+ switch (fileMode) {
+ case FILE:
+ if (project != null) {
+ for (ProjectState p : project.tree()) {
+ String t = p.getConfig().getMimeTypes().getMimeType(meta.name);
+ if (t != null) {
+ mimeType = t;
+ break;
+ }
+ }
+ }
+ meta.contentType = mimeType;
+ break;
+ case GITLINK:
+ meta.contentType = "x-git/gitlink";
+ break;
+ case SYMLINK:
+ meta.contentType = "x-git/symlink";
+ break;
+ default:
+ throw new IllegalStateException("file mode: " + fileMode);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ConfiguredMimeTypes.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ConfiguredMimeTypes.java
new file mode 100644
index 0000000..082e1a2
--- /dev/null
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ConfiguredMimeTypes.java
@@ -0,0 +1,117 @@
+// Copyright (C) 2014 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.git;
+
+import org.eclipse.jgit.errors.InvalidPatternException;
+import org.eclipse.jgit.fnmatch.FileNameMatcher;
+import org.eclipse.jgit.lib.Config;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+public class ConfiguredMimeTypes {
+ private static final Logger log = LoggerFactory
+ .getLogger(ConfiguredMimeTypes.class);
+
+ private static final String MIMETYPE = "mimetype";
+ private static final String KEY_PATH = "path";
+
+ private final List<TypeMatcher> matchers;
+
+ ConfiguredMimeTypes(String projectName, Config rc) {
+ Set<String> types = rc.getSubsections(MIMETYPE);
+ if (types.isEmpty()) {
+ matchers = Collections.emptyList();
+ } else {
+ matchers = new ArrayList<>();
+ for (String typeName : types) {
+ for (String path : rc.getStringList(MIMETYPE, typeName, KEY_PATH)) {
+ try {
+ add(typeName, path);
+ } catch (PatternSyntaxException | InvalidPatternException e) {
+ log.warn(String.format(
+ "Ignoring invalid %s.%s.%s = %s in project %s: %s",
+ MIMETYPE, typeName, KEY_PATH,
+ path, projectName, e.getMessage()));
+ }
+ }
+ }
+ }
+ }
+
+ private void add(String typeName, String path)
+ throws PatternSyntaxException, InvalidPatternException {
+ if (path.startsWith("^")) {
+ matchers.add(new ReType(typeName, path));
+ } else {
+ matchers.add(new FnType(typeName, path));
+ }
+ }
+
+ public String getMimeType(String path) {
+ for (TypeMatcher m : matchers) {
+ if (m.matches(path)) {
+ return m.type;
+ }
+ }
+ return null;
+ }
+
+ private abstract static class TypeMatcher {
+ final String type;
+
+ TypeMatcher(String type) {
+ this.type = type;
+ }
+
+ abstract boolean matches(String path);
+ }
+
+ private static class FnType extends TypeMatcher {
+ private final FileNameMatcher matcher;
+
+ FnType(String type, String pattern) throws InvalidPatternException {
+ super(type);
+ this.matcher = new FileNameMatcher(pattern, null);
+ }
+
+ @Override
+ boolean matches(String input) {
+ FileNameMatcher m = new FileNameMatcher(matcher);
+ m.append(input);
+ return m.isMatch();
+ }
+ }
+
+ private static class ReType extends TypeMatcher {
+ private final Pattern re;
+
+ ReType(String type, String pattern) throws PatternSyntaxException {
+ super(type);
+ this.re = Pattern.compile(pattern);
+ }
+
+ @Override
+ boolean matches(String input) {
+ return re.matcher(input).matches();
+ }
+ }
+}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
index 4971f84..5d4d946 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ProjectConfig.java
@@ -43,9 +43,9 @@
import com.google.gerrit.extensions.common.InheritableBoolean;
import com.google.gerrit.extensions.common.SubmitType;
import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.GroupBackend;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.PluginConfig;
@@ -129,6 +129,7 @@
private static final String LABEL = "label";
private static final String KEY_ABBREVIATION = "abbreviation";
private static final String KEY_FUNCTION = "function";
+ private static final String KEY_DEFAULT_VALUE = "defaultValue";
private static final String KEY_COPY_MIN_SCORE = "copyMinScore";
private static final String KEY_COPY_MAX_SCORE = "copyMaxScore";
private static final String KEY_COPY_ALL_SCORES_ON_TRIVIAL_REBASE = "copyAllScoresOnTrivialRebase";
@@ -154,6 +155,7 @@
private Map<String, ContributorAgreement> contributorAgreements;
private Map<String, NotifyConfig> notifySections;
private Map<String, LabelType> labelSections;
+ private ConfiguredMimeTypes mimeTypes;
private List<CommentLinkInfo> commentLinkSections;
private List<ValidationError> validationErrors;
private ObjectId rulesId;
@@ -300,6 +302,10 @@
return commentLinkSections;
}
+ public ConfiguredMimeTypes getMimeTypes() {
+ return mimeTypes;
+ }
+
public GroupReference resolve(AccountGroup group) {
return resolve(GroupReference.forGroup(group));
}
@@ -417,6 +423,7 @@
loadNotifySections(rc, groupsByName);
loadLabelSections(rc);
loadCommentLinkSections(rc);
+ mimeTypes = new ConfiguredMimeTypes(projectName.get(), rc);
loadPluginSections(rc);
loadReceiveSection(rc);
}
@@ -665,6 +672,15 @@
KEY_FUNCTION, name, Joiner.on(", ").join(LABEL_FUNCTIONS))));
label.setFunctionName(null);
}
+
+ short dv = (short) rc.getInt(LABEL, name, KEY_DEFAULT_VALUE, 0);
+ if (isInRange(dv, values)) {
+ label.setDefaultValue(dv);
+ } else {
+ error(new ValidationError(PROJECT_CONFIG, String.format(
+ "Invalid %s \"%s\" for label \"%s\"",
+ KEY_DEFAULT_VALUE, dv, name)));
+ }
label.setCopyMinScore(
rc.getBoolean(LABEL, name, KEY_COPY_MIN_SCORE, false));
label.setCopyMaxScore(
@@ -680,6 +696,15 @@
}
}
+ private boolean isInRange(short value, List<LabelValue> labelValues) {
+ for (LabelValue lv : labelValues) {
+ if (lv.getValue() == value) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private List<String> getStringListOrNull(Config rc, String section,
String subSection, String name) {
String[] ac = rc.getStringList(section, subSection, name);
@@ -1018,6 +1043,8 @@
} else {
rc.unset(LABEL, name, KEY_ABBREVIATION);
}
+
+ rc.setInt(LABEL, name, KEY_DEFAULT_VALUE, label.getDefaultValue());
if (label.isCopyMinScore()) {
rc.setBoolean(LABEL, name, KEY_COPY_MIN_SCORE, true);
} else {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
index 4540017..db9b29d 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/EqualsLabelPredicate.java
@@ -63,13 +63,19 @@
//
return false;
}
+
ProjectState project = projectCache.get(c.getDest().getParentKey());
if (project == null) {
// The project has disappeared.
//
return false;
}
+
LabelType labelType = type(project.getLabelTypes(), label);
+ if (labelType == null) {
+ return false; // Label is not defined by this project.
+ }
+
boolean hasVote = false;
for (PatchSetApproval p : object.currentApprovals()) {
if (labelType.matches(p)) {
@@ -103,8 +109,7 @@
return lt;
}
}
-
- return LabelType.withDefaultValuesDoNotCheckName(toFind);
+ return null;
}
private boolean match(Change change, int value, Account.Id approver,
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
index 1a9f74b..7b3ede2 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/git/ProjectConfigTest.java
@@ -21,9 +21,11 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import com.google.common.collect.Iterables;
import com.google.gerrit.common.data.AccessSection;
import com.google.gerrit.common.data.ContributorAgreement;
import com.google.gerrit.common.data.GroupReference;
+import com.google.gerrit.common.data.LabelType;
import com.google.gerrit.common.data.Permission;
import com.google.gerrit.common.data.PermissionRule;
import com.google.gerrit.reviewdb.client.AccountGroup;
@@ -47,6 +49,7 @@
import java.io.IOException;
import java.util.Collections;
+import java.util.Map;
public class ProjectConfigTest extends LocalDiskRepositoryTestCase {
private final GroupReference developers = new GroupReference(
@@ -115,6 +118,60 @@
}
@Test
+ public void testReadConfigLabelDefaultValue() throws Exception {
+ RevCommit rev = util.commit(util.tree( //
+ util.file("groups", util.blob(group(developers))), //
+ util.file("project.config", util.blob(""//
+ + "[label \"CustomLabel\"]\n" //
+ + " value = -1 Negative\n" //
+ + " value = 0 No Score\n" //
+ + " value = 1 Positive\n")) //
+ ));
+
+ ProjectConfig cfg = read(rev);
+ Map<String, LabelType> labels = cfg.getLabelSections();
+ Short dv = labels.entrySet().iterator().next().getValue().getDefaultValue();
+ assertEquals(0, (int) dv);
+ }
+
+ @Test
+ public void testReadConfigLabelDefaultValueInRange() throws Exception {
+ RevCommit rev = util.commit(util.tree( //
+ util.file("groups", util.blob(group(developers))), //
+ util.file("project.config", util.blob(""//
+ + "[label \"CustomLabel\"]\n" //
+ + " value = -1 Negative\n" //
+ + " value = 0 No Score\n" //
+ + " value = 1 Positive\n" //
+ + " defaultValue = -1\n")) //
+ ));
+
+ ProjectConfig cfg = read(rev);
+ Map<String, LabelType> labels = cfg.getLabelSections();
+ Short dv = labels.entrySet().iterator().next().getValue().getDefaultValue();
+ assertEquals(-1, (int) dv);
+ }
+
+ @Test
+ public void testReadConfigLabelDefaultValueNotInRange() throws Exception {
+ RevCommit rev = util.commit(util.tree( //
+ util.file("groups", util.blob(group(developers))), //
+ util.file("project.config", util.blob(""//
+ + "[label \"CustomLabel\"]\n" //
+ + " value = -1 Negative\n" //
+ + " value = 0 No Score\n" //
+ + " value = 1 Positive\n" //
+ + " defaultValue = -2\n")) //
+ ));
+
+ ProjectConfig cfg = read(rev);
+ assertEquals(1, cfg.getValidationErrors().size());
+ assertEquals("project.config: Invalid defaultValue \"-2\" "
+ + "for label \"CustomLabel\"",
+ Iterables.getOnlyElement(cfg.getValidationErrors()).getMessage());
+ }
+
+ @Test
public void testEditConfig() throws Exception {
RevCommit rev = util.commit(util.tree( //
util.file("groups", util.blob(group(developers))), //
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
index 4756390..15a66ab 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/schema/SchemaCreatorTest.java
@@ -129,6 +129,7 @@
assertNotNull(codeReview);
assertEquals("Code-Review", codeReview.getName());
assertEquals("CR", codeReview.getAbbreviation());
+ assertEquals(0, codeReview.getDefaultValue());
assertEquals("MaxWithBlock", codeReview.getFunctionName());
assertTrue(codeReview.isCopyMinScore());
assertValueRange(codeReview, 2, 1, 0, -1, -2);
diff --git a/lib/jetty/BUCK b/lib/jetty/BUCK
index 9637598..a6fc4a7 100644
--- a/lib/jetty/BUCK
+++ b/lib/jetty/BUCK
@@ -60,6 +60,18 @@
)
maven_jar(
+ name = 'jmx',
+ id = 'org.eclipse.jetty:jetty-jmx:' + VERSION,
+ sha1 = 'eb1492a8c6362410f84c97907b2ffb94c4dfcc2f',
+ license = 'Apache2.0',
+ exported_deps = [
+ ':continuation',
+ ':http',
+ ],
+ exclude = EXCLUDE,
+)
+
+maven_jar(
name = 'continuation',
id = 'org.eclipse.jetty:jetty-continuation:' + VERSION,
sha1 = '5751f7ea38488dd32180bd3273f7f8591928aee3',