Merge "Expand INFO check chips, if there are no errors and running runs"
diff --git a/Documentation/access-control.txt b/Documentation/access-control.txt
index 31c3536..bc70451 100644
--- a/Documentation/access-control.txt
+++ b/Documentation/access-control.txt
@@ -951,15 +951,6 @@
can always edit or remove hashtags (even without having the `Edit Hashtags`
access right assigned).
-[[category_edit_assigned_to]]
-=== Edit Assignee
-
-This category permits users to set who is assigned to a change that is
-uploaded for review.
-
-The change owner, ref owners, and the user currently assigned to a change
-can always change the assignee.
-
[[example_roles]]
== Examples of typical roles in a project
diff --git a/Documentation/cmd-stream-events.txt b/Documentation/cmd-stream-events.txt
index 5fd0bfc..2456662 100644
--- a/Documentation/cmd-stream-events.txt
+++ b/Documentation/cmd-stream-events.txt
@@ -58,21 +58,6 @@
[[events]]
== EVENTS
-=== Assignee Changed
-
-Sent when the assignee of a change has been modified.
-
-type:: "assignee-changed"
-
-change:: link:json.html#change[change attribute]
-
-changer:: link:json.html#account[account attribute]
-
-oldAssignee:: Assignee before it was changed.
-
-eventCreatedOn:: Time in seconds since the UNIX epoch when this event was
-created.
-
=== Change Abandoned
Sent when a change has been abandoned.
diff --git a/Documentation/concept-changes.txt b/Documentation/concept-changes.txt
index 6e76a8a..323b32a 100644
--- a/Documentation/concept-changes.txt
+++ b/Documentation/concept-changes.txt
@@ -39,10 +39,6 @@
`git push` command, or the user that triggered the patch set creation through
an action in the UI).
-|Assignee
-|The contributor responsible for the change. Often used when a change has
-mulitple reviewers to identify the individual responsible for final approval.
-
|Reviewers
|A list of one or more contributors responsible for reviewing the change.
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 8d30db2..9e76efe 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -1415,20 +1415,6 @@
+
The default is false.
-[[change.enableAttentionSet]]change.enableAttentionSet::
-+
-If set to true, then all UI features for using and interacting with the
-attention set are enabled.
-+
-The default is true.
-
-[[change.enableAssignee]]change.enableAssignee::
-+
-If set to true, then all UI features for using and interacting with the
-assignee are enabled.
-+
-The default is false.
-
[[change.maxComments]]change.maxComments::
+
Maximum number of comments (regular plus robot) allowed per change. Additional
diff --git a/Documentation/config-mail.txt b/Documentation/config-mail.txt
index 8bd5dc7..4f11ca8 100644
--- a/Documentation/config-mail.txt
+++ b/Documentation/config-mail.txt
@@ -139,12 +139,6 @@
change being reverted. It is a `ChangeEmail`: see `ChangeSubject.soy` and
ChangeFooter.
-=== SetAssignee.soy and SetAssigneeHtml.soy
-
-The SetAssignee templates will determine the contents of the email related to a
-user being assigned to a change. It is a `ChangeEmail`: see `ChangeSubject.soy`
-and ChangeFooter.
-
== Mail Variables and Methods
diff --git a/Documentation/config-submit-requirements.txt b/Documentation/config-submit-requirements.txt
index d61dbc43..ba20cea 100644
--- a/Documentation/config-submit-requirements.txt
+++ b/Documentation/config-submit-requirements.txt
@@ -160,6 +160,22 @@
link:http://www.brics.dk/automaton/[dk.brics.automaton library,role=external,window=_blank]
is used for the evaluation of such patterns.
+[[operator_committeremail]]
+committeremail:'EMAIL_PATTERN'::
++
+An operator that returns true if the change committer's email address matches a
+specific regular expression pattern. The
+link:http://www.brics.dk/automaton/[dk.brics.automaton library,role=external,window=_blank]
+is used for the evaluation of such patterns.
+
+[[operator_uploaderemail]]
+uploaderemail:'EMAIL_PATTERN'::
++
+An operator that returns true if the change uploader's primary email address
+matches a specific regular expression pattern. The
+link:http://www.brics.dk/automaton/[dk.brics.automaton library,role=external,window=_blank]
+is used for the evaluation of such patterns.
+
[[operator_distinctvoters]]
distinctvoters:'[Label1,Label2,...,LabelN],value=MAX,count>1'::
+
diff --git a/Documentation/config-validation.txt b/Documentation/config-validation.txt
index 56c9ecd..b0149fe 100644
--- a/Documentation/config-validation.txt
+++ b/Documentation/config-validation.txt
@@ -100,13 +100,6 @@
E.g. a plugin could use this to enforce a certain name scheme for
group names.
-[[assignee-validation]]
-== Assignee validation
-
-
-Plugins implementing the `AssigneeValidationListener` interface can perform
-validation of assignees before they are assigned to a change.
-
[[hashtag-validation]]
== Hashtag validation
diff --git a/Documentation/index.txt b/Documentation/index.txt
index 89b88aa..ee2c289 100644
--- a/Documentation/index.txt
+++ b/Documentation/index.txt
@@ -22,12 +22,13 @@
. link:intro-project-owner.html[Project Owner Guide]
. link:https://source.android.com/source/developing[Default Android Workflow,role=external,window=_blank] (external)
-== Tutorials
+== Features and Workflows
. Web
.. link:user-review-ui.html[Review UI Overview]
.. link:user-search.html[Searching Changes]
.. link:user-inline-edit.html[Manipulating Changes in Browser]
.. link:user-notify.html[Subscribing to Email Notifications]
+.. link:user-attention-set.html[Attention Set]
. SSH
.. link:user-upload.html#ssh[SSH connection details]
.. link:cmd-index.html[Command Line Tools]
diff --git a/Documentation/js_licenses.txt b/Documentation/js_licenses.txt
index 114aa3a..f685af9 100644
--- a/Documentation/js_licenses.txt
+++ b/Documentation/js_licenses.txt
@@ -603,39 +603,6 @@
----
-[[ba-linkify]]
-ba-linkify
-
-* ba-linkify
-
-[[ba-linkify_license]]
-----
-Copyright (c) 2009 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-----
-
-
[[codemirror-minified]]
codemirror-minified
diff --git a/Documentation/licenses.txt b/Documentation/licenses.txt
index f8ca85b..be41d0c 100644
--- a/Documentation/licenses.txt
+++ b/Documentation/licenses.txt
@@ -3507,39 +3507,6 @@
----
-[[ba-linkify]]
-ba-linkify
-
-* ba-linkify
-
-[[ba-linkify_license]]
-----
-Copyright (c) 2009 "Cowboy" Ben Alman
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-----
-
-
[[codemirror-minified]]
codemirror-minified
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 46724e5..b761687 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -1125,154 +1125,6 @@
HTTP/1.1 204 No Content
----
-[[get-assignee]]
-=== Get Assignee
---
-'GET /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Retrieves the account of the user assigned to a change.
-
-.Request
-----
- GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the assigned account is returned.
-
-.Response
-----
- HTTP/1.1 200 OK
- Content-Disposition: attachment
- Content-Type: application/json; charset=UTF-8
-
- )]}'
- {
- "_account_id": 1000096,
- "name": "John Doe",
- "email": "john.doe@example.com",
- "username": "jdoe"
- }
-----
-
-If the change has no assignee the response is "`204 No Content`".
-
-[[get-past-assignees]]
-=== Get Past Assignees
---
-'GET /changes/link:#change-id[\{change-id\}]/past_assignees'
---
-
-Returns a list of every user ever assigned to a change, in the order in which
-they were first assigned.
-
-.Request
-----
- GET /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/past_assignees HTTP/1.0
-----
-
-As a response a list of link:rest-api-accounts.html#account-info[AccountInfo]
-entities is returned.
-
-.Response
-----
- HTTP/1.1 200 OK
- Content-Disposition: attachment
- Content-Type: application/json; charset=UTF-8
-
- )]}'
- [
- {
- "_account_id": 1000051,
- "name": "Jane Doe",
- "email": "jane.doe@example.com",
- "username": "janed"
- },
- {
- "_account_id": 1000096,
- "name": "John Doe",
- "email": "john.doe@example.com",
- "username": "jdoe"
- }
- ]
-
-----
-
-
-[[set-assignee]]
-=== Set Assignee
---
-'PUT /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Sets the assignee of a change.
-
-The new assignee must be provided in the request body inside a
-link:#assignee-input[AssigneeInput] entity.
-
-.Request
-----
- PUT /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
- Content-Type: application/json; charset=UTF-8
-
- {
- "assignee": "jdoe"
- }
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the assigned account is returned.
-
-.Response
-----
- HTTP/1.1 200 OK
- Content-Disposition: attachment
- Content-Type: application/json; charset=UTF-8
-
- )]}'
- {
- "_account_id": 1000096,
- "name": "John Doe",
- "email": "john.doe@example.com",
- "username": "jdoe"
- }
-----
-
-[[delete-assignee]]
-=== Delete Assignee
---
-'DELETE /changes/link:#change-id[\{change-id\}]/assignee'
---
-
-Deletes the assignee of a change.
-
-
-.Request
-----
- DELETE /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/assignee HTTP/1.0
-----
-
-As a response an link:rest-api-accounts.html#account-info[AccountInfo] entity
-describing the account of the deleted assignee is returned.
-
-.Response
-----
- HTTP/1.1 200 OK
- Content-Disposition: attachment
- Content-Type: application/json; charset=UTF-8
-
- )]}'
- {
- "_account_id": 1000096,
- "name": "John Doe",
- "email": "john.doe@example.com",
- "username": "jdoe"
- }
-----
-
-If the change had no assignee the response is "`204 No Content`".
-
[[get-pure-revert]]
=== Get Pure Revert
--
@@ -6918,18 +6770,6 @@
If true, this vote was made after the change was submitted.
|===========================
-[[assignee-input]]
-=== AssigneeInput
-The `AssigneeInput` entity contains the identity of the user to be set as assignee.
-
-[options="header",cols="1,^1,5"]
-|===========================
-|Field Name ||Description
-|`assignee` ||
-The link:rest-api-accounts.html#account-id[ID] of one account that
-should be added as assignee.
-|===========================
-
[[attention-set-info]]
=== AttentionSetInfo
The `AttentionSetInfo` entity contains details of users that are in
diff --git a/Documentation/rest-api-config.txt b/Documentation/rest-api-config.txt
index 505def0..9f3ef6d 100644
--- a/Documentation/rest-api-config.txt
+++ b/Documentation/rest-api-config.txt
@@ -1575,10 +1575,6 @@
configuration parameter] that controls whether the mergeability bit in
link:rest-api-changes.html#change-info[ChangeInfo] will never be set and if the
bit is indexed.
-|`enable_attention_set` |defaults to `false`|
-Returns true if attention set UI features are enabled.
-|`enable_assignee` |defaults to `true`|
-Returns true if assignee related UI features are enabled.
|=============================
[[change-index-config-info]]
diff --git a/Documentation/user-attention-set.txt b/Documentation/user-attention-set.txt
index 5e5d3f8..738205a 100644
--- a/Documentation/user-attention-set.txt
+++ b/Documentation/user-attention-set.txt
@@ -164,13 +164,7 @@
=== For Gerrit Admins
-The Attention Set has been available since the 3.3 release (late 2020). It
-is enabled by default, but you can disable it by setting
-link:config-gerrit.html#change.enableAttentionSet[enableAttentionSet] to false.
-
-As part of Gerrit 3.3 upgrade, the user group "Non-Interactive Users" is
-renamed "Service Users". For a new installation, the group is automatically
-created upon initialization.
+The Attention Set has been available since the 3.3 release (late 2020).
=== Important note for all host owners, project owners, and bot owners
diff --git a/Documentation/user-notify.txt b/Documentation/user-notify.txt
index 24c35f0..d2a22a7 100644
--- a/Documentation/user-notify.txt
+++ b/Documentation/user-notify.txt
@@ -181,7 +181,6 @@
* newpatchset
* restore
* revert
-* setassignee
[[Gerrit-Change-Id]]Gerrit-Change-Id::
diff --git a/Documentation/user-review-ui.txt b/Documentation/user-review-ui.txt
index 780d3ec..39929e1 100644
--- a/Documentation/user-review-ui.txt
+++ b/Documentation/user-review-ui.txt
@@ -116,7 +116,7 @@
need to vote/review. If the CC'ed user votes they are moved to reviewers.
+
-- [[attention-set]]Attention set:
+- [[attention-set]]link:user-attention-set.html[Attention set]:
+
Users in attention set are marked by "chevron" symbol (see screenshot above).
The mark indicates that there are actions their attention is required on the
diff --git a/Documentation/user-search.txt b/Documentation/user-search.txt
index e12c27c..32cb639 100644
--- a/Documentation/user-search.txt
+++ b/Documentation/user-search.txt
@@ -85,11 +85,6 @@
means 'everything older than 2 days' while `-age:2d` means
'everything with an age of at most 2 days'.
-[[assignee]]
-assignee:'USER'::
-+
-Changes assigned to the given user.
-
[[attention]]
attention:'USER'::
+
@@ -485,20 +480,12 @@
[[is]]
-is:assigned::
-+
-True if the change has an assignee.
-
[[is-starred]]
is:starred::
+
Same as 'has:star', true if the change has been starred by the
current user with the default label.
-is:unassigned::
-+
-True if the change does not have an assignee.
-
is:attention::
+
True if the change has attention by the current user.
diff --git a/java/com/google/gerrit/common/PageLinks.java b/java/com/google/gerrit/common/PageLinks.java
index 38de5b1..836eb32 100644
--- a/java/com/google/gerrit/common/PageLinks.java
+++ b/java/com/google/gerrit/common/PageLinks.java
@@ -106,10 +106,6 @@
return toChangeQuery(op("owner", fullname) + " " + status(status));
}
- public static String toAssigneeQuery(String fullname) {
- return toChangeQuery(op("assignee", fullname));
- }
-
public static String toCustomDashboard(String params) {
return "/dashboard/?" + params;
}
diff --git a/java/com/google/gerrit/entities/Permission.java b/java/com/google/gerrit/entities/Permission.java
index d029fad..6a50711 100644
--- a/java/com/google/gerrit/entities/Permission.java
+++ b/java/com/google/gerrit/entities/Permission.java
@@ -35,7 +35,6 @@
public static final String DELETE = "delete";
public static final String DELETE_CHANGES = "deleteChanges";
public static final String DELETE_OWN_CHANGES = "deleteOwnChanges";
- public static final String EDIT_ASSIGNEE = "editAssignee";
public static final String EDIT_HASHTAGS = "editHashtags";
public static final String EDIT_TOPIC_NAME = "editTopicName";
public static final String FORGE_AUTHOR = "forgeAuthor";
@@ -73,7 +72,6 @@
NAMES_LC.add(DELETE.toLowerCase());
NAMES_LC.add(DELETE_CHANGES.toLowerCase());
NAMES_LC.add(DELETE_OWN_CHANGES.toLowerCase());
- NAMES_LC.add(EDIT_ASSIGNEE.toLowerCase());
NAMES_LC.add(EDIT_HASHTAGS.toLowerCase());
NAMES_LC.add(EDIT_TOPIC_NAME.toLowerCase());
NAMES_LC.add(FORGE_AUTHOR.toLowerCase());
diff --git a/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java b/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java
deleted file mode 100644
index e17e1c9..0000000
--- a/java/com/google/gerrit/extensions/api/changes/AssigneeInput.java
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.extensions.api.changes;
-
-import com.google.gerrit.extensions.restapi.DefaultInput;
-
-public class AssigneeInput {
- @DefaultInput public String assignee;
-}
diff --git a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
index 0ebb859..ef61b68 100644
--- a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
+++ b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
@@ -347,22 +347,6 @@
/** Adds a user to the attention set. */
AccountInfo addToAttentionSet(AttentionSetInput input) throws RestApiException;
- /** Set the assignee of a change. */
- AccountInfo setAssignee(AssigneeInput input) throws RestApiException;
-
- /** Get the assignee of a change. */
- AccountInfo getAssignee() throws RestApiException;
-
- /** Get all past assignees. */
- List<AccountInfo> getPastAssignees() throws RestApiException;
-
- /**
- * Delete the assignee of a change.
- *
- * @return the assignee that was deleted, or null if there was no assignee.
- */
- AccountInfo deleteAssignee() throws RestApiException;
-
/**
* Get all published comments on a change.
*
@@ -746,26 +730,6 @@
}
@Override
- public AccountInfo setAssignee(AssigneeInput input) throws RestApiException {
- throw new NotImplementedException();
- }
-
- @Override
- public AccountInfo getAssignee() throws RestApiException {
- throw new NotImplementedException();
- }
-
- @Override
- public List<AccountInfo> getPastAssignees() throws RestApiException {
- throw new NotImplementedException();
- }
-
- @Override
- public AccountInfo deleteAssignee() throws RestApiException {
- throw new NotImplementedException();
- }
-
- @Override
@Deprecated
public Map<String, List<CommentInfo>> comments() throws RestApiException {
throw new NotImplementedException();
diff --git a/java/com/google/gerrit/extensions/common/ChangeConfigInfo.java b/java/com/google/gerrit/extensions/common/ChangeConfigInfo.java
index fc09b49..0142e01 100644
--- a/java/com/google/gerrit/extensions/common/ChangeConfigInfo.java
+++ b/java/com/google/gerrit/extensions/common/ChangeConfigInfo.java
@@ -22,6 +22,5 @@
public int updateDelay;
public Boolean submitWholeTopic;
public String mergeabilityComputationBehavior;
- public Boolean enableAttentionSet;
public Boolean enableAssignee;
}
diff --git a/java/com/google/gerrit/extensions/events/AssigneeChangedListener.java b/java/com/google/gerrit/extensions/events/AssigneeChangedListener.java
deleted file mode 100644
index 7fc0f03..0000000
--- a/java/com/google/gerrit/extensions/events/AssigneeChangedListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.extensions.events;
-
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.extensions.annotations.ExtensionPoint;
-import com.google.gerrit.extensions.common.AccountInfo;
-
-/** Notified whenever a change assignee is changed. */
-@ExtensionPoint
-public interface AssigneeChangedListener {
- interface Event extends ChangeEvent {
- @Nullable
- AccountInfo getOldAssignee();
- }
-
- void onAssigneeChanged(Event event);
-}
diff --git a/java/com/google/gerrit/httpd/raw/IndexPreloadingUtil.java b/java/com/google/gerrit/httpd/raw/IndexPreloadingUtil.java
index 5cf63d9..bb3b6d5 100644
--- a/java/com/google/gerrit/httpd/raw/IndexPreloadingUtil.java
+++ b/java/com/google/gerrit/httpd/raw/IndexPreloadingUtil.java
@@ -58,25 +58,21 @@
// polygerrit-ui/app/elements/core/gr-navigation/gr-navigation.ts
public static final String DASHBOARD_HAS_UNPUBLISHED_DRAFTS_QUERY = "has:draft limit:10";
public static final String YOUR_TURN = "attention:${user} limit:25";
- public static final String DASHBOARD_ASSIGNED_QUERY =
- "assignee:${user} (-is:wip OR " + "owner:self OR assignee:self) is:open limit:25";
public static final String DASHBOARD_WORK_IN_PROGRESS_QUERY =
"is:open owner:${user} is:wip limit:25";
public static final String DASHBOARD_OUTGOING_QUERY = "is:open owner:${user} -is:wip limit:25";
public static final String DASHBOARD_INCOMING_QUERY =
- "is:open -owner:${user} -is:wip (reviewer:${user} OR assignee:${user}) limit:25";
+ "is:open -owner:${user} -is:wip reviewer:${user} limit:25";
public static final String CC_QUERY = "is:open -is:wip cc:${user} limit:10";
public static final String DASHBOARD_RECENTLY_CLOSED_QUERY =
"is:closed (-is:wip OR owner:self) "
- + "(owner:${user} OR reviewer:${user} OR assignee:${user} "
- + "OR cc:${user}) -age:4w limit:10";
+ + "(owner:${user} OR reviewer:${user} OR cc:${user}) "
+ + "-age:4w limit:10";
public static final String NEW_USER = "owner:${user} limit:1";
public static final String SELF_DASHBOARD_HAS_UNPUBLISHED_DRAFTS_QUERY =
DASHBOARD_HAS_UNPUBLISHED_DRAFTS_QUERY.replaceAll("\\$\\{user}", "self");
public static final String SELF_YOUR_TURN = YOUR_TURN.replaceAll("\\$\\{user}", "self");
- public static final String SELF_DASHBOARD_ASSIGNED_QUERY =
- DASHBOARD_ASSIGNED_QUERY.replaceAll("\\$\\{user}", "self");
public static final ImmutableList<String> SELF_DASHBOARD_QUERIES =
Stream.of(
DASHBOARD_WORK_IN_PROGRESS_QUERY,
@@ -195,31 +191,11 @@
public static List<String> computeDashboardQueryList(Server serverApi) throws RestApiException {
List<String> queryList = new ArrayList<>();
queryList.add(SELF_DASHBOARD_HAS_UNPUBLISHED_DRAFTS_QUERY);
- if (isEnabledAttentionSet(serverApi)) {
- queryList.add(SELF_YOUR_TURN);
- }
- if (isEnabledAssignee(serverApi)) {
- queryList.add(SELF_DASHBOARD_ASSIGNED_QUERY);
- }
-
+ queryList.add(SELF_YOUR_TURN);
queryList.addAll(SELF_DASHBOARD_QUERIES);
return queryList;
}
- private static boolean isEnabledAttentionSet(Server serverApi) throws RestApiException {
- return serverApi.getInfo() != null
- && serverApi.getInfo().change != null
- && serverApi.getInfo().change.enableAttentionSet != null
- && serverApi.getInfo().change.enableAttentionSet;
- }
-
- private static boolean isEnabledAssignee(Server serverApi) throws RestApiException {
- return serverApi.getInfo() != null
- && serverApi.getInfo().change != null
- && serverApi.getInfo().change.enableAssignee != null
- && serverApi.getInfo().change.enableAssignee;
- }
-
private IndexPreloadingUtil() {}
}
diff --git a/java/com/google/gerrit/mail/MailHeader.java b/java/com/google/gerrit/mail/MailHeader.java
index 2700f81..6933140 100644
--- a/java/com/google/gerrit/mail/MailHeader.java
+++ b/java/com/google/gerrit/mail/MailHeader.java
@@ -17,7 +17,6 @@
/** Variables used by emails to hold data */
public enum MailHeader {
// Gerrit metadata holders
- ASSIGNEE("Gerrit-Assignee"),
ATTENTION("Gerrit-Attention"),
BRANCH("Gerrit-Branch"),
CC("Gerrit-CC"),
diff --git a/java/com/google/gerrit/pgm/init/SitePathInitializer.java b/java/com/google/gerrit/pgm/init/SitePathInitializer.java
index 236d185..a057e66 100644
--- a/java/com/google/gerrit/pgm/init/SitePathInitializer.java
+++ b/java/com/google/gerrit/pgm/init/SitePathInitializer.java
@@ -144,8 +144,6 @@
extractMailExample("RestoredHtml.soy");
extractMailExample("Reverted.soy");
extractMailExample("RevertedHtml.soy");
- extractMailExample("SetAssignee.soy");
- extractMailExample("SetAssigneeHtml.soy");
if (!ui.isBatch()) {
System.err.println();
diff --git a/java/com/google/gerrit/server/AssigneeStatusUpdate.java b/java/com/google/gerrit/server/AssigneeStatusUpdate.java
deleted file mode 100644
index 812aad1..0000000
--- a/java/com/google/gerrit/server/AssigneeStatusUpdate.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (C) 2019 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;
-
-import com.google.auto.value.AutoValue;
-import com.google.gerrit.entities.Account;
-import java.time.Instant;
-import java.util.Optional;
-
-/** Change to an assignee's status. */
-@AutoValue
-public abstract class AssigneeStatusUpdate {
- public static AssigneeStatusUpdate create(
- Instant ts, Account.Id updatedBy, Optional<Account.Id> currentAssignee) {
- return new AutoValue_AssigneeStatusUpdate(ts, updatedBy, currentAssignee);
- }
-
- public abstract Instant date();
-
- public abstract Account.Id updatedBy();
-
- public abstract Optional<Account.Id> currentAssignee();
-}
diff --git a/java/com/google/gerrit/server/ChangeMessagesUtil.java b/java/com/google/gerrit/server/ChangeMessagesUtil.java
index c84c0e7..400da58 100644
--- a/java/com/google/gerrit/server/ChangeMessagesUtil.java
+++ b/java/com/google/gerrit/server/ChangeMessagesUtil.java
@@ -40,8 +40,6 @@
public static final String TAG_ABANDON = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "abandon";
public static final String TAG_CHERRY_PICK_CHANGE =
AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "cherryPickChange";
- public static final String TAG_DELETE_ASSIGNEE =
- AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteAssignee";
public static final String TAG_DELETE_REVIEWER =
AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteReviewer";
public static final String TAG_DELETE_VOTE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "deleteVote";
@@ -49,7 +47,6 @@
public static final String TAG_MOVE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "move";
public static final String TAG_RESTORE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "restore";
public static final String TAG_REVERT = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "revert";
- public static final String TAG_SET_ASSIGNEE = AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "setAssignee";
public static final String TAG_UPDATE_ATTENTION_SET =
AUTOGENERATED_BY_GERRIT_TAG_PREFIX + "updateAttentionSet";
public static final String TAG_SET_DESCRIPTION =
diff --git a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index 66a845a..4fba660 100644
--- a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -21,7 +21,6 @@
import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.api.changes.ApplyPatchPatchSetInput;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
import com.google.gerrit.extensions.api.changes.AttentionSetApi;
import com.google.gerrit.extensions.api.changes.AttentionSetInput;
import com.google.gerrit.extensions.api.changes.ChangeApi;
@@ -78,14 +77,11 @@
import com.google.gerrit.server.restapi.change.Check;
import com.google.gerrit.server.restapi.change.CheckSubmitRequirement;
import com.google.gerrit.server.restapi.change.CreateMergePatchSet;
-import com.google.gerrit.server.restapi.change.DeleteAssignee;
import com.google.gerrit.server.restapi.change.DeleteChange;
import com.google.gerrit.server.restapi.change.DeletePrivate;
-import com.google.gerrit.server.restapi.change.GetAssignee;
import com.google.gerrit.server.restapi.change.GetChange;
import com.google.gerrit.server.restapi.change.GetHashtags;
import com.google.gerrit.server.restapi.change.GetMetaDiff;
-import com.google.gerrit.server.restapi.change.GetPastAssignees;
import com.google.gerrit.server.restapi.change.GetPureRevert;
import com.google.gerrit.server.restapi.change.GetTopic;
import com.google.gerrit.server.restapi.change.Index;
@@ -97,7 +93,6 @@
import com.google.gerrit.server.restapi.change.PostHashtags;
import com.google.gerrit.server.restapi.change.PostPrivate;
import com.google.gerrit.server.restapi.change.PostReviewers;
-import com.google.gerrit.server.restapi.change.PutAssignee;
import com.google.gerrit.server.restapi.change.PutMessage;
import com.google.gerrit.server.restapi.change.PutTopic;
import com.google.gerrit.server.restapi.change.Rebase;
@@ -159,10 +154,6 @@
private final AttentionSet attentionSet;
private final AttentionSetApiImpl.Factory attentionSetApi;
private final AddToAttentionSet addToAttentionSet;
- private final PutAssignee putAssignee;
- private final GetAssignee getAssignee;
- private final GetPastAssignees getPastAssignees;
- private final DeleteAssignee deleteAssignee;
private final Provider<ListChangeComments> listCommentsProvider;
private final ListChangeRobotComments listChangeRobotComments;
private final Provider<ListChangeDrafts> listDraftsProvider;
@@ -213,10 +204,6 @@
AttentionSet attentionSet,
AttentionSetApiImpl.Factory attentionSetApi,
AddToAttentionSet addToAttentionSet,
- PutAssignee putAssignee,
- GetAssignee getAssignee,
- GetPastAssignees getPastAssignees,
- DeleteAssignee deleteAssignee,
Provider<ListChangeComments> listCommentsProvider,
ListChangeRobotComments listChangeRobotComments,
Provider<ListChangeDrafts> listDraftsProvider,
@@ -265,10 +252,6 @@
this.attentionSet = attentionSet;
this.attentionSetApi = attentionSetApi;
this.addToAttentionSet = addToAttentionSet;
- this.putAssignee = putAssignee;
- this.getAssignee = getAssignee;
- this.getPastAssignees = getPastAssignees;
- this.deleteAssignee = deleteAssignee;
this.listCommentsProvider = listCommentsProvider;
this.listChangeRobotComments = listChangeRobotComments;
this.listDraftsProvider = listDraftsProvider;
@@ -603,46 +586,6 @@
}
@Override
- public AccountInfo setAssignee(AssigneeInput input) throws RestApiException {
- try {
- return putAssignee.apply(change, input).value();
- } catch (Exception e) {
- throw asRestApiException("Cannot set assignee", e);
- }
- }
-
- @Nullable
- @Override
- public AccountInfo getAssignee() throws RestApiException {
- try {
- Response<AccountInfo> r = getAssignee.apply(change);
- return r.isNone() ? null : r.value();
- } catch (Exception e) {
- throw asRestApiException("Cannot get assignee", e);
- }
- }
-
- @Override
- public List<AccountInfo> getPastAssignees() throws RestApiException {
- try {
- return getPastAssignees.apply(change).value();
- } catch (Exception e) {
- throw asRestApiException("Cannot get past assignees", e);
- }
- }
-
- @Nullable
- @Override
- public AccountInfo deleteAssignee() throws RestApiException {
- try {
- Response<AccountInfo> r = deleteAssignee.apply(change, null);
- return r.isNone() ? null : r.value();
- } catch (Exception e) {
- throw asRestApiException("Cannot delete assignee", e);
- }
- }
-
- @Override
public CommentsRequest commentsRequest() {
return new CommentsRequest() {
@Override
diff --git a/java/com/google/gerrit/server/change/SetAssigneeOp.java b/java/com/google/gerrit/server/change/SetAssigneeOp.java
deleted file mode 100644
index fd3e972..0000000
--- a/java/com/google/gerrit/server/change/SetAssigneeOp.java
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (C) 2016 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.change;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.extensions.restapi.ResourceConflictException;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.extensions.events.AssigneeChanged;
-import com.google.gerrit.server.mail.send.MessageIdGenerator;
-import com.google.gerrit.server.mail.send.SetAssigneeSender;
-import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.plugincontext.PluginSetContext;
-import com.google.gerrit.server.update.BatchUpdateOp;
-import com.google.gerrit.server.update.ChangeContext;
-import com.google.gerrit.server.update.PostUpdateContext;
-import com.google.gerrit.server.util.AccountTemplateUtil;
-import com.google.gerrit.server.validators.AssigneeValidationListener;
-import com.google.gerrit.server.validators.ValidationException;
-import com.google.inject.Inject;
-import com.google.inject.Provider;
-import com.google.inject.assistedinject.Assisted;
-
-public class SetAssigneeOp implements BatchUpdateOp {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- public interface Factory {
- SetAssigneeOp create(IdentifiedUser assignee);
- }
-
- private final ChangeMessagesUtil cmUtil;
- private final PluginSetContext<AssigneeValidationListener> validationListeners;
- private final IdentifiedUser newAssignee;
- private final AssigneeChanged assigneeChanged;
- private final SetAssigneeSender.Factory setAssigneeSenderFactory;
- private final Provider<IdentifiedUser> user;
- private final IdentifiedUser.GenericFactory userFactory;
- private final MessageIdGenerator messageIdGenerator;
-
- private Change change;
- private IdentifiedUser oldAssignee;
-
- @Inject
- SetAssigneeOp(
- ChangeMessagesUtil cmUtil,
- PluginSetContext<AssigneeValidationListener> validationListeners,
- AssigneeChanged assigneeChanged,
- SetAssigneeSender.Factory setAssigneeSenderFactory,
- Provider<IdentifiedUser> user,
- IdentifiedUser.GenericFactory userFactory,
- MessageIdGenerator messageIdGenerator,
- @Assisted IdentifiedUser newAssignee) {
- this.cmUtil = cmUtil;
- this.validationListeners = validationListeners;
- this.assigneeChanged = assigneeChanged;
- this.setAssigneeSenderFactory = setAssigneeSenderFactory;
- this.user = user;
- this.userFactory = userFactory;
- this.messageIdGenerator = messageIdGenerator;
- this.newAssignee = requireNonNull(newAssignee, "assignee");
- }
-
- @Override
- public boolean updateChange(ChangeContext ctx) throws RestApiException {
- change = ctx.getChange();
- if (newAssignee.getAccountId().equals(change.getAssignee())) {
- return false;
- }
- try {
- validationListeners.runEach(
- l -> l.validateAssignee(change, newAssignee.getAccount()), ValidationException.class);
- } catch (ValidationException e) {
- throw new ResourceConflictException(e.getMessage(), e);
- }
-
- if (change.getAssignee() != null) {
- oldAssignee = userFactory.create(change.getAssignee());
- }
-
- ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
- // notedb
- update.setAssignee(newAssignee.getAccountId());
- // reviewdb
- change.setAssignee(newAssignee.getAccountId());
- addMessage(ctx);
- return true;
- }
-
- private void addMessage(ChangeContext ctx) {
- StringBuilder msg = new StringBuilder();
- msg.append("Assignee ");
- if (oldAssignee == null) {
- msg.append("added: ");
- msg.append(AccountTemplateUtil.getAccountTemplate(newAssignee.getAccountId()));
- } else {
- msg.append("changed from: ");
- msg.append(AccountTemplateUtil.getAccountTemplate(oldAssignee.getAccountId()));
- msg.append(" to: ");
- msg.append(AccountTemplateUtil.getAccountTemplate(newAssignee.getAccountId()));
- }
- cmUtil.setChangeMessage(ctx, msg.toString(), ChangeMessagesUtil.TAG_SET_ASSIGNEE);
- }
-
- @Override
- public void postUpdate(PostUpdateContext ctx) {
- try {
- SetAssigneeSender emailSender =
- setAssigneeSenderFactory.create(
- change.getProject(), change.getId(), newAssignee.getAccountId());
- emailSender.setFrom(user.get().getAccountId());
- emailSender.setMessageId(
- messageIdGenerator.fromChangeUpdate(ctx.getRepoView(), change.currentPatchSetId()));
- emailSender.send();
- } catch (Exception err) {
- logger.atSevere().withCause(err).log(
- "Cannot send email to new assignee of change %s", change.getId());
- }
- assigneeChanged.fire(
- ctx.getChangeData(change),
- ctx.getAccount(),
- oldAssignee != null ? oldAssignee.state() : null,
- ctx.getWhen());
- }
-}
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index f194434..ae6dcfd 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -36,7 +36,6 @@
import com.google.gerrit.extensions.events.AccountActivationListener;
import com.google.gerrit.extensions.events.AccountIndexedListener;
import com.google.gerrit.extensions.events.AgreementSignupListener;
-import com.google.gerrit.extensions.events.AssigneeChangedListener;
import com.google.gerrit.extensions.events.AttentionSetListener;
import com.google.gerrit.extensions.events.ChangeAbandonedListener;
import com.google.gerrit.extensions.events.ChangeDeletedListener;
@@ -222,7 +221,6 @@
import com.google.gerrit.server.util.IdGenerator;
import com.google.gerrit.server.util.ThreadLocalRequestContext;
import com.google.gerrit.server.validators.AccountActivationValidationListener;
-import com.google.gerrit.server.validators.AssigneeValidationListener;
import com.google.gerrit.server.validators.GroupCreationValidationListener;
import com.google.gerrit.server.validators.HashtagValidationListener;
import com.google.gerrit.server.validators.OutgoingEmailValidationListener;
@@ -360,7 +358,6 @@
DynamicMap.mapOf(binder(), PluginProjectPermissionDefinition.class);
DynamicSet.setOf(binder(), GitReferenceUpdatedListener.class);
DynamicSet.setOf(binder(), GitBatchRefUpdateListener.class);
- DynamicSet.setOf(binder(), AssigneeChangedListener.class);
DynamicSet.setOf(binder(), ChangeAbandonedListener.class);
DynamicSet.setOf(binder(), ChangeDeletedListener.class);
DynamicSet.setOf(binder(), CommentAddedListener.class);
@@ -441,7 +438,6 @@
DynamicSet.setOf(binder(), AccountExternalIdCreator.class);
DynamicSet.setOf(binder(), WebUiPlugin.class);
DynamicItem.itemOf(binder(), AccountPatchReviewStore.class);
- DynamicSet.setOf(binder(), AssigneeValidationListener.class);
DynamicSet.setOf(binder(), ActionVisitor.class);
DynamicItem.itemOf(binder(), MergeSuperSetComputation.class);
DynamicItem.itemOf(binder(), ProjectNameLockManager.class);
diff --git a/java/com/google/gerrit/server/data/ChangeAttribute.java b/java/com/google/gerrit/server/data/ChangeAttribute.java
index ec27c0c..cdc982f 100644
--- a/java/com/google/gerrit/server/data/ChangeAttribute.java
+++ b/java/com/google/gerrit/server/data/ChangeAttribute.java
@@ -32,7 +32,6 @@
public int number;
public String subject;
public AccountAttribute owner;
- public AccountAttribute assignee;
public String url;
public String commitMessage;
public List<String> hashtags;
diff --git a/java/com/google/gerrit/server/edit/ChangeEditModifier.java b/java/com/google/gerrit/server/edit/ChangeEditModifier.java
index 903a4c0..ad0dd8b 100644
--- a/java/com/google/gerrit/server/edit/ChangeEditModifier.java
+++ b/java/com/google/gerrit/server/edit/ChangeEditModifier.java
@@ -34,12 +34,14 @@
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.PatchSetUtil;
+import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.edit.tree.ChangeFileContentModification;
import com.google.gerrit.server.edit.tree.DeleteFileModification;
import com.google.gerrit.server.edit.tree.RenameFileModification;
import com.google.gerrit.server.edit.tree.RestoreFileModification;
import com.google.gerrit.server.edit.tree.TreeCreator;
import com.google.gerrit.server.edit.tree.TreeModification;
+import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.permissions.ChangePermission;
@@ -108,15 +110,15 @@
PermissionBackend permissionBackend,
ChangeEditUtil changeEditUtil,
PatchSetUtil patchSetUtil,
- ProjectCache projectCache) {
+ ProjectCache projectCache,
+ GitReferenceUpdated gitReferenceUpdated) {
this.currentUser = currentUser;
this.permissionBackend = permissionBackend;
this.zoneId = gerritIdent.getZoneId();
this.changeEditUtil = changeEditUtil;
this.patchSetUtil = patchSetUtil;
this.projectCache = projectCache;
-
- noteDbEdits = new NoteDbEdits(zoneId, indexer, currentUser);
+ noteDbEdits = new NoteDbEdits(gitReferenceUpdated, zoneId, indexer, currentUser);
}
/**
@@ -173,10 +175,14 @@
notes.getChangeId(), currentPatchSet.id()));
}
- rebase(repository, changeEdit, currentPatchSet);
+ rebase(notes.getProjectName(), repository, changeEdit, currentPatchSet);
}
- private void rebase(Repository repository, ChangeEdit changeEdit, PatchSet currentPatchSet)
+ private void rebase(
+ Project.NameKey project,
+ Repository repository,
+ ChangeEdit changeEdit,
+ PatchSet currentPatchSet)
throws IOException, MergeConflictException, InvalidChangeOperationException {
RevCommit currentEditCommit = changeEdit.getEditCommit();
if (currentEditCommit.getParentCount() == 0) {
@@ -194,7 +200,13 @@
createCommit(repository, basePatchSetCommit, newTreeId, commitMessage, nowTimestamp);
noteDbEdits.baseEditOnDifferentPatchset(
- repository, changeEdit, currentPatchSet, currentEditCommit, newEditCommitId, nowTimestamp);
+ project,
+ repository,
+ changeEdit,
+ currentPatchSet,
+ currentEditCommit,
+ newEditCommitId,
+ nowTimestamp);
}
/**
@@ -719,11 +731,17 @@
private final ZoneId zoneId;
private final ChangeIndexer indexer;
private final Provider<CurrentUser> currentUser;
+ private final GitReferenceUpdated gitReferenceUpdated;
- NoteDbEdits(ZoneId zoneId, ChangeIndexer indexer, Provider<CurrentUser> currentUser) {
+ NoteDbEdits(
+ GitReferenceUpdated gitReferenceUpdated,
+ ZoneId zoneId,
+ ChangeIndexer indexer,
+ Provider<CurrentUser> currentUser) {
this.zoneId = zoneId;
this.indexer = indexer;
this.currentUser = currentUser;
+ this.gitReferenceUpdated = gitReferenceUpdated;
}
ChangeEdit createEdit(
@@ -753,6 +771,10 @@
return RefNames.refsEdit(me.getAccountId(), change.getId(), basePatchset.id());
}
+ private AccountState getUpdater() {
+ return currentUser.get().asIdentifiedUser().state();
+ }
+
ChangeEdit updateEdit(
Project.NameKey projectName,
Repository repository,
@@ -795,9 +817,11 @@
throw new IOException(message);
}
}
+ gitReferenceUpdated.fire(projectName, ru, getUpdater());
}
void baseEditOnDifferentPatchset(
+ Project.NameKey project,
Repository repository,
ChangeEdit changeEdit,
PatchSet currentPatchSet,
@@ -807,6 +831,7 @@
throws IOException {
String newEditRefName = getEditRefName(changeEdit.getChange(), currentPatchSet);
updateReferenceWithNameChange(
+ project,
repository,
changeEdit.getRefName(),
currentEditCommit,
@@ -817,6 +842,7 @@
}
private void updateReferenceWithNameChange(
+ Project.NameKey projectName,
Repository repository,
String currentRefName,
ObjectId currentObjectId,
@@ -838,6 +864,7 @@
throw new IOException("failed: " + cmd);
}
}
+ gitReferenceUpdated.fire(projectName, batchRefUpdate, getUpdater());
}
static RevCommit lookupCommit(Repository repository, ObjectId commitId) throws IOException {
diff --git a/java/com/google/gerrit/server/edit/ChangeEditUtil.java b/java/com/google/gerrit/server/edit/ChangeEditUtil.java
index 74834ab..3474590 100644
--- a/java/com/google/gerrit/server/edit/ChangeEditUtil.java
+++ b/java/com/google/gerrit/server/edit/ChangeEditUtil.java
@@ -32,6 +32,7 @@
import com.google.gerrit.server.change.ChangeKindCache;
import com.google.gerrit.server.change.NotifyResolver;
import com.google.gerrit.server.change.PatchSetInserter;
+import com.google.gerrit.server.extensions.events.GitReferenceUpdated;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.index.change.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeNotes;
@@ -70,6 +71,8 @@
private final ChangeKindCache changeKindCache;
private final PatchSetUtil psUtil;
+ private final GitReferenceUpdated gitReferenceUpdated;
+
@Inject
ChangeEditUtil(
GitRepositoryManager gitManager,
@@ -77,13 +80,15 @@
ChangeIndexer indexer,
Provider<CurrentUser> userProvider,
ChangeKindCache changeKindCache,
- PatchSetUtil psUtil) {
+ PatchSetUtil psUtil,
+ GitReferenceUpdated gitReferenceUpdated) {
this.gitManager = gitManager;
this.patchSetInserterFactory = patchSetInserterFactory;
this.indexer = indexer;
this.userProvider = userProvider;
this.changeKindCache = changeKindCache;
this.psUtil = psUtil;
+ this.gitReferenceUpdated = gitReferenceUpdated;
}
/**
@@ -237,7 +242,7 @@
return writeSquashedCommit(rw, inserter, parent, edit);
}
- private static void deleteRef(Repository repo, ChangeEdit edit) throws IOException {
+ private void deleteRef(Repository repo, ChangeEdit edit) throws IOException {
String refName = edit.getRefName();
RefUpdate ru = repo.updateRef(refName, true);
ru.setExpectedOldObjectId(edit.getEditCommit());
@@ -261,6 +266,10 @@
default:
throw new IOException(String.format("Failed to delete ref %s: %s", refName, result));
}
+ gitReferenceUpdated.fire(
+ edit.getChange().getProject(),
+ ru,
+ /* updater= */ userProvider.get().asIdentifiedUser().state());
}
private static RevCommit writeSquashedCommit(
diff --git a/java/com/google/gerrit/server/events/AssigneeChangedEvent.java b/java/com/google/gerrit/server/events/AssigneeChangedEvent.java
deleted file mode 100644
index 490d6d14..0000000
--- a/java/com/google/gerrit/server/events/AssigneeChangedEvent.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (C) 2016 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.events;
-
-import com.google.common.base.Supplier;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.server.data.AccountAttribute;
-
-public class AssigneeChangedEvent extends ChangeEvent {
- static final String TYPE = "assignee-changed";
- public Supplier<AccountAttribute> changer;
- public Supplier<AccountAttribute> oldAssignee;
-
- public AssigneeChangedEvent(Change change) {
- super(TYPE, change);
- }
-}
diff --git a/java/com/google/gerrit/server/events/EventFactory.java b/java/com/google/gerrit/server/events/EventFactory.java
index cd7e29a..14aadf47 100644
--- a/java/com/google/gerrit/server/events/EventFactory.java
+++ b/java/com/google/gerrit/server/events/EventFactory.java
@@ -133,7 +133,6 @@
a.subject = change.getSubject();
a.url = getChangeUrl(change);
a.owner = asAccountAttribute(change.getOwner(), accountLoader);
- a.assignee = asAccountAttribute(change.getAssignee(), accountLoader);
a.status = change.getStatus();
a.createdOn = change.getCreatedOn().getEpochSecond();
a.wip = change.isWorkInProgress() ? true : null;
diff --git a/java/com/google/gerrit/server/events/EventTypes.java b/java/com/google/gerrit/server/events/EventTypes.java
index 229ef86..e24bbd2 100644
--- a/java/com/google/gerrit/server/events/EventTypes.java
+++ b/java/com/google/gerrit/server/events/EventTypes.java
@@ -23,7 +23,6 @@
private static final Map<String, Class<?>> typesByString = new HashMap<>();
static {
- register(AssigneeChangedEvent.TYPE, AssigneeChangedEvent.class);
register(ChangeAbandonedEvent.TYPE, ChangeAbandonedEvent.class);
register(ChangeDeletedEvent.TYPE, ChangeDeletedEvent.class);
register(ChangeMergedEvent.TYPE, ChangeMergedEvent.class);
diff --git a/java/com/google/gerrit/server/events/StreamEventsApiListener.java b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
index 18f3d7a..50c15b7 100644
--- a/java/com/google/gerrit/server/events/StreamEventsApiListener.java
+++ b/java/com/google/gerrit/server/events/StreamEventsApiListener.java
@@ -32,7 +32,6 @@
import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
import com.google.gerrit.extensions.common.RevisionInfo;
-import com.google.gerrit.extensions.events.AssigneeChangedListener;
import com.google.gerrit.extensions.events.ChangeAbandonedListener;
import com.google.gerrit.extensions.events.ChangeDeletedListener;
import com.google.gerrit.extensions.events.ChangeMergedListener;
@@ -73,8 +72,7 @@
@Singleton
public class StreamEventsApiListener
- implements AssigneeChangedListener,
- ChangeAbandonedListener,
+ implements ChangeAbandonedListener,
ChangeDeletedListener,
ChangeMergedListener,
ChangeRestoredListener,
@@ -95,7 +93,6 @@
public static class StreamEventsApiListenerModule extends AbstractModule {
@Override
protected void configure() {
- DynamicSet.bind(binder(), AssigneeChangedListener.class).to(StreamEventsApiListener.class);
DynamicSet.bind(binder(), ChangeAbandonedListener.class).to(StreamEventsApiListener.class);
DynamicSet.bind(binder(), ChangeDeletedListener.class).to(StreamEventsApiListener.class);
DynamicSet.bind(binder(), ChangeMergedListener.class).to(StreamEventsApiListener.class);
@@ -244,23 +241,6 @@
}
@Override
- public void onAssigneeChanged(AssigneeChangedListener.Event ev) {
- try {
- ChangeNotes notes = getNotes(ev.getChange());
- Change change = notes.getChange();
- AssigneeChangedEvent event = new AssigneeChangedEvent(change);
-
- event.change = changeAttributeSupplier(change, notes);
- event.changer = accountAttributeSupplier(ev.getWho());
- event.oldAssignee = accountAttributeSupplier(ev.getOldAssignee());
-
- dispatcher.run(d -> d.postEvent(change, event));
- } catch (StorageException e) {
- logger.atSevere().withCause(e).log("Failed to dispatch event");
- }
- }
-
- @Override
public void onTopicEdited(TopicEditedListener.Event ev) {
try {
ChangeNotes notes = getNotes(ev.getChange());
diff --git a/java/com/google/gerrit/server/extensions/events/AssigneeChanged.java b/java/com/google/gerrit/server/extensions/events/AssigneeChanged.java
deleted file mode 100644
index 8e4d1e2..0000000
--- a/java/com/google/gerrit/server/extensions/events/AssigneeChanged.java
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (C) 2016 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.extensions.events;
-
-import com.google.common.flogger.FluentLogger;
-import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.common.ChangeInfo;
-import com.google.gerrit.extensions.events.AssigneeChangedListener;
-import com.google.gerrit.server.account.AccountState;
-import com.google.gerrit.server.plugincontext.PluginSetContext;
-import com.google.gerrit.server.query.change.ChangeData;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.time.Instant;
-
-/** Helper class to fire an event when a user has been set as assignee on a change. */
-@Singleton
-public class AssigneeChanged {
- private static final FluentLogger logger = FluentLogger.forEnclosingClass();
-
- private final PluginSetContext<AssigneeChangedListener> listeners;
- private final EventUtil util;
-
- @Inject
- AssigneeChanged(PluginSetContext<AssigneeChangedListener> listeners, EventUtil util) {
- this.listeners = listeners;
- this.util = util;
- }
-
- public void fire(
- ChangeData changeData, AccountState accountState, AccountState oldAssignee, Instant when) {
- if (listeners.isEmpty()) {
- return;
- }
- try {
- Event event =
- new Event(
- util.changeInfo(changeData),
- util.accountInfo(accountState),
- util.accountInfo(oldAssignee),
- when);
- listeners.runEach(l -> l.onAssigneeChanged(event));
- } catch (StorageException e) {
- logger.atSevere().withCause(e).log("Couldn't fire event");
- }
- }
-
- /** Event to be fired when a user has been set as assignee on a change. */
- private static class Event extends AbstractChangeEvent implements AssigneeChangedListener.Event {
- private final AccountInfo oldAssignee;
-
- Event(ChangeInfo change, AccountInfo editor, AccountInfo oldAssignee, Instant when) {
- super(change, editor, when, NotifyHandling.ALL);
- this.oldAssignee = oldAssignee;
- }
-
- @Override
- public AccountInfo getOldAssignee() {
- return oldAssignee;
- }
- }
-}
diff --git a/java/com/google/gerrit/server/index/change/ChangeField.java b/java/com/google/gerrit/server/index/change/ChangeField.java
index 2045dba..8e443f82 100644
--- a/java/com/google/gerrit/server/index/change/ChangeField.java
+++ b/java/com/google/gerrit/server/index/change/ChangeField.java
@@ -504,9 +504,9 @@
ATTENTION_SET_FULL_FIELD.storedOnly(ChangeQueryBuilder.FIELD_ATTENTION_SET_FULL);
/** The user assigned to the change. */
+ // The getter always returns NO_ASSIGNEE, since assignee field is deprecated.
public static final IndexedField<ChangeData, Integer> ASSIGNEE_FIELD =
- IndexedField.<ChangeData>integerBuilder("Assignee")
- .build(changeGetter(c -> c.getAssignee() != null ? c.getAssignee().get() : NO_ASSIGNEE));
+ IndexedField.<ChangeData>integerBuilder("Assignee").build(changeGetter(c -> NO_ASSIGNEE));
public static final IndexedField<ChangeData, Integer>.SearchSpec ASSIGNEE_SPEC =
ASSIGNEE_FIELD.integer(ChangeQueryBuilder.FIELD_ASSIGNEE);
diff --git a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
index 895c4d8..6ddf7a3 100644
--- a/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
+++ b/java/com/google/gerrit/server/index/change/ChangeSchemaDefinitions.java
@@ -232,12 +232,21 @@
.build();
/** Add prefixsubject field. */
+ @Deprecated
static final Schema<ChangeData> V81 =
new Schema.Builder<ChangeData>()
.add(V80)
.addSearchSpecs(ChangeField.PREFIX_SUBJECT_SPEC)
.build();
+ /** Remove assignee field. */
+ static final Schema<ChangeData> V82 =
+ new Schema.Builder<ChangeData>()
+ .add(V81)
+ .remove(ChangeField.ASSIGNEE_SPEC)
+ .remove(ChangeField.ASSIGNEE_FIELD)
+ .build();
+
/**
* Name of the change index to be used when contacting index backends or loading configurations.
*/
diff --git a/java/com/google/gerrit/server/mail/EmailModule.java b/java/com/google/gerrit/server/mail/EmailModule.java
index c659b5f..50f26bb 100644
--- a/java/com/google/gerrit/server/mail/EmailModule.java
+++ b/java/com/google/gerrit/server/mail/EmailModule.java
@@ -31,7 +31,6 @@
import com.google.gerrit.server.mail.send.ReplacePatchSetSender;
import com.google.gerrit.server.mail.send.RestoredSender;
import com.google.gerrit.server.mail.send.RevertedSender;
-import com.google.gerrit.server.mail.send.SetAssigneeSender;
public class EmailModule extends FactoryModule {
@Override
@@ -50,7 +49,6 @@
factory(ReplacePatchSetSender.Factory.class);
factory(RestoredSender.Factory.class);
factory(RevertedSender.Factory.class);
- factory(SetAssigneeSender.Factory.class);
factory(AddToAttentionSetSender.Factory.class);
factory(RemoveFromAttentionSetSender.Factory.class);
}
diff --git a/java/com/google/gerrit/server/mail/EmailSettings.java b/java/com/google/gerrit/server/mail/EmailSettings.java
index 15b61d0..c411af5 100644
--- a/java/com/google/gerrit/server/mail/EmailSettings.java
+++ b/java/com/google/gerrit/server/mail/EmailSettings.java
@@ -38,7 +38,6 @@
public final Encryption encryption;
public final long fetchInterval; // in milliseconds
public final boolean sendNewPatchsetEmails;
- public final boolean isAttentionSetEnabled;
@Inject
EmailSettings(@GerritServerConfig Config cfg) {
@@ -61,6 +60,5 @@
TimeUnit.MILLISECONDS.convert(60, TimeUnit.SECONDS),
TimeUnit.MILLISECONDS);
sendNewPatchsetEmails = cfg.getBoolean("change", null, "sendNewPatchsetEmails", true);
- isAttentionSetEnabled = cfg.getBoolean("change", null, "enableAttentionSet", true);
}
}
diff --git a/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
index 8be5548..7bbee2a 100644
--- a/java/com/google/gerrit/server/mail/send/ChangeEmail.java
+++ b/java/com/google/gerrit/server/mail/send/ChangeEmail.java
@@ -546,9 +546,6 @@
footers.add(MailHeader.CHANGE_NUMBER.withDelimiter() + change.getChangeId());
footers.add(MailHeader.PATCH_SET.withDelimiter() + patchSet.number());
footers.add(MailHeader.OWNER.withDelimiter() + getNameEmailFor(change.getOwner()));
- if (change.getAssignee() != null) {
- footers.add(MailHeader.ASSIGNEE.withDelimiter() + getNameEmailFor(change.getAssignee()));
- }
for (String reviewer : getEmailsByState(ReviewerStateInternal.REVIEWER)) {
footers.add(MailHeader.REVIEWER.withDelimiter() + reviewer);
}
@@ -558,8 +555,7 @@
for (Account.Id attentionUser : currentAttentionSet) {
footers.add(MailHeader.ATTENTION.withDelimiter() + getNameEmailFor(attentionUser));
}
- // Since this would be user visible, only show it if attention set is enabled
- if (args.settings.isAttentionSetEnabled && !currentAttentionSet.isEmpty()) {
+ if (!currentAttentionSet.isEmpty()) {
// We need names rather than account ids / emails to make it user readable.
soyContext.put(
"attentionSet",
diff --git a/java/com/google/gerrit/server/mail/send/MailSoySauceLoader.java b/java/com/google/gerrit/server/mail/send/MailSoySauceLoader.java
index 9d75abd..ce54708 100644
--- a/java/com/google/gerrit/server/mail/send/MailSoySauceLoader.java
+++ b/java/com/google/gerrit/server/mail/send/MailSoySauceLoader.java
@@ -88,8 +88,6 @@
"RestoredHtml.soy",
"Reverted.soy",
"RevertedHtml.soy",
- "SetAssignee.soy",
- "SetAssigneeHtml.soy",
};
private static final SoySauce DEFAULT = getDefault().build().compileTemplates();
diff --git a/java/com/google/gerrit/server/mail/send/SetAssigneeSender.java b/java/com/google/gerrit/server/mail/send/SetAssigneeSender.java
deleted file mode 100644
index 29f4c69..0000000
--- a/java/com/google/gerrit/server/mail/send/SetAssigneeSender.java
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright (C) 2016 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.mail.send;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.entities.Project;
-import com.google.gerrit.exceptions.EmailException;
-import com.google.gerrit.extensions.api.changes.RecipientType;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-
-/**
- * Sender that informs a user by email that they were set as assignee on a change.
- *
- * <p>In contrast to other change emails this email is not sent to the change authors (owner, patch
- * set uploader, author). This is why this class extends {@link ChangeEmail} directly, instead of
- * extending {@link ReplyToChangeSender}.
- */
-public class SetAssigneeSender extends ChangeEmail {
- public interface Factory {
- SetAssigneeSender create(Project.NameKey project, Change.Id changeId, Account.Id assignee);
- }
-
- private final Account.Id assignee;
-
- @Inject
- public SetAssigneeSender(
- EmailArguments args,
- @Assisted Project.NameKey project,
- @Assisted Change.Id changeId,
- @Assisted Account.Id assignee) {
- super(args, "setassignee", newChangeData(args, project, changeId));
- this.assignee = assignee;
- }
-
- @Override
- protected void init() throws EmailException {
- super.init();
-
- add(RecipientType.TO, assignee);
- }
-
- @Override
- protected void formatChange() throws EmailException {
- appendText(textTemplate("SetAssignee"));
- if (useHtml()) {
- appendHtml(soyHtmlTemplate("SetAssigneeHtml"));
- }
- }
-
- @Override
- protected void setupSoyContext() {
- super.setupSoyContext();
- soyContextEmailData.put("assigneeName", getNameFor(assignee));
- }
-}
diff --git a/java/com/google/gerrit/server/notedb/ChangeNoteFooters.java b/java/com/google/gerrit/server/notedb/ChangeNoteFooters.java
index 771d72b..3be55ea 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNoteFooters.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNoteFooters.java
@@ -19,7 +19,6 @@
/** Footers, that can be set in NoteDb commits. */
public class ChangeNoteFooters {
public static final FooterKey FOOTER_ATTENTION = new FooterKey("Attention");
- public static final FooterKey FOOTER_ASSIGNEE = new FooterKey("Assignee");
public static final FooterKey FOOTER_BRANCH = new FooterKey("Branch");
public static final FooterKey FOOTER_CHANGE_ID = new FooterKey("Change-id");
public static final FooterKey FOOTER_COMMIT = new FooterKey("Commit");
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotes.java b/java/com/google/gerrit/server/notedb/ChangeNotes.java
index 52f540d..c75fd29 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotes.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotes.java
@@ -16,7 +16,6 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
-import static com.google.common.collect.ImmutableSet.toImmutableSet;
import static com.google.gerrit.entities.RefNames.changeMetaRef;
import static java.util.Comparator.comparing;
@@ -29,7 +28,6 @@
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
@@ -53,7 +51,6 @@
import com.google.gerrit.entities.RobotComment;
import com.google.gerrit.entities.SubmitRecord;
import com.google.gerrit.entities.SubmitRequirementResult;
-import com.google.gerrit.server.AssigneeStatusUpdate;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate;
@@ -498,26 +495,6 @@
return state.submitRequirementsResult();
}
- /**
- * Returns an ImmutableSet of Account.Ids of all users that have been assigned to this change. The
- * order of the set is the order in which they were assigned.
- */
- public ImmutableSet<Account.Id> getPastAssignees() {
- return Lists.reverse(state.assigneeUpdates()).stream()
- .map(AssigneeStatusUpdate::currentAssignee)
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(toImmutableSet());
- }
-
- /**
- * Returns an ImmutableList of AssigneeStatusUpdate of all the updates to the assignee field to
- * this change. The order of the list is from most recent updates to least recent.
- */
- public ImmutableList<AssigneeStatusUpdate> getAssigneeUpdates() {
- return state.assigneeUpdates();
- }
-
/** Returns an ImmutableSet of all hashtags for this change sorted in alphabetical order. */
public ImmutableSet<String> getHashtags() {
return ImmutableSortedSet.copyOf(state.hashtags());
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesCache.java b/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
index 0f2c877..2d3902c 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesCache.java
@@ -181,8 +181,6 @@
+ P
+ list(state.reviewerUpdates(), 4 * O + K + K + P)
+ P
- + list(state.assigneeUpdates(), 4 * O + K + K)
- + P
+ set(state.attentionSet(), 4 * O + K + I + str(15))
+ P
+ list(state.allAttentionSetUpdates(), 4 * O + K + I + str(15))
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
index 467095c..0ee0689 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesParser.java
@@ -15,7 +15,6 @@
package com.google.gerrit.server.notedb;
import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ASSIGNEE;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ATTENTION;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_BRANCH;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_CHANGE_ID;
@@ -75,7 +74,6 @@
import com.google.gerrit.entities.SubmitRecord.Label.Status;
import com.google.gerrit.entities.SubmitRequirementResult;
import com.google.gerrit.metrics.Timer0;
-import com.google.gerrit.server.AssigneeStatusUpdate;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate;
@@ -160,7 +158,6 @@
/** Holds all updates to attention set. */
private final List<AttentionSetUpdate> allAttentionSetUpdates;
- private final List<AssigneeStatusUpdate> assigneeUpdates;
private final List<SubmitRecord> submitRecords;
private final ListMultimap<ObjectId, HumanComment> humanComments;
private final List<SubmitRequirementResult> submitRequirementResults;
@@ -228,7 +225,6 @@
reviewerUpdates = new ArrayList<>();
latestAttentionStatus = new HashMap<>();
allAttentionSetUpdates = new ArrayList<>();
- assigneeUpdates = new ArrayList<>();
submitRecords = Lists.newArrayListWithExpectedSize(1);
allChangeMessages = new ArrayList<>();
humanComments = MultimapBuilder.hashKeys().arrayListValues().build();
@@ -301,7 +297,6 @@
buildReviewerUpdates(),
ImmutableSet.copyOf(latestAttentionStatus.values()),
allAttentionSetUpdates,
- assigneeUpdates,
submitRecords,
buildAllMessages(),
humanComments,
@@ -496,7 +491,6 @@
parseHashtags(commit);
parseAttentionSetUpdates(commit);
- parseAssigneeUpdates(commitTimestamp, commit);
parseSubmission(commit, commitTimestamp);
@@ -745,22 +739,6 @@
}
}
- private void parseAssigneeUpdates(Instant ts, ChangeNotesCommit commit)
- throws ConfigInvalidException {
- String assigneeValue = parseOneFooter(commit, FOOTER_ASSIGNEE);
- if (assigneeValue != null) {
- Optional<Account.Id> parsedAssignee;
- if (assigneeValue.equals("")) {
- // Empty footer found, assignee deleted
- parsedAssignee = Optional.empty();
- } else {
- PersonIdent ident = RawParseUtils.parsePersonIdent(assigneeValue);
- parsedAssignee = Optional.ofNullable(parseIdent(ident));
- }
- assigneeUpdates.add(AssigneeStatusUpdate.create(ts, ownerId, parsedAssignee));
- }
- }
-
private void parseTag(ChangeNotesCommit commit) throws ConfigInvalidException {
tag = null;
List<String> tagLines = commit.getFooterLineValues(FOOTER_TAG);
diff --git a/java/com/google/gerrit/server/notedb/ChangeNotesState.java b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
index b0079d7..1715b43 100644
--- a/java/com/google/gerrit/server/notedb/ChangeNotesState.java
+++ b/java/com/google/gerrit/server/notedb/ChangeNotesState.java
@@ -50,12 +50,10 @@
import com.google.gerrit.entities.converter.PatchSetProtoConverter;
import com.google.gerrit.json.OutputFormat;
import com.google.gerrit.proto.Protos;
-import com.google.gerrit.server.AssigneeStatusUpdate;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto;
-import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.AssigneeStatusUpdateProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.AttentionSetUpdateProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ChangeColumnsProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerByEmailSetEntryProto;
@@ -68,7 +66,6 @@
import java.time.Instant;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
import org.eclipse.jgit.lib.ObjectId;
@@ -124,7 +121,6 @@
List<ReviewerStatusUpdate> reviewerUpdates,
Set<AttentionSetUpdate> attentionSetUpdates,
List<AttentionSetUpdate> allAttentionSetUpdates,
- List<AssigneeStatusUpdate> assigneeUpdates,
List<SubmitRecord> submitRecords,
List<ChangeMessage> changeMessages,
ListMultimap<ObjectId, HumanComment> publishedComments,
@@ -178,7 +174,6 @@
.reviewerUpdates(reviewerUpdates)
.attentionSet(attentionSetUpdates)
.allAttentionSetUpdates(allAttentionSetUpdates)
- .assigneeUpdates(assigneeUpdates)
.submitRecords(submitRecords)
.changeMessages(changeMessages)
.publishedComments(publishedComments)
@@ -320,8 +315,6 @@
/** Returns all attention set updates. */
abstract ImmutableList<AttentionSetUpdate> allAttentionSetUpdates();
- abstract ImmutableList<AssigneeStatusUpdate> assigneeUpdates();
-
abstract ImmutableList<SubmitRecord> submitRecords();
abstract ImmutableList<ChangeMessage> changeMessages();
@@ -369,9 +362,6 @@
change.setTopic(Strings.emptyToNull(c.topic()));
change.setLastUpdatedOn(c.lastUpdatedOn());
change.setSubmissionId(c.submissionId());
- if (!assigneeUpdates().isEmpty()) {
- change.setAssignee(assigneeUpdates().get(0).currentAssignee().orElse(null));
- }
change.setPrivate(c.isPrivate());
change.setWorkInProgress(c.workInProgress());
change.setReviewStarted(c.reviewStarted());
@@ -404,7 +394,6 @@
.reviewerUpdates(ImmutableList.of())
.attentionSet(ImmutableSet.of())
.allAttentionSetUpdates(ImmutableList.of())
- .assigneeUpdates(ImmutableList.of())
.submitRecords(ImmutableList.of())
.changeMessages(ImmutableList.of())
.publishedComments(ImmutableListMultimap.of())
@@ -442,8 +431,6 @@
abstract Builder allAttentionSetUpdates(List<AttentionSetUpdate> attentionSetUpdates);
- abstract Builder assigneeUpdates(List<AssigneeStatusUpdate> assigneeUpdates);
-
abstract Builder submitRecords(List<SubmitRecord> submitRecords);
abstract Builder changeMessages(List<ChangeMessage> changeMessages);
@@ -519,7 +506,6 @@
object
.allAttentionSetUpdates()
.forEach(u -> b.addAllAttentionSetUpdate(toAttentionSetUpdateProto(u)));
- object.assigneeUpdates().forEach(u -> b.addAssigneeUpdate(toAssigneeStatusUpdateProto(u)));
object
.submitRecords()
.forEach(r -> b.addSubmitRecord(GSON.toJson(new StoredSubmitRecord(r))));
@@ -616,17 +602,6 @@
.build();
}
- private static AssigneeStatusUpdateProto toAssigneeStatusUpdateProto(AssigneeStatusUpdate u) {
- AssigneeStatusUpdateProto.Builder builder =
- AssigneeStatusUpdateProto.newBuilder()
- .setTimestampMillis(u.date().toEpochMilli())
- .setUpdatedBy(u.updatedBy().get())
- .setHasCurrentAssignee(u.currentAssignee().isPresent());
-
- u.currentAssignee().ifPresent(assignee -> builder.setCurrentAssignee(assignee.get()));
- return builder.build();
- }
-
@Override
public ChangeNotesState deserialize(byte[] in) {
ChangeNotesStateProto proto = Protos.parseUnchecked(ChangeNotesStateProto.parser(), in);
@@ -659,7 +634,6 @@
.attentionSet(toAttentionSetUpdates(proto.getAttentionSetUpdateList()))
.allAttentionSetUpdates(
toAllAttentionSetUpdates(proto.getAllAttentionSetUpdateList()))
- .assigneeUpdates(toAssigneeStatusUpdateList(proto.getAssigneeUpdateList()))
.submitRecords(
proto.getSubmitRecordList().stream()
.map(r -> GSON.fromJson(r, StoredSubmitRecord.class).toSubmitRecord())
@@ -783,20 +757,5 @@
}
return b.build();
}
-
- private static ImmutableList<AssigneeStatusUpdate> toAssigneeStatusUpdateList(
- List<AssigneeStatusUpdateProto> protos) {
- ImmutableList.Builder<AssigneeStatusUpdate> b = ImmutableList.builder();
- for (AssigneeStatusUpdateProto proto : protos) {
- b.add(
- AssigneeStatusUpdate.create(
- Instant.ofEpochMilli(proto.getTimestampMillis()),
- Account.id(proto.getUpdatedBy()),
- proto.getHasCurrentAssignee()
- ? Optional.of(Account.id(proto.getCurrentAssignee()))
- : Optional.empty()));
- }
- return b.build();
- }
}
}
diff --git a/java/com/google/gerrit/server/notedb/ChangeUpdate.java b/java/com/google/gerrit/server/notedb/ChangeUpdate.java
index 5d43e28..ef62f2e 100644
--- a/java/com/google/gerrit/server/notedb/ChangeUpdate.java
+++ b/java/com/google/gerrit/server/notedb/ChangeUpdate.java
@@ -18,7 +18,6 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState;
import static com.google.gerrit.entities.RefNames.changeMetaRef;
-import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ASSIGNEE;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ATTENTION;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_BRANCH;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_CHANGE_ID;
@@ -160,7 +159,6 @@
private String commit;
private Map<Account.Id, AttentionSetUpdate> plannedAttentionSetUpdates;
private boolean ignoreFurtherAttentionSetUpdates;
- private Optional<Account.Id> assignee;
private Set<String> hashtags;
private String changeMessage;
private String tag;
@@ -510,15 +508,6 @@
return attentionSetUpdatesBuilder.build();
}
- public void setAssignee(Account.Id assignee) {
- checkArgument(assignee != null, "use removeAssignee");
- this.assignee = Optional.of(assignee);
- }
-
- public void removeAssignee() {
- this.assignee = Optional.empty();
- }
-
public Map<Account.Id, ReviewerStateInternal> getReviewers() {
return reviewers;
}
@@ -765,15 +754,6 @@
addFooter(msg, FOOTER_COMMIT, commit);
}
- if (assignee != null) {
- if (assignee.isPresent()) {
- addFooter(msg, FOOTER_ASSIGNEE);
- noteUtil.appendAccountIdIdentString(msg, assignee.get()).append('\n');
- } else {
- addFooter(msg, FOOTER_ASSIGNEE).append('\n');
- }
- }
-
Joiner comma = Joiner.on(',');
if (hashtags != null) {
addFooter(msg, FOOTER_HASHTAGS, comma.join(hashtags));
@@ -1101,7 +1081,7 @@
// remove users that are currently being removed from the attention set.
.filter(
a ->
- plannedAttentionSetUpdates.getOrDefault(a, /*defaultValue= */ null) == null
+ plannedAttentionSetUpdates.getOrDefault(a, /* defaultValue= */ null) == null
|| plannedAttentionSetUpdates.get(a).operation().equals(Operation.REMOVE))
// remove users that are still active on the change.
.filter(a -> !isActiveOnChange(currentReviewers, a))
@@ -1173,7 +1153,6 @@
&& status == null
&& submissionId == null
&& submitRecords == null
- && assignee == null
&& hashtags == null
&& topic == null
&& commit == null
diff --git a/java/com/google/gerrit/server/notedb/CommitRewriter.java b/java/com/google/gerrit/server/notedb/CommitRewriter.java
index a67dc07..4d71d84 100644
--- a/java/com/google/gerrit/server/notedb/CommitRewriter.java
+++ b/java/com/google/gerrit/server/notedb/CommitRewriter.java
@@ -15,7 +15,6 @@
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkState;
-import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ASSIGNEE;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_ATTENTION;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_LABEL;
import static com.google.gerrit.server.notedb.ChangeNoteFooters.FOOTER_REAL_USER;
@@ -89,6 +88,7 @@
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.FooterKey;
import org.eclipse.jgit.revwalk.FooterLine;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevSort;
@@ -110,6 +110,10 @@
@UsedAt(UsedAt.Project.GOOGLE)
@Singleton
public class CommitRewriter {
+ // Reading and Writing assignee footer no longer supported. We keep the definition here to be able
+ // to rewrite older commit messages.
+ public static final FooterKey FOOTER_ASSIGNEE = new FooterKey("Assignee");
+
/** Options to run {@link #backfillProject}. */
public static class RunOptions implements Serializable {
private static final long serialVersionUID = 1L;
@@ -365,7 +369,9 @@
}
}
accounts.addAll(changeNotes.getAllPastReviewers());
- accounts.addAll(changeNotes.getPastAssignees());
+ // Change Notes class can no longer read or write assignees, we skip assignee accounts at
+ // verifyCommit stage.
+ // accounts.addAll(changeNotes.getPastAssignees());
changeNotes
.getAttentionSetUpdates()
.forEach(attentionSetUpdate -> accounts.add(attentionSetUpdate.account()));
diff --git a/java/com/google/gerrit/server/permissions/ChangeControl.java b/java/com/google/gerrit/server/permissions/ChangeControl.java
index b963361..993c68d 100644
--- a/java/com/google/gerrit/server/permissions/ChangeControl.java
+++ b/java/com/google/gerrit/server/permissions/ChangeControl.java
@@ -133,16 +133,6 @@
return false;
}
- /** Is this user assigned to this change? */
- private boolean isAssignee() {
- Account.Id currentAssignee = getChange().getAssignee();
- if (currentAssignee != null && getUser().isIdentifiedUser()) {
- Account.Id id = getUser().getAccountId();
- return id.equals(currentAssignee);
- }
- return false;
- }
-
/** Is this user a reviewer for the change? */
private boolean isReviewer(ChangeData cd) {
if (getUser().isIdentifiedUser()) {
@@ -184,13 +174,6 @@
return false;
}
- private boolean canEditAssignee() {
- return isOwner()
- || getProjectControl().isOwner()
- || refControl.canPerform(Permission.EDIT_ASSIGNEE)
- || isAssignee();
- }
-
/** Can this user edit the hashtag name? */
private boolean canEditHashtags() {
return isOwner() // owner (aka creator) of the change can edit hashtags
@@ -275,8 +258,6 @@
return getProjectControl().isAdmin() || refControl.canDeleteChanges(isOwner());
case ADD_PATCH_SET:
return canAddPatchSet();
- case EDIT_ASSIGNEE:
- return canEditAssignee();
case EDIT_DESCRIPTION:
return canEditDescription();
case EDIT_HASHTAGS:
diff --git a/java/com/google/gerrit/server/permissions/ChangePermission.java b/java/com/google/gerrit/server/permissions/ChangePermission.java
index c456bf8..7741adac 100644
--- a/java/com/google/gerrit/server/permissions/ChangePermission.java
+++ b/java/com/google/gerrit/server/permissions/ChangePermission.java
@@ -37,7 +37,6 @@
* change is not locked by calling {@code PatchSetUtil.isPatchSetLocked}.
*/
ABANDON,
- EDIT_ASSIGNEE,
EDIT_DESCRIPTION,
EDIT_HASHTAGS,
EDIT_TOPIC_NAME,
diff --git a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java
index 89f0493..da24dcd 100644
--- a/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java
+++ b/java/com/google/gerrit/server/permissions/DefaultPermissionMappings.java
@@ -90,7 +90,6 @@
ImmutableBiMap.<ChangePermission, String>builder()
.put(ChangePermission.READ, Permission.READ)
.put(ChangePermission.ABANDON, Permission.ABANDON)
- .put(ChangePermission.EDIT_ASSIGNEE, Permission.EDIT_ASSIGNEE)
.put(ChangePermission.EDIT_HASHTAGS, Permission.EDIT_HASHTAGS)
.put(ChangePermission.EDIT_TOPIC_NAME, Permission.EDIT_TOPIC_NAME)
.put(ChangePermission.REMOVE_REVIEWER, Permission.REMOVE_REVIEWER)
diff --git a/java/com/google/gerrit/server/query/change/ChangePredicates.java b/java/com/google/gerrit/server/query/change/ChangePredicates.java
index 5f909a1..9c340c4 100644
--- a/java/com/google/gerrit/server/query/change/ChangePredicates.java
+++ b/java/com/google/gerrit/server/query/change/ChangePredicates.java
@@ -46,14 +46,6 @@
}
/**
- * Returns a predicate that matches changes that are assigned to the provided {@link
- * com.google.gerrit.entities.Account.Id}.
- */
- public static Predicate<ChangeData> assignee(Account.Id id) {
- return new ChangeIndexPredicate(ChangeField.ASSIGNEE_SPEC, id.toString());
- }
-
- /**
* Returns a predicate that matches changes that are a revert of the provided {@link
* com.google.gerrit.entities.Change.Id}.
*/
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index 03cdfaa..738eab3 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -153,7 +153,7 @@
public static final String FIELD_ATTENTION_SET_USERS = "attentionusers";
public static final String FIELD_ATTENTION_SET_USERS_COUNT = "attentionuserscount";
public static final String FIELD_ATTENTION_SET_FULL = "attentionfull";
- public static final String FIELD_ASSIGNEE = "assignee";
+ @Deprecated public static final String FIELD_ASSIGNEE = "assignee";
public static final String FIELD_AUTHOR = "author";
public static final String FIELD_EXACTAUTHOR = "exactauthor";
@@ -714,14 +714,6 @@
return new IsAttentionPredicate();
}
- if ("assigned".equalsIgnoreCase(value)) {
- return Predicate.not(ChangePredicates.assignee(Account.id(ChangeField.NO_ASSIGNEE)));
- }
-
- if ("unassigned".equalsIgnoreCase(value)) {
- return ChangePredicates.assignee(Account.id(ChangeField.NO_ASSIGNEE));
- }
-
if ("pure-revert".equalsIgnoreCase(value)) {
checkOperatorAvailable(ChangeField.IS_PURE_REVERT_SPEC, "is:pure-revert");
return ChangePredicates.pureRevert("1");
@@ -1269,20 +1261,6 @@
}
@Operator
- public Predicate<ChangeData> assignee(String who)
- throws QueryParseException, IOException, ConfigInvalidException {
- return assignee(parseAccount(who, (AccountState s) -> true));
- }
-
- private Predicate<ChangeData> assignee(Set<Account.Id> who) {
- List<Predicate<ChangeData>> p = Lists.newArrayListWithCapacity(who.size());
- for (Account.Id id : who) {
- p.add(ChangePredicates.assignee(id));
- }
- return Predicate.or(p);
- }
-
- @Operator
public Predicate<ChangeData> ownerin(String group) throws QueryParseException, IOException {
GroupReference g = GroupBackends.findBestSuggestion(args.groupBackend, group);
if (g == null) {
diff --git a/java/com/google/gerrit/server/query/change/SubmitRequirementChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/SubmitRequirementChangeQueryBuilder.java
index 698628e..5632c14 100644
--- a/java/com/google/gerrit/server/query/change/SubmitRequirementChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/SubmitRequirementChangeQueryBuilder.java
@@ -25,6 +25,8 @@
import com.google.gerrit.server.submitrequirement.predicate.FileEditsPredicate.FileEditsArgs;
import com.google.gerrit.server.submitrequirement.predicate.HasSubmoduleUpdatePredicate;
import com.google.gerrit.server.submitrequirement.predicate.RegexAuthorEmailPredicate;
+import com.google.gerrit.server.submitrequirement.predicate.RegexCommitterEmailPredicate;
+import com.google.gerrit.server.submitrequirement.predicate.RegexUploaderEmailPredicateFactory;
import com.google.inject.Inject;
import java.util.List;
import java.util.Locale;
@@ -60,17 +62,20 @@
private static final Splitter SUBMODULE_UPDATE_SPLITTER = Splitter.on(",");
private final FileEditsPredicate.Factory fileEditsPredicateFactory;
+ private final RegexUploaderEmailPredicateFactory regexUploaderEmailPredicateFactory;
@Inject
SubmitRequirementChangeQueryBuilder(
Arguments args,
DistinctVotersPredicate.Factory distinctVotersPredicateFactory,
FileEditsPredicate.Factory fileEditsPredicateFactory,
- HasSubmoduleUpdatePredicate.Factory hasSubmoduleUpdateFactory) {
+ HasSubmoduleUpdatePredicate.Factory hasSubmoduleUpdateFactory,
+ RegexUploaderEmailPredicateFactory regexUploaderEmailPredicateFactory) {
super(def, args);
this.distinctVotersPredicateFactory = distinctVotersPredicateFactory;
this.fileEditsPredicateFactory = fileEditsPredicateFactory;
this.hasSubmoduleUpdateFactory = hasSubmoduleUpdateFactory;
+ this.regexUploaderEmailPredicateFactory = regexUploaderEmailPredicateFactory;
}
@Override
@@ -129,6 +134,16 @@
}
@Operator
+ public Predicate<ChangeData> committerEmail(String who) throws QueryParseException {
+ return new RegexCommitterEmailPredicate(who);
+ }
+
+ @Operator
+ public Predicate<ChangeData> uploaderEmail(String who) throws QueryParseException {
+ return regexUploaderEmailPredicateFactory.create(who);
+ }
+
+ @Operator
public Predicate<ChangeData> distinctvoters(String value) throws QueryParseException {
return distinctVotersPredicateFactory.create(value);
}
diff --git a/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java b/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
index f49ee7f..33e6342 100644
--- a/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
+++ b/java/com/google/gerrit/server/restapi/change/ChangeRestApiModule.java
@@ -42,7 +42,6 @@
import com.google.gerrit.server.change.RebaseChangeOp;
import com.google.gerrit.server.change.RemoveFromAttentionSetOp;
import com.google.gerrit.server.change.ReviewerResource;
-import com.google.gerrit.server.change.SetAssigneeOp;
import com.google.gerrit.server.change.SetCherryPickOp;
import com.google.gerrit.server.change.SetHashtagsOp;
import com.google.gerrit.server.change.SetPrivateOp;
@@ -91,10 +90,6 @@
delete(ATTENTION_SET_ENTRY_KIND).to(RemoveFromAttentionSet.class);
post(ATTENTION_SET_ENTRY_KIND, "delete").to(RemoveFromAttentionSet.class);
postOnCollection(ATTENTION_SET_ENTRY_KIND).to(AddToAttentionSet.class);
- get(CHANGE_KIND, "assignee").to(GetAssignee.class);
- get(CHANGE_KIND, "past_assignees").to(GetPastAssignees.class);
- put(CHANGE_KIND, "assignee").to(PutAssignee.class);
- delete(CHANGE_KIND, "assignee").to(DeleteAssignee.class);
get(CHANGE_KIND, "hashtags").to(GetHashtags.class);
get(CHANGE_KIND, "comments").to(ListChangeComments.class);
get(CHANGE_KIND, "robotcomments").to(ListChangeRobotComments.class);
@@ -220,7 +215,6 @@
factory(PreviewFix.Factory.class);
factory(RebaseChangeOp.Factory.class);
factory(ReviewerResource.Factory.class);
- factory(SetAssigneeOp.Factory.class);
factory(SetCherryPickOp.Factory.class);
factory(SetHashtagsOp.Factory.class);
factory(SetTopicOp.Factory.class);
diff --git a/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java b/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
deleted file mode 100644
index 66171c4..0000000
--- a/java/com/google/gerrit/server/restapi/change/DeleteAssignee.java
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright (C) 2016 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.restapi.change;
-
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.common.Input;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.server.ChangeMessagesUtil;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountState;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.extensions.events.AssigneeChanged;
-import com.google.gerrit.server.notedb.ChangeUpdate;
-import com.google.gerrit.server.permissions.ChangePermission;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.update.BatchUpdate;
-import com.google.gerrit.server.update.BatchUpdateOp;
-import com.google.gerrit.server.update.ChangeContext;
-import com.google.gerrit.server.update.PostUpdateContext;
-import com.google.gerrit.server.update.UpdateException;
-import com.google.gerrit.server.util.AccountTemplateUtil;
-import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-@Singleton
-public class DeleteAssignee implements RestModifyView<ChangeResource, Input> {
- private final BatchUpdate.Factory updateFactory;
- private final ChangeMessagesUtil cmUtil;
- private final AssigneeChanged assigneeChanged;
- private final IdentifiedUser.GenericFactory userFactory;
- private final AccountLoader.Factory accountLoaderFactory;
-
- @Inject
- DeleteAssignee(
- BatchUpdate.Factory updateFactory,
- ChangeMessagesUtil cmUtil,
- AssigneeChanged assigneeChanged,
- IdentifiedUser.GenericFactory userFactory,
- AccountLoader.Factory accountLoaderFactory) {
- this.updateFactory = updateFactory;
- this.cmUtil = cmUtil;
- this.assigneeChanged = assigneeChanged;
- this.userFactory = userFactory;
- this.accountLoaderFactory = accountLoaderFactory;
- }
-
- @Override
- public Response<AccountInfo> apply(ChangeResource rsrc, Input input)
- throws RestApiException, UpdateException, PermissionBackendException {
- rsrc.permissions().check(ChangePermission.EDIT_ASSIGNEE);
-
- try (BatchUpdate bu = updateFactory.create(rsrc.getProject(), rsrc.getUser(), TimeUtil.now())) {
- Op op = new Op();
- bu.addOp(rsrc.getChange().getId(), op);
- bu.execute();
- Account.Id deletedAssignee = op.getDeletedAssignee();
- return deletedAssignee == null
- ? Response.none()
- : Response.ok(accountLoaderFactory.create(true).fillOne(deletedAssignee));
- }
- }
-
- private class Op implements BatchUpdateOp {
- private Change change;
- private AccountState deletedAssignee;
-
- @Override
- public boolean updateChange(ChangeContext ctx) throws RestApiException {
- change = ctx.getChange();
- ChangeUpdate update = ctx.getUpdate(change.currentPatchSetId());
- Account.Id currentAssigneeId = change.getAssignee();
- if (currentAssigneeId == null) {
- return false;
- }
- IdentifiedUser deletedAssigneeUser = userFactory.create(currentAssigneeId);
- deletedAssignee = deletedAssigneeUser.state();
- update.removeAssignee();
- addMessage(ctx, deletedAssigneeUser);
- return true;
- }
-
- @Nullable
- public Account.Id getDeletedAssignee() {
- return deletedAssignee != null ? deletedAssignee.account().id() : null;
- }
-
- private void addMessage(ChangeContext ctx, IdentifiedUser deletedAssignee) {
- cmUtil.setChangeMessage(
- ctx,
- "Assignee deleted: "
- + AccountTemplateUtil.getAccountTemplate(deletedAssignee.getAccountId()),
- ChangeMessagesUtil.TAG_DELETE_ASSIGNEE);
- }
-
- @Override
- public void postUpdate(PostUpdateContext ctx) {
- assigneeChanged.fire(
- ctx.getChangeData(change), ctx.getAccount(), deletedAssignee, ctx.getWhen());
- }
- }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/GetAssignee.java b/java/com/google/gerrit/server/restapi/change/GetAssignee.java
deleted file mode 100644
index a5820bf..0000000
--- a/java/com/google/gerrit/server/restapi/change/GetAssignee.java
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2016 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.restapi.change;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.Optional;
-
-@Singleton
-public class GetAssignee implements RestReadView<ChangeResource> {
- private final AccountLoader.Factory accountLoaderFactory;
-
- @Inject
- GetAssignee(AccountLoader.Factory accountLoaderFactory) {
- this.accountLoaderFactory = accountLoaderFactory;
- }
-
- @Override
- public Response<AccountInfo> apply(ChangeResource rsrc) throws PermissionBackendException {
- Optional<Account.Id> assignee = Optional.ofNullable(rsrc.getChange().getAssignee());
- if (assignee.isPresent()) {
- return Response.ok(accountLoaderFactory.create(true).fillOne(assignee.get()));
- }
- return Response.none();
- }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java b/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
deleted file mode 100644
index c1c9a34..0000000
--- a/java/com/google/gerrit/server/restapi/change/GetPastAssignees.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2016 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.restapi.change;
-
-import static java.util.stream.Collectors.toList;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-@Singleton
-public class GetPastAssignees implements RestReadView<ChangeResource> {
- private final AccountLoader.Factory accountLoaderFactory;
-
- @Inject
- GetPastAssignees(AccountLoader.Factory accountLoaderFactory) {
- this.accountLoaderFactory = accountLoaderFactory;
- }
-
- @Override
- public Response<List<AccountInfo>> apply(ChangeResource rsrc) throws PermissionBackendException {
-
- Set<Account.Id> pastAssignees = rsrc.getNotes().load().getPastAssignees();
- if (pastAssignees == null) {
- return Response.ok(Collections.emptyList());
- }
-
- AccountLoader accountLoader = accountLoaderFactory.create(true);
- List<AccountInfo> infos = pastAssignees.stream().map(accountLoader::get).collect(toList());
- accountLoader.fill();
- return Response.ok(infos);
- }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/PutAssignee.java b/java/com/google/gerrit/server/restapi/change/PutAssignee.java
deleted file mode 100644
index d41620e..0000000
--- a/java/com/google/gerrit/server/restapi/change/PutAssignee.java
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright (C) 2016 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.restapi.change;
-
-import com.google.common.base.Strings;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
-import com.google.gerrit.extensions.api.changes.NotifyHandling;
-import com.google.gerrit.extensions.api.changes.ReviewerInput;
-import com.google.gerrit.extensions.client.ReviewerState;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.extensions.restapi.BadRequestException;
-import com.google.gerrit.extensions.restapi.Response;
-import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.extensions.webui.UiAction;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.ReviewerSet;
-import com.google.gerrit.server.account.AccountLoader;
-import com.google.gerrit.server.account.AccountResolver;
-import com.google.gerrit.server.approval.ApprovalsUtil;
-import com.google.gerrit.server.change.ChangeResource;
-import com.google.gerrit.server.change.ReviewerModifier;
-import com.google.gerrit.server.change.ReviewerModifier.ReviewerModification;
-import com.google.gerrit.server.change.SetAssigneeOp;
-import com.google.gerrit.server.permissions.ChangePermission;
-import com.google.gerrit.server.permissions.PermissionBackend;
-import com.google.gerrit.server.permissions.PermissionBackendException;
-import com.google.gerrit.server.update.BatchUpdate;
-import com.google.gerrit.server.update.UpdateException;
-import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import java.io.IOException;
-import org.eclipse.jgit.errors.ConfigInvalidException;
-
-@Singleton
-public class PutAssignee
- implements RestModifyView<ChangeResource, AssigneeInput>, UiAction<ChangeResource> {
-
- private final BatchUpdate.Factory updateFactory;
- private final AccountResolver accountResolver;
- private final SetAssigneeOp.Factory assigneeFactory;
- private final ReviewerModifier reviewerModifier;
- private final AccountLoader.Factory accountLoaderFactory;
- private final PermissionBackend permissionBackend;
- private final ApprovalsUtil approvalsUtil;
-
- @Inject
- PutAssignee(
- BatchUpdate.Factory updateFactory,
- AccountResolver accountResolver,
- SetAssigneeOp.Factory assigneeFactory,
- ReviewerModifier reviewerModifier,
- AccountLoader.Factory accountLoaderFactory,
- PermissionBackend permissionBackend,
- ApprovalsUtil approvalsUtil) {
- this.updateFactory = updateFactory;
- this.accountResolver = accountResolver;
- this.assigneeFactory = assigneeFactory;
- this.reviewerModifier = reviewerModifier;
- this.accountLoaderFactory = accountLoaderFactory;
- this.permissionBackend = permissionBackend;
- this.approvalsUtil = approvalsUtil;
- }
-
- @Override
- public Response<AccountInfo> apply(ChangeResource rsrc, AssigneeInput input)
- throws RestApiException, UpdateException, IOException, PermissionBackendException,
- ConfigInvalidException {
- rsrc.permissions().check(ChangePermission.EDIT_ASSIGNEE);
-
- input.assignee = Strings.nullToEmpty(input.assignee).trim();
- if (input.assignee.isEmpty()) {
- throw new BadRequestException("missing assignee field");
- }
-
- IdentifiedUser assignee = accountResolver.resolve(input.assignee).asUniqueUser();
- try {
- permissionBackend
- .absentUser(assignee.getAccountId())
- .change(rsrc.getNotes())
- .check(ChangePermission.READ);
- } catch (AuthException e) {
- throw new AuthException("read not permitted for " + input.assignee, e);
- }
-
- try (BatchUpdate bu =
- updateFactory.create(rsrc.getChange().getProject(), rsrc.getUser(), TimeUtil.now())) {
- SetAssigneeOp op = assigneeFactory.create(assignee);
- bu.addOp(rsrc.getId(), op);
-
- ReviewerSet currentReviewers = approvalsUtil.getReviewers(rsrc.getNotes());
- if (!currentReviewers.all().contains(assignee.getAccountId())) {
- ReviewerModification reviewersAddition = addAssigneeAsCC(rsrc, input.assignee);
- reviewersAddition.op.suppressEmail();
- bu.addOp(rsrc.getId(), reviewersAddition.op);
- }
-
- bu.execute();
- return Response.ok(accountLoaderFactory.create(true).fillOne(assignee.getAccountId()));
- }
- }
-
- private ReviewerModification addAssigneeAsCC(ChangeResource rsrc, String assignee)
- throws IOException, PermissionBackendException, ConfigInvalidException {
- ReviewerInput reviewerInput = new ReviewerInput();
- reviewerInput.reviewer = assignee;
- reviewerInput.state = ReviewerState.CC;
- reviewerInput.confirmed = true;
- reviewerInput.notify = NotifyHandling.NONE;
- return reviewerModifier.prepare(rsrc.getNotes(), rsrc.getUser(), reviewerInput, false);
- }
-
- @Override
- public UiAction.Description getDescription(ChangeResource rsrc) {
- return new UiAction.Description()
- .setLabel("Edit Assignee")
- .setVisible(rsrc.permissions().testCond(ChangePermission.EDIT_ASSIGNEE));
- }
-}
diff --git a/java/com/google/gerrit/server/restapi/change/ReplyAttentionSetUpdates.java b/java/com/google/gerrit/server/restapi/change/ReplyAttentionSetUpdates.java
index 3d9d588..b262b46 100644
--- a/java/com/google/gerrit/server/restapi/change/ReplyAttentionSetUpdates.java
+++ b/java/com/google/gerrit/server/restapi/change/ReplyAttentionSetUpdates.java
@@ -259,10 +259,13 @@
/**
* Bots don't process automatic rules, the only attention set change they do is this rule: Add
- * owner and uploader when a bot votes negatively.
+ * owner and uploader when a bot votes negatively, but only if the change is open.
*/
private void botsWithNegativeLabelsAddOwnerAndUploader(
BatchUpdate bu, ChangeNotes changeNotes, ReviewInput input) {
+ if (changeNotes.getChange().isClosed()) {
+ return;
+ }
if (input.labels != null && input.labels.values().stream().anyMatch(vote -> vote < 0)) {
Account.Id uploader = changeNotes.getCurrentPatchSet().uploader();
Account.Id owner = changeNotes.getChange().getOwner();
diff --git a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
index 103a5ac..66536dd 100644
--- a/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
+++ b/java/com/google/gerrit/server/restapi/config/GetServerInfo.java
@@ -232,10 +232,7 @@
toBoolean(this.config.getBoolean("change", null, "disablePrivateChanges", false));
info.mergeabilityComputationBehavior =
MergeabilityComputationBehavior.fromConfig(config).name();
- info.enableAttentionSet =
- toBoolean(this.config.getBoolean("change", null, "enableAttentionSet", true));
- info.enableAssignee =
- toBoolean(this.config.getBoolean("change", null, "enableAssignee", false));
+ info.enableAssignee = false;
return info;
}
diff --git a/java/com/google/gerrit/server/submitrequirement/predicate/RegexCommitterEmailPredicate.java b/java/com/google/gerrit/server/submitrequirement/predicate/RegexCommitterEmailPredicate.java
new file mode 100644
index 0000000..f991d31
--- /dev/null
+++ b/java/com/google/gerrit/server/submitrequirement/predicate/RegexCommitterEmailPredicate.java
@@ -0,0 +1,57 @@
+// Copyright (C) 2023 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.submitrequirement.predicate;
+
+import com.google.gerrit.index.query.QueryParseException;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.SubmitRequirementPredicate;
+import dk.brics.automaton.RegExp;
+import dk.brics.automaton.RunAutomaton;
+
+/**
+ * A submit requirement predicate that matches with changes having the committer email's address
+ * matching a specific regular expression pattern.
+ */
+public class RegexCommitterEmailPredicate extends SubmitRequirementPredicate {
+ protected final RunAutomaton committerEmailPattern;
+
+ public RegexCommitterEmailPredicate(String pattern) throws QueryParseException {
+ super("committeremail", pattern);
+
+ if (pattern.startsWith("^")) {
+ pattern = pattern.substring(1);
+ }
+
+ if (pattern.endsWith("$") && !pattern.endsWith("\\$")) {
+ pattern = pattern.substring(0, pattern.length() - 1);
+ }
+
+ try {
+ this.committerEmailPattern = new RunAutomaton(new RegExp(pattern).toAutomaton());
+ } catch (IllegalArgumentException e) {
+ throw new QueryParseException(String.format("invalid regular expression: %s", pattern), e);
+ }
+ }
+
+ @Override
+ public boolean match(ChangeData cd) {
+ return committerEmailPattern.run(cd.getCommitter().getEmailAddress());
+ }
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
+}
diff --git a/java/com/google/gerrit/server/submitrequirement/predicate/RegexUploaderEmailPredicate.java b/java/com/google/gerrit/server/submitrequirement/predicate/RegexUploaderEmailPredicate.java
new file mode 100644
index 0000000..9566546
--- /dev/null
+++ b/java/com/google/gerrit/server/submitrequirement/predicate/RegexUploaderEmailPredicate.java
@@ -0,0 +1,71 @@
+// Copyright (C) 2023 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.submitrequirement.predicate;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import com.google.gerrit.index.query.QueryParseException;
+import com.google.gerrit.server.account.AccountCache;
+import com.google.gerrit.server.account.AccountState;
+import com.google.gerrit.server.query.change.ChangeData;
+import com.google.gerrit.server.query.change.SubmitRequirementPredicate;
+import dk.brics.automaton.RegExp;
+import dk.brics.automaton.RunAutomaton;
+import java.util.Optional;
+
+/**
+ * A submit requirement predicate that matches with changes having the uploader's email address
+ * matching a specific regular expression pattern.
+ */
+@AutoFactory
+public class RegexUploaderEmailPredicate extends SubmitRequirementPredicate {
+ protected final RunAutomaton uploaderEmailPattern;
+ private final AccountCache accountCache;
+
+ public RegexUploaderEmailPredicate(@Provided AccountCache accountCache, String pattern)
+ throws QueryParseException {
+ super("uploaderemail", pattern);
+ this.accountCache = accountCache;
+
+ if (pattern.startsWith("^")) {
+ pattern = pattern.substring(1);
+ }
+
+ if (pattern.endsWith("$") && !pattern.endsWith("\\$")) {
+ pattern = pattern.substring(0, pattern.length() - 1);
+ }
+
+ try {
+ this.uploaderEmailPattern = new RunAutomaton(new RegExp(pattern).toAutomaton());
+ } catch (IllegalArgumentException e) {
+ throw new QueryParseException(String.format("invalid regular expression: %s", pattern), e);
+ }
+ }
+
+ @Override
+ public boolean match(ChangeData cd) {
+ Optional<AccountState> accountState = accountCache.get(cd.currentPatchSet().uploader());
+ if (!accountState.isPresent()) {
+ return false;
+ }
+ String email = accountState.get().account().preferredEmail();
+ return email == null ? false : uploaderEmailPattern.run(email);
+ }
+
+ @Override
+ public int getCost() {
+ return 1;
+ }
+}
diff --git a/java/com/google/gerrit/server/validators/AssigneeValidationListener.java b/java/com/google/gerrit/server/validators/AssigneeValidationListener.java
deleted file mode 100644
index 514125f..0000000
--- a/java/com/google/gerrit/server/validators/AssigneeValidationListener.java
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (C) 2016 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.validators;
-
-import com.google.gerrit.entities.Account;
-import com.google.gerrit.entities.Change;
-import com.google.gerrit.extensions.annotations.ExtensionPoint;
-
-/** Listener to provide validation of assignees. */
-@ExtensionPoint
-public interface AssigneeValidationListener {
- /**
- * Invoked by Gerrit before the assignee of a change is modified.
- *
- * @param change the change on which the assignee is changed
- * @param assignee the new assignee. Null if removed
- * @throws ValidationException if validation fails
- */
- void validateAssignee(Change change, Account assignee) throws ValidationException;
-}
diff --git a/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java b/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
index 2d663df..27bd6b9 100644
--- a/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/binding/ChangesRestApiBindingsIT.java
@@ -65,10 +65,6 @@
RestCall.get("/changes/%s/drafts"),
RestCall.get("/changes/%s/attention"),
RestCall.post("/changes/%s/attention"),
- RestCall.get("/changes/%s/assignee"),
- RestCall.get("/changes/%s/past_assignees"),
- RestCall.put("/changes/%s/assignee"),
- RestCall.delete("/changes/%s/assignee"),
RestCall.post("/changes/%s/private"),
RestCall.post("/changes/%s/private.delete"),
RestCall.delete("/changes/%s/private"),
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java b/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java
deleted file mode 100644
index be94cdf..0000000
--- a/javatests/com/google/gerrit/acceptance/rest/change/AssigneeIT.java
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (C) 2016 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 static com.google.gerrit.acceptance.testsuite.project.TestProjectUpdate.allow;
-import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LABELS;
-import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import com.google.common.collect.Iterables;
-import com.google.gerrit.acceptance.AbstractDaemonTest;
-import com.google.gerrit.acceptance.NoHttpd;
-import com.google.gerrit.acceptance.PushOneCommit;
-import com.google.gerrit.acceptance.UseClockStep;
-import com.google.gerrit.acceptance.testsuite.project.ProjectOperations;
-import com.google.gerrit.acceptance.testsuite.request.RequestScopeOperations;
-import com.google.gerrit.entities.Permission;
-import com.google.gerrit.entities.RefNames;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
-import com.google.gerrit.extensions.client.ReviewerState;
-import com.google.gerrit.extensions.common.AccountInfo;
-import com.google.gerrit.extensions.restapi.AuthException;
-import com.google.gerrit.server.account.AccountResolver.UnresolvableAccountException;
-import com.google.gerrit.testing.FakeEmailSender.Message;
-import com.google.inject.Inject;
-import java.util.Iterator;
-import java.util.List;
-import org.eclipse.jgit.transport.RefSpec;
-import org.junit.Test;
-
-@NoHttpd
-@UseClockStep
-public class AssigneeIT extends AbstractDaemonTest {
- @Inject private ProjectOperations projectOperations;
- @Inject private RequestScopeOperations requestScopeOperations;
-
- @Test
- public void getNoAssignee() throws Exception {
- PushOneCommit.Result r = createChange();
- assertThat(getAssignee(r)).isNull();
- }
-
- @Test
- public void addGetAssignee() throws Exception {
- PushOneCommit.Result r = createChange();
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- assertThat(getAssignee(r)._accountId).isEqualTo(user.id().get());
-
- assertThat(sender.getMessages()).hasSize(1);
- Message m = sender.getMessages().get(0);
- assertThat(m.rcpt()).containsExactly(user.getNameEmail());
- }
-
- @Test
- public void setNewAssigneeWhenExists() throws Exception {
- PushOneCommit.Result r = createChange();
- setAssignee(r, user.email());
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- }
-
- @Test
- public void getPastAssignees() throws Exception {
- PushOneCommit.Result r = createChange();
- setAssignee(r, user.email());
- setAssignee(r, admin.email());
- List<AccountInfo> assignees = getPastAssignees(r);
- assertThat(assignees).hasSize(2);
- Iterator<AccountInfo> itr = assignees.iterator();
- assertThat(itr.next()._accountId).isEqualTo(user.id().get());
- assertThat(itr.next()._accountId).isEqualTo(admin.id().get());
- }
-
- @Test
- public void assigneeAddedAsCc() throws Exception {
- PushOneCommit.Result r = createChange();
- Iterable<AccountInfo> reviewers = getReviewers(r, ReviewerState.CC);
- assertThat(reviewers).isNull();
-
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- reviewers = getReviewers(r, ReviewerState.CC);
- assertThat(reviewers).hasSize(1);
- assertThat(Iterables.getFirst(reviewers, null)._accountId).isEqualTo(user.id().get());
- assertThat(getReviewers(r, ReviewerState.REVIEWER)).isNull();
- }
-
- @Test
- public void assigneeStaysReviewer() throws Exception {
- PushOneCommit.Result r = createChange();
- gApi.changes().id(r.getChangeId()).addReviewer(user.email());
- Iterable<AccountInfo> reviewers = getReviewers(r, ReviewerState.REVIEWER);
- assertThat(reviewers).hasSize(1);
- assertThat(Iterables.getFirst(reviewers, null)._accountId).isEqualTo(user.id().get());
- assertThat(getReviewers(r, ReviewerState.CC)).isNull();
-
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- reviewers = getReviewers(r, ReviewerState.REVIEWER);
- assertThat(reviewers).hasSize(1);
- assertThat(Iterables.getFirst(reviewers, null)._accountId).isEqualTo(user.id().get());
- assertThat(getReviewers(r, ReviewerState.CC)).isNull();
- }
-
- @Test
- public void setAlreadyExistingAssignee() throws Exception {
- PushOneCommit.Result r = createChange();
- setAssignee(r, user.email());
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- }
-
- @Test
- public void deleteAssignee() throws Exception {
- PushOneCommit.Result r = createChange();
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- assertThat(deleteAssignee(r)._accountId).isEqualTo(user.id().get());
- assertThat(getAssignee(r)).isNull();
- }
-
- @Test
- public void deleteAssigneeWhenNoAssignee() throws Exception {
- PushOneCommit.Result r = createChange();
- assertThat(deleteAssignee(r)).isNull();
- }
-
- @Test
- public void setAssigneeToInactiveUser() throws Exception {
- PushOneCommit.Result r = createChange();
- gApi.accounts().id(user.id().get()).setActive(false);
- UnresolvableAccountException thrown =
- assertThrows(UnresolvableAccountException.class, () -> setAssignee(r, user.email()));
- assertThat(thrown)
- .hasMessageThat()
- .isEqualTo(
- "Account '"
- + user.email()
- + "' only matches inactive accounts. To use an inactive account, retry with one"
- + " of the following exact account IDs:\n"
- + user.id()
- + ": User1 <user1@example.com>");
- }
-
- @Test
- public void setAssigneeToInactiveUserById() throws Exception {
- PushOneCommit.Result r = createChange();
- gApi.accounts().id(user.id().get()).setActive(false);
- setAssignee(r, user.id().toString());
- assertThat(getAssignee(r)._accountId).isEqualTo(user.id().get());
- }
-
- @Test
- public void setAssigneeForNonVisibleChange() throws Exception {
- git().fetch().setRefSpecs(new RefSpec("refs/meta/config:refs/meta/config")).call();
- testRepo.reset(RefNames.REFS_CONFIG);
- PushOneCommit.Result r = createChange("refs/for/refs/meta/config");
- AuthException thrown = assertThrows(AuthException.class, () -> setAssignee(r, user.email()));
- assertThat(thrown).hasMessageThat().contains("read not permitted");
- }
-
- @Test
- public void setAssigneeNotAllowedWithoutPermission() throws Exception {
- PushOneCommit.Result r = createChange();
- requestScopeOperations.setApiUser(user.id());
- AuthException thrown = assertThrows(AuthException.class, () -> setAssignee(r, user.email()));
- assertThat(thrown).hasMessageThat().contains("not permitted");
- }
-
- @Test
- public void setAssigneeAllowedWithPermission() throws Exception {
- PushOneCommit.Result r = createChange();
- projectOperations
- .project(project)
- .forUpdate()
- .add(allow(Permission.EDIT_ASSIGNEE).ref("refs/heads/master").group(REGISTERED_USERS))
- .update();
- requestScopeOperations.setApiUser(user.id());
- assertThat(setAssignee(r, user.email())._accountId).isEqualTo(user.id().get());
- }
-
- private AccountInfo getAssignee(PushOneCommit.Result r) throws Exception {
- return change(r).getAssignee();
- }
-
- private List<AccountInfo> getPastAssignees(PushOneCommit.Result r) throws Exception {
- return change(r).getPastAssignees();
- }
-
- private Iterable<AccountInfo> getReviewers(PushOneCommit.Result r, ReviewerState state)
- throws Exception {
- return get(r.getChangeId(), DETAILED_LABELS).reviewers.get(state);
- }
-
- private AccountInfo setAssignee(PushOneCommit.Result r, String identifieer) throws Exception {
- AssigneeInput input = new AssigneeInput();
- input.assignee = identifieer;
- return change(r).setAssignee(input);
- }
-
- private AccountInfo deleteAssignee(PushOneCommit.Result r) throws Exception {
- return change(r).deleteAssignee();
- }
-}
diff --git a/javatests/com/google/gerrit/acceptance/rest/change/AttentionSetIT.java b/javatests/com/google/gerrit/acceptance/rest/change/AttentionSetIT.java
index ea52690..1d2ddc2 100644
--- a/javatests/com/google/gerrit/acceptance/rest/change/AttentionSetIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/change/AttentionSetIT.java
@@ -1488,6 +1488,64 @@
}
@Test
+ public void robotReviewWithNegativeLabelDoesntAddOwnerIfChangeIsMerged() throws Exception {
+ TestAccount robot =
+ accountCreator.create(
+ "robot2", "robot2@example.com", "Ro Bot", "Ro", ServiceUserClassifier.SERVICE_USERS);
+
+ PushOneCommit.Result r = createChange();
+
+ // The robot votes with Code-Review-1 on patch set 1.
+ // Without this vote the robot cannot (re-)apply a negative vote on the change after it was
+ // merged change later.
+ requestScopeOperations.setApiUser(robot.id());
+ change(r).revision(1).review(ReviewInput.dislike());
+
+ // Amend the change so that patch set 2 gets created.
+ requestScopeOperations.setApiUser(admin.id());
+ amendChange(r.getChangeId()).assertOkStatus();
+
+ // Approve the change.
+ approve(r.getChangeId());
+
+ // User adds a comment so that the admin user is added to the attention set.
+ // This has to be a comment from a user, since comments from robots do not trigger attention set
+ // updates.
+ requestScopeOperations.setApiUser(user.id());
+ ReviewInput reviewInput = new ReviewInput();
+ reviewInput.message = "A comment";
+ change(r).current().review(reviewInput);
+
+ // Verify that the admin user was added to the attention set.
+ AttentionSetUpdate attentionSet =
+ Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
+ assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.ADD);
+ assertThat(attentionSet).hasReasonThat().isEqualTo("Someone else replied on the change");
+
+ // Submit the change.
+ requestScopeOperations.setApiUser(admin.id());
+ change(r).current().submit();
+
+ // Verify that the attention set was cleared on submit.
+ attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
+ assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
+ assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
+
+ // Re-apply the negative robot vote on patch set 1.
+ // Note it's possible to a apply a negative vote on merged changes if it wasn't already present
+ // since we disallow downgrading votes on merged changes (e.g. downgrade from not present aka 0
+ // to -1 is not allowed).
+ requestScopeOperations.setApiUser(robot.id());
+ change(r).revision(1).review(ReviewInput.dislike());
+
+ // Verify that re-applying the negative robot vote on patch set 1 didn't add the admin user
+ // back to the attention set.
+ attentionSet = Iterables.getOnlyElement(getAttentionSetUpdatesForUser(r, admin));
+ assertThat(attentionSet).hasOperationThat().isEqualTo(AttentionSetUpdate.Operation.REMOVE);
+ assertThat(attentionSet).hasReasonThat().isEqualTo("Change was submitted");
+ }
+
+ @Test
public void robotCommentDoesNotAddOwnerOnClosedChanges() throws Exception {
TestAccount robot =
accountCreator.create(
@@ -1613,7 +1671,6 @@
}
@Test
- @GerritConfig(name = "change.enableAttentionSet", value = "true")
public void attentionSetEmailHeader() throws Exception {
PushOneCommit.Result r = createChange();
TestAccount user2 = accountCreator.user2();
@@ -1654,21 +1711,6 @@
}
@Test
- @GerritConfig(name = "change.enableAttentionSet", value = "false")
- public void noReferenceToAttentionSetInEmailsWhenDisabled() throws Exception {
- PushOneCommit.Result r = createChange();
- // Add user and to the attention set.
- change(r).addReviewer(user.id().toString());
-
- // Attention set is not referenced.
- assertThat(Iterables.getOnlyElement(sender.getMessages()).body())
- .doesNotContain("Attention is currently required");
- assertThat(Iterables.getOnlyElement(sender.getMessages()).htmlBody())
- .doesNotContain("Attention is currently required");
- sender.clear();
- }
-
- @Test
public void attentionSetWithEmailFilter() throws Exception {
PushOneCommit.Result r = createChange();
diff --git a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
index 8131352..1236afd 100644
--- a/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/config/ServerInfoIT.java
@@ -60,8 +60,6 @@
// change
@GerritConfig(name = "change.updateDelay", value = "50s")
@GerritConfig(name = "change.disablePrivateChanges", value = "true")
- @GerritConfig(name = "change.enableAttentionSet", value = "true")
- @GerritConfig(name = "change.enableAssignee", value = "true")
// download
@GerritConfig(
@@ -102,8 +100,6 @@
// change
assertThat(i.change.updateDelay).isEqualTo(50);
assertThat(i.change.disablePrivateChanges).isTrue();
- assertThat(i.change.enableAttentionSet).isTrue();
- assertThat(i.change.enableAssignee).isTrue();
// download
assertThat(i.download.archives).containsExactly("tar", "tbz2", "tgz", "txz");
diff --git a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
index b68afc5..e44bfcf 100644
--- a/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/mail/ChangeNotificationsIT.java
@@ -45,7 +45,6 @@
import com.google.gerrit.entities.Permission;
import com.google.gerrit.entities.Project;
import com.google.gerrit.extensions.api.changes.AbandonInput;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
import com.google.gerrit.extensions.api.changes.DeleteReviewerInput;
import com.google.gerrit.extensions.api.changes.DeleteVoteInput;
import com.google.gerrit.extensions.api.changes.NotifyHandling;
@@ -2452,154 +2451,6 @@
}
/*
- * SetAssigneeSender tests.
- */
-
- @Test
- public void setAssigneeOnReviewableChange() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, sc.owner, sc.assignee);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeOnReviewableChangeByOwnerCcingSelf() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, sc.owner, sc.assignee, CC_ON_OWN_COMMENTS);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(sc.owner)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeOnReviewableChangeByAdmin() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, admin, sc.assignee);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeOnReviewableChangeByAdminCcingSelf() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, admin, sc.assignee, CC_ON_OWN_COMMENTS);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(admin)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeToSelfOnReviewableChange() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, sc.owner, sc.owner);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void changeAssigneeOnReviewableChange() throws Exception {
- StagedChange sc = stageReviewableChange();
- TestAccount other = accountCreator.create("other", "other@example.com", "other", null);
- assign(sc, sc.owner, other);
- sender.clear();
- assign(sc, sc.owner, sc.assignee);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void changeAssigneeToSelfOnReviewableChange() throws Exception {
- StagedChange sc = stageReviewableChange();
- assign(sc, sc.owner, sc.assignee);
- sender.clear();
- assign(sc, sc.owner, sc.owner);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeOnReviewableWipChange() throws Exception {
- StagedChange sc = stageReviewableWipChange();
- assign(sc, sc.owner, sc.assignee);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- @Test
- public void setAssigneeOnWipChange() throws Exception {
- StagedChange sc = stageWipChange();
- assign(sc, sc.owner, sc.assignee);
- assertThat(sender)
- .sent("setassignee", sc)
- .cc(
- StagedUsers.REVIEWER_BY_EMAIL,
- StagedUsers.CC_BY_EMAIL) // TODO(logan): This is probably not intended!
- .to(sc.assignee)
- .noOneElse();
- assertThat(sender).didNotSend();
- }
-
- private void assign(StagedChange sc, TestAccount by, TestAccount to) throws Exception {
- assign(sc, by, to, ENABLED);
- }
-
- private void assign(StagedChange sc, TestAccount by, TestAccount to, EmailStrategy emailStrategy)
- throws Exception {
- setEmailStrategy(by, emailStrategy);
- requestScopeOperations.setApiUser(by.id());
- AssigneeInput in = new AssigneeInput();
- in.assignee = to.email();
- gApi.changes().id(sc.changeId).setAssignee(in);
- }
-
- /*
* Start review and WIP tests.
*/
diff --git a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
index d3c4949..9e27e93 100644
--- a/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/project/SubmitRequirementsEvaluatorIT.java
@@ -493,6 +493,74 @@
SubmitRequirementResult.Status.UNSATISFIED);
}
+ @Test
+ public void byCommitterEmail() throws Exception {
+ TestAccount user2 =
+ accountCreator.create("Foo", "user@example.com", "User", /* displayName = */ null);
+ requestScopeOperations.setApiUser(user2.id());
+ ChangeInfo info =
+ gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get();
+ ChangeData cd =
+ changeQueryProvider
+ .get()
+ .byLegacyChangeId(Change.Id.tryParse(Integer.toString(info._number)).get())
+ .get(0);
+
+ // Match by email works
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "committeremail:\"^.*@example\\.com\"",
+ SubmitRequirementResult.Status.SATISFIED);
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "committeremail:\"^user@.*\\.com\"",
+ SubmitRequirementResult.Status.SATISFIED);
+
+ // Match by name does not work
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "committeremail:\"^Foo$\"",
+ SubmitRequirementResult.Status.UNSATISFIED);
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "committeremail:\"^User$\"",
+ SubmitRequirementResult.Status.UNSATISFIED);
+ }
+
+ @Test
+ public void byUploaderEmail() throws Exception {
+ TestAccount user2 =
+ accountCreator.create("Foo", "user@example.com", "User", /* displayName = */ null);
+ requestScopeOperations.setApiUser(user2.id());
+ ChangeInfo info =
+ gApi.changes().create(new ChangeInput(project.get(), "master", "Test Change")).get();
+ ChangeData cd =
+ changeQueryProvider
+ .get()
+ .byLegacyChangeId(Change.Id.tryParse(Integer.toString(info._number)).get())
+ .get(0);
+
+ // Match by email works
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "uploaderemail:\"^.*@example\\.com\"",
+ SubmitRequirementResult.Status.SATISFIED);
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "uploaderemail:\"^user@.*\\.com\"",
+ SubmitRequirementResult.Status.SATISFIED);
+
+ // Match by name does not work
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "uploaderemail:\"^Foo$\"",
+ SubmitRequirementResult.Status.UNSATISFIED);
+ checkSubmitRequirementResult(
+ cd,
+ /* submittabilityExpr= */ "uploaderemail:\"^User$\"",
+ SubmitRequirementResult.Status.UNSATISFIED);
+ }
+
private void checkSubmitRequirementResult(
ChangeData cd, String submittabilityExpr, SubmitRequirementResult.Status expectedStatus) {
SubmitRequirement sr =
diff --git a/javatests/com/google/gerrit/acceptance/ssh/StreamEventsIT.java b/javatests/com/google/gerrit/acceptance/ssh/StreamEventsIT.java
index 13a9e0c..f02d244 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/StreamEventsIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/StreamEventsIT.java
@@ -65,7 +65,7 @@
() ->
pollEventsContaining("ref-updated", refName.substring(0, refName.lastIndexOf('/')))
.size()
- == 2);
+ == 1);
}
private void waitForEvent(Supplier<Boolean> waitCondition) throws InterruptedException {
diff --git a/javatests/com/google/gerrit/server/events/EventDeserializerTest.java b/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
index 00b92b4..390aa84 100644
--- a/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
+++ b/javatests/com/google/gerrit/server/events/EventDeserializerTest.java
@@ -69,22 +69,6 @@
}
@Test
- public void assigneeChangedEvent() {
- Change change = newChange();
- AssigneeChangedEvent orig = new AssigneeChangedEvent(change);
- orig.change = asChangeAttribute(change);
- orig.changer = newAccount("changer");
- orig.oldAssignee = newAccount("oldAssignee");
-
- AssigneeChangedEvent e = roundTrip(orig);
-
- assertThat(e).isNotNull();
- assertSameChangeEvent(e, orig);
- assertSameAccount(e.changer, orig.changer);
- assertSameAccount(e.oldAssignee, orig.oldAssignee);
- }
-
- @Test
public void changeDeletedEvent() {
Change change = newChange();
ChangeDeletedEvent orig = new ChangeDeletedEvent(change);
diff --git a/javatests/com/google/gerrit/server/events/EventJsonTest.java b/javatests/com/google/gerrit/server/events/EventJsonTest.java
index c2b67c3..3f8519e 100644
--- a/javatests/com/google/gerrit/server/events/EventJsonTest.java
+++ b/javatests/com/google/gerrit/server/events/EventJsonTest.java
@@ -153,51 +153,6 @@
}
@Test
- public void assigneeChangedEvent() {
- Change change = newChange();
- AssigneeChangedEvent event = new AssigneeChangedEvent(change);
- event.change = asChangeAttribute(change);
- event.changer = newAccount("changer");
- event.oldAssignee = newAccount("oldAssignee");
-
- assertThatJsonMap(event)
- .isEqualTo(
- ImmutableMap.builder()
- .put(
- "changer",
- ImmutableMap.builder()
- .put("name", event.changer.get().name)
- .put("email", event.changer.get().email)
- .put("username", event.changer.get().username)
- .build())
- .put(
- "oldAssignee",
- ImmutableMap.builder()
- .put("name", event.oldAssignee.get().name)
- .put("email", event.oldAssignee.get().email)
- .put("username", event.oldAssignee.get().username)
- .build())
- .put(
- "change",
- ImmutableMap.builder()
- .put("project", PROJECT)
- .put("branch", BRANCH)
- .put("id", CHANGE_ID)
- .put("number", CHANGE_NUM_DOUBLE)
- .put("url", URL)
- .put("commitMessage", COMMIT_MESSAGE)
- .put("createdOn", TS1)
- .put("status", NEW.name())
- .build())
- .put("project", PROJECT)
- .put("refName", REF)
- .put("changeKey", map("id", CHANGE_ID))
- .put("type", "assignee-changed")
- .put("eventCreatedOn", TS2)
- .build());
- }
-
- @Test
public void changeDeletedEvent() {
Change change = newChange();
ChangeDeletedEvent event = new ChangeDeletedEvent(change);
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
index 4543b50..8d7066f 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesParserTest.java
@@ -166,7 +166,8 @@
+ "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
+ "Patch-set: 1\n"
+ "Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7\n"
- + "Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 2 <2@gerrit>\n"
+ + "Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 2"
+ + " <2@gerrit>\n"
+ "Label: Label1=0, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 2 <2@gerrit>\n"
+ "Subject: This is a test change\n");
@@ -183,14 +184,24 @@
assertParseFails("Update change\n\nPatch-set: 1\nLabel: Label1=+1, \n");
assertParseFails("Update change\n\nPatch-set: 1\nLabel: Label1=+1,\n");
assertParseFails(
- "Update change\n\nPatch-set: 1\nLabel: Label1=-1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 2 <2@gerrit>\n");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Label: Label1=-1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 2"
+ + " <2@gerrit>\n");
assertParseFails(
- "Update change\n\nPatch-set: 1\nLabel: Label1=-1, 577fb248e474018276351785930358ec0450e9f7\n");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Label: Label1=-1, 577fb248e474018276351785930358ec0450e9f7\n");
// UUID for removals is not supported.
assertParseFails(
- "Update change\n\nPatch-set: 1\nLabel: -Label1, 577fb248e474018276351785930358ec0450e9f7\n");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Label: -Label1, 577fb248e474018276351785930358ec0450e9f7\n");
assertParseFails(
- "Update change\n\nPatch-set: 1\nLabel: -Label1, 577fb248e474018276351785930358ec0450e9f7 Other Account <2@gerrit>\n");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Label: -Label1, 577fb248e474018276351785930358ec0450e9f7 Other Account"
+ + " <2@gerrit>\n");
}
@Test
@@ -234,13 +245,20 @@
+ "Branch: refs/heads/master\n"
+ "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
+ "Patch-set: 1\n"
- + "Copied-Label: Label2=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>\n"
- + "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit>\n"
- + "Copied-Label: Label3=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag\"\n"
- + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit> :\"tag with characters %^#@^( *::!\"\n"
- + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit> :\"tag with uuid delimiter , \"\n"
- + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with characters %^#@^( *::!\"\n"
- + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with uuid delimiter , \"\n"
+ + "Copied-Label: Label2=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>\n"
+ + "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>,Gerrit User 2 <2@gerrit>\n"
+ + "Copied-Label: Label3=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag\"\n"
+ + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit> :\"tag with characters %^#@^( *::!\"\n"
+ + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit> :\"tag with uuid delimiter , \"\n"
+ + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with characters %^#@^( *::!\"\n"
+ + "Copied-Label: Label4=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with uuid delimiter , \"\n"
+ "Subject: This is a test change\n");
assertParseSucceeds(
@@ -250,23 +268,34 @@
+ "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
+ "Patch-set: 1\n"
+ "Copied-Label: Label2=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>\n"
- + "Copied-Label: Label1=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit>\n"
- + "Copied-Label: Label3=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag\"\n"
- + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit> :\"tag with characters %^#@^( *::!\"\n"
- + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit> :\"tag with uuid delimiter , \"\n"
- + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with characters %^#@^( *::!\"\n"
- + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit> :\"tag with uuid delimiter , \"\n"
+ + "Copied-Label: Label1=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2"
+ + " <2@gerrit>\n"
+ + "Copied-Label: Label3=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2"
+ + " <2@gerrit> :\"tag\"\n"
+ + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit> :\"tag with"
+ + " characters %^#@^( *::!\"\n"
+ + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit> :\"tag with uuid"
+ + " delimiter , \"\n"
+ + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2"
+ + " <2@gerrit> :\"tag with characters %^#@^( *::!\"\n"
+ + "Copied-Label: Label4=+1, non-SHA1_UUID Gerrit User 1 <1@gerrit>,Gerrit User 2"
+ + " <2@gerrit> :\"tag with uuid delimiter , \"\n"
+ "Subject: This is a test change\n");
assertParseFails("Update change\n\nPatch-set: 1\nCopied-Label: Label1=+1,\n");
assertParseFails("Update change\n\nPatch-set: 1\nCopied-Label: Label1=+1,\n");
assertParseFails("Update change\n\nPatch-set: 1\nCopied-Label: Label1=+1 ,\n");
assertParseFails(
- "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1 <1@gerrit>,Gerrit User 2 <2@gerrit>\n\n");
+ "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 Gerrit User 1"
+ + " <1@gerrit>,Gerrit User 2 <2@gerrit>\n\n");
assertParseFails(
- "Update change\n\nPatch-set: 1\nCopied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7");
assertParseFails(
- "Update change\n\nPatch-set: 1\nCopied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 :\"tag\"\n");
+ "Update change\n\n"
+ + "Patch-set: 1\n"
+ + "Copied-Label: Label1=+1, 577fb248e474018276351785930358ec0450e9f7 :\"tag\"\n");
// UUID for removals is not supported.
assertParseFails(
@@ -350,26 +379,6 @@
}
@Test
- public void parseAssignee() throws Exception {
- assertParseSucceeds(
- "Update change\n"
- + "\n"
- + "Branch: refs/heads/master\n"
- + "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
- + "Patch-set: 1\n"
- + "Assignee: Change Owner <1@gerrit>\n"
- + "Subject: This is a test change\n");
- assertParseSucceeds(
- "Update change\n"
- + "\n"
- + "Branch: refs/heads/master\n"
- + "Change-id: I577fb248e474018276351785930358ec0450e9f7\n"
- + "Patch-set: 2\n"
- + "Assignee:\n"
- + "Subject: This is a test change\n");
- }
-
- @Test
public void parseTopic() throws Exception {
assertParseSucceeds(
"Update change\n"
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
index c654828..9a29230 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesStateTest.java
@@ -45,12 +45,10 @@
import com.google.gerrit.entities.converter.PatchSetProtoConverter;
import com.google.gerrit.proto.Entities;
import com.google.gerrit.proto.Protos;
-import com.google.gerrit.server.AssigneeStatusUpdate;
import com.google.gerrit.server.ReviewerByEmailSet;
import com.google.gerrit.server.ReviewerSet;
import com.google.gerrit.server.ReviewerStatusUpdate;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto;
-import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.AssigneeStatusUpdateProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.AttentionSetUpdateProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ChangeColumnsProto;
import com.google.gerrit.server.cache.proto.Cache.ChangeNotesStateProto.ReviewerByEmailSetEntryProto;
@@ -806,37 +804,6 @@
}
@Test
- public void serializeAssigneeUpdates() throws Exception {
- assertRoundTrip(
- newBuilder()
- .assigneeUpdates(
- ImmutableList.of(
- AssigneeStatusUpdate.create(
- Instant.ofEpochMilli(1212L),
- Account.id(1000),
- Optional.of(Account.id(2001))),
- AssigneeStatusUpdate.create(
- Instant.ofEpochMilli(3434L), Account.id(1000), Optional.empty())))
- .build(),
- ChangeNotesStateProto.newBuilder()
- .setMetaId(SHA_BYTES)
- .setChangeId(ID.get())
- .setColumns(colsProto)
- .addAssigneeUpdate(
- AssigneeStatusUpdateProto.newBuilder()
- .setTimestampMillis(1212L)
- .setUpdatedBy(1000)
- .setCurrentAssignee(2001)
- .setHasCurrentAssignee(true))
- .addAssigneeUpdate(
- AssigneeStatusUpdateProto.newBuilder()
- .setTimestampMillis(3434L)
- .setUpdatedBy(1000)
- .setHasCurrentAssignee(false))
- .build());
- }
-
- @Test
public void serializeSubmitRecords() throws Exception {
SubmitRecord sr1 = new SubmitRecord();
sr1.status = SubmitRecord.Status.OK;
@@ -971,9 +938,6 @@
.put(
"allAttentionSetUpdates",
new TypeLiteral<ImmutableList<AttentionSetUpdate>>() {}.getType())
- .put(
- "assigneeUpdates",
- new TypeLiteral<ImmutableList<AssigneeStatusUpdate>>() {}.getType())
.put("submitRecords", new TypeLiteral<ImmutableList<SubmitRecord>>() {}.getType())
.put("changeMessages", new TypeLiteral<ImmutableList<ChangeMessage>>() {}.getType())
.put(
@@ -1088,19 +1052,6 @@
}
@Test
- public void assigneeStatusUpdateMethods() throws Exception {
- assertThatSerializedClass(AssigneeStatusUpdate.class)
- .hasAutoValueMethods(
- ImmutableMap.of(
- "date",
- Instant.class,
- "updatedBy",
- Account.Id.class,
- "currentAssignee",
- new TypeLiteral<Optional<Account.Id>>() {}.getType()));
- }
-
- @Test
public void submitRecordFields() throws Exception {
assertThatSerializedClass(SubmitRecord.class)
.hasFields(
diff --git a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
index 9cd002e..cf739f6 100644
--- a/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
+++ b/javatests/com/google/gerrit/server/notedb/ChangeNotesTest.java
@@ -53,7 +53,6 @@
import com.google.gerrit.entities.SubmissionId;
import com.google.gerrit.entities.SubmitRecord;
import com.google.gerrit.exceptions.StorageException;
-import com.google.gerrit.server.AssigneeStatusUpdate;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ReviewerSet;
@@ -1474,91 +1473,6 @@
}
@Test
- public void assigneeCommit() throws Exception {
- Change c = newChange();
- ChangeUpdate update = newUpdate(c, changeOwner);
- update.setAssignee(otherUserId);
- ObjectId result = update.commit();
- assertThat(result).isNotNull();
- try (RevWalk rw = new RevWalk(repo)) {
- RevCommit commit = rw.parseCommit(update.getResult());
- rw.parseBody(commit);
- String strIdent = "Gerrit User " + otherUserId + " <" + otherUserId + "@" + serverId + ">";
- assertThat(commit.getFullMessage()).contains("Assignee: " + strIdent);
- }
- }
-
- @Test
- public void assigneeChangeNotes() throws Exception {
- Change c = newChange();
- ChangeUpdate update = newUpdate(c, changeOwner);
- update.setAssignee(otherUserId);
- update.commit();
-
- ChangeNotes notes = newNotes(c);
- assertThat(notes.getChange().getAssignee()).isEqualTo(otherUserId);
-
- update = newUpdate(c, changeOwner);
- update.setAssignee(changeOwner.getAccountId());
- update.commit();
-
- notes = newNotes(c);
- assertThat(notes.getChange().getAssignee()).isEqualTo(changeOwner.getAccountId());
- }
-
- @Test
- public void pastAssigneesChangeNotes() throws Exception {
- Change c = newChange();
- ChangeUpdate update = newUpdate(c, changeOwner);
- update.setAssignee(otherUserId);
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.setAssignee(changeOwner.getAccountId());
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.setAssignee(otherUserId);
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.removeAssignee();
- update.commit();
-
- ChangeNotes notes = newNotes(c);
- assertThat(notes.getPastAssignees()).hasSize(2);
- }
-
- @Test
- public void assigneeStatusUpdateChangeNotes() throws Exception {
- Change c = newChange();
- ChangeUpdate update = newUpdate(c, otherUser);
- update.setAssignee(otherUserId);
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.removeAssignee();
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.setAssignee(changeOwner.getAccountId());
- update.commit();
-
- update = newUpdate(c, changeOwner);
- update.setAssignee(otherUserId);
- update.commit();
-
- ChangeNotes notes = newNotes(c);
- ImmutableList<AssigneeStatusUpdate> statusUpdates = notes.getAssigneeUpdates();
- assertThat(statusUpdates).hasSize(4);
- assertThat(statusUpdates.get(3).updatedBy()).isEqualTo(otherUserId);
- assertThat(statusUpdates.get(3).currentAssignee()).hasValue(otherUserId);
- assertThat(statusUpdates.get(2).currentAssignee()).isEmpty();
- assertThat(statusUpdates.get(1).currentAssignee()).hasValue(changeOwner.getAccountId());
- assertThat(statusUpdates.get(0).currentAssignee()).hasValue(otherUserId);
- }
-
- @Test
public void hashtagCommit() throws Exception {
Change c = newChange();
ChangeUpdate update = newUpdate(c, changeOwner);
diff --git a/javatests/com/google/gerrit/server/notedb/CommitRewriterTest.java b/javatests/com/google/gerrit/server/notedb/CommitRewriterTest.java
index 527e78e..4f4911a 100644
--- a/javatests/com/google/gerrit/server/notedb/CommitRewriterTest.java
+++ b/javatests/com/google/gerrit/server/notedb/CommitRewriterTest.java
@@ -214,37 +214,37 @@
@Test
public void maxRefsToUpdate_coversAllInvalid_inMultipleBatches() throws Exception {
testMaxRefsToUpdate(
- /*numberOfInvalidChanges=*/ 11,
- /*numberOfValidChanges=*/ 9,
- /*maxRefsToUpdate=*/ 12,
- /*maxRefsInBatch=*/ 2);
+ /* numberOfInvalidChanges= */ 11,
+ /* numberOfValidChanges= */ 9,
+ /* maxRefsToUpdate= */ 12,
+ /* maxRefsInBatch= */ 2);
}
@Test
public void maxRefsToUpdate_coversAllInvalid_inSingleBatch() throws Exception {
testMaxRefsToUpdate(
- /*numberOfInvalidChanges=*/ 11,
- /*numberOfValidChanges=*/ 9,
- /*maxRefsToUpdate=*/ 12,
- /*maxRefsInBatch=*/ 12);
+ /* numberOfInvalidChanges= */ 11,
+ /* numberOfValidChanges= */ 9,
+ /* maxRefsToUpdate= */ 12,
+ /* maxRefsInBatch= */ 12);
}
@Test
public void moreInvalidRefs_thenMaxRefsToUpdate_inMultipleBatches() throws Exception {
testMaxRefsToUpdate(
- /*numberOfInvalidChanges=*/ 11,
- /*numberOfValidChanges=*/ 9,
- /*maxRefsToUpdate=*/ 10,
- /*maxRefsInBatch=*/ 2);
+ /* numberOfInvalidChanges= */ 11,
+ /* numberOfValidChanges= */ 9,
+ /* maxRefsToUpdate= */ 10,
+ /* maxRefsInBatch= */ 2);
}
@Test
public void moreInvalidRefs_thenMaxRefsToUpdate_inSingleBatch() throws Exception {
testMaxRefsToUpdate(
- /*numberOfInvalidChanges=*/ 11,
- /*numberOfValidChanges=*/ 9,
- /*maxRefsToUpdate=*/ 10,
- /*maxRefsInBatch=*/ 10);
+ /* numberOfInvalidChanges= */ 11,
+ /* numberOfValidChanges= */ 9,
+ /* maxRefsToUpdate= */ 10,
+ /* maxRefsInBatch= */ 10);
}
private void testMaxRefsToUpdate(
@@ -333,7 +333,7 @@
RevCommit invalidUpdateCommit =
writeUpdate(
RefNames.changeMetaRef(c.getId()),
- getChangeUpdateBody(c, /*changeMessage=*/ null),
+ getChangeUpdateBody(c, /* changeMessage= */ null),
invalidAuthorIdent);
ChangeUpdate validUpdate = newUpdate(c, changeOwner);
validUpdate.setChangeMessage("verification from jenkins");
@@ -472,7 +472,8 @@
// valid change message that should not be overwritten
getChangeUpdateBody(
c,
- "Removed cc <GERRIT_ACCOUNT_2> with the following votes:\n\n * Code-Review+2 by <GERRIT_ACCOUNT_2>",
+ "Removed cc <GERRIT_ACCOUNT_2> with the following votes:\n\n"
+ + " * Code-Review+2 by <GERRIT_ACCOUNT_2>",
"CC: " + reviewerIdentToFix),
getAuthorIdent(otherUser.getAccount())))
.add(
@@ -677,7 +678,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ null,
+ /* changeMessage= */ null,
"Label: -Verified " + approverIdentToFix,
"Label: Custom-Label-1=-1 " + approverIdentToFix,
"Label: Verified=+1",
@@ -690,7 +691,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ null,
+ /* changeMessage= */ null,
"Label: -Verified " + changeOwnerIdentToFix,
"Label: Custom-Label-1=+1"),
getAuthorIdent(otherUser.getAccount())))
@@ -812,7 +813,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed Code-Review+2 by " + otherUser.getNameEmail(),
+ /* changeMessage= */ "Removed Code-Review+2 by " + otherUser.getNameEmail(),
"Label: -Code-Review " + approverIdentToFix),
getAuthorIdent(changeOwner.getAccount())))
.add(
@@ -820,7 +821,8 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed Custom-Label-1 by " + otherUser.getNameEmail(),
+ /* changeMessage= */ "Removed Custom-Label-1 by "
+ + otherUser.getNameEmail(),
"Label: -Custom-Label " + getValidIdentAsString(otherUser.getAccount())),
getAuthorIdent(changeOwner.getAccount())))
.add(
@@ -828,7 +830,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed Verified+2 by " + changeOwner.getNameEmail(),
+ /* changeMessage= */ "Removed Verified+2 by " + changeOwner.getNameEmail(),
"Label: -Verified"),
getAuthorIdent(changeOwner.getAccount())))
.build();
@@ -928,7 +930,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed Verified+2 by " + otherUser.getNameEmail(),
+ /* changeMessage= */ "Removed Verified+2 by " + otherUser.getNameEmail(),
"Label: -Verified"),
invalidAuthorIdent);
@@ -961,19 +963,19 @@
RefNames.changeMetaRef(c.getId()),
// Even though footer is missing, accounts are matched among the account in change updates.
- getChangeUpdateBody(c, /*changeMessage=*/ "Removed Verified-1 by Other Account (0002)"),
+ getChangeUpdateBody(c, /* changeMessage= */ "Removed Verified-1 by Other Account (0002)"),
getAuthorIdent(changeOwner.getAccount()));
writeUpdate(
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
- c, /*changeMessage=*/ "Removed Verified+2 by " + changeOwner.getNameEmail()),
+ c, /* changeMessage= */ "Removed Verified+2 by " + changeOwner.getNameEmail()),
getAuthorIdent(changeOwner.getAccount()));
// No rewrite for default
writeUpdate(
RefNames.changeMetaRef(c.getId()),
- getChangeUpdateBody(c, /*changeMessage=*/ "Removed Verified+2 by Gerrit Account"),
+ getChangeUpdateBody(c, /* changeMessage= */ "Removed Verified+2 by Gerrit Account"),
getAuthorIdent(changeOwner.getAccount()));
RunOptions options = new RunOptions();
@@ -1006,7 +1008,8 @@
writeUpdate(
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
- c, /*changeMessage=*/ "Removed Verified+2 by Renamed Change Owner <change@owner.com>"),
+ c,
+ /* changeMessage= */ "Removed Verified+2 by Renamed Change Owner <change@owner.com>"),
getAuthorIdent(changeOwner.getAccount()));
RunOptions options = new RunOptions();
@@ -1035,7 +1038,7 @@
approvalUpdate.commit();
writeUpdate(
RefNames.changeMetaRef(c.getId()),
- getChangeUpdateBody(c, /*changeMessage=*/ "Removed Verified+2 by Change Owner"),
+ getChangeUpdateBody(c, /* changeMessage= */ "Removed Verified+2 by Change Owner"),
getAuthorIdent(changeOwner.getAccount()));
RunOptions options = new RunOptions();
@@ -1072,17 +1075,17 @@
writeUpdate(
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
- c, /*changeMessage=*/ "Removed Verified+2 by Change Owner <other@test.com>"),
+ c, /* changeMessage= */ "Removed Verified+2 by Change Owner <other@test.com>"),
getAuthorIdent(changeOwner.getAccount()));
writeUpdate(
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
- c, /*changeMessage=*/ "Removed Verified+2 by Change Owner <change@owner.com>"),
+ c, /* changeMessage= */ "Removed Verified+2 by Change Owner <change@owner.com>"),
getAuthorIdent(changeOwner.getAccount()));
writeUpdate(
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
- c, /*changeMessage=*/ "Removed Verified-1 by Change Owner <other@test.com>"),
+ c, /* changeMessage= */ "Removed Verified-1 by Change Owner <other@test.com>"),
getAuthorIdent(changeOwner.getAccount()));
RunOptions options = new RunOptions();
@@ -1121,7 +1124,7 @@
// Even though footer is missing, accounts are matched among the account in change updates.
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed the following votes:\n"
+ /* changeMessage= */ "Removed the following votes:\n"
+ String.format("* Verified-1 by %s\n", otherUser.getNameEmail())),
getAuthorIdent(changeOwner.getAccount()));
@@ -1129,7 +1132,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed the following votes:\n"
+ /* changeMessage= */ "Removed the following votes:\n"
+ String.format("* Verified+2 by %s\n", changeOwner.getNameEmail())
+ String.format("* Verified-1 by %s\n", changeOwner.getNameEmail())
+ String.format("* Code-Review by %s\n", otherUser.getNameEmail())),
@@ -1140,7 +1143,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ "Removed the following votes:\n"
+ /* changeMessage= */ "Removed the following votes:\n"
+ "* Verified+2 by Gerrit Account\n"
+ "* Verified-1 by <GERRIT_ACCOUNT_2>\n"),
getAuthorIdent(changeOwner.getAccount()));
@@ -1200,7 +1203,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ null,
+ /* changeMessage= */ null,
// Only 'person_ident' fix is required
"Attention: "
+ gson.toJson(
@@ -1354,27 +1357,51 @@
assertThat(commitHistoryDiff.get(0))
.isEqualTo(
"@@ -8 +8 @@\n"
- + "-Attention: {\"person_ident\":\"Gerrit User 2 \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by Other Account using the hovercard menu\"}\n"
- + "+Attention: {\"person_ident\":\"Gerrit User 2 \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone using the hovercard menu\"}\n");
+ + "-Attention: {\"person_ident\":\"Gerrit User 2"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by Other"
+ + " Account using the hovercard menu\"}\n"
+ + "+Attention: {\"person_ident\":\"Gerrit User 2"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone"
+ + " using the hovercard menu\"}\n");
assertThat(Arrays.asList(commitHistoryDiff.get(1).split("\n")))
.containsExactly(
"@@ -7,2 +7,2 @@",
- "-Attention: {\"person_ident\":\"Gerrit User 1 \\u003c1@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Other Account replied on the change\"}",
- "-Attention: {\"person_ident\":\"Gerrit User 2 \\u003c2@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by Other Account using the hovercard menu\"}",
- "+Attention: {\"person_ident\":\"Gerrit User 1 \\u003c1@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Someone replied on the change\"}",
- "+Attention: {\"person_ident\":\"Gerrit User 2 \\u003c2@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by someone using the hovercard menu\"}");
+ "-Attention: {\"person_ident\":\"Gerrit User 1"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Other Account"
+ + " replied on the change\"}",
+ "-Attention: {\"person_ident\":\"Gerrit User 2"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by Other"
+ + " Account using the hovercard menu\"}",
+ "+Attention: {\"person_ident\":\"Gerrit User 1"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Someone replied on"
+ + " the change\"}",
+ "+Attention: {\"person_ident\":\"Gerrit User 2"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by"
+ + " someone using the hovercard menu\"}");
assertThat(Arrays.asList(commitHistoryDiff.get(2).split("\n")))
.containsExactly(
"@@ -7,2 +7,2 @@",
- "-Attention: {\"person_ident\":\"Other Account \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone using the hovercard menu\"}",
- "-Attention: {\"person_ident\":\"Change Owner \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Other Account replied on the change\"}",
- "+Attention: {\"person_ident\":\"Gerrit User 2 \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone using the hovercard menu\"}",
- "+Attention: {\"person_ident\":\"Gerrit User 1 \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Someone replied on the change\"}");
+ "-Attention: {\"person_ident\":\"Other Account"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone"
+ + " using the hovercard menu\"}",
+ "-Attention: {\"person_ident\":\"Change Owner"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Other Account"
+ + " replied on the change\"}",
+ "+Attention: {\"person_ident\":\"Gerrit User 2"
+ + " \\u003c2@gerrit\\u003e\",\"operation\":\"ADD\",\"reason\":\"Added by someone"
+ + " using the hovercard menu\"}",
+ "+Attention: {\"person_ident\":\"Gerrit User 1"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Someone replied"
+ + " on the change\"}");
assertThat(commitHistoryDiff.get(3))
.isEqualTo(
"@@ -7 +7 @@\n"
- + "-Attention: {\"person_ident\":\"Gerrit User 1 \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by Other Account by clicking the attention icon\"}\n"
- + "+Attention: {\"person_ident\":\"Gerrit User 1 \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by someone by clicking the attention icon\"}\n");
+ + "-Attention: {\"person_ident\":\"Gerrit User 1"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by Other"
+ + " Account by clicking the attention icon\"}\n"
+ + "+Attention: {\"person_ident\":\"Gerrit User 1"
+ + " \\u003c1@gerrit\\u003e\",\"operation\":\"REMOVE\",\"reason\":\"Removed by"
+ + " someone by clicking the attention icon\"}\n");
BackfillResult secondRunResult = rewriter.backfillProject(project, repo, options);
assertThat(secondRunResult.fixedRefDiff.keySet()).isEmpty();
assertThat(secondRunResult.refsFailedToFix).isEmpty();
@@ -1483,13 +1510,15 @@
commitsToFix.add(invalidCherryPickedMessageUpdate.commit());
ChangeUpdate invalidRebasedMessageUpdate = newUpdate(c, changeOwner);
invalidRebasedMessageUpdate.setChangeMessage(
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b by "
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b by "
+ changeOwner.getName());
commitsToFix.add(invalidRebasedMessageUpdate.commit());
ChangeUpdate validSubmitMessageUpdate = newUpdate(c, changeOwner);
validSubmitMessageUpdate.setChangeMessage(
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b");
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b");
validSubmitMessageUpdate.commit();
Ref metaRefBeforeRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
@@ -1512,15 +1541,21 @@
assertThat(changeMessages(notesBeforeRewrite))
.containsExactly(
"Change has been successfully merged by Change Owner",
- "Change has been successfully cherry-picked as e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner",
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner",
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b");
+ "Change has been successfully cherry-picked as e40dc1a50dc7f457a37579e2755374f3e1a5413b"
+ + " by Change Owner",
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner",
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b");
assertThat(changeMessages(notesAfterRewrite))
.containsExactly(
"Change has been successfully merged",
- "Change has been successfully cherry-picked as e40dc1a50dc7f457a37579e2755374f3e1a5413b",
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b",
- "Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b");
+ "Change has been successfully cherry-picked as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b",
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b",
+ "Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b");
Ref metaRefAfterRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
assertThat(metaRefAfterRewrite.getObjectId()).isNotEqualTo(metaRefBeforeRewrite.getObjectId());
@@ -1536,11 +1571,15 @@
+ "-Change has been successfully merged by Change Owner\n"
+ "+Change has been successfully merged\n",
"@@ -6 +6 @@\n"
- + "-Change has been successfully cherry-picked as e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner\n"
- + "+Change has been successfully cherry-picked as e40dc1a50dc7f457a37579e2755374f3e1a5413b\n",
+ + "-Change has been successfully cherry-picked as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner\n"
+ + "+Change has been successfully cherry-picked as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b\n",
"@@ -6 +6 @@\n"
- + "-Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner\n"
- + "+Change has been successfully rebased and submitted as e40dc1a50dc7f457a37579e2755374f3e1a5413b\n");
+ + "-Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b by Change Owner\n"
+ + "+Change has been successfully rebased and submitted as"
+ + " e40dc1a50dc7f457a37579e2755374f3e1a5413b\n");
BackfillResult secondRunResult = rewriter.backfillProject(project, repo, options);
assertThat(secondRunResult.fixedRefDiff.keySet()).isEmpty();
assertThat(secondRunResult.refsFailedToFix).isEmpty();
@@ -1610,7 +1649,7 @@
RefNames.changeMetaRef(c.getId()),
getChangeUpdateBody(
c,
- /*changeMessage=*/ null,
+ /* changeMessage= */ null,
"Label: SUBM=+1",
"Submission-id: 5271-1496917120975-10a10df9",
"Submitted-with: NOT_READY",
@@ -1876,59 +1915,72 @@
ChangeUpdate invalidOnReviewUpdate = newUpdate(c, changeOwner);
invalidOnReviewUpdate.setChangeMessage(
"Patch Set 1: Any-Label+2 Other-Label+2 Code-Review+2\n\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by Change Owner:\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by Change"
+ + " Owner:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n"
- + "By voting Other-Label+2 the code-owners submit requirement is still overridden by Change Owner\n");
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change"
+ + " Owner\n"
+ + "By voting Other-Label+2 the code-owners submit requirement is still overridden by"
+ + " Change Owner\n");
commitsToFix.add(invalidOnReviewUpdate.commit());
ChangeUpdate invalidOnReviewUpdateAnyOrder = newUpdate(c, changeOwner);
invalidOnReviewUpdateAnyOrder.setChangeMessage(
"Patch Set 1: Any-Label+2 Other-Label+2 Code-Review+2\n\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n"
- + "By voting Other-Label+2 the code-owners submit requirement is still overridden by Change Owner\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by Change Owner:\n"
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change"
+ + " Owner\n"
+ + "By voting Other-Label+2 the code-owners submit requirement is still overridden by"
+ + " Change Owner\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by Change"
+ + " Owner:\n"
+ " * file1.java\n"
+ " * file2.ts\n");
commitsToFix.add(invalidOnReviewUpdateAnyOrder.commit());
ChangeUpdate invalidOnApprovalUpdate = newUpdate(c, otherUser);
invalidOnApprovalUpdate.setChangeMessage(
"Patch Set 1: -Code-Review\n\n"
- + "By removing the Code-Review+2 vote the following files are no longer explicitly code-owner approved by Other Account:\n"
+ + "By removing the Code-Review+2 vote the following files are no longer explicitly"
+ + " code-owner approved by Other Account:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "\nThe listed files are still implicitly approved by Other Account.\n");
+ + "\n"
+ + "The listed files are still implicitly approved by Other Account.\n");
commitsToFix.add(invalidOnApprovalUpdate.commit());
ChangeUpdate invalidOnOverrideUpdate = newUpdate(c, changeOwner);
invalidOnOverrideUpdate.setChangeMessage(
"Patch Set 1: -Owners-Override\n\n"
+ "(1 comment)\n\n"
- + "By removing the Owners-Override+1 vote the code-owners submit requirement is no longer overridden by Change Owner\n");
+ + "By removing the Owners-Override+1 vote the code-owners submit requirement is no"
+ + " longer overridden by Change Owner\n");
commitsToFix.add(invalidOnOverrideUpdate.commit());
ChangeUpdate partiallyValidOnReviewUpdate = newUpdate(c, changeOwner);
partiallyValidOnReviewUpdate.setChangeMessage(
"Patch Set 1: Any-Label+2 Code-Review+2\n\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n");
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by Change"
+ + " Owner\n");
commitsToFix.add(partiallyValidOnReviewUpdate.commit());
ChangeUpdate validOnApprovalUpdate = newUpdate(c, changeOwner);
validOnApprovalUpdate.setChangeMessage(
"Patch Set 1: Code-Review-2\n\n"
- + "By voting Code-Review-2 the following files are no longer explicitly code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Code-Review-2 the following files are no longer explicitly code-owner"
+ + " approved by <GERRIT_ACCOUNT_1>:\n"
+ " * file4.java\n");
validOnApprovalUpdate.commit();
ChangeUpdate validOnOverrideUpdate = newUpdate(c, changeOwner);
validOnOverrideUpdate.setChangeMessage(
"Patch Set 1: Owners-Override+1\n\n"
- + "By voting Owners-Override+1 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n");
+ + "By voting Owners-Override+1 the code-owners submit requirement is still overridden"
+ + " by <GERRIT_ACCOUNT_1>\n");
validOnOverrideUpdate.commit();
Ref metaRefBeforeRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
@@ -1952,39 +2004,52 @@
assertThat(changeMessages(notesAfterRewrite))
.containsExactly(
"Patch Set 1: Any-Label+2 Other-Label+2 Code-Review+2\n\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n"
- + "By voting Other-Label+2 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n",
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n"
+ + "By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by <GERRIT_ACCOUNT_1>\n",
"Patch Set 1: Any-Label+2 Other-Label+2 Code-Review+2\n\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n"
- + "By voting Other-Label+2 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n"
+ + "By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by <GERRIT_ACCOUNT_1>\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n"
+ " * file1.java\n"
+ " * file2.ts\n",
"Patch Set 1: -Code-Review\n"
+ "\n"
- + "By removing the Code-Review+2 vote the following files are no longer explicitly code-owner approved by <GERRIT_ACCOUNT_2>:\n"
+ + "By removing the Code-Review+2 vote the following files are no longer explicitly"
+ + " code-owner approved by <GERRIT_ACCOUNT_2>:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "\nThe listed files are still implicitly approved by <GERRIT_ACCOUNT_2>.\n",
+ + "\n"
+ + "The listed files are still implicitly approved by <GERRIT_ACCOUNT_2>.\n",
"Patch Set 1: -Owners-Override\n"
+ "\n"
+ "(1 comment)\n"
+ "\n"
- + "By removing the Owners-Override+1 vote the code-owners submit requirement is no longer overridden by <GERRIT_ACCOUNT_1>\n",
+ + "By removing the Owners-Override+1 vote the code-owners submit requirement is no"
+ + " longer overridden by <GERRIT_ACCOUNT_1>\n",
"Patch Set 1: Any-Label+2 Code-Review+2\n\n"
- + "By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n"
+ " * file1.java\n"
+ " * file2.ts\n"
- + "By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n",
+ + "By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n",
"Patch Set 1: Code-Review-2\n\n"
- + "By voting Code-Review-2 the following files are no longer explicitly code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "By voting Code-Review-2 the following files are no longer explicitly code-owner"
+ + " approved by <GERRIT_ACCOUNT_1>:\n"
+ " * file4.java\n",
"Patch Set 1: Owners-Override+1\n"
+ "\n"
- + "By voting Owners-Override+1 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n");
+ + "By voting Owners-Override+1 the code-owners submit requirement is still"
+ + " overridden by <GERRIT_ACCOUNT_1>\n");
Ref metaRefAfterRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
assertThat(metaRefAfterRewrite.getObjectId()).isNotEqualTo(metaRefBeforeRewrite.getObjectId());
@@ -1997,32 +2062,50 @@
assertThat(commitHistoryDiff)
.containsExactly(
"@@ -8 +8 @@\n"
- + "-By voting Code-Review+2 the following files are now code-owner approved by Change Owner:\n"
- + "+By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n"
+ + "-By voting Code-Review+2 the following files are now code-owner approved by"
+ + " Change Owner:\n"
+ + "+By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n"
+ "@@ -11,2 +11,2 @@\n"
- + "-By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n"
- + "-By voting Other-Label+2 the code-owners submit requirement is still overridden by Change Owner\n"
- + "+By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n"
- + "+By voting Other-Label+2 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n",
+ + "-By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " Change Owner\n"
+ + "-By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by Change Owner\n"
+ + "+By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n"
+ + "+By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by <GERRIT_ACCOUNT_1>\n",
"@@ -8,3 +8,3 @@\n"
- + "-By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n"
- + "-By voting Other-Label+2 the code-owners submit requirement is still overridden by Change Owner\n"
- + "-By voting Code-Review+2 the following files are now code-owner approved by Change Owner:\n"
- + "+By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n"
- + "+By voting Other-Label+2 the code-owners submit requirement is still overridden by <GERRIT_ACCOUNT_1>\n"
- + "+By voting Code-Review+2 the following files are now code-owner approved by <GERRIT_ACCOUNT_1>:\n",
+ + "-By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " Change Owner\n"
+ + "-By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by Change Owner\n"
+ + "-By voting Code-Review+2 the following files are now code-owner approved by"
+ + " Change Owner:\n"
+ + "+By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n"
+ + "+By voting Other-Label+2 the code-owners submit requirement is still overridden"
+ + " by <GERRIT_ACCOUNT_1>\n"
+ + "+By voting Code-Review+2 the following files are now code-owner approved by"
+ + " <GERRIT_ACCOUNT_1>:\n",
"@@ -8 +8 @@\n"
- + "-By removing the Code-Review+2 vote the following files are no longer explicitly code-owner approved by Other Account:\n"
- + "+By removing the Code-Review+2 vote the following files are no longer explicitly code-owner approved by <GERRIT_ACCOUNT_2>:\n"
+ + "-By removing the Code-Review+2 vote the following files are no longer explicitly"
+ + " code-owner approved by Other Account:\n"
+ + "+By removing the Code-Review+2 vote the following files are no longer explicitly"
+ + " code-owner approved by <GERRIT_ACCOUNT_2>:\n"
+ "@@ -12 +12 @@\n"
+ "-The listed files are still implicitly approved by Other Account.\n"
+ "+The listed files are still implicitly approved by <GERRIT_ACCOUNT_2>.\n",
"@@ -10 +10 @@\n"
- + "-By removing the Owners-Override+1 vote the code-owners submit requirement is no longer overridden by Change Owner\n"
- + "+By removing the Owners-Override+1 vote the code-owners submit requirement is no longer overridden by <GERRIT_ACCOUNT_1>\n",
+ + "-By removing the Owners-Override+1 vote the code-owners submit requirement is no"
+ + " longer overridden by Change Owner\n"
+ + "+By removing the Owners-Override+1 vote the code-owners submit requirement is no"
+ + " longer overridden by <GERRIT_ACCOUNT_1>\n",
"@@ -11 +11 @@\n"
- + "-By voting Any-Label+2 the code-owners submit requirement is overridden by Change Owner\n"
- + "+By voting Any-Label+2 the code-owners submit requirement is overridden by <GERRIT_ACCOUNT_1>\n");
+ + "-By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " Change Owner\n"
+ + "+By voting Any-Label+2 the code-owners submit requirement is overridden by"
+ + " <GERRIT_ACCOUNT_1>\n");
BackfillResult secondRunResult = rewriter.backfillProject(project, repo, options);
assertThat(secondRunResult.fixedRefDiff.keySet()).isEmpty();
assertThat(secondRunResult.refsFailedToFix).isEmpty();
@@ -2039,34 +2122,30 @@
getChangeUpdateBody(c, "Assignee added", "Assignee: " + assigneeIdentToFix),
getAuthorIdent(changeOwner.getAccount()));
- ChangeUpdate changeAssigneeUpdate = newUpdate(c, changeOwner);
- changeAssigneeUpdate.setAssignee(otherUserId);
- changeAssigneeUpdate.commit();
-
- ChangeUpdate removeAssigneeUpdate = newUpdate(c, changeOwner);
- removeAssigneeUpdate.removeAssignee();
- removeAssigneeUpdate.commit();
+ // Valid commits
+ writeUpdate(
+ RefNames.changeMetaRef(c.getId()),
+ getChangeUpdateBody(
+ c,
+ "Assignee added: <GERRIT_ACCOUNT_2>",
+ "Assignee: " + getValidIdentAsString(otherUser.getAccount())),
+ getAuthorIdent(changeOwner.getAccount()));
+ writeUpdate(
+ RefNames.changeMetaRef(c.getId()),
+ getChangeUpdateBody(c, "Assignee deleted: <GERRIT_ACCOUNT_2>", "Assignee:"),
+ getAuthorIdent(changeOwner.getAccount()));
Ref metaRefBeforeRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
ImmutableList<RevCommit> commitsBeforeRewrite = logMetaRef(repo, metaRefBeforeRewrite);
int invalidCommitIndex = commitsBeforeRewrite.indexOf(invalidUpdateCommit);
- ChangeNotes notesBeforeRewrite = newNotes(c);
RunOptions options = new RunOptions();
options.dryRun = false;
BackfillResult result = rewriter.backfillProject(project, repo, options);
assertThat(result.fixedRefDiff.keySet()).containsExactly(RefNames.changeMetaRef(c.getId()));
- ChangeNotes notesAfterRewrite = newNotes(c);
- assertThat(notesBeforeRewrite.getPastAssignees())
- .containsExactly(changeOwner.getAccountId(), otherUser.getAccountId());
- assertThat(notesBeforeRewrite.getChange().getAssignee()).isNull();
- assertThat(notesAfterRewrite.getPastAssignees())
- .containsExactly(changeOwner.getAccountId(), otherUser.getAccountId());
- assertThat(notesAfterRewrite.getChange().getAssignee()).isNull();
-
Ref metaRefAfterRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
assertThat(metaRefAfterRewrite.getObjectId()).isNotEqualTo(metaRefBeforeRewrite.getObjectId());
@@ -2145,18 +2224,13 @@
assertThat(result.fixedRefDiff.keySet()).containsExactly(RefNames.changeMetaRef(c.getId()));
ChangeNotes notesAfterRewrite = newNotes(c);
- assertThat(notesBeforeRewrite.getPastAssignees())
- .containsExactly(changeOwner.getAccountId(), otherUser.getAccountId());
- assertThat(notesBeforeRewrite.getChange().getAssignee()).isNull();
assertThat(changeMessages(notesBeforeRewrite))
.containsExactly(
"Assignee added: Change Owner <change@owner.com>",
- "Assignee changed from: Change Owner <change@owner.com> to: Other Account <other@account.com>",
+ "Assignee changed from: Change Owner <change@owner.com> to: Other Account"
+ + " <other@account.com>",
"Assignee deleted: Other Account <other@account.com>");
- assertThat(notesAfterRewrite.getPastAssignees())
- .containsExactly(changeOwner.getAccountId(), otherUser.getAccountId());
- assertThat(notesAfterRewrite.getChange().getAssignee()).isNull();
assertThat(changeMessages(notesAfterRewrite))
.containsExactly(
"Assignee added: " + AccountTemplateUtil.getAccountTemplate(changeOwner.getAccountId()),
@@ -2181,7 +2255,8 @@
+ "-Assignee added: Change Owner <change@owner.com>\n"
+ "+Assignee added: <GERRIT_ACCOUNT_1>\n",
"@@ -6 +6 @@\n"
- + "-Assignee changed from: Change Owner <change@owner.com> to: Other Account <other@account.com>\n"
+ + "-Assignee changed from: Change Owner <change@owner.com> to: Other Account"
+ + " <other@account.com>\n"
+ "+Assignee changed from: <GERRIT_ACCOUNT_1> to: <GERRIT_ACCOUNT_2>\n",
"@@ -6 +6 @@\n"
+ "-Assignee deleted: Other Account <other@account.com>\n"
@@ -2244,7 +2319,8 @@
+ "-Assignee added: Change Owner\n"
+ "+Assignee added: <GERRIT_ACCOUNT_1>\n",
"@@ -6 +6 @@\n"
- + "-Assignee changed from: Change Owner <change@owner.com> to: Other Account <other@account.com>\n"
+ + "-Assignee changed from: Change Owner <change@owner.com> to: Other Account"
+ + " <other@account.com>\n"
+ "+Assignee changed from: <GERRIT_ACCOUNT_1> to: <GERRIT_ACCOUNT_2>\n",
"@@ -6 +6 @@\n"
+ "-Assignee deleted: Other Account\n"
@@ -2280,17 +2356,12 @@
ImmutableList<RevCommit> commitsBeforeRewrite = logMetaRef(repo, metaRefBeforeRewrite);
int invalidCommitIndex = commitsBeforeRewrite.indexOf(invalidUpdateCommit);
- ChangeNotes notesBeforeRewrite = newNotes(c);
RunOptions options = new RunOptions();
options.dryRun = false;
BackfillResult result = rewriter.backfillProject(project, repo, options);
assertThat(result.fixedRefDiff.keySet()).containsExactly(RefNames.changeMetaRef(c.getId()));
- ChangeNotes notesAfterRewrite = newNotes(c);
- assertThat(notesBeforeRewrite.getChange().getAssignee()).isEqualTo(otherUserId);
- assertThat(notesAfterRewrite.getChange().getAssignee()).isEqualTo(otherUserId);
-
Ref metaRefAfterRewrite = repo.exactRef(RefNames.changeMetaRef(c.getId()));
assertThat(metaRefAfterRewrite.getObjectId()).isNotEqualTo(metaRefBeforeRewrite.getObjectId());
diff --git a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 153c62c..96a8dea 100644
--- a/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -70,7 +70,6 @@
import com.google.gerrit.entities.Project;
import com.google.gerrit.entities.RefNames;
import com.google.gerrit.extensions.api.GerritApi;
-import com.google.gerrit.extensions.api.changes.AssigneeInput;
import com.google.gerrit.extensions.api.changes.AttentionSetInput;
import com.google.gerrit.extensions.api.changes.ChangeApi;
import com.google.gerrit.extensions.api.changes.Changes.QueryRequest;
@@ -3456,7 +3455,6 @@
private boolean wip;
private boolean abandoned;
@Nullable private Account.Id mergedBy;
- @Nullable private Account.Id assigneeId;
@Nullable Change.Id id;
@@ -3468,11 +3466,6 @@
deleteDraftCommentBy = new ArrayList<>();
}
- DashboardChangeState assignTo(Account.Id assigneeId) {
- this.assigneeId = assigneeId;
- return this;
- }
-
DashboardChangeState wip() {
wip = true;
return this;
@@ -3513,11 +3506,6 @@
Change change = insert("repo", newChange(repo), ownerId);
id = change.getId();
ChangeApi cApi = gApi.changes().id(change.getChangeId());
- if (assigneeId != null) {
- AssigneeInput in = new AssigneeInput();
- in.assignee = "" + assigneeId;
- cApi.setAssignee(in);
- }
if (wip) {
cApi.setWorkInProgress();
}
@@ -3595,33 +3583,6 @@
}
@Test
- public void dashboardAssignedReviews() throws Exception {
- repo = createAndOpenProject("repo");
- Account.Id otherAccountId = createAccount("other");
- DashboardChangeState otherOpenWip =
- new DashboardChangeState(otherAccountId).wip().assignTo(user.getAccountId()).create(repo);
- DashboardChangeState selfOpenWip =
- new DashboardChangeState(user.getAccountId())
- .wip()
- .assignTo(user.getAccountId())
- .create(repo);
-
- // Create changes that should not be returned by query.
- new DashboardChangeState(user.getAccountId()).assignTo(user.getAccountId()).abandon();
- new DashboardChangeState(user.getAccountId())
- .assignTo(user.getAccountId())
- .mergeBy(user.getAccountId());
-
- assertDashboardQuery(
- "self", IndexPreloadingUtil.DASHBOARD_ASSIGNED_QUERY, selfOpenWip, otherOpenWip);
-
- // Viewing another user's dashboard.
- requestContext.setContext(newRequestContext(otherAccountId));
- assertDashboardQuery(
- userId.toString(), IndexPreloadingUtil.DASHBOARD_ASSIGNED_QUERY, otherOpenWip);
- }
-
- @Test
public void dashboardWorkInProgressReviews() throws Exception {
repo = createAndOpenProject("repo");
DashboardChangeState ownedOpenWip =
@@ -3662,12 +3623,9 @@
Account.Id otherAccountId = createAccount("other");
DashboardChangeState reviewingReviewable =
new DashboardChangeState(otherAccountId).addReviewer(user.getAccountId()).create(repo);
- DashboardChangeState assignedReviewable =
- new DashboardChangeState(otherAccountId).assignTo(user.getAccountId()).create(repo);
// Create changes that should not be returned by any queries in this test.
new DashboardChangeState(otherAccountId).wip().addReviewer(user.getAccountId()).create(repo);
- new DashboardChangeState(otherAccountId).wip().assignTo(user.getAccountId()).create(repo);
new DashboardChangeState(otherAccountId).addReviewer(otherAccountId).create(repo);
new DashboardChangeState(otherAccountId)
.addReviewer(user.getAccountId())
@@ -3675,19 +3633,12 @@
.create(repo);
// Viewing one's own dashboard.
- assertDashboardQuery(
- "self",
- IndexPreloadingUtil.DASHBOARD_INCOMING_QUERY,
- assignedReviewable,
- reviewingReviewable);
+ assertDashboardQuery("self", IndexPreloadingUtil.DASHBOARD_INCOMING_QUERY, reviewingReviewable);
// Viewing another user's dashboard.
requestContext.setContext(newRequestContext(otherAccountId));
assertDashboardQuery(
- userId.toString(),
- IndexPreloadingUtil.DASHBOARD_INCOMING_QUERY,
- assignedReviewable,
- reviewingReviewable);
+ userId.toString(), IndexPreloadingUtil.DASHBOARD_INCOMING_QUERY, reviewingReviewable);
}
@Test
@@ -3706,11 +3657,6 @@
.addCc(user.getAccountId())
.mergeBy(user.getAccountId())
.create(repo);
- DashboardChangeState mergedAssigned =
- new DashboardChangeState(otherAccountId)
- .assignTo(user.getAccountId())
- .mergeBy(user.getAccountId())
- .create(repo);
DashboardChangeState abandonedOwned =
new DashboardChangeState(user.getAccountId()).abandon().create(repo);
DashboardChangeState abandonedOwnedWip =
@@ -3720,17 +3666,6 @@
.addReviewer(user.getAccountId())
.abandon()
.create(repo);
- DashboardChangeState abandonedAssigned =
- new DashboardChangeState(otherAccountId)
- .assignTo(user.getAccountId())
- .abandon()
- .create(repo);
- DashboardChangeState abandonedAssignedWip =
- new DashboardChangeState(otherAccountId)
- .assignTo(user.getAccountId())
- .wip()
- .abandon()
- .create(repo);
// Create changes that should not be returned by any queries in this test.
new DashboardChangeState(otherAccountId)
@@ -3743,11 +3678,9 @@
assertDashboardQuery(
"self",
IndexPreloadingUtil.DASHBOARD_RECENTLY_CLOSED_QUERY,
- abandonedAssigned,
abandonedReviewing,
abandonedOwnedWip,
abandonedOwned,
- mergedAssigned,
mergedCced,
mergedReviewing,
mergedOwned);
@@ -3757,11 +3690,8 @@
assertDashboardQuery(
userId.toString(),
IndexPreloadingUtil.DASHBOARD_RECENTLY_CLOSED_QUERY,
- abandonedAssignedWip,
- abandonedAssigned,
abandonedReviewing,
abandonedOwned,
- mergedAssigned,
mergedCced,
mergedReviewing,
mergedOwned);
@@ -3822,24 +3752,6 @@
assertThat(changeInfo.attentionSet.get(user2Id.get()).reason).isEqualTo("reason 2");
}
- @Test
- public void assignee() throws Exception {
- repo = createAndOpenProject("repo");
- Change change1 = insert("repo", newChange(repo));
- Change change2 = insert("repo", newChange(repo));
-
- AssigneeInput input = new AssigneeInput();
- input.assignee = user.getAccountId().toString();
- gApi.changes().id(change1.getChangeId()).setAssignee(input);
-
- assertQuery("is:assigned", change1);
- assertQuery("-is:assigned", change2);
- assertQuery("is:unassigned", change2);
- assertQuery("-is:unassigned", change1);
- assertQuery("assignee:" + user.getAccountId(), change1);
- assertQuery("-assignee:" + user.getAccountId(), change2);
- }
-
@GerritConfig(name = "accounts.visibility", value = "NONE")
@Test
public void userDestination() throws Exception {
@@ -3986,14 +3898,6 @@
}
@Test
- public void byOwnerInvalidQuery() throws Exception {
- repo = createAndOpenProject("repo");
- insert("repo", newChange(repo), userId);
- String nameEmail = user.asIdentifiedUser().getNameEmail();
- assertQuery("owner: \"" + nameEmail + "\"\\");
- }
-
- @Test
public void byDeletedChange() throws Exception {
repo = createAndOpenProject("repo");
Change change = insert("repo", newChange(repo));
@@ -4067,7 +3971,7 @@
@Test
public void selfFailsForAnonymousUser() throws Exception {
- for (String query : ImmutableList.of("assignee:self", "has:star", "is:starred")) {
+ for (String query : ImmutableList.of("has:star", "is:starred")) {
assertQuery(query);
RequestContext oldContext = requestContext.setContext(anonymousUserProvider::get);
diff --git a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
index 5cae012..7f383f9 100644
--- a/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
+++ b/javatests/com/google/gerrit/server/query/change/LuceneQueryChangesTest.java
@@ -59,16 +59,9 @@
}
@Test
- @Override
- public void byOwnerInvalidQuery() throws Exception {
- repo = createAndOpenProject("repo");
- Change change1 = insert("repo", newChange(repo), userId);
- String nameEmail = user.asIdentifiedUser().getNameEmail();
-
+ public void invalidQuery() throws Exception {
BadRequestException thrown =
- assertThrows(
- BadRequestException.class,
- () -> assertQuery("owner: \"" + nameEmail + "\"\\", change1));
+ assertThrows(BadRequestException.class, () -> newQuery("\\").get());
assertThat(thrown).hasMessageThat().contains("Cannot create full-text query with value: \\");
}
diff --git a/package.json b/package.json
index ae1bb2f..362b9dc 100644
--- a/package.json
+++ b/package.json
@@ -35,8 +35,8 @@
"scripts": {
"setup": "yarn && yarn --cwd=polygerrit-ui && yarn --cwd=polygerrit-ui/app",
"clean": "git clean -fdx && bazel clean --expunge",
- "compile:local": "tsc --project ./polygerrit-ui/app/tsconfig.json",
- "compile:watch": "npm run compile:local -- --preserveWatchOutput --watch",
+ "compile": "tsc --project ./polygerrit-ui/app/tsconfig.json",
+ "compile:watch": "npm run compile -- --preserveWatchOutput --watch",
"start": "run-p -rl compile:watch start:server",
"start:server": "web-dev-server",
"test": "yarn --cwd=polygerrit-ui test",
@@ -50,7 +50,8 @@
"safe_bazelisk": "if which bazelisk >/dev/null; then bazel_bin=bazelisk; else bazel_bin=bazel; fi && $bazel_bin",
"eslint": "npm run safe_bazelisk test polygerrit-ui/app:lint_test",
"eslintfix": "npm run safe_bazelisk run polygerrit-ui/app:lint_bin -- -- --fix $(pwd)/polygerrit-ui/app",
- "litlint": "npm run safe_bazelisk run polygerrit-ui/app:lit_analysis"
+ "litlint": "npm run safe_bazelisk run polygerrit-ui/app:lit_analysis",
+ "lint": "eslint -c polygerrit-ui/app/.eslintrc.js --ignore-path polygerrit-ui/app/.eslintignore polygerrit-ui/app"
},
"repository": {
"type": "git",
diff --git a/plugins/package.json b/plugins/package.json
index 331a417..b7e373a 100644
--- a/plugins/package.json
+++ b/plugins/package.json
@@ -3,7 +3,7 @@
"description": "Gerrit Code Review - frontend plugin dependencies, each plugin may depend on a subset of these",
"browser": true,
"dependencies": {
- "@gerritcodereview/typescript-api": "3.7.0",
+ "@gerritcodereview/typescript-api": "3.8.0",
"@polymer/decorators": "^3.0.0",
"@polymer/polymer": "^3.4.1",
"@open-wc/testing": "^3.1.6",
diff --git a/plugins/yarn.lock b/plugins/yarn.lock
index 368b3e0..010bf92 100644
--- a/plugins/yarn.lock
+++ b/plugins/yarn.lock
@@ -35,10 +35,10 @@
dependencies:
"@types/chai" "^4.2.12"
-"@gerritcodereview/typescript-api@3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@gerritcodereview/typescript-api/-/typescript-api-3.7.0.tgz#ae3886b5c4ddc6a02659a11d577e1df0b6158727"
- integrity sha512-8zeZClN1gur+Isrn02bRXJ0wUjYvK99jQxg36ZbDelrGDglXKddf8QQkZmaH9sYIRcCFDLlh5+ZlRUTcXTuDVA==
+"@gerritcodereview/typescript-api@3.8.0":
+ version "3.8.0"
+ resolved "https://registry.yarnpkg.com/@gerritcodereview/typescript-api/-/typescript-api-3.8.0.tgz#2e418b814d7451c40365b2dc4f88e9965ece0769"
+ integrity sha512-wUkIWUx99Rj1vxRYQISxyzN0nplqu7t5sRDyJ8R3yNNkvALQAMC6Whj63qzCsZsymVFzC5up3y+ZVxaeh7b+xA==
"@lit/reactive-element@^1.0.0", "@lit/reactive-element@^1.3.0", "@lit/reactive-element@^1.4.0":
version "1.4.1"
diff --git a/polygerrit-ui/README.md b/polygerrit-ui/README.md
index 510ce54..a89c0b7 100644
--- a/polygerrit-ui/README.md
+++ b/polygerrit-ui/README.md
@@ -189,7 +189,7 @@
Compiling code:
```sh
# Compile frontend once to check for type errors:
-yarn compile:local
+yarn compile
# Watch mode:
yarn compile:watch
diff --git a/polygerrit-ui/app/.eslintrc.js b/polygerrit-ui/app/.eslintrc.js
index c519465..89259dc 100644
--- a/polygerrit-ui/app/.eslintrc.js
+++ b/polygerrit-ui/app/.eslintrc.js
@@ -399,19 +399,6 @@
},
},
{
- files: ['test/functional/**/*.js'],
- // Settings for functional tests. These scripts are node scripts.
- // Turn off "no-undef" to allow any global variable
- env: {
- browser: false,
- node: true,
- es6: false,
- },
- rules: {
- 'no-undef': 'off',
- },
- },
- {
files: ['*_html.js', 'gr-icons.js', '*-theme.js', '*-styles.js'],
rules: {
'max-len': 'off',
diff --git a/polygerrit-ui/app/api/package.json b/polygerrit-ui/app/api/package.json
index 79c8bb6..7df755b 100644
--- a/polygerrit-ui/app/api/package.json
+++ b/polygerrit-ui/app/api/package.json
@@ -1,9 +1,9 @@
{
"name": "@gerritcodereview/typescript-api",
- "version": "3.7.0",
+ "version": "3.8.0",
"description": "Gerrit Code Review - TypeScript API",
"homepage": "https://www.gerritcodereview.com/",
"browser": true,
"dependencies": {},
"license": "Apache-2.0"
-}
+}
\ No newline at end of file
diff --git a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.ts b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.ts
index 312f384..bef3166 100644
--- a/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.ts
+++ b/polygerrit-ui/app/elements/change-list/gr-change-list/gr-change-list_test.ts
@@ -513,7 +513,6 @@
test('obsolete column in preferences not visible', () => {
assert.isTrue(element.isColumnEnabled('Subject'));
- assert.isFalse(element.isColumnEnabled('Assignee'));
});
test('showStar and showNumber', async () => {
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
index 371e5b5..72a6a3a 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view.ts
@@ -2080,13 +2080,7 @@
// Private but used in tests.
viewStateChanged() {
if (!this.viewState) return;
-
- if (this.isChangeObsolete()) {
- // Tell the app element that we are not going to handle the new change
- // number and that they have to create a new change view.
- fireEvent(this, EventType.RECREATE_CHANGE_VIEW);
- return;
- }
+ if (this.isChangeObsolete()) return;
if (this.viewState.basePatchNum === undefined)
this.viewState.basePatchNum = PARENT;
diff --git a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
index 9b78e64..ac4c1f9 100644
--- a/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
+++ b/polygerrit-ui/app/elements/change/gr-change-view/gr-change-view_test.ts
@@ -1557,21 +1557,6 @@
assert.isOk(element.patchRange?.patchNum);
});
- test('do not handle new change numbers', async () => {
- const recreateSpy = sinon.spy();
- element.addEventListener('recreate-change-view', recreateSpy);
-
- const value: ChangeViewState = createChangeViewState();
- element.viewState = value;
- await element.updateComplete;
- assert.isFalse(recreateSpy.calledOnce);
-
- value.changeNum = 555111333 as NumericChangeId;
- element.viewState = {...value};
- await element.updateComplete;
- assert.isTrue(recreateSpy.calledOnce);
- });
-
test('related changes are updated when loadData is called', async () => {
await element.updateComplete;
const relatedChanges = element.shadowRoot!.querySelector(
diff --git a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
index 218594b..f3c23aa 100644
--- a/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
+++ b/polygerrit-ui/app/elements/change/gr-reply-dialog/gr-reply-dialog.ts
@@ -588,7 +588,7 @@
border: 1px solid var(--border-color);
border-radius: var(--border-radius);
margin-top: var(--spacing-m);
- background-color: var(--assignee-highlight-color);
+ background-color: var(--line-item-highlight-color);
}
.attentionTip div gr-icon {
margin-right: var(--spacing-s);
diff --git a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
index 4f7d56f..997d9d5 100644
--- a/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
+++ b/polygerrit-ui/app/elements/core/gr-router/gr-router.ts
@@ -1310,15 +1310,17 @@
const repo = ctx.params[0] as RepoName;
const commentId = ctx.params[2] as UrlEncodedCommentId;
- const [comments, robotComments, change] = await Promise.all([
+ const [comments, robotComments, drafts, change] = await Promise.all([
this.restApiService.getDiffComments(changeNum),
this.restApiService.getDiffRobotComments(changeNum),
+ this.restApiService.getDiffDrafts(changeNum),
this.restApiService.getChangeDetail(changeNum),
]);
const comment =
findComment(addPath(comments), commentId) ??
- findComment(addPath(robotComments), commentId);
+ findComment(addPath(robotComments), commentId) ??
+ findComment(addPath(drafts), commentId);
const path = comment?.path;
const patchsets = computeAllPatchSets(change);
const latestPatchNum = computeLatestPatchNum(patchsets);
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
index c74993f..c7d6948 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -53,11 +53,7 @@
import {CommentSide, DiffViewMode, Side} from '../../../constants/constants';
import {GrApplyFixDialog} from '../gr-apply-fix-dialog/gr-apply-fix-dialog';
import {CommentMap} from '../../../utils/comment-util';
-import {
- EventType,
- OpenFixPreviewEvent,
- ValueChangedEvent,
-} from '../../../types/events';
+import {OpenFixPreviewEvent, ValueChangedEvent} from '../../../types/events';
import {fireAlert, fireEvent, fireTitleChange} from '../../../utils/event-util';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {Key, toggleClass, whenVisible} from '../../../utils/dom-util';
@@ -417,14 +413,12 @@
changeNum => {
if (!changeNum || this.changeNum === changeNum) return;
- // We are only setting the changeNum of the diff view once!
+ // We are only setting the changeNum of the diff view once.
// Everything in the diff view is tied to the change. It seems better to
// force the re-creation of the diff view when the change number changes.
- if (!this.changeNum) {
- this.changeNum = changeNum;
- } else {
- fireEvent(this, EventType.RECREATE_DIFF_VIEW);
- }
+ // The parent element will make sure that a new change view is created
+ // when the change number changes (using the `keyed` directive).
+ if (!this.changeNum) this.changeNum = changeNum;
}
);
subscribe(
diff --git a/polygerrit-ui/app/elements/gr-app-element.ts b/polygerrit-ui/app/elements/gr-app-element.ts
index eceb05e..b096f76 100644
--- a/polygerrit-ui/app/elements/gr-app-element.ts
+++ b/polygerrit-ui/app/elements/gr-app-element.ts
@@ -32,7 +32,7 @@
import {navigationToken} from './core/gr-navigation/gr-navigation';
import {getAppContext} from '../services/app-context';
import {routerToken} from './core/gr-router/gr-router';
-import {AccountDetailInfo} from '../types/common';
+import {AccountDetailInfo, NumericChangeId} from '../types/common';
import {
constructServerErrorMsg,
GrErrorManager,
@@ -62,6 +62,7 @@
import {customElement, property, query, state} from 'lit/decorators.js';
import {Shortcut, ShortcutController} from './lit/shortcut-controller';
import {cache} from 'lit/directives/cache.js';
+import {keyed} from 'lit/directives/keyed.js';
import {assertIsDefined} from '../utils/common-util';
import './gr-css-mixins';
import {isDarkTheme, prefersDarkColorScheme} from '../utils/theme-util';
@@ -123,6 +124,9 @@
// TODO: Introduce a wrapper element for CHANGE, DIFF, EDIT view.
@state() private childView?: ChangeChildView;
+ // Used as a key for caching the CHANGE, DIFF, EDIT view.
+ @state() private changeNum?: NumericChangeId;
+
@state() private lastError?: ErrorInfo;
// private but used in test
@@ -148,12 +152,6 @@
// (e.g. shortcut dialog) is open
@state() private mainAriaHidden = false;
- // Triggers dom-if unsetting/setting restamp behaviour in lit
- @state() private invalidateChangeViewCache = false;
-
- // Triggers dom-if unsetting/setting restamp behaviour in lit
- @state() private invalidateDiffViewCache = false;
-
@state() private theme = AppTheme.AUTO;
readonly getRouter = resolve(this, routerToken);
@@ -189,12 +187,6 @@
document.addEventListener(EventType.LOCATION_CHANGE, () =>
this.handleLocationChange()
);
- this.addEventListener(EventType.RECREATE_CHANGE_VIEW, () =>
- this.handleRecreateView()
- );
- this.addEventListener(EventType.RECREATE_DIFF_VIEW, () =>
- this.handleRecreateView()
- );
document.addEventListener(EventType.GR_RPC_LOG, e => this.handleRpcLog(e));
this.shortcuts.addAbstract(Shortcut.OPEN_SHORTCUT_HELP_DIALOG, () =>
this.showKeyboardShortcuts()
@@ -246,8 +238,13 @@
subscribe(
this,
() => this.getChangeViewModel().childView$,
- childView => {
- this.childView = childView;
+ childView => (this.childView = childView)
+ );
+ subscribe(
+ this,
+ () => this.getChangeViewModel().changeNum$,
+ changeNum => {
+ this.changeNum = changeNum;
}
);
@@ -375,8 +372,19 @@
${this.renderHeader()}
<main ?aria-hidden=${this.mainAriaHidden}>
${this.renderMobileSearch()} ${this.renderChangeListView()}
- ${this.renderDashboardView()} ${this.renderChangeView()}
- ${this.renderEditorView()} ${this.renderDiffView()}
+ ${this.renderDashboardView()}
+ ${
+ // `keyed(this.changeNum, ...)` makes sure that these views are not
+ // re-used across changes, which is a precaution, because we have run
+ // into issue with that. That could be re-considered at some point.
+ keyed(
+ this.changeNum,
+ html`
+ ${this.renderChangeView()} ${this.renderEditorView()}
+ ${this.renderDiffView()}
+ `
+ )
+ }
${this.renderSettingsView()} ${this.renderAdminView()}
${this.renderPluginScreen()} ${this.renderCLAView()}
${this.renderDocumentationSearch()}
@@ -473,18 +481,15 @@
}
private renderChangeView() {
- if (this.invalidateChangeViewCache) {
- this.updateComplete.then(() => (this.invalidateChangeViewCache = false));
- return nothing;
- }
- return cache(this.isChangeView() ? this.changeViewTemplate() : nothing);
- }
-
- // Template as not to create duplicates, for renderChangeView() only.
- private changeViewTemplate() {
- return html`
- <gr-change-view .backPage=${this.lastSearchPage}></gr-change-view>
- `;
+ // The `cache()` is required for re-using the change view when switching
+ // back and forth between change, diff and editor views.
+ return cache(
+ this.isChangeView()
+ ? html`<gr-change-view
+ .backPage=${this.lastSearchPage}
+ ></gr-change-view>`
+ : nothing
+ );
}
private isChangeView() {
@@ -494,9 +499,11 @@
);
}
- private isDiffView() {
- return (
- this.view === GerritView.CHANGE && this.childView === ChangeChildView.DIFF
+ private renderEditorView() {
+ // The `cache()` is required for re-using the editor view when switching
+ // back and forth between change, diff and editor views.
+ return cache(
+ this.isEditorView() ? html`<gr-editor-view></gr-editor-view>` : nothing
);
}
@@ -506,21 +513,18 @@
);
}
- private renderEditorView() {
- if (!this.isEditorView()) return nothing;
- return html`<gr-editor-view></gr-editor-view>`;
- }
-
private renderDiffView() {
- if (this.invalidateDiffViewCache) {
- this.updateComplete.then(() => (this.invalidateDiffViewCache = false));
- return nothing;
- }
- return cache(this.isDiffView() ? this.diffViewTemplate() : nothing);
+ // The `cache()` is required for re-using the diff view when switching
+ // back and forth between change, diff and editor views.
+ return cache(
+ this.isDiffView() ? html`<gr-diff-view></gr-diff-view>` : nothing
+ );
}
- private diffViewTemplate() {
- return html`<gr-diff-view></gr-diff-view>`;
+ private isDiffView() {
+ return (
+ this.view === GerritView.CHANGE && this.childView === ChangeChildView.DIFF
+ );
}
private renderSettingsView() {
@@ -619,15 +623,6 @@
(this.account && this.account._account_id) || null;
}
- /**
- * Throws away the view and re-creates it. The view itself fires an event, if
- * it wants to be re-created.
- */
- private handleRecreateView() {
- this.invalidateChangeViewCache = true;
- this.invalidateDiffViewCache = true;
- }
-
private async viewChanged() {
if (
this.params &&
diff --git a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
index 3187ada..cf279ba 100644
--- a/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
+++ b/polygerrit-ui/app/elements/shared/gr-formatted-text/gr-formatted-text_test.ts
@@ -69,19 +69,19 @@
});
test('does not apply rewrites within links', async () => {
- element.content = 'google.com/LinkRewriteMe';
+ element.content = 'http://google.com/LinkRewriteMe';
await element.updateComplete;
assert.shadowDom.equal(
element,
/* HTML */ `
<pre class="plaintext">
- <a
+ http://google.com/<a
href="http://google.com/LinkRewriteMe"
rel="noopener"
target="_blank"
>
- google.com/LinkRewriteMe
+ LinkRewriteMe
</a>
</pre>
`
@@ -149,20 +149,18 @@
});
test('renders text with links and rewrites', async () => {
- element.content = `text with plain link: google.com
- \ntext with config link: LinkRewriteMe
- \ntext with complex link: A Link 12`;
+ element.content = `
+ text with plain link: http://google.com
+ text with config link: LinkRewriteMe
+ text with complex link: A Link 12`;
await element.updateComplete;
assert.shadowDom.equal(
element,
/* HTML */ `
<pre class="plaintext">
- text with plain link:
- <a href="http://google.com" rel="noopener" target="_blank">
- google.com
- </a>
- text with config link:
+ text with plain link: http://google.com
+ text with config link:
<a
href="http://google.com/LinkRewriteMe"
rel="noopener"
@@ -212,7 +210,7 @@
});
test('renders text with links and rewrites', async () => {
element.content = `text
- \ntext with plain link: google.com
+ \ntext with plain link: http://google.com
\ntext with config link: LinkRewriteMe
\ntext without a link: NotA Link 15 cats
\ntext with complex link: A Link 12`;
@@ -227,7 +225,7 @@
<p>
text with plain link:
<a href="http://google.com" rel="noopener" target="_blank">
- google.com
+ http://google.com
</a>
</p>
<p>
@@ -259,7 +257,7 @@
test('does not render if too long', async () => {
element.content = `text
- text with plain link: google.com
+ text with plain link: http://google.com
text with config link: LinkRewriteMe
text without a link: NotA Link 15 cats
text with complex link: A Link 12`;
@@ -271,9 +269,8 @@
/* HTML */ `
<pre class="plaintext">
text
- text with plain link:
- <a href="http://google.com" rel="noopener" target="_blank">google.com</a>
- text with config link:
+ text with plain link: http://google.com
+ text with config link:
<a
href="http://google.com/LinkRewriteMe"
rel="noopener"
@@ -302,7 +299,7 @@
\n#### h4-heading
\n##### h5-heading
\n###### h6-heading
- \n# heading with plain link: google.com
+ \n# heading with plain link: http://google.com
\n# heading with config link: LinkRewriteMe`;
await element.updateComplete;
@@ -320,7 +317,7 @@
<h1>
heading with plain link:
<a href="http://google.com" rel="noopener" target="_blank">
- google.com
+ http://google.com
</a>
</h1>
<h1>
@@ -480,7 +477,7 @@
test('renders block quotes with links and rewrites', async () => {
element.content = `> block quote
- \n> block quote with plain link: google.com
+ \n> block quote with plain link: http://google.com
\n> block quote with config link: LinkRewriteMe`;
await element.updateComplete;
@@ -496,7 +493,7 @@
<p>
block quote with plain link:
<a href="http://google.com" rel="noopener" target="_blank">
- google.com
+ http://google.com
</a>
</p>
</blockquote>
diff --git a/polygerrit-ui/app/models/views/change_test.ts b/polygerrit-ui/app/models/views/change_test.ts
index 1e71bbd..837e362 100644
--- a/polygerrit-ui/app/models/views/change_test.ts
+++ b/polygerrit-ui/app/models/views/change_test.ts
@@ -74,7 +74,7 @@
...createChangeViewState(),
repo: 'x+/y+/z+/w' as RepoName,
};
- assert.equal(createChangeUrl(state), '/c/x%2B/y%2B/z%2B/w/+/42');
+ assert.equal(createChangeUrl(state), '/c/x%252B/y%252B/z%252B/w/+/42');
});
test('createDiffUrl', () => {
@@ -85,7 +85,7 @@
};
assert.equal(
createDiffUrl(params),
- '/c/test-project/+/42/12/x%2By/path.cpp'
+ '/c/test-project/+/42/12/x%252By/path.cpp'
);
window.CANONICAL_PATH = '/base';
@@ -93,10 +93,10 @@
window.CANONICAL_PATH = undefined;
params.repo = 'test' as RepoName;
- assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/test/+/42/12/x%252By/path.cpp');
params.basePatchNum = 6 as BasePatchSetNum;
- assert.equal(createDiffUrl(params), '/c/test/+/42/6..12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/test/+/42/6..12/x%252By/path.cpp');
params.diffView = {
path: 'foo bar/my+file.txt%',
@@ -105,7 +105,7 @@
delete params.basePatchNum;
assert.equal(
createDiffUrl(params),
- '/c/test/+/42/2/foo+bar/my%2Bfile.txt%2525'
+ '/c/test/+/42/2/foo+bar/my%252Bfile.txt%2525'
);
params.diffView = {
@@ -129,7 +129,7 @@
repo: 'x+/y' as RepoName,
diffView: {path: 'x+y/path.cpp'},
};
- assert.equal(createDiffUrl(params), '/c/x%2B/y/+/42/12/x%2By/path.cpp');
+ assert.equal(createDiffUrl(params), '/c/x%252B/y/+/42/12/x%252By/path.cpp');
});
test('createEditUrl', () => {
@@ -140,7 +140,7 @@
};
assert.equal(
createEditUrl(params),
- '/c/test-project/+/42/12/x%2By/path.cpp,edit#31'
+ '/c/test-project/+/42/12/x%252By/path.cpp,edit#31'
);
window.CANONICAL_PATH = '/base';
diff --git a/polygerrit-ui/app/node_modules_licenses/licenses.ts b/polygerrit-ui/app/node_modules_licenses/licenses.ts
index c65e7a31..155dd6c 100644
--- a/polygerrit-ui/app/node_modules_licenses/licenses.ts
+++ b/polygerrit-ui/app/node_modules_licenses/licenses.ts
@@ -329,14 +329,6 @@
license: SharedLicenses.Polymer2018,
},
{
- name: 'ba-linkify',
- license: {
- name: 'ba-linkify',
- type: LicenseTypes.Mit,
- packageLicenseFile: 'LICENSE-MIT',
- },
- },
- {
name: 'codemirror-minified',
license: {
name: 'codemirror-minified',
diff --git a/polygerrit-ui/app/package.json b/polygerrit-ui/app/package.json
index 0df1eda..41f4043 100644
--- a/polygerrit-ui/app/package.json
+++ b/polygerrit-ui/app/package.json
@@ -34,7 +34,6 @@
"@types/resize-observer-browser": "^0.1.5",
"@webcomponents/shadycss": "^1.10.2",
"@webcomponents/webcomponentsjs": "^1.3.3",
- "ba-linkify": "^1.0.1",
"codemirror-minified": "^5.65.0",
"highlight.js": "^11.5.0",
"highlightjs-closure-templates": "https://github.com/highlightjs/highlightjs-closure-templates",
@@ -50,4 +49,4 @@
},
"license": "Apache-2.0",
"private": true
-}
\ No newline at end of file
+}
diff --git a/polygerrit-ui/app/services/gr-reporting/gr-reporting_impl.ts b/polygerrit-ui/app/services/gr-reporting/gr-reporting_impl.ts
index b81f6d5..06e8204 100644
--- a/polygerrit-ui/app/services/gr-reporting/gr-reporting_impl.ts
+++ b/polygerrit-ui/app/services/gr-reporting/gr-reporting_impl.ts
@@ -188,13 +188,22 @@
export function initWebVitals(reportingService: ReportingService) {
function reportWebVitalMetric(name: Timing, metric: Metric) {
+ let score = metric.value;
+ // CLS good score is 0.1 and poor score is 0.25. Logging system
+ // prefers integers, so we multiple by 100;
+ if (name === Timing.CLS) {
+ score *= 100;
+ }
reportingService.reporter(
TIMING.TYPE,
TIMING.CATEGORY.UI_LATENCY,
name,
- metric.value,
- JSON.stringify(metric),
- false
+ score,
+ {
+ navigationType: metric.navigationType,
+ rating: metric.rating,
+ entries: metric.entries,
+ }
);
}
diff --git a/polygerrit-ui/app/styles/gr-change-list-styles.ts b/polygerrit-ui/app/styles/gr-change-list-styles.ts
index 3763213..34cf872 100644
--- a/polygerrit-ui/app/styles/gr-change-list-styles.ts
+++ b/polygerrit-ui/app/styles/gr-change-list-styles.ts
@@ -14,11 +14,11 @@
background-color: var(--selection-background-color);
}
gr-change-list-item[highlight] {
- background-color: var(--assignee-highlight-color);
+ background-color: var(--line-item-highlight-color);
}
gr-change-list-item[highlight][selected],
gr-change-list-item[highlight]:focus {
- background-color: var(--assignee-highlight-selection-color);
+ background-color: var(--line-item-highlight-selection-color);
}
.groupTitle td,
.cell {
diff --git a/polygerrit-ui/app/styles/themes/app-theme.ts b/polygerrit-ui/app/styles/themes/app-theme.ts
index 659ec9b..107ee16 100644
--- a/polygerrit-ui/app/styles/themes/app-theme.ts
+++ b/polygerrit-ui/app/styles/themes/app-theme.ts
@@ -248,10 +248,13 @@
--table-subheader-background-color: var(--background-color-tertiary);
--view-background-color: var(--background-color-primary);
/* unique background colors */
+ /* TODO: Remove assignee colors once references are migrated */
--assignee-highlight-color: #fcfad6;
- /* TODO: Find a nicer way to combine the --assignee-highlight-color and the
- --selection-background-color than to just invent another unique color. */
--assignee-highlight-selection-color: #f6f4d0;
+ --line-item-highlight-color: #fcfad6;
+ /* TODO: Find a nicer way to combine the --line-item-highlight-color and the
+ --selection-background-color than to just invent another unique color. */
+ --line-item-highlight-selection-color: #f6f4d0;
--chip-selected-background-color: var(--blue-50);
--edit-mode-background-color: #ebf5fb;
--emphasis-color: #fff9c4;
diff --git a/polygerrit-ui/app/styles/themes/dark-theme.ts b/polygerrit-ui/app/styles/themes/dark-theme.ts
index 5e414f0..a183c86 100644
--- a/polygerrit-ui/app/styles/themes/dark-theme.ts
+++ b/polygerrit-ui/app/styles/themes/dark-theme.ts
@@ -123,8 +123,8 @@
/* directly derived from primary background colors */
/* empty, because inheriting from app-theme is just fine
/* unique background colors */
- --assignee-highlight-color: #3a361c;
- --assignee-highlight-selection-color: #423e24;
+ --line-item-highlight-color: #3a361c;
+ --line-item-highlight-selection-color: #423e24;
--chip-selected-background-color: #3c4455;
--edit-mode-background-color: #5c0a36;
--emphasis-color: #383f4a;
diff --git a/polygerrit-ui/app/test/functional/README.md b/polygerrit-ui/app/test/functional/README.md
deleted file mode 100644
index 82c6133..0000000
--- a/polygerrit-ui/app/test/functional/README.md
+++ /dev/null
@@ -1,54 +0,0 @@
-# Functional test suite
-
-## Installing Docker (OSX)
-
-Simplest way to install all of those is to use Homebrew:
-
-```
-brew cask install docker
-```
-
-This will install a Docker in Applications. To run if from the command-line:
-
-```
-open /Applications/Docker.app
-```
-
-It'll require privileged access and will require user password to be entered.
-
-To validate Docker is installed correctly, run hello-world image:
-
-```
-docker run hello-world
-```
-
-## Building a Docker image
-
-Should be done once only for development purposes, run from the Gerrit checkout
-path:
-
-```
-docker build -t gerrit/polygerrit-functional:v1 \
- polygerrit-ui/app/test/functional/infra
-```
-
-## Running a smoke test
-
-Running a smoke test from Gerrit checkout path:
-
-```
-./polygerrit-ui/app/test/functional/run_functional.sh
-```
-
-The successful output should be something similar to this:
-
-```
-Starting local server..
-Starting Webdriver..
-Started
-.
-
-
-1 spec, 0 failures
-Finished in 2.565 seconds
-```
diff --git a/polygerrit-ui/app/test/functional/infra/Dockerfile b/polygerrit-ui/app/test/functional/infra/Dockerfile
deleted file mode 100644
index e642176..0000000
--- a/polygerrit-ui/app/test/functional/infra/Dockerfile
+++ /dev/null
@@ -1,38 +0,0 @@
-FROM selenium/standalone-chrome-debug
-
-USER root
-
-# nvm environment variables
-ENV NVM_DIR /usr/local/nvm
-ENV NODE_VERSION 9.4.0
-
-# install nvm
-# https://github.com/creationix/nvm#install-script
-RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
-
-# install node and npm
-RUN [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \
- && nvm install $NODE_VERSION \
- && nvm alias default $NODE_VERSION \
- && nvm use default
-
-ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
-ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
-
-RUN npm install -g jasmine
-RUN npm install -g http-server
-
-USER seluser
-
-RUN mkdir -p /tmp/app
-WORKDIR /tmp/app
-
-RUN npm init -y
-RUN npm install --save selenium-webdriver
-
-EXPOSE 8080
-
-COPY test-infra.js /tmp/app/node_modules
-COPY run.sh /tmp/app/
-
-ENTRYPOINT [ "/tmp/app/run.sh" ]
diff --git a/polygerrit-ui/app/test/functional/infra/run.sh b/polygerrit-ui/app/test/functional/infra/run.sh
deleted file mode 100755
index 4beb3dd..0000000
--- a/polygerrit-ui/app/test/functional/infra/run.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-echo Starting local server..
-cp /app/polygerrit_ui.zip .
-unzip -q polygerrit_ui.zip
-nohup http-server polygerrit_ui > /tmp/http-server.log 2>&1 &
-
-echo Starting Webdriver..
-nohup /opt/bin/entry_point.sh > /tmp/webdriver.log 2>&1 &
-
-# Wait for servers to start
-sleep 5
-
-cp $@ .
-jasmine $(basename $@)
diff --git a/polygerrit-ui/app/test/functional/infra/test-infra.js b/polygerrit-ui/app/test/functional/infra/test-infra.js
deleted file mode 100644
index 2619694..0000000
--- a/polygerrit-ui/app/test/functional/infra/test-infra.js
+++ /dev/null
@@ -1,24 +0,0 @@
-'use strict';
-
-const {Builder} = require('selenium-webdriver');
-
-let driver;
-
-function setup() {
- return new Builder()
- .forBrowser('chrome')
- .usingServer('http://localhost:4444/wd/hub')
- .build()
- .then(d => {
- driver = d;
- return driver.get('http://localhost:8080');
- })
- .then(() => driver);
-}
-
-function cleanup() {
- return driver.quit();
-}
-
-exports.setup = setup;
-exports.cleanup = cleanup;
diff --git a/polygerrit-ui/app/test/functional/run_functional.sh b/polygerrit-ui/app/test/functional/run_functional.sh
deleted file mode 100755
index 7ce57b8..0000000
--- a/polygerrit-ui/app/test/functional/run_functional.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env bash
-
-bazel build //polygerrit-ui/app:polygerrit_ui
-
-docker run --rm \
- -p 5900:5900 \
- -v `pwd`/polygerrit-ui/app/test/functional:/tests \
- -v `pwd`/bazel-genfiles/polygerrit-ui/app:/app \
- -it gerrit/polygerrit-functional:v1 \
- /tests/test.js
diff --git a/polygerrit-ui/app/test/functional/test.js b/polygerrit-ui/app/test/functional/test.js
deleted file mode 100644
index ae572af..0000000
--- a/polygerrit-ui/app/test/functional/test.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * @fileoverview Minimal viable frontend functional test.
- */
-'use strict';
-
-const {until} = require('selenium-webdriver');
-const {setup, cleanup} = require('test-infra');
-
-jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
-
-describe('example ', () => {
- let driver;
-
- beforeAll(() => setup().then(d => driver = d));
-
- afterAll(() => cleanup());
-
- it('should update title', () => driver.wait(
- until.titleIs('status:open · Gerrit Code Review'), 5000
- ));
-});
diff --git a/polygerrit-ui/app/types/events.ts b/polygerrit-ui/app/types/events.ts
index f642af7..2cc6742 100644
--- a/polygerrit-ui/app/types/events.ts
+++ b/polygerrit-ui/app/types/events.ts
@@ -28,8 +28,6 @@
OPEN_FIX_PREVIEW = 'open-fix-preview',
CLOSE_FIX_PREVIEW = 'close-fix-preview',
PAGE_ERROR = 'page-error',
- RECREATE_CHANGE_VIEW = 'recreate-change-view',
- RECREATE_DIFF_VIEW = 'recreate-diff-view',
RELOAD = 'reload',
REPLY = 'reply',
SERVER_ERROR = 'server-error',
diff --git a/polygerrit-ui/app/utils/link-util.ts b/polygerrit-ui/app/utils/link-util.ts
index ec1e7e7..48e9c07 100644
--- a/polygerrit-ui/app/utils/link-util.ts
+++ b/polygerrit-ui/app/utils/link-util.ts
@@ -3,7 +3,6 @@
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
-import 'ba-linkify/ba-linkify';
import {CommentLinkInfo, CommentLinks} from '../types/common';
import {getBaseUrl} from './url-util';
@@ -16,21 +15,8 @@
base: string,
repoCommentLinks: CommentLinks
): string {
- const parts: string[] = [];
- window.linkify(insertZeroWidthSpace(base), {
- callback: (text, href) => {
- if (href) {
- parts.push(removeZeroWidthSpace(createLinkTemplate(href, text)));
- } else {
- const rewriteResults = getRewriteResultsFromConfig(
- text,
- repoCommentLinks
- );
- parts.push(removeZeroWidthSpace(applyRewrites(text, rewriteResults)));
- }
- },
- });
- return parts.join('');
+ const rewriteResults = getRewriteResultsFromConfig(base, repoCommentLinks);
+ return applyRewrites(base, rewriteResults);
}
/**
@@ -141,22 +127,6 @@
);
}
-/**
- * Some tools are known to look for reviewers/CCs by finding lines such as
- * "R=foo@gmail.com, bar@gmail.com". However, "=" is technically a valid email
- * character, so ba-linkify interprets the entire string "R=foo@gmail.com" as an
- * email address. To fix this, we insert a zero width space character \u200B
- * before linking that prevents ba-linkify from associating the prefix with the
- * email. After linking we remove the zero width space.
- */
-function insertZeroWidthSpace(base: string) {
- return base.replace(/^(R=|CC=)/g, '$&\u200B');
-}
-
-function removeZeroWidthSpace(base: string) {
- return base.replace(/\u200B/g, '');
-}
-
function createLinkTemplate(
href: string,
displayText: string,
diff --git a/polygerrit-ui/app/utils/link-util_test.ts b/polygerrit-ui/app/utils/link-util_test.ts
index f5c13e8..e4e719b 100644
--- a/polygerrit-ui/app/utils/link-util_test.ts
+++ b/polygerrit-ui/app/utils/link-util_test.ts
@@ -63,18 +63,6 @@
`${link('foo', 'foo.gov')} ${link('foo', 'foo.gov')}`
);
});
-
- test('does not apply within normal links', () => {
- assert.equal(
- linkifyUrlsAndApplyRewrite('google.com', {
- ogle: {
- match: 'ogle',
- link: 'gerritcodereview.com',
- },
- }),
- link('google.com', 'http://google.com')
- );
- });
});
test('for overlapping rewrites prefer the latest ending', () => {
@@ -165,45 +153,4 @@
)}`
);
});
-
- suite('normal links', () => {
- test('links urls', () => {
- const googleLink = link('google.com', 'http://google.com');
- const mapsLink = link('maps.google.com', 'http://maps.google.com');
-
- assert.equal(
- linkifyUrlsAndApplyRewrite('google.com, maps.google.com', {}),
- `${googleLink}, ${mapsLink}`
- );
- });
-
- test('links emails without including R= prefix', () => {
- const fooEmail = link('foo@gmail.com', 'mailto:foo@gmail.com');
- const barEmail = link('bar@gmail.com', 'mailto:bar@gmail.com');
- assert.equal(
- linkifyUrlsAndApplyRewrite('R=foo@gmail.com, bar@gmail.com', {}),
- `R=${fooEmail}, ${barEmail}`
- );
- });
-
- test('links emails without including CC= prefix', () => {
- const fooEmail = link('foo@gmail.com', 'mailto:foo@gmail.com');
- const barEmail = link('bar@gmail.com', 'mailto:bar@gmail.com');
- assert.equal(
- linkifyUrlsAndApplyRewrite('CC=foo@gmail.com, bar@gmail.com', {}),
- `CC=${fooEmail}, ${barEmail}`
- );
- });
-
- test('links emails maintains R= and CC= within addresses', () => {
- const fooBarBazEmail = link(
- 'fooR=barCC=baz@gmail.com',
- 'mailto:fooR=barCC=baz@gmail.com'
- );
- assert.equal(
- linkifyUrlsAndApplyRewrite('fooR=barCC=baz@gmail.com', {}),
- fooBarBazEmail
- );
- });
- });
});
diff --git a/polygerrit-ui/app/utils/url-util.ts b/polygerrit-ui/app/utils/url-util.ts
index 5e294cb..af1e32e 100644
--- a/polygerrit-ui/app/utils/url-util.ts
+++ b/polygerrit-ui/app/utils/url-util.ts
@@ -92,6 +92,9 @@
// to not double encode *everything* (just for readaiblity and simplicity),
// but `%` *must* be double encoded.
let output = url.replaceAll('%', '%25');
+ // `+` also requires double encoding, because `%2B` would be decoded to `+`
+ // and then replaced by ` `.
+ output = output.replaceAll('+', '%2B');
// This escapes ALL characters EXCEPT:
// A–Z a–z 0–9 - _ . ! ~ * ' ( )
@@ -138,6 +141,10 @@
* Single decode for URL components. Will decode plus signs ('+') to spaces.
* Note: because this function decodes once, it is not the inverse of
* encodeURL.
+ *
+ * This function must only be used for decoding data returned by the REST API.
+ * Don't use it for decoding browser URLs. The only place for decoding browser
+ * URLs must gr-page.ts.
*/
export function singleDecodeURL(url: string): string {
const withoutPlus = url.replace(/\+/g, '%20');
diff --git a/polygerrit-ui/app/utils/url-util_test.ts b/polygerrit-ui/app/utils/url-util_test.ts
index 16f85dd..7466a90 100644
--- a/polygerrit-ui/app/utils/url-util_test.ts
+++ b/polygerrit-ui/app/utils/url-util_test.ts
@@ -110,6 +110,10 @@
assert.equal(encodeURL('abc%def'), 'abc%2525def');
});
+ test('double encodes +', () => {
+ assert.equal(encodeURL('abc+def'), 'abc%252Bdef');
+ });
+
test('does not encode colon and slash', () => {
assert.equal(encodeURL(':/'), ':/');
});
diff --git a/polygerrit-ui/app/yarn.lock b/polygerrit-ui/app/yarn.lock
index 2edce7e..7f8168e 100644
--- a/polygerrit-ui/app/yarn.lock
+++ b/polygerrit-ui/app/yarn.lock
@@ -488,11 +488,6 @@
delegates "^1.0.0"
readable-stream "^2.0.6"
-ba-linkify@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/ba-linkify/-/ba-linkify-1.0.1.tgz#664cf5744947c6e8611f1fbbaf7d9f315f982f4c"
- integrity sha1-Zkz1dElHxuhhHx+7r32fMV+YL0w=
-
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
diff --git a/proto/cache.proto b/proto/cache.proto
index 0cecdea..7063ee5 100644
--- a/proto/cache.proto
+++ b/proto/cache.proto
@@ -198,14 +198,7 @@
string server_id = 20;
bool has_server_id = 21;
- message AssigneeStatusUpdateProto {
- // Epoch millis.
- int64 timestamp_millis = 1;
- int32 updated_by = 2;
- int32 current_assignee = 3;
- bool has_current_assignee = 4;
- }
- repeated AssigneeStatusUpdateProto assignee_update = 22;
+ reserved 22; // assignee_update;
// An update to the attention set of the change. See class AttentionSetUpdate
// for context.
diff --git a/resources/com/google/gerrit/server/mail/SetAssignee.soy b/resources/com/google/gerrit/server/mail/SetAssignee.soy
deleted file mode 100644
index 83aa580..0000000
--- a/resources/com/google/gerrit/server/mail/SetAssignee.soy
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * Copyright (C) 2016 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.
- */
-
-{namespace com.google.gerrit.server.mail.template.SetAssignee}
-
-/**
- * The .SetAssignee template will determine the contents of the email related
- * to a user being assigned to a change.
- */
-{template SetAssignee kind="text"}
- {@param change: ?}
- {@param email: ?}
- {@param fromName: ?}
- {@param patchSet: ?}
- {@param projectName: ?}
- Hello{sp}
- {$email.assigneeName},
-
- {\n}
- {\n}
-
- {$fromName} has assigned a change to you.
-
- {sp}Please visit
-
- {\n}
- {\n}
-
- {sp}{sp}{sp}{sp}{$email.changeUrl}
-
- {\n}
- {\n}
-
- to view the change.
-
- {\n}
- {\n}
-
- Change subject: {$change.subject}{\n}
- ......................................................................{\n}
-
- {\n}
-
- {$email.changeDetail}{\n}
-
- {if $email.sshHost}
- {\n}
- {sp}{sp}git pull ssh:{print '//'}{$email.sshHost}/{$projectName}
- {sp}{$patchSet.refName}
- {\n}
- {/if}
-
- {if $email.includeDiff}
- {\n}
- {$email.unifiedDiff}
- {\n}
- {/if}
-{/template}
diff --git a/resources/com/google/gerrit/server/mail/SetAssigneeHtml.soy b/resources/com/google/gerrit/server/mail/SetAssigneeHtml.soy
deleted file mode 100644
index 5435cab..0000000
--- a/resources/com/google/gerrit/server/mail/SetAssigneeHtml.soy
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * Copyright (C) 2016 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.
- */
-
-{namespace com.google.gerrit.server.mail.template.SetAssigneeHtml}
-
-import * as mailTemplate from 'com/google/gerrit/server/mail/Private.soy';
-
-{template SetAssigneeHtml}
- {@param diffLines: ?}
- {@param email: ?}
- {@param fromName: ?}
- {@param patchSet: ?}
- {@param projectName: ?}
- <p>
- {$fromName} has <strong>assigned</strong> a change to{sp}
- {$email.assigneeName}.{sp}
- </p>
-
- {if $email.changeUrl}
- <p>
- {call mailTemplate.ViewChangeButton data="all" /}
- </p>
- {/if}
-
- {call mailTemplate.Pre}
- {param content: $email.changeDetail /}
- {/call}
-
- {if $email.sshHost}
- {call mailTemplate.Pre}
- {param content kind="html"}
- git pull ssh:{print '//'}{$email.sshHost}/{$projectName}
- {sp}{$patchSet.refName}
- {/param}
- {/call}
- {/if}
-
- {if $email.includeDiff}
- {call mailTemplate.UnifiedDiff}
- {param diffLines: $diffLines /}
- {/call}
- {/if}
-{/template}