Merge branch 'stable-2.15' * stable-2.15: Polygerrit: Always create new changes as WIP ElasticIndexIT: replace member with local variable Elasticsearch tests: remove password duplication Fix call to the fail skylark global in junit.bzl Set version to 2.14.11-SNAPSHOT Set version to 2.14.10 AbstractQueryChangesTest: Add byMessageSubstring test AbstractQueryChangesTest: Expand byTopic with more 'intopic' tests Elasticsearch: Add char analyzer to ensure consistency of query results Elasticsearch: remove overridden build assignment Elasticsearch: run no other test at the same time ElasticVersionTest: run it through bazel as well Elasticsearch: cover V5 and flaky V6 tests -for CI Split Elasticsearch query tests into separate rules dev-contributing: Document that we format .bzl files with buildifier Add account setting for defaulting new changes to WIP Add project setting for defaulting new changes to WIP Apply buildifier to .bzl files. Update Bower to 1.8.2 Bump commons-io version to 2.2 Add missing elasticsearch dependency in pgm tests Highlight.js: style gr-syntax-name as gr-syntax-keyword Elasticsearch: remove unnecessary test build deps Clarify behavior of "Ignore" feature in REST API documentation Expose commons-compress in plugin API Bump commons-io version to 2.2 Change-Id: I99edb118d193ebe9150f89a902a1407e69711cfc
diff --git a/Documentation/config-project-config.txt b/Documentation/config-project-config.txt index 3b2b65f..cad9489 100644 --- a/Documentation/config-project-config.txt +++ b/Documentation/config-project-config.txt
@@ -217,6 +217,19 @@ Default is `INHERIT`, which means that this property is inherited from the parent project. +[[change.workInProgressByDefault]]change.workInProgressByDefault:: ++ +Controls whether all new changes in the project are set as WIP by default. ++ +Note that a new change will be ready if the `workInProgress` field in +link:rest-api-changes.html#change-input[ChangeInput] is set to `false` explicitly +when calling the link:rest-api-changes.html#create-change[CreateChange] REST API +or the `ready` link:user-upload.html#wip[PushOption] is used during +the Git push. ++ +Default is `INHERIT`, which means that this property is inherited from +the parent project. + [[submit-section]] === Submit section
diff --git a/Documentation/dev-contributing.txt b/Documentation/dev-contributing.txt index e065e57..62d73cc 100644 --- a/Documentation/dev-contributing.txt +++ b/Documentation/dev-contributing.txt
@@ -164,7 +164,7 @@ To format Java source code, Gerrit uses the link:https://github.com/google/google-java-format[`google-java-format`] -tool (version 1.5), and to format Bazel BUILD and WORKSPACE files the +tool (version 1.5), and to format Bazel BUILD, WORKSPACE and .bzl files the link:https://github.com/bazelbuild/buildtools/tree/master/buildifier[`buildifier`] tool (version 0.12.0). These tools automatically apply format according to the style guides; this
diff --git a/Documentation/intro-user.txt b/Documentation/intro-user.txt index 436408d..662e0b3 100644 --- a/Documentation/intro-user.txt +++ b/Documentation/intro-user.txt
@@ -827,6 +827,12 @@ and download commands. Note that this option is only shown if the Flash plugin is available and the JavaScript Clipboard API is unavailable. +- [[work-in-progress-by-default]]`Set new changes work-in-progress`: ++ +Whether new changes are uploaded as work-in-progress per default. This +preference just sets the default; the behavior can still be overridden using a +link:user-upload.html#wip[push option]. + [[my-menu]] In addition it is possible to customize the menu entries of the `My` menu. This can be used to make the navigation to frequently used
diff --git a/Documentation/rest-api-accounts.txt b/Documentation/rest-api-accounts.txt index 025b29d..edb642e 100644 --- a/Documentation/rest-api-accounts.txt +++ b/Documentation/rest-api-accounts.txt
@@ -1255,6 +1255,7 @@ "review_category_strategy": "ABBREV", "mute_common_path_prefixes": true, "publish_comments_on_push": true, + "work_in_progress_by_default": true, "default_base_for_merges": "FIRST_PARENT", "my": [ { @@ -1361,6 +1362,7 @@ "review_category_strategy": "NAME", "diff_view": "SIDE_BY_SIDE", "publish_comments_on_push": true, + "work_in_progress_by_default": true, "mute_common_path_prefixes": true, "my": [ { @@ -2654,6 +2656,9 @@ |`publish_comments_on_push` |not set if `false`| Whether to link:user-upload.html#publish-comments[publish draft comments] on push by default. +|`work_in_progress_by_default` |not set if `false`| +Whether to link:user-upload.html#wip[set work-in-progress] on +push or on create changes online by default. |============================================ [[preferences-input]]
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt index 1c66c44..3b25f47 100644 --- a/Documentation/rest-api-changes.txt +++ b/Documentation/rest-api-changes.txt
@@ -2277,7 +2277,9 @@ -- Marks a change as ignored. The change will not be shown in the incoming -reviews dashboard, and email notifications will be suppressed. +reviews dashboard, and email notifications will be suppressed. Ignoring +a change does not cause the change's "updated" timestamp to be modified, +and the owner is not notified. .Request ----
diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt index 792cca8..4a5cd1d 100644 --- a/Documentation/rest-api-projects.txt +++ b/Documentation/rest-api-projects.txt
@@ -2890,10 +2890,13 @@ |`reject_implicit_merges`|optional| link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether implicit merges should be rejected on changes pushed to the project. -|`private_by_default` || +|`private_by_default` || link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether all new changes are set as private by default. -|`max_object_size_limit` || +|`work_in_progress_by_default`|| +link:#inherited-boolean-info[InheritedBooleanInfo] that tells whether +all new changes are set as work-in-progress by default. +|`max_object_size_limit` || The link:config-gerrit.html#receive.maxObjectSizeLimit[max object size limit] of this project as a link:#max-object-size-limit-info[ MaxObjectSizeLimitInfo] entity.
diff --git a/Documentation/user-upload.txt b/Documentation/user-upload.txt index ce62b93..baf388e 100644 --- a/Documentation/user-upload.txt +++ b/Documentation/user-upload.txt
@@ -309,6 +309,11 @@ Only change owners, project owners and site administrators can specify `work-in-progress` and `ready` options on push. +The default for this option can be set as a +link:intro-user.html#work-in-progress-by-default[user preference]. If the +preference is set so the default behavior is to create `work-in-progress` +changes, this can be overridden with the `ready` option. + [[message]] ==== Message
diff --git a/WORKSPACE b/WORKSPACE index dfe2a45..96f3903 100644 --- a/WORKSPACE +++ b/WORKSPACE
@@ -878,8 +878,8 @@ maven_jar( name = "commons-io", - artifact = "commons-io:commons-io:1.4", - sha1 = "a8762d07e76cfde2395257a5da47ba7c1dbd3dce", + artifact = "commons-io:commons-io:2.2", + sha1 = "83b5b8a7ba1c08f9e8c8ff2373724e33d3c1e22a", ) maven_jar(
diff --git a/gerrit-acceptance-tests/tests.bzl b/gerrit-acceptance-tests/tests.bzl new file mode 100644 index 0000000..c1e34dd --- /dev/null +++ b/gerrit-acceptance-tests/tests.bzl
@@ -0,0 +1,21 @@ +load("//tools/bzl:junit.bzl", "junit_tests") + +def acceptance_tests( + group, + deps = [], + labels = [], + vm_args = ["-Xmx256m"], + **kwargs): + junit_tests( + name = group, + deps = deps + [ + "//gerrit-acceptance-tests:lib", + ], + tags = labels + [ + "acceptance", + "slow", + ], + size = "large", + jvm_flags = vm_args, + **kwargs + )
diff --git a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java index 1dcb284..fbdf52c 100644 --- a/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java +++ b/gerrit-gwtui-common/src/main/java/com/google/gerrit/client/info/GeneralPreferences.java
@@ -151,6 +151,9 @@ public final native boolean publishCommentsOnPush() /*-{ return this.publish_comments_on_push || false }-*/; + public final native boolean + workInProgressByDefault() /*-{ return this.work_in_progress_by_default || false }-*/; + public final native JsArray<TopMenuItem> my() /*-{ return this.my; }-*/; public final native void changesPerPage(int n) /*-{ this.changes_per_page = n }-*/; @@ -230,6 +233,9 @@ public final native void publishCommentsOnPush( boolean p) /*-{ this.publish_comments_on_push = p }-*/; + public final native void workInProgressByDefault( + boolean p) /*-{ this.work_in_progress_by_default = p }-*/; + public final void setMyMenus(List<TopMenuItem> myMenus) { initMy(); for (TopMenuItem n : myMenus) {
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java index 0b32cd5..3e21619 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.java
@@ -69,6 +69,8 @@ String publishCommentsOnPush(); + String workInProgressByDefault(); + String myMenu(); String myMenuInfo();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties index 4b01513..c32efed 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/AccountConstants.properties
@@ -39,6 +39,7 @@ muteCommonPathPrefixes = Mute Common Path Prefixes In File List signedOffBy = Insert Signed-off-by Footer For Inline Edit Changes publishCommentsOnPush = Publish Comments On Push +workInProgressByDefault = Set all new changes work-in-progress by default myMenu = My Menu myMenuInfo = \ Menu items for the 'My' top level menu. \
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java index f349065..afb8718 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/account/MyPreferencesScreen.java
@@ -56,6 +56,7 @@ private CheckBox muteCommonPathPrefixes; private CheckBox signedOffBy; private CheckBox publishCommentsOnPush; + private CheckBox workInProgressByDefault; private ListBox maximumPageSize; private ListBox dateFormat; private ListBox timeFormat; @@ -163,9 +164,10 @@ muteCommonPathPrefixes = new CheckBox(Util.C.muteCommonPathPrefixes()); signedOffBy = new CheckBox(Util.C.signedOffBy()); publishCommentsOnPush = new CheckBox(Util.C.publishCommentsOnPush()); + workInProgressByDefault = new CheckBox(Util.C.workInProgressByDefault()); boolean flashClippy = !UserAgent.hasJavaScriptClipboard() && UserAgent.Flash.isInstalled(); - final Grid formGrid = new Grid(15 + (flashClippy ? 1 : 0), 2); + final Grid formGrid = new Grid(16 + (flashClippy ? 1 : 0), 2); int row = 0; @@ -229,6 +231,10 @@ formGrid.setWidget(row, fieldIdx, publishCommentsOnPush); row++; + formGrid.setText(row, labelIdx, ""); + formGrid.setWidget(row, fieldIdx, workInProgressByDefault); + row++; + if (flashClippy) { formGrid.setText(row, labelIdx, ""); formGrid.setWidget(row, fieldIdx, useFlashClipboard); @@ -264,6 +270,7 @@ e.listenTo(muteCommonPathPrefixes); e.listenTo(signedOffBy); e.listenTo(publishCommentsOnPush); + e.listenTo(workInProgressByDefault); e.listenTo(diffView); e.listenTo(reviewCategoryStrategy); e.listenTo(emailStrategy); @@ -303,6 +310,7 @@ muteCommonPathPrefixes.setEnabled(on); signedOffBy.setEnabled(on); publishCommentsOnPush.setEnabled(on); + workInProgressByDefault.setEnabled(on); reviewCategoryStrategy.setEnabled(on); diffView.setEnabled(on); emailStrategy.setEnabled(on); @@ -329,6 +337,7 @@ muteCommonPathPrefixes.setValue(p.muteCommonPathPrefixes()); signedOffBy.setValue(p.signedOffBy()); publishCommentsOnPush.setValue(p.publishCommentsOnPush()); + workInProgressByDefault.setValue(p.workInProgressByDefault()); setListBox( reviewCategoryStrategy, GeneralPreferencesInfo.ReviewCategoryStrategy.NONE, @@ -421,6 +430,7 @@ p.muteCommonPathPrefixes(muteCommonPathPrefixes.getValue()); p.signedOffBy(signedOffBy.getValue()); p.publishCommentsOnPush(publishCommentsOnPush.getValue()); + p.workInProgressByDefault(workInProgressByDefault.getValue()); p.reviewCategoryStrategy( getListBox( reviewCategoryStrategy, ReviewCategoryStrategy.NONE, ReviewCategoryStrategy.values()));
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java index c0947a8..9def3b3 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.java
@@ -79,6 +79,8 @@ String privateByDefault(); + String workInProgressByDefault(); + String enableReviewerByEmail(); String matchAuthorToCommitterDate();
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties index 8d6878f..1d1bb6d 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/AdminConstants.properties
@@ -31,6 +31,7 @@ requireChangeID = Require <code>Change-Id</code> in commit message rejectImplicitMerges = Reject implicit merges when changes are pushed for review privateByDefault = Set all new changes private by default +workInProgressByDefault = Set all new changes work-in-progress by default headingMaxObjectSizeLimit = Maximum Git object size limit headingGroupOptions = Group Options isVisibleToAll = Make group visible to all registered users.
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java index 64e147d..751e951 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/admin/ProjectInfoScreen.java
@@ -88,6 +88,7 @@ private ListBox requireSignedPush; private ListBox rejectImplicitMerges; private ListBox privateByDefault; + private ListBox workInProgressByDefault; private ListBox enableReviewerByEmail; private ListBox matchAuthorToCommitterDate; private NpTextBox maxObjectSizeLimit; @@ -198,6 +199,7 @@ requireChangeID.setEnabled(isOwner); rejectImplicitMerges.setEnabled(isOwner); privateByDefault.setEnabled(isOwner); + workInProgressByDefault.setEnabled(isOwner); maxObjectSizeLimit.setEnabled(isOwner); enableReviewerByEmail.setEnabled(isOwner); matchAuthorToCommitterDate.setEnabled(isOwner); @@ -278,6 +280,10 @@ saveEnabler.listenTo(privateByDefault); grid.addHtml(AdminConstants.I.privateByDefault(), privateByDefault); + workInProgressByDefault = newInheritedBooleanBox(); + saveEnabler.listenTo(workInProgressByDefault); + grid.addHtml(AdminConstants.I.workInProgressByDefault(), workInProgressByDefault); + enableReviewerByEmail = newInheritedBooleanBox(); saveEnabler.listenTo(enableReviewerByEmail); grid.addHtml(AdminConstants.I.enableReviewerByEmail(), enableReviewerByEmail); @@ -427,6 +433,7 @@ } setBool(rejectImplicitMerges, result.rejectImplicitMerges()); setBool(privateByDefault, result.privateByDefault()); + setBool(workInProgressByDefault, result.workInProgressByDefault()); setBool(enableReviewerByEmail, result.enableReviewerByEmail()); setBool(matchAuthorToCommitterDate, result.matchAuthorToCommitterDate()); setSubmitType(result.defaultSubmitType()); @@ -700,6 +707,7 @@ rsp, getBool(rejectImplicitMerges), getBool(privateByDefault), + getBool(workInProgressByDefault), getBool(enableReviewerByEmail), getBool(matchAuthorToCommitterDate), maxObjectSizeLimit.getText().trim(),
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java index f670ac7..4185ef3 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ConfigInfo.java
@@ -60,6 +60,9 @@ public final native InheritedBooleanInfo privateByDefault() /*-{ return this.private_by_default; }-*/ ; + public final native InheritedBooleanInfo workInProgressByDefault() + /*-{ return this.work_in_progress_by_default; }-*/ ; + public final native InheritedBooleanInfo enableReviewerByEmail() /*-{ return this.enable_reviewer_by_email; }-*/ ;
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java index 66afdb2..3be52e6 100644 --- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java +++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/projects/ProjectApi.java
@@ -153,6 +153,7 @@ InheritableBoolean requireSignedPush, InheritableBoolean rejectImplicitMerges, InheritableBoolean privateByDefault, + InheritableBoolean workInProgressByDefault, InheritableBoolean enableReviewerByEmail, InheritableBoolean matchAuthorToCommitterDate, String maxObjectSizeLimit, @@ -175,6 +176,7 @@ } in.setRejectImplicitMerges(rejectImplicitMerges); in.setPrivateByDefault(privateByDefault); + in.setWorkInProgressByDefault(workInProgressByDefault); in.setMaxObjectSizeLimit(maxObjectSizeLimit); if (submitType != null) { in.setSubmitType(submitType); @@ -313,6 +315,13 @@ private native void setPrivateByDefault(String v) /*-{ if(v)this.private_by_default=v; }-*/; + final void setWorkInProgressByDefault(InheritableBoolean v) { + setWorkInProgressByDefault(v.name()); + } + + private native void setWorkInProgressByDefault( + String v) /*-{ if(v)this.work_in_progress_by_default=v; }-*/; + final void setEnableReviewerByEmail(InheritableBoolean v) { setEnableReviewerByEmailRaw(v.name()); }
diff --git a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java index 3755faa..f322c3d 100644 --- a/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java +++ b/java/com/google/gerrit/elasticsearch/AbstractElasticIndex.java
@@ -21,6 +21,7 @@ import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.FluentIterable; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ListMultimap; import com.google.common.collect.Lists; import com.google.common.flogger.FluentLogger; @@ -79,6 +80,7 @@ protected static final String MAPPINGS = "mappings"; protected static final String ORDER = "order"; protected static final String SEARCH = "_search"; + protected static final String SETTINGS = "settings"; protected static <T> List<T> decodeProtos( JsonObject doc, String fieldName, ProtobufCodec<T> codec) { @@ -181,7 +183,8 @@ } // Recreate the index. - response = performRequest("PUT", getMappings(), indexName, Collections.emptyMap()); + String indexCreationFields = concatJsonString(getSettings(), getMappings()); + response = performRequest("PUT", indexCreationFields, indexName, Collections.emptyMap()); statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { String error = String.format("Failed to create index %s: %s", indexName, statusCode); @@ -193,6 +196,10 @@ protected abstract String getMappings(); + private String getSettings() { + return gson.toJson(ImmutableMap.of(SETTINGS, ElasticSetting.createSetting())); + } + protected abstract String getId(V v); protected String getMappingsForSingleType(String candidateType, MappingProperties properties) { @@ -294,6 +301,10 @@ return performRequest("POST", payload, uri, params); } + private String concatJsonString(String target, String addition) { + return target.substring(0, target.length() - 1) + "," + addition.substring(1); + } + private Response performRequest( String method, Object payload, String uri, Map<String, String> params) throws IOException { String payloadStr = payload instanceof String ? (String) payload : payload.toString();
diff --git a/java/com/google/gerrit/elasticsearch/ElasticMapping.java b/java/com/google/gerrit/elasticsearch/ElasticMapping.java index a30e546..f8c4168 100644 --- a/java/com/google/gerrit/elasticsearch/ElasticMapping.java +++ b/java/com/google/gerrit/elasticsearch/ElasticMapping.java
@@ -34,9 +34,9 @@ || fieldType == FieldType.INTEGER_RANGE || fieldType == FieldType.LONG) { mapping.addNumber(name); - } else if (fieldType == FieldType.PREFIX - || fieldType == FieldType.FULL_TEXT - || fieldType == FieldType.STORED_ONLY) { + } else if (fieldType == FieldType.FULL_TEXT) { + mapping.addStringWithAnalyzer(name); + } else if (fieldType == FieldType.PREFIX || fieldType == FieldType.STORED_ONLY) { mapping.addString(name); } else { throw new IllegalStateException("Unsupported field type: " + fieldType.getName()); @@ -88,6 +88,13 @@ return this; } + Builder addStringWithAnalyzer(String name) { + FieldProperties key = new FieldProperties(adapter.stringFieldType()); + key.analyzer = "custom_with_char_filter"; + fields.put(name, key); + return this; + } + Builder add(String name, String type) { fields.put(name, new FieldProperties(type)); return this; @@ -102,6 +109,7 @@ String type; String index; String format; + String analyzer; Map<String, FieldProperties> fields; FieldProperties(String type) {
diff --git a/java/com/google/gerrit/elasticsearch/ElasticSetting.java b/java/com/google/gerrit/elasticsearch/ElasticSetting.java new file mode 100644 index 0000000..6fd234d --- /dev/null +++ b/java/com/google/gerrit/elasticsearch/ElasticSetting.java
@@ -0,0 +1,92 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.elasticsearch; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; + +class ElasticSetting { + /** The custom char mappings of "." to " " and "_" to " " in the form of UTF-8 */ + private static final ImmutableMap<String, String> CUSTOM_CHAR_MAPPING = + ImmutableMap.of("\\u002E", "\\u0020", "\\u005F", "\\u0020"); + + static SettingProperties createSetting() { + ElasticSetting.Builder settings = new ElasticSetting.Builder(); + settings.addCharFilter(); + settings.addAnalyzer(); + return settings.build(); + } + + static class Builder { + private final ImmutableMap.Builder<String, FieldProperties> fields = + new ImmutableMap.Builder<>(); + + SettingProperties build() { + SettingProperties properties = new SettingProperties(); + properties.analysis = fields.build(); + return properties; + } + + void addCharFilter() { + FieldProperties charMapping = new FieldProperties("mapping"); + charMapping.mappings = getCustomCharMappings(CUSTOM_CHAR_MAPPING); + + FieldProperties charFilter = new FieldProperties(); + charFilter.customMapping = charMapping; + fields.put("char_filter", charFilter); + } + + void addAnalyzer() { + FieldProperties customAnalyzer = new FieldProperties("custom"); + customAnalyzer.tokenizer = "standard"; + customAnalyzer.charFilter = new String[] {"custom_mapping"}; + customAnalyzer.filter = new String[] {"lowercase"}; + + FieldProperties analyzer = new FieldProperties(); + analyzer.customWithCharFilter = customAnalyzer; + fields.put("analyzer", analyzer); + } + + private static String[] getCustomCharMappings(ImmutableMap<String, String> map) { + int mappingIndex = 0; + int numOfMappings = map.size(); + String[] mapping = new String[numOfMappings]; + for (Map.Entry<String, String> e : map.entrySet()) { + mapping[mappingIndex++] = e.getKey() + "=>" + e.getValue(); + } + return mapping; + } + } + + static class SettingProperties { + Map<String, FieldProperties> analysis; + } + + static class FieldProperties { + String tokenizer; + String type; + String[] charFilter; + String[] filter; + String[] mappings; + FieldProperties customMapping; + FieldProperties customWithCharFilter; + + FieldProperties() {} + + FieldProperties(String type) { + this.type = type; + } + } +}
diff --git a/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java b/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java index 80115aa..b3dd1f1 100644 --- a/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java +++ b/java/com/google/gerrit/extensions/api/projects/ConfigInfo.java
@@ -33,6 +33,7 @@ public InheritedBooleanInfo requireSignedPush; public InheritedBooleanInfo rejectImplicitMerges; public InheritedBooleanInfo privateByDefault; + public InheritedBooleanInfo workInProgressByDefault; public InheritedBooleanInfo enableReviewerByEmail; public InheritedBooleanInfo matchAuthorToCommitterDate; public InheritedBooleanInfo rejectEmptyCommit;
diff --git a/java/com/google/gerrit/extensions/api/projects/ConfigInput.java b/java/com/google/gerrit/extensions/api/projects/ConfigInput.java index 37a2e8b..1a6d77b 100644 --- a/java/com/google/gerrit/extensions/api/projects/ConfigInput.java +++ b/java/com/google/gerrit/extensions/api/projects/ConfigInput.java
@@ -30,6 +30,7 @@ public InheritableBoolean requireSignedPush; public InheritableBoolean rejectImplicitMerges; public InheritableBoolean privateByDefault; + public InheritableBoolean workInProgressByDefault; public InheritableBoolean enableReviewerByEmail; public InheritableBoolean matchAuthorToCommitterDate; public InheritableBoolean rejectEmptyCommit;
diff --git a/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java b/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java index 9dcba5e..1f16d8d 100644 --- a/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java +++ b/java/com/google/gerrit/extensions/client/GeneralPreferencesInfo.java
@@ -158,6 +158,7 @@ public EmailFormat emailFormat; public DefaultBase defaultBaseForMerges; public Boolean publishCommentsOnPush; + public Boolean workInProgressByDefault; public boolean isShowInfoInReviewCategory() { return getReviewCategoryStrategy() != ReviewCategoryStrategy.NONE; @@ -227,6 +228,7 @@ p.signedOffBy = false; p.defaultBaseForMerges = DefaultBase.FIRST_PARENT; p.publishCommentsOnPush = false; + p.workInProgressByDefault = false; return p; } }
diff --git a/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java b/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java index 765e38c..a70d254 100644 --- a/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java +++ b/java/com/google/gerrit/reviewdb/client/BooleanProjectConfig.java
@@ -40,7 +40,8 @@ PRIVATE_BY_DEFAULT("change", "privateByDefault"), ENABLE_REVIEWER_BY_EMAIL("reviewer", "enableByEmail"), MATCH_AUTHOR_TO_COMMITTER_DATE("submit", "matchAuthorToCommitterDate"), - REJECT_EMPTY_COMMIT("submit", "rejectEmptyCommit"); + REJECT_EMPTY_COMMIT("submit", "rejectEmptyCommit"), + WORK_IN_PROGRESS_BY_DEFAULT("change", "workInProgressByDefault"); // Git config private final String section;
diff --git a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java index e93b2c57..516dcd4 100644 --- a/java/com/google/gerrit/server/git/receive/ReceiveCommits.java +++ b/java/com/google/gerrit/server/git/receive/ReceiveCommits.java
@@ -2204,6 +2204,7 @@ } private void setChangeId(int id) { + possiblyOverrideWorkInProgress(); changeId = new Change.Id(id); ins = @@ -2224,6 +2225,16 @@ } } + private void possiblyOverrideWorkInProgress() { + // When wip or ready explicitly provided, leave it as is. + if (magicBranch.workInProgress || magicBranch.ready) { + return; + } + magicBranch.workInProgress = + projectState.is(BooleanProjectConfig.WORK_IN_PROGRESS_BY_DEFAULT) + || firstNonNull(user.state().getGeneralPreferences().workInProgressByDefault, false); + } + private void addOps(BatchUpdate bu) throws RestApiException { checkState(changeId != null, "must call setChangeId before addOps"); try {
diff --git a/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java b/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java index 61a7ef2..79eccbb 100644 --- a/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java +++ b/java/com/google/gerrit/server/project/BooleanProjectConfigTransformations.java
@@ -68,6 +68,9 @@ .put( BooleanProjectConfig.REJECT_EMPTY_COMMIT, new Mapper(i -> i.rejectEmptyCommit, (i, v) -> i.rejectEmptyCommit = v)) + .put( + BooleanProjectConfig.WORK_IN_PROGRESS_BY_DEFAULT, + new Mapper(i -> i.workInProgressByDefault, (i, v) -> i.workInProgressByDefault = v)) .build(); static {
diff --git a/java/com/google/gerrit/server/restapi/change/CreateChange.java b/java/com/google/gerrit/server/restapi/change/CreateChange.java index 0dcbeb0..a04716d 100644 --- a/java/com/google/gerrit/server/restapi/change/CreateChange.java +++ b/java/com/google/gerrit/server/restapi/change/CreateChange.java
@@ -266,6 +266,12 @@ AccountState accountState = me.state(); GeneralPreferencesInfo info = accountState.getGeneralPreferences(); + boolean isWorkInProgress = + input.workInProgress == null + ? rsrc.getProjectState().is(BooleanProjectConfig.WORK_IN_PROGRESS_BY_DEFAULT) + || MoreObjects.firstNonNull(info.workInProgressByDefault, false) + : input.workInProgress; + // Add a Change-Id line if there isn't already one String commitMessage = subject; if (ChangeIdUtil.indexOfChangeId(commitMessage, "\n") == -1) { @@ -309,7 +315,7 @@ } ins.setTopic(topic); ins.setPrivate(isPrivate); - ins.setWorkInProgress(input.workInProgress != null && input.workInProgress); + ins.setWorkInProgress(isWorkInProgress); ins.setGroups(groups); ins.setNotify(input.notify); ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java index 624e1b0..0a42b1e 100644 --- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java +++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -449,6 +449,16 @@ } @Test + public void createWipChangeWithWorkInProgressByDefaultForProject() throws Exception { + ConfigInput input = new ConfigInput(); + input.workInProgressByDefault = InheritableBoolean.TRUE; + gApi.projects().name(project.get()).config(input); + String changeId = + gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get().id; + assertThat(gApi.changes().id(changeId).get().workInProgress).isTrue(); + } + + @Test public void setReadyForReviewNotAllowedWithoutPermission() throws Exception { PushOneCommit.Result rready = createChange(); String changeId = rready.getChangeId();
diff --git a/javatests/com/google/gerrit/acceptance/pgm/BUILD b/javatests/com/google/gerrit/acceptance/pgm/BUILD index 583ecc8..ea4c87d 100644 --- a/javatests/com/google/gerrit/acceptance/pgm/BUILD +++ b/javatests/com/google/gerrit/acceptance/pgm/BUILD
@@ -22,6 +22,7 @@ group = "elastic", labels = [ "elastic", + "exclusive", "flaky", "pgm", "no_windows",
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java new file mode 100644 index 0000000..34d87d0 --- /dev/null +++ b/javatests/com/google/gerrit/acceptance/rest/change/WorkInProgressByDefaultIT.java
@@ -0,0 +1,158 @@ +// Copyright (C) 2018 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.acceptance.rest.change; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.gerrit.acceptance.AbstractDaemonTest; +import com.google.gerrit.acceptance.PushOneCommit; +import com.google.gerrit.extensions.api.projects.ConfigInput; +import com.google.gerrit.extensions.client.GeneralPreferencesInfo; +import com.google.gerrit.extensions.client.InheritableBoolean; +import com.google.gerrit.extensions.common.ChangeInfo; +import com.google.gerrit.extensions.common.ChangeInput; +import com.google.gerrit.reviewdb.client.Project; +import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository; +import org.eclipse.jgit.junit.TestRepository; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class WorkInProgressByDefaultIT extends AbstractDaemonTest { + private Project.NameKey project1; + private Project.NameKey project2; + + @Before + public void setUp() throws Exception { + project1 = createProject("project-1"); + project2 = createProject("project-2", project1); + } + + @After + public void tearDown() throws Exception { + setApiUser(admin); + GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id.get()).getPreferences(); + prefs.workInProgressByDefault = false; + gApi.accounts().id(admin.id.get()).setPreferences(prefs); + } + + @Test + public void createChangeWithWorkInProgressByDefaultForProjectDisabled() throws Exception { + ChangeInfo info = + gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get(); + assertThat(info.workInProgress).isNull(); + } + + @Test + public void createChangeWithWorkInProgressByDefaultForProjectEnabled() throws Exception { + setWorkInProgressByDefaultForProject(project2); + ChangeInput input = new ChangeInput(project2.get(), "master", "empty change"); + assertThat(gApi.changes().create(input).get().workInProgress).isTrue(); + } + + @Test + public void createChangeWithWorkInProgressByDefaultForUserEnabled() throws Exception { + setWorkInProgressByDefaultForUser(); + ChangeInput input = new ChangeInput(project2.get(), "master", "empty change"); + assertThat(gApi.changes().create(input).get().workInProgress).isTrue(); + } + + @Test + public void createChangeBypassWorkInProgressByDefaultForProjectEnabled() throws Exception { + setWorkInProgressByDefaultForProject(project2); + ChangeInput input = new ChangeInput(project2.get(), "master", "empty change"); + input.workInProgress = false; + assertThat(gApi.changes().create(input).get().workInProgress).isNull(); + } + + @Test + public void createChangeBypassWorkInProgressByDefaultForUserEnabled() throws Exception { + setWorkInProgressByDefaultForUser(); + ChangeInput input = new ChangeInput(project2.get(), "master", "empty change"); + input.workInProgress = false; + assertThat(gApi.changes().create(input).get().workInProgress).isNull(); + } + + @Test + public void createChangeWithWorkInProgressByDefaultForProjectInherited() throws Exception { + setWorkInProgressByDefaultForProject(project1); + ChangeInfo info = + gApi.changes().create(new ChangeInput(project2.get(), "master", "empty change")).get(); + assertThat(info.workInProgress).isTrue(); + } + + @Test + public void pushWithWorkInProgressByDefaultForProjectEnabled() throws Exception { + setWorkInProgressByDefaultForProject(project2); + assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue(); + } + + @Test + public void pushWithWorkInProgressByDefaultForUserEnabled() throws Exception { + setWorkInProgressByDefaultForUser(); + assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue(); + } + + @Test + public void pushBypassWorkInProgressByDefaultForProjectEnabled() throws Exception { + setWorkInProgressByDefaultForProject(project2); + assertThat( + createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress()) + .isFalse(); + } + + @Test + public void pushBypassWorkInProgressByDefaultForUserEnabled() throws Exception { + setWorkInProgressByDefaultForUser(); + assertThat( + createChange(project2, "refs/for/master%ready").getChange().change().isWorkInProgress()) + .isFalse(); + } + + @Test + public void pushWithWorkInProgressByDefaultForProjectDisabled() throws Exception { + assertThat(createChange(project2).getChange().change().isWorkInProgress()).isFalse(); + } + + @Test + public void pushWorkInProgressByDefaultForProjectInherited() throws Exception { + setWorkInProgressByDefaultForProject(project1); + assertThat(createChange(project2).getChange().change().isWorkInProgress()).isTrue(); + } + + private void setWorkInProgressByDefaultForProject(Project.NameKey p) throws Exception { + ConfigInput input = new ConfigInput(); + input.workInProgressByDefault = InheritableBoolean.TRUE; + gApi.projects().name(p.get()).config(input); + } + + private void setWorkInProgressByDefaultForUser() throws Exception { + GeneralPreferencesInfo prefs = gApi.accounts().id(admin.id.get()).getPreferences(); + prefs.workInProgressByDefault = true; + gApi.accounts().id(admin.id.get()).setPreferences(prefs); + } + + private PushOneCommit.Result createChange(Project.NameKey p) throws Exception { + return createChange(p, "refs/for/master"); + } + + private PushOneCommit.Result createChange(Project.NameKey p, String r) throws Exception { + TestRepository<InMemoryRepository> testRepo = cloneProject(p); + PushOneCommit push = pushFactory.create(db, admin.getIdent(), testRepo); + PushOneCommit.Result result = push.to(r); + result.assertOkStatus(); + return result; + } +}
diff --git a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java index 7096581..9645a94 100644 --- a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java +++ b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
@@ -42,10 +42,14 @@ import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.changes.ReviewInput; import com.google.gerrit.extensions.api.changes.SubmitInput; +import com.google.gerrit.extensions.api.projects.ConfigInput; +import com.google.gerrit.extensions.client.GeneralPreferencesInfo; import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy; +import com.google.gerrit.extensions.client.InheritableBoolean; import com.google.gerrit.extensions.client.ReviewerState; import com.google.gerrit.extensions.common.CommitInfo; import com.google.gerrit.extensions.common.CommitMessageInput; +import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.project.ProjectConfig; import com.google.gerrit.server.project.testing.Util; import com.google.gerrit.server.restapi.change.PostReview; @@ -970,6 +974,38 @@ } @Test + public void createWipChangeWithWorkInProgressByDefaultForProject() throws Exception { + setWorkInProgressByDefault(project, InheritableBoolean.TRUE); + StagedPreChange spc = stagePreChange("refs/for/master"); + Truth.assertThat(gApi.changes().id(spc.changeId).get().workInProgress).isTrue(); + assertThat(sender).notSent(); + } + + @Test + public void createWipChangeWithWorkInProgressByDefaultForUser() throws Exception { + // Make sure owner user is created + StagedChange sc = stageReviewableChange(); + // All was cleaned already + assertThat(sender).notSent(); + + // Toggle workInProgress flag for owner + GeneralPreferencesInfo prefs = gApi.accounts().id(sc.owner.id.get()).getPreferences(); + prefs.workInProgressByDefault = true; + gApi.accounts().id(sc.owner.id.get()).setPreferences(prefs); + + // Create another change without notification that should be wip + StagedPreChange spc = stagePreChange("refs/for/master"); + Truth.assertThat(gApi.changes().id(spc.changeId).get().workInProgress).isTrue(); + assertThat(sender).notSent(); + + // Clean up workInProgressByDefault by owner + prefs = gApi.accounts().id(sc.owner.id.get()).getPreferences(); + Truth.assertThat(prefs.workInProgressByDefault).isTrue(); + prefs.workInProgressByDefault = false; + gApi.accounts().id(sc.owner.id.get()).setPreferences(prefs); + } + + @Test public void createReviewableChangeWithNotifyOwnerReviewers() throws Exception { stagePreChange("refs/for/master%notify=OWNER_REVIEWERS"); assertThat(sender).notSent(); @@ -2646,4 +2682,11 @@ // PolyGerrit current immediately follows up with a review. gApi.changes().id(sc.changeId).revision("current").review(ReviewInput.noScore()); } + + private void setWorkInProgressByDefault(Project.NameKey p, InheritableBoolean v) + throws Exception { + ConfigInput input = new ConfigInput(); + input.workInProgressByDefault = v; + gApi.projects().name(p.get()).config(input); + } }
diff --git a/javatests/com/google/gerrit/acceptance/ssh/BUILD b/javatests/com/google/gerrit/acceptance/ssh/BUILD index eefd9d3..b195ecc 100644 --- a/javatests/com/google/gerrit/acceptance/ssh/BUILD +++ b/javatests/com/google/gerrit/acceptance/ssh/BUILD
@@ -25,8 +25,9 @@ srcs = ["ElasticIndexIT.java"], group = "elastic", labels = [ - "elastic", "docker", + "elastic", + "exclusive", "ssh", ], deps = [
diff --git a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java index 13bb2f2..95da5a6 100644 --- a/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java +++ b/javatests/com/google/gerrit/acceptance/ssh/ElasticIndexIT.java
@@ -24,16 +24,14 @@ import org.eclipse.jgit.lib.Config; public class ElasticIndexIT extends AbstractIndexTests { - private static ElasticContainer<?> container; private static Config getConfig(ElasticVersion version) { ElasticNodeInfo elasticNodeInfo; - container = ElasticContainer.createAndStart(version); + ElasticContainer<?> container = ElasticContainer.createAndStart(version); elasticNodeInfo = new ElasticNodeInfo(container.getHttpHost().getPort()); String indicesPrefix = UUID.randomUUID().toString(); Config cfg = new Config(); - String password = version == ElasticVersion.V5_6 ? "changeme" : null; - ElasticTestUtils.configure(cfg, elasticNodeInfo.port, indicesPrefix, password); + ElasticTestUtils.configure(cfg, elasticNodeInfo.port, indicesPrefix, version); return cfg; }
diff --git a/javatests/com/google/gerrit/elasticsearch/BUILD b/javatests/com/google/gerrit/elasticsearch/BUILD index fe9d516..cc849eb 100644 --- a/javatests/com/google/gerrit/elasticsearch/BUILD +++ b/javatests/com/google/gerrit/elasticsearch/BUILD
@@ -49,6 +49,7 @@ ELASTICSEARCH_TAGS = [ "docker", "elastic", + "exclusive", ] [junit_tests(
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java b/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java index 02e0ba2..b46e040 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticTestUtils.java
@@ -32,11 +32,12 @@ } } - public static void configure(Config config, int port, String prefix, String password) { + public static void configure(Config config, int port, String prefix, ElasticVersion version) { config.setEnum("index", null, "type", IndexType.ELASTICSEARCH); config.setString("elasticsearch", null, "server", "http://localhost:" + port); config.setString("elasticsearch", null, "prefix", prefix); config.setInt("index", null, "maxLimit", 10000); + String password = version == ElasticVersion.V5_6 ? "changeme" : null; if (password != null) { config.setString("elasticsearch", null, "password", password); }
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java index 0fcdb20..5d2f944 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryAccountsTest.java
@@ -67,7 +67,8 @@ Config elasticsearchConfig = new Config(config); InMemoryModule.setDefaults(elasticsearchConfig); String indicesPrefix = testName(); - ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix, "changeme"); + ElasticTestUtils.configure( + elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6); return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration)); } }
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java index 4520020..5d76162 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryChangesTest.java
@@ -67,7 +67,8 @@ Config elasticsearchConfig = new Config(config); InMemoryModule.setDefaults(elasticsearchConfig); String indicesPrefix = testName(); - ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix, "changeme"); + ElasticTestUtils.configure( + elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6); return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration)); } }
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java index d953139..9ce2e93 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryGroupsTest.java
@@ -67,7 +67,8 @@ Config elasticsearchConfig = new Config(config); InMemoryModule.setDefaults(elasticsearchConfig); String indicesPrefix = testName(); - ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix, "changeme"); + ElasticTestUtils.configure( + elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6); return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration)); } }
diff --git a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java index 98e466e..4184935 100644 --- a/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java +++ b/javatests/com/google/gerrit/elasticsearch/ElasticV5QueryProjectsTest.java
@@ -67,7 +67,8 @@ Config elasticsearchConfig = new Config(config); InMemoryModule.setDefaults(elasticsearchConfig); String indicesPrefix = testName(); - ElasticTestUtils.configure(elasticsearchConfig, nodeInfo.port, indicesPrefix, "changeme"); + ElasticTestUtils.configure( + elasticsearchConfig, nodeInfo.port, indicesPrefix, ElasticVersion.V5_6); return Guice.createInjector(new InMemoryModule(elasticsearchConfig, notesMigration)); } }
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java index cf85aeb..0ff16bb 100644 --- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java +++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -831,7 +831,13 @@ ChangeInserter ins4 = newChangeWithTopic(repo, "feature2-fixup"); Change change4 = insert(repo, ins4); - Change change5 = insert(repo, newChange(repo)); + ChangeInserter ins5 = newChangeWithTopic(repo, "https://gerrit.local"); + Change change5 = insert(repo, ins5); + + ChangeInserter ins6 = newChangeWithTopic(repo, "git_gerrit_training"); + Change change6 = insert(repo, ins6); + + Change change_no_topic = insert(repo, newChange(repo)); assertQuery("intopic:foo"); assertQuery("intopic:feature1", change1); @@ -839,8 +845,9 @@ assertQuery("topic:feature2", change2); assertQuery("intopic:feature2", change4, change3, change2); assertQuery("intopic:fixup", change4); - assertQuery("topic:\"\"", change5); - assertQuery("intopic:\"\"", change5); + assertQuery("intopic:gerrit", change6, change5); + assertQuery("topic:\"\"", change_no_topic); + assertQuery("intopic:\"\"", change_no_topic); } @Test @@ -899,6 +906,14 @@ } @Test + public void byMessageSubstring() throws Exception { + TestRepository<Repo> repo = createProject("repo"); + RevCommit commit1 = repo.parseBody(repo.commit().message("https://gerrit.local").create()); + Change change1 = insert(repo, newChangeForCommit(repo, commit1)); + assertQuery("message:gerrit", change1); + } + + @Test public void byLabel() throws Exception { accountManager.authenticate(AuthRequest.forUser("anotheruser")); TestRepository<Repo> repo = createProject("repo");
diff --git a/plugins/BUILD b/plugins/BUILD index 4cc982a..cc59cc0 100644 --- a/plugins/BUILD +++ b/plugins/BUILD
@@ -37,6 +37,7 @@ "//java/com/google/gerrit/metrics/dropwizard", "//java/com/google/gerrit/reviewdb:server", "//java/com/google/gerrit/util/http", + "//lib/commons:compress", "//lib/commons:dbcp", "//lib/commons:lang", "//lib/dropwizard:dropwizard-core",
diff --git a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html index 704974d..fd6eb80 100644 --- a/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html +++ b/polygerrit-ui/app/elements/admin/gr-repo/gr-repo.html
@@ -243,6 +243,22 @@ </span> </section> <section> + <span class="title"> + Set new changes to "work in progress" by default</span> + <span class="value"> + <gr-select + id="setAllNewChangesWorkInProgressByDefaultSelect" + bind-value="{{_repoConfig.work_in_progress_by_default.configured_value}}"> + <select disabled$="[[_readOnly]]"> + <template is="dom-repeat" + items="[[_formatBooleanSelect(_repoConfig.work_in_progress_by_default)]]"> + <option value="[[item.value]]">[[item.label]]</option> + </template> + </select> + </gr-select> + </span> + </section> + <section> <span class="title">Maximum Git object size limit</span> <span class="value"> <input
diff --git a/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-syntax-theme.html b/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-syntax-theme.html index 0e028d8..41d3804 100644 --- a/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-syntax-theme.html +++ b/polygerrit-ui/app/elements/diff/gr-syntax-themes/gr-syntax-theme.html
@@ -32,7 +32,8 @@ .gr-syntax-meta { color: var(--syntax-meta-color); } - .gr-syntax-keyword { + .gr-syntax-keyword, + .gr-syntax-name { color: var(--syntax-keyword-color); line-height: 1; }
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html index 14e5e6f..18c1734 100644 --- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.html
@@ -227,6 +227,16 @@ </span> </section> <section> + <span class="title">Set new changes to "work in progress" by default</span> + <span class="value"> + <input + id="workInProgressByDefault" + type="checkbox" + checked$="[[_localPrefs.work_in_progress_by_default]]" + on-change="_handleWorkInProgressByDefault"> + </span> + </section> + <section> <span class="title"> Insert Signed-off-by Footer For Inline Edit Changes </span>
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js index 213ab65..8eefc0a 100644 --- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view.js
@@ -24,6 +24,7 @@ 'email_strategy', 'diff_view', 'publish_comments_on_push', + 'work_in_progress_by_default', 'signed_off_by', 'email_format', 'size_bar_in_change_table', @@ -291,6 +292,11 @@ this.$.publishCommentsOnPush.checked); }, + _handleWorkInProgressByDefault() { + this.set('_localPrefs.work_in_progress_by_default', + this.$.workInProgressByDefault.checked); + }, + _handleInsertSignedOff() { this.set('_localPrefs.signed_off_by', this.$.insertSignedOff.checked); },
diff --git a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html index b208ba2..f47816f 100644 --- a/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html +++ b/polygerrit-ui/app/elements/settings/gr-settings-view/gr-settings-view_test.html
@@ -175,6 +175,9 @@ assert.equal(valueOf('Publish comments on push', 'preferences') .firstElementChild.checked, false); assert.equal(valueOf( + 'Set new changes to "work in progress" by default', 'preferences') + .firstElementChild.checked, false); + assert.equal(valueOf( 'Insert Signed-off-by Footer For Inline Edit Changes', 'preferences') .firstElementChild.checked, false); @@ -234,6 +237,30 @@ }); }); + test('set new changes work-in-progress', done => { + const newChangesWorkInProgress = + valueOf('Set new changes to "work in progress" by default', + 'preferences').firstElementChild; + MockInteractions.tap(newChangesWorkInProgress); + + assert.isFalse(element._menuChanged); + assert.isTrue(element._prefsChanged); + + stub('gr-rest-api-interface', { + savePreferences(prefs) { + assert.equal(prefs.work_in_progress_by_default, true); + return Promise.resolve(); + }, + }); + + // Save the change. + element._handleSavePreferences().then(() => { + assert.isFalse(element._prefsChanged); + assert.isFalse(element._menuChanged); + done(); + }); + }); + test('diff preferences', done => { // Rendered with the expected preferences selected. assert.equal(valueOf('Context', 'diffPreferences')
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl index 8076059..d711356 100644 --- a/tools/bzl/junit.bzl +++ b/tools/bzl/junit.bzl
@@ -43,11 +43,7 @@ if findex != -1: break if findex == -1: - fail( - "%s does not contain any of %s", - fname, - _PREFIXES, - ) + fail("%s does not contain any of %s" % (fname, _PREFIXES)) return ".".join(toks[findex:]) + ".class" def _impl(ctx):