diff --git a/BUILD b/BUILD index 72e557c419..3989a75bdd 100644 --- a/BUILD +++ b/BUILD @@ -1,8 +1,8 @@ -package(default_visibility = ["//visibility:public"]) - load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:pkg_war.bzl", "pkg_war") +package(default_visibility = ["//visibility:public"]) + config_setting( name = "java9", values = { diff --git a/Documentation/BUILD b/Documentation/BUILD index 8a7a313134..368e929927 100644 --- a/Documentation/BUILD +++ b/Documentation/BUILD @@ -1,10 +1,8 @@ -package(default_visibility = ["//visibility:public"]) - -load("//tools/bzl:asciidoc.bzl", "documentation_attributes") -load("//tools/bzl:asciidoc.bzl", "genasciidoc") -load("//tools/bzl:asciidoc.bzl", "genasciidoc_zip") +load("//tools/bzl:asciidoc.bzl", "documentation_attributes", "genasciidoc", "genasciidoc_zip") load("//tools/bzl:license.bzl", "license_map") +package(default_visibility = ["//visibility:public"]) + exports_files([ "replace_macros.py", ]) diff --git a/Documentation/config-accounts.txt b/Documentation/config-accounts.txt index 51d8cec638..13e663e0bb 100644 --- a/Documentation/config-accounts.txt +++ b/Documentation/config-accounts.txt @@ -200,7 +200,7 @@ The parameter names match the names that are used in the preferences REST API: * link:rest-api-accounts.html#edit-preferences-info[Edit Preferences] If the value for a preference is the same as the default value for this -preference, it can be omitted in the `preference.config` file. +preference, it can be omitted in the `preferences.config` file. Defaults for preferences that apply for all accounts can be configured in the `refs/users/default` branch in the `All-Users` repository. diff --git a/Documentation/intro-user.txt b/Documentation/intro-user.txt index 5e8e670ef0..544039b6f6 100644 --- a/Documentation/intro-user.txt +++ b/Documentation/intro-user.txt @@ -565,6 +565,11 @@ and users with the link:access-control.html#category_view_private_changes[ View Private Changes] global capability. Private changes are useful in a number of cases: +* You want a set of collaborators to review the change before formal review + starts. By creating a Private change and adding only a selected few as + reviewers you can control who can see the change and get a first opinion + before opening up for all reviewers. + * You want to check what the change looks like before formal review starts. By marking the change private without reviewers, nobody can prematurely comment on your changes. diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD index be7995fecb..b590e64242 100644 --- a/java/com/google/gerrit/acceptance/BUILD +++ b/java/com/google/gerrit/acceptance/BUILD @@ -1,4 +1,5 @@ load("//tools/bzl:java.bzl", "java_library2") +load("//tools/bzl:javadoc.bzl", "java_doc") java_library( name = "lib", @@ -129,8 +130,6 @@ java_library2( ], ) -load("//tools/bzl:javadoc.bzl", "java_doc") - java_doc( name = "framework-javadoc", testonly = True, diff --git a/java/com/google/gerrit/common/BUILD b/java/com/google/gerrit/common/BUILD index 9ceea390a0..f0c069d58f 100644 --- a/java/com/google/gerrit/common/BUILD +++ b/java/com/google/gerrit/common/BUILD @@ -1,5 +1,3 @@ -load("//tools/bzl:genrule2.bzl", "genrule2") - ANNOTATIONS = [ "Nullable.java", "audit/Audit.java", diff --git a/java/com/google/gerrit/extensions/BUILD b/java/com/google/gerrit/extensions/BUILD index 5f9220e721..797c6563f1 100644 --- a/java/com/google/gerrit/extensions/BUILD +++ b/java/com/google/gerrit/extensions/BUILD @@ -1,5 +1,6 @@ -load("//lib:guava.bzl", "GUAVA_DOC_URL") load("//lib/jgit:jgit.bzl", "JGIT_DOC_URL") +load("//lib:guava.bzl", "GUAVA_DOC_URL") +load("//tools/bzl:javadoc.bzl", "java_doc") java_binary( name = "extension-api", @@ -34,8 +35,6 @@ java_library( ], ) -load("//tools/bzl:javadoc.bzl", "java_doc") - java_doc( name = "extension-api-javadoc", external_docs = [ diff --git a/java/com/google/gerrit/extensions/api/accounts/Accounts.java b/java/com/google/gerrit/extensions/api/accounts/Accounts.java index 651e786fe8..db7f506e9f 100644 --- a/java/com/google/gerrit/extensions/api/accounts/Accounts.java +++ b/java/com/google/gerrit/extensions/api/accounts/Accounts.java @@ -172,16 +172,19 @@ public interface Accounts { return this; } + /** Set an option on the request, appending to existing options. */ public QueryRequest withOption(ListAccountsOption options) { this.options.add(options); return this; } + /** Set options on the request, appending to existing options. */ public QueryRequest withOptions(ListAccountsOption... options) { this.options.addAll(Arrays.asList(options)); return this; } + /** Set options on the request, replacing existing options. */ public QueryRequest withOptions(EnumSet options) { this.options = options; return this; diff --git a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java index 14e0ed7b78..2a3bf07cf1 100644 --- a/java/com/google/gerrit/extensions/api/changes/ChangeApi.java +++ b/java/com/google/gerrit/extensions/api/changes/ChangeApi.java @@ -215,6 +215,11 @@ public interface ChangeApi { return suggestReviewers().withQuery(query); } + /** + * Retrieve reviewers ({@code ReviewerState.REVIEWER} and {@code ReviewerState.CC}) on the change. + */ + List reviewers() throws RestApiException; + ChangeInfo get(EnumSet options) throws RestApiException; default ChangeInfo get(Iterable options) throws RestApiException { @@ -472,6 +477,16 @@ public interface ChangeApi { throw new NotImplementedException(); } + @Override + public SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException { + throw new NotImplementedException(); + } + + @Override + public List reviewers() throws RestApiException { + throw new NotImplementedException(); + } + @Override public ChangeInfo get(EnumSet options) throws RestApiException { throw new NotImplementedException(); diff --git a/java/com/google/gerrit/extensions/api/changes/ChangeEditApi.java b/java/com/google/gerrit/extensions/api/changes/ChangeEditApi.java index 9d0275ac19..25eb7a83a3 100644 --- a/java/com/google/gerrit/extensions/api/changes/ChangeEditApi.java +++ b/java/com/google/gerrit/extensions/api/changes/ChangeEditApi.java @@ -14,11 +14,13 @@ package com.google.gerrit.extensions.api.changes; +import com.google.gerrit.extensions.client.ChangeEditDetailOption; import com.google.gerrit.extensions.common.EditInfo; import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.NotImplementedException; import com.google.gerrit.extensions.restapi.RawInput; import com.google.gerrit.extensions.restapi.RestApiException; +import java.util.EnumSet; import java.util.Optional; /** @@ -29,6 +31,33 @@ import java.util.Optional; */ public interface ChangeEditApi { + abstract class ChangeEditDetailRequest { + private String base; + private EnumSet options = EnumSet.noneOf(ChangeEditDetailOption.class); + + public abstract Optional get() throws RestApiException; + + public ChangeEditDetailRequest withBase(String base) { + this.base = base; + return this; + } + + public ChangeEditDetailRequest withOption(ChangeEditDetailOption option) { + this.options.add(option); + return this; + } + + public String getBase() { + return base; + } + + public EnumSet options() { + return options; + } + } + + ChangeEditDetailRequest detail() throws RestApiException; + /** * Retrieves details regarding the change edit. * @@ -155,6 +184,11 @@ public interface ChangeEditApi { * interface. */ class NotImplemented implements ChangeEditApi { + @Override + public ChangeEditDetailRequest detail() throws RestApiException { + throw new NotImplementedException(); + } + @Override public Optional get() throws RestApiException { throw new NotImplementedException(); diff --git a/java/com/google/gerrit/extensions/api/changes/Changes.java b/java/com/google/gerrit/extensions/api/changes/Changes.java index 0708ef5dc9..dc0a250174 100644 --- a/java/com/google/gerrit/extensions/api/changes/Changes.java +++ b/java/com/google/gerrit/extensions/api/changes/Changes.java @@ -94,16 +94,19 @@ public interface Changes { return this; } + /** Set an option on the request, appending to existing options. */ public QueryRequest withOption(ListChangesOption options) { this.options.add(options); return this; } + /** Set options on the request, appending to existing options. */ public QueryRequest withOptions(ListChangesOption... options) { this.options.addAll(Arrays.asList(options)); return this; } + /** Set options on the request, replacing existing options. */ public QueryRequest withOptions(EnumSet options) { this.options = options; return this; diff --git a/java/com/google/gerrit/extensions/api/groups/Groups.java b/java/com/google/gerrit/extensions/api/groups/Groups.java index 0243ba3bf0..86c2d772fb 100644 --- a/java/com/google/gerrit/extensions/api/groups/Groups.java +++ b/java/com/google/gerrit/extensions/api/groups/Groups.java @@ -253,16 +253,19 @@ public interface Groups { return this; } + /** Set an option on the request, appending to existing options. */ public QueryRequest withOption(ListGroupsOption options) { this.options.add(options); return this; } + /** Set options on the request, appending to existing options. */ public QueryRequest withOptions(ListGroupsOption... options) { this.options.addAll(Arrays.asList(options)); return this; } + /** Set options on the request, replacing existing options. */ public QueryRequest withOptions(EnumSet options) { this.options = options; return this; diff --git a/java/com/google/gerrit/extensions/client/ChangeEditDetailOption.java b/java/com/google/gerrit/extensions/client/ChangeEditDetailOption.java new file mode 100644 index 0000000000..156b76883a --- /dev/null +++ b/java/com/google/gerrit/extensions/client/ChangeEditDetailOption.java @@ -0,0 +1,20 @@ +// 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.extensions.client; + +public enum ChangeEditDetailOption { + LIST_FILES, + DOWNLOAD_COMMANDS +} diff --git a/java/com/google/gerrit/extensions/client/ListChangesOption.java b/java/com/google/gerrit/extensions/client/ListChangesOption.java index ffc5029f70..5e4a3a7ca7 100644 --- a/java/com/google/gerrit/extensions/client/ListChangesOption.java +++ b/java/com/google/gerrit/extensions/client/ListChangesOption.java @@ -17,7 +17,7 @@ package com.google.gerrit.extensions.client; import java.util.EnumSet; import java.util.Set; -/** Output options available for retrieval change details. */ +/** Output options available for retrieval of change details. */ public enum ListChangesOption { LABELS(0), DETAILED_LABELS(8), diff --git a/java/com/google/gerrit/index/BUILD b/java/com/google/gerrit/index/BUILD index c927b95676..9d61c025f2 100644 --- a/java/com/google/gerrit/index/BUILD +++ b/java/com/google/gerrit/index/BUILD @@ -1,5 +1,3 @@ -load("//tools/bzl:genrule2.bzl", "genrule2") - QUERY_PARSE_EXCEPTION_SRCS = [ "query/QueryParseException.java", "query/QueryRequiresAuthException.java", diff --git a/java/com/google/gerrit/server/BUILD b/java/com/google/gerrit/server/BUILD index e5a5152160..263404819d 100644 --- a/java/com/google/gerrit/server/BUILD +++ b/java/com/google/gerrit/server/BUILD @@ -1,3 +1,5 @@ +load("//tools/bzl:javadoc.bzl", "java_doc") + CONSTANTS_SRC = [ "documentation/Constants.java", ] @@ -143,8 +145,6 @@ java_library( ], ) -load("//tools/bzl:javadoc.bzl", "java_doc") - java_doc( name = "doc", libs = [":server"], diff --git a/java/com/google/gerrit/server/account/AccountManager.java b/java/com/google/gerrit/server/account/AccountManager.java index c7cd48d411..6534f0fe9d 100644 --- a/java/com/google/gerrit/server/account/AccountManager.java +++ b/java/com/google/gerrit/server/account/AccountManager.java @@ -136,21 +136,7 @@ public class AccountManager { try { Optional optionalExtId = externalIds.get(who.getExternalIdKey()); if (!optionalExtId.isPresent()) { - if (who.getUserName().isPresent()) { - ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, who.getUserName().get()); - Optional existingId = externalIds.get(key); - if (existingId.isPresent()) { - // An inconsistency is detected in the database, having a record for scheme "username:" - // but no record for scheme "gerrit:". Try to recover by linking - // "gerrit:" identity to the existing account. - logger.atWarning().log( - "User %s already has an account; link new identity to the existing account.", - who.getUserName()); - return link(existingId.get().accountId(), who); - } - } // New account, automatically create and return. - logger.atFine().log("External ID not found. Attempting to create new account."); return create(who); } @@ -416,7 +402,6 @@ public class AccountManager { public AuthResult link(Account.Id to, AuthRequest who) throws AccountException, OrmException, IOException, ConfigInvalidException { Optional optionalExtId = externalIds.get(who.getExternalIdKey()); - logger.atFine().log("Link another authentication identity to an existing account"); if (optionalExtId.isPresent()) { ExternalId extId = optionalExtId.get(); if (!extId.accountId().equals(to)) { @@ -425,7 +410,6 @@ public class AccountManager { } update(who, extId); } else { - logger.atFine().log("Linking new external ID to the existing account"); ExternalId newExtId = ExternalId.createWithEmail(who.getExternalIdKey(), to, who.getEmailAddress()); checkEmailNotUsed(newExtId); diff --git a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java index 6f89058e56..d80ff9b580 100644 --- a/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java +++ b/java/com/google/gerrit/server/api/accounts/AccountApiImpl.java @@ -228,7 +228,7 @@ public class AccountApiImpl implements AccountApi { accountLoader.fill(); return ai; } catch (Exception e) { - throw asRestApiException("Cannot parse change", e); + throw asRestApiException("Cannot parse account", e); } } diff --git a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java index 8588dfa16f..d1ae1762db 100644 --- a/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java +++ b/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java @@ -33,6 +33,7 @@ import com.google.gerrit.extensions.api.changes.RebaseInput; import com.google.gerrit.extensions.api.changes.RestoreInput; import com.google.gerrit.extensions.api.changes.RevertInput; import com.google.gerrit.extensions.api.changes.ReviewerApi; +import com.google.gerrit.extensions.api.changes.ReviewerInfo; import com.google.gerrit.extensions.api.changes.RevisionApi; import com.google.gerrit.extensions.api.changes.SubmittedTogetherInfo; import com.google.gerrit.extensions.api.changes.SubmittedTogetherOption; @@ -75,6 +76,7 @@ import com.google.gerrit.server.restapi.change.Index; import com.google.gerrit.server.restapi.change.ListChangeComments; import com.google.gerrit.server.restapi.change.ListChangeDrafts; import com.google.gerrit.server.restapi.change.ListChangeRobotComments; +import com.google.gerrit.server.restapi.change.ListReviewers; import com.google.gerrit.server.restapi.change.MarkAsReviewed; import com.google.gerrit.server.restapi.change.MarkAsUnreviewed; import com.google.gerrit.server.restapi.change.Move; @@ -117,6 +119,7 @@ class ChangeApiImpl implements ChangeApi { private final ChangeMessageApiImpl.Factory changeMessageApi; private final ChangeMessages changeMessages; private final SuggestChangeReviewers suggestReviewers; + private final ListReviewers listReviewers; private final ChangeResource change; private final Abandon abandon; private final Revert revert; @@ -165,6 +168,7 @@ class ChangeApiImpl implements ChangeApi { ChangeMessageApiImpl.Factory changeMessageApi, ChangeMessages changeMessages, SuggestChangeReviewers suggestReviewers, + ListReviewers listReviewers, Abandon abandon, Revert revert, Restore restore, @@ -211,6 +215,7 @@ class ChangeApiImpl implements ChangeApi { this.changeMessageApi = changeMessageApi; this.changeMessages = changeMessages; this.suggestReviewers = suggestReviewers; + this.listReviewers = listReviewers; this.abandon = abandon; this.restore = restore; this.updateByMerge = updateByMerge; @@ -437,6 +442,15 @@ class ChangeApiImpl implements ChangeApi { } } + @Override + public List reviewers() throws RestApiException { + try { + return listReviewers.apply(change); + } catch (Exception e) { + throw asRestApiException("Cannot retrieve reviewers", e); + } + } + @Override public ChangeInfo get(EnumSet s) throws RestApiException { try { diff --git a/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java b/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java index 73f6740e02..5aa4cf13ad 100644 --- a/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java +++ b/java/com/google/gerrit/server/api/changes/ChangeEditApiImpl.java @@ -18,6 +18,7 @@ import static com.google.gerrit.server.api.ApiUtil.asRestApiException; import com.google.gerrit.extensions.api.changes.ChangeEditApi; import com.google.gerrit.extensions.api.changes.PublishChangeEditInput; +import com.google.gerrit.extensions.client.ChangeEditDetailOption; import com.google.gerrit.extensions.common.EditInfo; import com.google.gerrit.extensions.common.Input; import com.google.gerrit.extensions.restapi.AuthException; @@ -35,6 +36,7 @@ import com.google.gerrit.server.restapi.change.PublishChangeEdit; import com.google.gerrit.server.restapi.change.RebaseChangeEdit; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.assistedinject.Assisted; import java.io.IOException; import java.util.Optional; @@ -44,51 +46,79 @@ public class ChangeEditApiImpl implements ChangeEditApi { ChangeEditApiImpl create(ChangeResource changeResource); } - private final ChangeEdits.Detail editDetail; + private final Provider editDetailProvider; private final ChangeEdits.Post changeEditsPost; private final DeleteChangeEdit deleteChangeEdit; private final RebaseChangeEdit rebaseChangeEdit; private final PublishChangeEdit publishChangeEdit; - private final ChangeEdits.Get changeEditsGet; + private final Provider changeEditsGetProvider; private final ChangeEdits.Put changeEditsPut; private final ChangeEdits.DeleteContent changeEditDeleteContent; - private final ChangeEdits.GetMessage getChangeEditCommitMessage; + private final Provider getChangeEditCommitMessageProvider; private final ChangeEdits.EditMessage modifyChangeEditCommitMessage; private final ChangeEdits changeEdits; private final ChangeResource changeResource; @Inject public ChangeEditApiImpl( - ChangeEdits.Detail editDetail, + Provider editDetailProvider, ChangeEdits.Post changeEditsPost, DeleteChangeEdit deleteChangeEdit, RebaseChangeEdit rebaseChangeEdit, PublishChangeEdit publishChangeEdit, - ChangeEdits.Get changeEditsGet, + Provider changeEditsGetProvider, ChangeEdits.Put changeEditsPut, ChangeEdits.DeleteContent changeEditDeleteContent, - ChangeEdits.GetMessage getChangeEditCommitMessage, + Provider getChangeEditCommitMessageProvider, ChangeEdits.EditMessage modifyChangeEditCommitMessage, ChangeEdits changeEdits, @Assisted ChangeResource changeResource) { - this.editDetail = editDetail; + this.editDetailProvider = editDetailProvider; this.changeEditsPost = changeEditsPost; this.deleteChangeEdit = deleteChangeEdit; this.rebaseChangeEdit = rebaseChangeEdit; this.publishChangeEdit = publishChangeEdit; - this.changeEditsGet = changeEditsGet; + this.changeEditsGetProvider = changeEditsGetProvider; this.changeEditsPut = changeEditsPut; this.changeEditDeleteContent = changeEditDeleteContent; - this.getChangeEditCommitMessage = getChangeEditCommitMessage; + this.getChangeEditCommitMessageProvider = getChangeEditCommitMessageProvider; this.modifyChangeEditCommitMessage = modifyChangeEditCommitMessage; this.changeEdits = changeEdits; this.changeResource = changeResource; } + @Override + public ChangeEditDetailRequest detail() throws RestApiException { + try { + return new ChangeEditDetailRequest() { + @Override + public Optional get() throws RestApiException { + return ChangeEditApiImpl.this.get(this); + } + }; + } catch (Exception e) { + throw asRestApiException("Cannot retrieve change edit", e); + } + } + + private Optional get(ChangeEditDetailRequest r) throws RestApiException { + try { + ChangeEdits.Detail editDetail = editDetailProvider.get(); + editDetail.setBase(r.getBase()); + editDetail.setList(r.options().contains(ChangeEditDetailOption.LIST_FILES)); + editDetail.setDownloadCommands( + r.options().contains(ChangeEditDetailOption.DOWNLOAD_COMMANDS)); + Response edit = editDetail.apply(changeResource); + return edit.isNone() ? Optional.empty() : Optional.of(edit.value()); + } catch (Exception e) { + throw asRestApiException("Cannot retrieve change edit", e); + } + } + @Override public Optional get() throws RestApiException { try { - Response edit = editDetail.apply(changeResource); + Response edit = editDetailProvider.get().apply(changeResource); return edit.isNone() ? Optional.empty() : Optional.of(edit.value()); } catch (Exception e) { throw asRestApiException("Cannot retrieve change edit", e); @@ -140,7 +170,7 @@ public class ChangeEditApiImpl implements ChangeEditApi { public Optional getFile(String filePath) throws RestApiException { try { ChangeEditResource changeEditResource = getChangeEditResource(filePath); - Response fileResponse = changeEditsGet.apply(changeEditResource); + Response fileResponse = changeEditsGetProvider.get().apply(changeEditResource); return fileResponse.isNone() ? Optional.empty() : Optional.of(fileResponse.value()); } catch (Exception e) { throw asRestApiException("Cannot retrieve file of change edit", e); @@ -191,7 +221,8 @@ public class ChangeEditApiImpl implements ChangeEditApi { @Override public String getCommitMessage() throws RestApiException { try { - try (BinaryResult binaryResult = getChangeEditCommitMessage.apply(changeResource)) { + try (BinaryResult binaryResult = + getChangeEditCommitMessageProvider.get().apply(changeResource)) { return binaryResult.asString(); } } catch (Exception e) { diff --git a/java/com/google/gerrit/server/mail/send/ChangeEmail.java b/java/com/google/gerrit/server/mail/send/ChangeEmail.java index 09d3e5187d..62d629a7da 100644 --- a/java/com/google/gerrit/server/mail/send/ChangeEmail.java +++ b/java/com/google/gerrit/server/mail/send/ChangeEmail.java @@ -283,6 +283,21 @@ public abstract class ChangeEmail extends NotificationEmail { } } + /** Get the patch list corresponding to patch set patchSetId of this change. */ + protected PatchList getPatchList(int patchSetId) throws PatchListNotAvailableException { + PatchSet ps; + if (patchSetId == patchSet.getPatchSetId()) { + ps = patchSet; + } else { + try { + ps = args.patchSetUtil.get(changeData.notes(), new PatchSet.Id(change.getId(), patchSetId)); + } catch (OrmException e) { + throw new PatchListNotAvailableException("Failed to get patchSet"); + } + } + return args.patchListCache.get(change, ps); + } + /** Get the patch list corresponding to this patch set. */ protected PatchList getPatchList() throws PatchListNotAvailableException { if (patchSet != null) { diff --git a/java/com/google/gerrit/server/mail/send/CommentSender.java b/java/com/google/gerrit/server/mail/send/CommentSender.java index c8aa259be0..ec28bcbd6d 100644 --- a/java/com/google/gerrit/server/mail/send/CommentSender.java +++ b/java/com/google/gerrit/server/mail/send/CommentSender.java @@ -198,17 +198,6 @@ public class CommentSender extends ReplyToChangeSender { */ private List getGroupedInlineComments(Repository repo) { List groups = new ArrayList<>(); - // Get the patch list: - PatchList patchList = null; - if (repo != null) { - try { - patchList = getPatchList(); - } catch (PatchListObjectTooLargeException e) { - logger.atWarning().log("Failed to get patch list: %s", e.getMessage()); - } catch (PatchListNotAvailableException e) { - logger.atSevere().withCause(e).log("Failed to get patch list"); - } - } // Loop over the comments and collect them into groups based on the file // location of the comment. @@ -221,6 +210,16 @@ public class CommentSender extends ReplyToChangeSender { currentGroup = new FileCommentGroup(); currentGroup.filename = c.key.filename; currentGroup.patchSetId = c.key.patchSetId; + // Get the patch list: + PatchList patchList = null; + try { + patchList = getPatchList(c.key.patchSetId); + } catch (PatchListObjectTooLargeException e) { + logger.atWarning().log("Failed to get patch list: %s", e.getMessage()); + } catch (PatchListNotAvailableException e) { + logger.atSevere().withCause(e).log("Failed to get patch list"); + } + groups.add(currentGroup); if (patchList != null) { try { diff --git a/java/com/google/gerrit/server/mail/send/EmailArguments.java b/java/com/google/gerrit/server/mail/send/EmailArguments.java index a3674cd79f..855fd8c21a 100644 --- a/java/com/google/gerrit/server/mail/send/EmailArguments.java +++ b/java/com/google/gerrit/server/mail/send/EmailArguments.java @@ -20,6 +20,7 @@ import com.google.gerrit.server.ApprovalsUtil; import com.google.gerrit.server.GerritPersonIdentProvider; import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser.GenericFactory; +import com.google.gerrit.server.PatchSetUtil; import com.google.gerrit.server.UsedAt; import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.GroupBackend; @@ -56,6 +57,7 @@ public class EmailArguments { final GroupBackend groupBackend; final AccountCache accountCache; final PatchListCache patchListCache; + final PatchSetUtil patchSetUtil; final ApprovalsUtil approvalsUtil; final FromAddressGenerator fromAddressGenerator; final EmailSender emailSender; @@ -88,6 +90,7 @@ public class EmailArguments { GroupBackend groupBackend, AccountCache accountCache, PatchListCache patchListCache, + PatchSetUtil patchSetUtil, ApprovalsUtil approvalsUtil, FromAddressGenerator fromAddressGenerator, EmailSender emailSender, @@ -116,6 +119,7 @@ public class EmailArguments { this.groupBackend = groupBackend; this.accountCache = accountCache; this.patchListCache = patchListCache; + this.patchSetUtil = patchSetUtil; this.approvalsUtil = approvalsUtil; this.fromAddressGenerator = fromAddressGenerator; this.emailSender = emailSender; diff --git a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java index 0b1651dd05..cabb30df7b 100644 --- a/java/com/google/gerrit/server/restapi/change/ChangeEdits.java +++ b/java/com/google/gerrit/server/restapi/change/ChangeEdits.java @@ -151,14 +151,24 @@ public class ChangeEdits implements ChildCollection { +public class ListReviewers implements RestReadView { private final ApprovalsUtil approvalsUtil; private final ReviewerJson json; private final ReviewerResource.Factory resourceFactory; diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java index 3511fc476e..f7eb342486 100644 --- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java +++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountIT.java @@ -108,11 +108,9 @@ import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.server.ServerInitiated; -import com.google.gerrit.server.account.AccountManager; import com.google.gerrit.server.account.AccountProperties; import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountsUpdate; -import com.google.gerrit.server.account.AuthRequest; import com.google.gerrit.server.account.Emails; import com.google.gerrit.server.account.ProjectWatches; import com.google.gerrit.server.account.ProjectWatches.NotifyType; @@ -224,8 +222,6 @@ public class AccountIT extends AbstractDaemonTest { @Inject private DynamicSet accountActivationValidationListeners; - @Inject private AccountManager accountManager; - @Inject protected GroupOperations groupOperations; private AccountIndexedCounter accountIndexedCounter; @@ -2712,18 +2708,6 @@ public class AccountIT extends AbstractDaemonTest { } } - @Test - public void updateDisplayName() throws Exception { - String name = name("test"); - gApi.accounts().create(name); - AuthRequest who = AuthRequest.forUser(name); - accountManager.authenticate(who); - assertThat(gApi.accounts().id(name).get().name).isEqualTo(name); - who.setDisplayName("Something Else"); - accountManager.authenticate(who); - assertThat(gApi.accounts().id(name).get().name).isEqualTo("Something Else"); - } - private void createDraft(PushOneCommit.Result r, String path, String message) throws Exception { DraftInput in = new DraftInput(); in.path = path; diff --git a/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java b/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java index 327c2cd292..edb98d0412 100644 --- a/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java +++ b/javatests/com/google/gerrit/acceptance/api/accounts/AccountManagerIT.java @@ -193,25 +193,28 @@ public class AccountManagerIT extends AbstractDaemonTest { } @Test - public void authenticateWhenUsernameExtIdAlreadyExists() throws Exception { + public void authenticateWithUsernameAndUpdateDisplayName() throws Exception { String username = "foo"; - ExternalId.Key gerritExtIdKey = ExternalId.Key.create(ExternalId.SCHEME_GERRIT, username); - ExternalId.Key usernameExtIdKey = ExternalId.Key.create(ExternalId.SCHEME_USERNAME, username); - assertNoSuchExternalIds(gerritExtIdKey, usernameExtIdKey); - - // Create account with SCHEME_USERNAME external ID, but no SCHEME_GERRIT external ID. + String email = "foo@example.com"; Account.Id accountId = new Account.Id(seq.nextAccountId()); + ExternalId.Key gerritExtIdKey = ExternalId.Key.create(ExternalId.SCHEME_GERRIT, username); accountsUpdate.insert( "Create Test Account", accountId, - u -> u.setFullName("Foo").addExternalId(ExternalId.create(usernameExtIdKey, accountId))); + u -> + u.setFullName("Initial Name") + .setPreferredEmail(email) + .addExternalId(ExternalId.createWithEmail(gerritExtIdKey, accountId, email))); AuthRequest who = AuthRequest.forUser(username); + String newName = "Updated Name"; + who.setDisplayName(newName); AuthResult authResult = accountManager.authenticate(who); - - // Expect that the missing SCHEME_GERRIT external ID was created. assertAuthResultForExistingAccount(authResult, accountId, gerritExtIdKey); - assertExternalIdsWithoutEmail(gerritExtIdKey, usernameExtIdKey); + + Optional accountState = accounts.get(accountId); + assertThat(accountState).isPresent(); + assertThat(accountState.get().getAccount().getFullName()).isEqualTo(newName); } @Test diff --git a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java index 31de4cfff8..06742eb446 100644 --- a/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java +++ b/javatests/com/google/gerrit/acceptance/api/change/ChangeIT.java @@ -1744,6 +1744,29 @@ public class ChangeIT extends AbstractDaemonTest { assertThat(rsrc.getETag()).isNotEqualTo(oldETag); } + @Test + public void listReviewers() throws Exception { + PushOneCommit.Result r = createChange(); + AddReviewerInput in = new AddReviewerInput(); + in.reviewer = user.email; + gApi.changes().id(r.getChangeId()).addReviewer(in); + assertThat(gApi.changes().id(r.getChangeId()).reviewers()).hasSize(1); + + String username1 = name("user1"); + String email1 = username1 + "@example.com"; + accountOperations + .newAccount() + .username(username1) + .preferredEmail(email1) + .fullname("User 1") + .create(); + in.reviewer = email1; + in.state = ReviewerState.CC; + gApi.changes().id(r.getChangeId()).addReviewer(in); + assertThat(gApi.changes().id(r.getChangeId()).reviewers().stream().map(a -> a.username)) + .containsExactly(user.username, username1); + } + @Test public void notificationsForAddedWorkInProgressReviewers() throws Exception { AddReviewerInput in = new AddReviewerInput(); diff --git a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java index 85b66c2bc1..8b5975dcb5 100644 --- a/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java +++ b/javatests/com/google/gerrit/acceptance/edit/ChangeEditIT.java @@ -22,6 +22,7 @@ import static com.google.gerrit.extensions.client.ListChangesOption.DETAILED_LAB import static com.google.gerrit.extensions.client.ListChangesOption.MESSAGES; import static com.google.gerrit.extensions.common.testing.EditInfoSubject.assertThat; import static com.google.gerrit.extensions.restapi.testing.BinaryResultSubject.assertThat; +import static com.google.gerrit.reviewdb.client.Patch.COMMIT_MSG; import static com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS; import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.concurrent.TimeUnit.SECONDS; @@ -43,6 +44,7 @@ import com.google.gerrit.extensions.api.changes.AddReviewerInput; import com.google.gerrit.extensions.api.changes.NotifyHandling; import com.google.gerrit.extensions.api.changes.PublishChangeEditInput; import com.google.gerrit.extensions.api.changes.ReviewInput; +import com.google.gerrit.extensions.client.ChangeEditDetailOption; import com.google.gerrit.extensions.client.ListChangesOption; import com.google.gerrit.extensions.common.ApprovalInfo; import com.google.gerrit.extensions.common.ChangeInfo; @@ -52,7 +54,6 @@ import com.google.gerrit.extensions.common.FileInfo; import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.ResourceConflictException; -import com.google.gerrit.reviewdb.client.Patch; import com.google.gerrit.reviewdb.client.PatchSet; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.server.ChangeMessagesUtil; @@ -400,7 +401,9 @@ public class ChangeEditIT extends AbstractDaemonTest { public void retrieveEdit() throws Exception { adminRestSession.get(urlEdit(changeId)).assertNoContent(); createArbitraryEditFor(changeId); - EditInfo editInfo = getEditInfo(changeId, false); + Optional maybeEditInfo = gApi.changes().id(changeId).edit().get(); + assertThat(maybeEditInfo).isPresent(); + EditInfo editInfo = maybeEditInfo.get(); ChangeInfo changeInfo = get(changeId, CURRENT_REVISION, CURRENT_COMMIT); assertThat(editInfo.commit.commit).isNotEqualTo(changeInfo.currentRevision); assertThat(editInfo).commit().parents().hasSize(1); @@ -414,11 +417,7 @@ public class ChangeEditIT extends AbstractDaemonTest { @Test public void retrieveFilesInEdit() throws Exception { createEmptyEditFor(changeId); - gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW)); - - EditInfo info = getEditInfo(changeId, true); - assertThat(info.files).isNotNull(); - assertThat(info.files.keySet()).containsExactly(Patch.COMMIT_MSG, FILE_NAME, FILE_NAME2); + assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2)); } @Test @@ -559,8 +558,10 @@ public class ChangeEditIT extends AbstractDaemonTest { @Test public void addNewFile() throws Exception { createEmptyEditFor(changeId); + assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2)); gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW)); ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW); + assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2, FILE_NAME3)); } @Test @@ -767,6 +768,19 @@ public class ChangeEditIT extends AbstractDaemonTest { assertThat(fileContent).value().bytes().isEqualTo(expectedFileBytes); } + private void assertFiles(String changeId, List expected) throws Exception { + Optional info = + gApi.changes() + .id(changeId) + .edit() + .detail() + .withOption(ChangeEditDetailOption.LIST_FILES) + .get(); + assertThat(info).isPresent(); + assertThat(info.get().files).isNotNull(); + assertThat(info.get().files.keySet()).containsExactlyElementsIn(expected); + } + private String urlEdit(String changeId) { return "/changes/" + changeId + "/edit"; } @@ -783,10 +797,6 @@ public class ChangeEditIT extends AbstractDaemonTest { return urlEdit(changeId) + "/" + fileName + (base ? "?base" : ""); } - private String urlGetFiles(String changeId) { - return urlEdit(changeId) + "?list"; - } - private String urlRevisionFiles(String changeId, String revisionId) { return "/changes/" + changeId + "/revisions/" + revisionId + "/files"; } @@ -821,11 +831,6 @@ public class ChangeEditIT extends AbstractDaemonTest { + "/diff?context=ALL&intraline"; } - private EditInfo getEditInfo(String changeId, boolean files) throws Exception { - RestResponse r = adminRestSession.get(files ? urlGetFiles(changeId) : urlEdit(changeId)); - return readContentFromJson(r, EditInfo.class); - } - private T readContentFromJson(RestResponse r, Class clazz) throws Exception { r.assertOK(); try (JsonReader jsonReader = new JsonReader(r.getReader())) { diff --git a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java index d5ceb9ad09..8a5fddd6ed 100644 --- a/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java +++ b/javatests/com/google/gerrit/acceptance/server/change/CommentsIT.java @@ -526,18 +526,26 @@ public class CommentsIT extends AbstractDaemonTest { @Test public void publishCommentsAllRevisions() throws Exception { - PushOneCommit.Result r1 = createChange(); + PushOneCommit.Result r1 = + pushFactory + .create(admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "old boring content\n") + .to("refs/for/master"); PushOneCommit.Result r2 = pushFactory .create( - admin.getIdent(), testRepo, SUBJECT, FILE_NAME, "new\ncntent\n", r1.getChangeId()) + admin.getIdent(), + testRepo, + SUBJECT, + FILE_NAME, + "new interesting\ncntent\n", + r1.getChangeId()) .to("refs/for/master"); addDraft( r1.getChangeId(), r1.getCommit().getName(), - newDraft(FILE_NAME, Side.REVISION, 1, "nit: trailing whitespace")); + newDraft(FILE_NAME, Side.REVISION, createLineRange(1, 4, 10), "Is it that bad?")); addDraft( r1.getChangeId(), r1.getCommit().getName(), @@ -545,7 +553,7 @@ public class CommentsIT extends AbstractDaemonTest { addDraft( r2.getChangeId(), r2.getCommit().getName(), - newDraft(FILE_NAME, Side.REVISION, 1, "join lines")); + newDraft(FILE_NAME, Side.REVISION, createLineRange(1, 4, 15), "better now")); addDraft( r2.getChangeId(), r2.getCommit().getName(), @@ -586,7 +594,7 @@ public class CommentsIT extends AbstractDaemonTest { assertThat(ps1List).hasSize(2); assertThat(ps1List.get(0).message).isEqualTo("what happened to this?"); assertThat(ps1List.get(0).side).isEqualTo(Side.PARENT); - assertThat(ps1List.get(1).message).isEqualTo("nit: trailing whitespace"); + assertThat(ps1List.get(1).message).isEqualTo("Is it that bad?"); assertThat(ps1List.get(1).side).isNull(); assertThat(gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).drafts()) @@ -598,7 +606,7 @@ public class CommentsIT extends AbstractDaemonTest { assertThat(ps2List).hasSize(4); assertThat(ps2List.get(0).message).isEqualTo("comment 1 on base"); assertThat(ps2List.get(1).message).isEqualTo("comment 2 on base"); - assertThat(ps2List.get(2).message).isEqualTo("join lines"); + assertThat(ps2List.get(2).message).isEqualTo("better now"); assertThat(ps2List.get(3).message).isEqualTo("typo: content"); List messages = email.getMessages(r2.getChangeId(), "comment"); @@ -631,8 +639,8 @@ public class CommentsIT extends AbstractDaemonTest { + "#/c/" + c + "/1/a.txt@1 \n" - + "PS1, Line 1: ew\n" - + "nit: trailing whitespace\n" + + "PS1, Line 1: boring\n" + + "Is it that bad?\n" + "\n" + "\n" + url @@ -661,8 +669,8 @@ public class CommentsIT extends AbstractDaemonTest { + "#/c/" + c + "/2/a.txt@1 \n" - + "PS2, Line 1: ew\n" - + "join lines\n" + + "PS2, Line 1: interesting\n" + + "better now\n" + "\n" + "\n" + url @@ -1093,30 +1101,49 @@ public class CommentsIT extends AbstractDaemonTest { return populate(d, path, side, null, line, message, false); } + private DraftInput newDraft(String path, Side side, Comment.Range range, String message) { + DraftInput d = new DraftInput(); + return populate(d, path, side, null, range, message, false); + } + private DraftInput newDraftOnParent(String path, int parent, int line, String message) { DraftInput d = new DraftInput(); return populate(d, path, Side.PARENT, Integer.valueOf(parent), line, message, false); } private static C populate( - C c, String path, Side side, Integer parent, int line, String message, Boolean unresolved) { + C c, + String path, + Side side, + Integer parent, + Comment.Range range, + String message, + Boolean unresolved) { + int line = range.startLine; c.path = path; c.side = side; c.parent = parent; c.line = line != 0 ? line : null; c.message = message; c.unresolved = unresolved; - if (line != 0) { - Comment.Range range = new Comment.Range(); - range.startLine = line; - range.startCharacter = 1; - range.endLine = line; - range.endCharacter = 5; - c.range = range; - } + if (line != 0) c.range = range; return c; } + private static C populate( + C c, String path, Side side, Integer parent, int line, String message, Boolean unresolved) { + return populate(c, path, side, parent, createLineRange(line, 1, 5), message, unresolved); + } + + private static Comment.Range createLineRange(int line, int startChar, int endChar) { + Comment.Range range = new Comment.Range(); + range.startLine = line; + range.startCharacter = startChar; + range.endLine = line; + range.endCharacter = endChar; + return range; + } + private static Function infoToInput(String path) { return infoToInput(path, CommentInput::new); } diff --git a/lib/fonts/BUILD b/lib/fonts/BUILD index 025b93e182..c4719d53c0 100644 --- a/lib/fonts/BUILD +++ b/lib/fonts/BUILD @@ -1,7 +1,6 @@ -load("//tools/bzl:genrule2.bzl", "genrule2") - # Roboto Mono. Version 2.136 # https://github.com/google/roboto/releases/tag/v2.136 + filegroup( name = "robotofonts", srcs = [ diff --git a/lib/jgit/jgit.bzl b/lib/jgit/jgit.bzl index 33489a2115..b3b73adef1 100644 --- a/lib/jgit/jgit.bzl +++ b/lib/jgit/jgit.bzl @@ -1,4 +1,4 @@ -load("//tools/bzl:maven_jar.bzl", "ECLIPSE", "GERRIT", "MAVEN_CENTRAL", "MAVEN_LOCAL", "maven_jar") +load("//tools/bzl:maven_jar.bzl", "MAVEN_CENTRAL", "maven_jar") _JGIT_VERS = "5.2.1.201812262042-r" @@ -6,7 +6,7 @@ _DOC_VERS = _JGIT_VERS # Set to _JGIT_VERS unless using a snapshot JGIT_DOC_URL = "http://download.eclipse.org/jgit/site/" + _DOC_VERS + "/apidocs" -_JGIT_REPO = ECLIPSE # Leave here even if set to MAVEN_CENTRAL. +_JGIT_REPO = MAVEN_CENTRAL # Leave here even if set to MAVEN_CENTRAL. # set this to use a local version. # "/home//projects/jgit" @@ -67,11 +67,11 @@ def jgit_maven_repos(): def jgit_dep(name): mapping = { - "@jgit-junit//jar": "@jgit//org.eclipse.jgit.junit:junit", - "@jgit-lib//jar:src": "@jgit//org.eclipse.jgit:libjgit-src.jar", - "@jgit-lib//jar": "@jgit//org.eclipse.jgit:jgit", - "@jgit-servlet//jar": "@jgit//org.eclipse.jgit.http.server:jgit-servlet", "@jgit-archive//jar": "@jgit//org.eclipse.jgit.archive:jgit-archive", + "@jgit-junit//jar": "@jgit//org.eclipse.jgit.junit:junit", + "@jgit-lib//jar": "@jgit//org.eclipse.jgit:jgit", + "@jgit-lib//jar:src": "@jgit//org.eclipse.jgit:libjgit-src.jar", + "@jgit-servlet//jar": "@jgit//org.eclipse.jgit.http.server:jgit-servlet", } if LOCAL_JGIT_REPO: diff --git a/lib/js/BUILD b/lib/js/BUILD index 706c472076..f73b9ecab2 100644 --- a/lib/js/BUILD +++ b/lib/js/BUILD @@ -1,7 +1,8 @@ -package(default_visibility = ["//visibility:public"]) - +load("//lib/js:bower_components.bzl", "define_bower_components") load("//tools/bzl:js.bzl", "bower_component", "js_component") +package(default_visibility = ["//visibility:public"]) + # For importing new versions of existing bower packages, # # 1) edit the versions of 'seed' components in WORKSPACE as desired @@ -20,8 +21,6 @@ load("//tools/bzl:js.bzl", "bower_component", "js_component") # 4) remove bower_component(name="my_new_dependency", .. ) here # -load("//lib/js:bower_components.bzl", "define_bower_components") - define_bower_components() js_component( diff --git a/lib/lucene/BUILD b/lib/lucene/BUILD index eab2ac8266..adb5030c2c 100644 --- a/lib/lucene/BUILD +++ b/lib/lucene/BUILD @@ -1,7 +1,7 @@ -package(default_visibility = ["//visibility:public"]) - load("//tools/bzl:maven.bzl", "merge_maven_jars") +package(default_visibility = ["//visibility:public"]) + # core and backward-codecs both provide # META-INF/services/org.apache.lucene.codecs.Codec, so they must be merged. merge_maven_jars( diff --git a/lib/polymer_externs/BUILD b/lib/polymer_externs/BUILD index cd71d64392..f07aa2f7a0 100644 --- a/lib/polymer_externs/BUILD +++ b/lib/polymer_externs/BUILD @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -package(default_visibility = ["//visibility:public"]) - load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") +package(default_visibility = ["//visibility:public"]) + closure_js_library( name = "polymer_closure", srcs = ["@polymer_closure//file"], diff --git a/plugins/BUILD b/plugins/BUILD index bddff41045..b38658b0e8 100644 --- a/plugins/BUILD +++ b/plugins/BUILD @@ -1,4 +1,5 @@ load("//tools/bzl:genrule2.bzl", "genrule2") +load("//tools/bzl:javadoc.bzl", "java_doc") load( "//tools/bzl:plugins.bzl", "CORE_PLUGINS", @@ -123,8 +124,6 @@ java_binary( ], ) -load("//tools/bzl:javadoc.bzl", "java_doc") - java_doc( name = "plugin-api-javadoc", libs = PLUGIN_API + [ diff --git a/plugins/replication b/plugins/replication index 38fc58bdd9..bdc5ad1fa5 160000 --- a/plugins/replication +++ b/plugins/replication @@ -1 +1 @@ -Subproject commit 38fc58bdd9b3c751b0da985e2c17b00dfab3b4fd +Subproject commit bdc5ad1fa51dc3facb96fc69a0dc8fed86f0c9d7 diff --git a/polygerrit-ui/BUILD b/polygerrit-ui/BUILD index 5889ffd50c..3988f956be 100644 --- a/polygerrit-ui/BUILD +++ b/polygerrit-ui/BUILD @@ -1,8 +1,8 @@ -package(default_visibility = ["//visibility:public"]) - load("@io_bazel_rules_go//go:def.bzl", "go_binary") -load("//tools/bzl:js.bzl", "bower_component_bundle") load("//tools/bzl:genrule2.bzl", "genrule2") +load("//tools/bzl:js.bzl", "bower_component_bundle") + +package(default_visibility = ["//visibility:public"]) bower_component_bundle( name = "polygerrit_components.bower_components", diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD index d48641b7b4..bba0640e92 100644 --- a/polygerrit-ui/app/BUILD +++ b/polygerrit-ui/app/BUILD @@ -1,8 +1,8 @@ -package(default_visibility = ["//visibility:public"]) - -load(":rules.bzl", "polygerrit_bundle") load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:js.bzl", "bower_component_bundle") +load(":rules.bzl", "polygerrit_bundle") + +package(default_visibility = ["//visibility:public"]) polygerrit_bundle( name = "polygerrit_ui", diff --git a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js index 4073798f23..1f5457af61 100644 --- a/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js +++ b/polygerrit-ui/app/elements/admin/gr-admin-group-list/gr-admin-group-list.js @@ -129,8 +129,7 @@ }, _refreshGroupsList() { - this.$.restAPI.invalidateGroupsCache(this._filter, - this._groupsPerPage, this._offset); + this.$.restAPI.invalidateGroupsCache(); return this._getGroups(this._filter, this._groupsPerPage, this._offset); }, diff --git a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js index 116f084faf..e0b054bd98 100644 --- a/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js +++ b/polygerrit-ui/app/elements/admin/gr-repo-list/gr-repo-list.js @@ -130,8 +130,7 @@ }, _refreshReposList() { - this.$.restAPI.invalidateReposCache(this._filter, - this._reposPerPage, this._offset); + this.$.restAPI.invalidateReposCache(); return this._getRepos(this._filter, this._reposPerPage, this._offset); }, diff --git a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js index 39f4d8dab6..6c475892ae 100644 --- a/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js +++ b/polygerrit-ui/app/elements/change/gr-related-changes-list/gr-related-changes-list.js @@ -190,7 +190,8 @@ }, _getChangesWithSameTopic() { - return this.$.restAPI.getChangesWithSameTopic(this.change.topic); + return this.$.restAPI.getChangesWithSameTopic(this.change.topic, + this.change._number); }, /** diff --git a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html index 4ea8cc7c40..1f885afd51 100644 --- a/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html +++ b/polygerrit-ui/app/elements/shared/gr-icons/gr-icons.html @@ -20,29 +20,29 @@ limitations under the License. - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js index c18f7537ed..eb0c7e0a54 100644 --- a/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js +++ b/polygerrit-ui/app/elements/shared/gr-js-api-interface/gr-plugin-rest-api.js @@ -38,6 +38,10 @@ return getRestApi().getVersion(); }; + GrPluginRestApi.prototype.invalidateReposCache = function() { + getRestApi().invalidateReposCache(); + }; + /** * Fetch and return native browser REST API Response. * @param {string} method HTTP Method (GET, POST, etc) diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js index d9b0cbf9bc..65f1f40f10 100644 --- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js +++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface.js @@ -1605,7 +1605,7 @@ this._invalidateSharedFetchPromisesPrefix('/groups/?'); }, - invalidateReposCache(filter, reposPerPage, opt_offset) { + invalidateReposCache() { this._invalidateSharedFetchPromisesPrefix('/projects/?'); }, @@ -1886,16 +1886,21 @@ }); }, - getChangesWithSameTopic(topic) { + getChangesWithSameTopic(topic, changeNum) { const options = this.listChangesOptionsToHex( this.ListChangesOption.LABELS, this.ListChangesOption.CURRENT_REVISION, this.ListChangesOption.CURRENT_COMMIT, this.ListChangesOption.DETAILED_LABELS ); + const query = [ + 'status:open', + '-change:' + changeNum, + 'topic:' + topic, + ].join(' '); const params = { O: options, - q: 'status:open topic:' + topic, + q: query, }; return this._fetchJSON({ url: '/changes/', diff --git a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html index 667f24c29e..5d4a3b0f41 100644 --- a/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html +++ b/polygerrit-ui/app/elements/shared/gr-rest-api-interface/gr-rest-api-interface_test.html @@ -956,7 +956,7 @@ limitations under the License. element._cache.set(url, {}); - element.invalidateReposCache('test', 25); + element.invalidateReposCache(); assert.isUndefined(element._sharedFetchPromises[url]); @@ -1043,7 +1043,7 @@ limitations under the License. element._cache.set(url, {}); - element.invalidateGroupsCache('test', 25); + element.invalidateGroupsCache(); assert.isUndefined(element._sharedFetchPromises[url]); diff --git a/polygerrit-ui/app/externs/BUILD b/polygerrit-ui/app/externs/BUILD index fab3954be5..26ead9a439 100644 --- a/polygerrit-ui/app/externs/BUILD +++ b/polygerrit-ui/app/externs/BUILD @@ -12,12 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") + package( default_visibility = ["//visibility:public"], ) -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") - closure_js_library( name = "plugin", srcs = ["plugin.js"], diff --git a/polygerrit-ui/app/rules.bzl b/polygerrit-ui/app/rules.bzl index 8bf104af0a..7788e5f0f5 100644 --- a/polygerrit-ui/app/rules.bzl +++ b/polygerrit-ui/app/rules.bzl @@ -1,10 +1,8 @@ -load("//tools/bzl:genrule2.bzl", "genrule2") load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library") +load("//tools/bzl:genrule2.bzl", "genrule2") load( "//tools/bzl:js.bzl", - "bower_component", "bundle_assets", - "js_component", ) def polygerrit_bundle(name, srcs, outs, app): diff --git a/tools/bzl/asciidoc.bzl b/tools/bzl/asciidoc.bzl index 97d68d6dc1..825ac98def 100644 --- a/tools/bzl/asciidoc.bzl +++ b/tools/bzl/asciidoc.bzl @@ -41,17 +41,17 @@ def _replace_macros_impl(ctx): _replace_macros = rule( attrs = { - "_exe": attr.label( - default = Label("//Documentation:replace_macros.py"), - allow_single_file = True, - ), "src": attr.label( mandatory = True, allow_single_file = [".txt"], ), - "suffix": attr.string(mandatory = True), - "searchbox": attr.bool(default = True), "out": attr.output(mandatory = True), + "searchbox": attr.bool(default = True), + "suffix": attr.string(mandatory = True), + "_exe": attr.label( + default = Label("//Documentation:replace_macros.py"), + allow_single_file = True, + ), }, implementation = _replace_macros_impl, ) @@ -108,23 +108,23 @@ def _asciidoc_impl(ctx): ) _asciidoc_attrs = { + "srcs": attr.label_list( + mandatory = True, + allow_files = True, + ), + "attributes": attr.string_list(), + "backend": attr.string(), + "suffix": attr.string(mandatory = True), + "version": attr.label( + default = Label("//:version.txt"), + allow_single_file = True, + ), "_exe": attr.label( default = Label("//java/com/google/gerrit/asciidoctor:asciidoc"), cfg = "host", allow_files = True, executable = True, ), - "srcs": attr.label_list( - mandatory = True, - allow_files = True, - ), - "version": attr.label( - default = Label("//:version.txt"), - allow_single_file = True, - ), - "suffix": attr.string(mandatory = True), - "backend": attr.string(), - "attributes": attr.string_list(), } _asciidoc = rule( @@ -279,11 +279,11 @@ _asciidoc_zip = rule( mandatory = True, allow_single_file = [".zip"], ), + "directory": attr.string(mandatory = True), "resources": attr.label_list( mandatory = True, allow_files = True, ), - "directory": attr.string(mandatory = True), }, outputs = { "out": "%{name}.zip", diff --git a/tools/bzl/classpath.bzl b/tools/bzl/classpath.bzl index b60e4e4c5e..f997fcf8ea 100644 --- a/tools/bzl/classpath.bzl +++ b/tools/bzl/classpath.bzl @@ -8,8 +8,8 @@ def _classpath_collector(ctx): elif hasattr(d, "files"): all += d.files - as_strs = [c.path for c in all] - ctx.file_action( + as_strs = [c.path for c in all.to_list()] + ctx.actions.write( output = ctx.outputs.runtime, content = "\n".join(sorted(as_strs)), ) diff --git a/tools/bzl/javadoc.bzl b/tools/bzl/javadoc.bzl index 8f2316c696..d315f8f6f6 100644 --- a/tools/bzl/javadoc.bzl +++ b/tools/bzl/javadoc.bzl @@ -23,7 +23,7 @@ def _impl(ctx): source_jars += l.java.source_jars transitive_jar_set += l.java.transitive_deps - transitive_jar_paths = [j.path for j in transitive_jar_set] + transitive_jar_paths = [j.path for j in transitive_jar_set.to_list()] dir = ctx.outputs.zip.path + ".dir" source = ctx.outputs.zip.path + ".source" external_docs = ["http://docs.oracle.com/javase/8/docs/api"] + ctx.attr.external_docs @@ -32,7 +32,7 @@ def _impl(ctx): "export TZ", "rm -rf %s" % source, "mkdir %s" % source, - " && ".join(["unzip -qud %s %s" % (source, j.path) for j in source_jars]), + " && ".join(["unzip -qud %s %s" % (source, j.path) for j in source_jars.to_list()]), "rm -rf %s" % dir, "mkdir %s" % dir, " ".join([ @@ -56,17 +56,17 @@ def _impl(ctx): "(cd %s && zip -Xqr ../%s *)" % (dir, ctx.outputs.zip.basename), ] ctx.actions.run_shell( - inputs = list(transitive_jar_set) + list(source_jars) + ctx.files._jdk, + inputs = transitive_jar_set.to_list() + source_jars.to_list() + ctx.files._jdk, outputs = [zip_output], command = " && ".join(cmd), ) java_doc = rule( attrs = { + "external_docs": attr.string_list(), "libs": attr.label_list(allow_files = False), "pkgs": attr.string_list(), "title": attr.string(), - "external_docs": attr.string_list(), "_jdk": attr.label( default = Label("@bazel_tools//tools/jdk:current_java_runtime"), allow_files = True, diff --git a/tools/bzl/js.bzl b/tools/bzl/js.bzl index 23d1ccd516..19d4436d42 100644 --- a/tools/bzl/js.bzl +++ b/tools/bzl/js.bzl @@ -1,10 +1,10 @@ +load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library") +load("//lib/js:npm.bzl", "NPM_SHA1S", "NPM_VERSIONS") + NPMJS = "NPMJS" GERRIT = "GERRIT:" -load("//lib/js:npm.bzl", "NPM_SHA1S", "NPM_VERSIONS") -load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library") - def _npm_tarball(name): return "%s@%s.npm_binary.tgz" % (name, NPM_VERSIONS[name]) @@ -37,9 +37,9 @@ def _npm_binary_impl(ctx): npm_binary = repository_rule( attrs = { + "repository": attr.string(default = NPMJS), # Label resolves within repo of the .bzl file. "_download_script": attr.label(default = Label("//tools:download_file.py")), - "repository": attr.string(default = NPMJS), }, local = True, implementation = _npm_binary_impl, @@ -120,13 +120,13 @@ def _bash(ctx, cmd): bower_archive = repository_rule( _bower_archive, attrs = { - "_bower_archive": attr.label(default = Label("@bower//:%s" % _npm_tarball("bower"))), - "_run_npm": attr.label(default = Label("//tools/js:run_npm_binary.py")), - "_download_bower": attr.label(default = Label("//tools/js:download_bower.py")), - "sha1": attr.string(mandatory = True), - "version": attr.string(mandatory = True), "package": attr.string(mandatory = True), "semver": attr.string(), + "sha1": attr.string(mandatory = True), + "version": attr.string(mandatory = True), + "_bower_archive": attr.label(default = Label("@bower//:%s" % _npm_tarball("bower"))), + "_download_bower": attr.label(default = Label("//tools/js:download_bower.py")), + "_run_npm": attr.label(default = Label("//tools/js:run_npm_binary.py")), }, ) @@ -207,12 +207,12 @@ js_component = rule( _bower_component = rule( _bower_component_impl, attrs = dict(_common_attrs.items() + { - "zipfile": attr.label(allow_single_file = [".zip"]), "license": attr.label(allow_single_file = True), - "version_json": attr.label(allow_files = [".json"]), # If set, define by hand, and don't regenerate this entry in bower2bazel. "seed": attr.bool(default = False), + "version_json": attr.label(allow_files = [".json"]), + "zipfile": attr.label(allow_single_file = [".zip"]), }.items()), ) @@ -247,7 +247,7 @@ def _bower_component_bundle_impl(ctx): out_versions = ctx.outputs.version_json ctx.actions.run_shell( - inputs = list(zips), + inputs = zips.to_list(), outputs = [out_zip], command = " && ".join([ "p=$PWD", @@ -256,7 +256,7 @@ def _bower_component_bundle_impl(ctx): "rm -rf %s.dir" % out_zip.path, "mkdir -p %s.dir/bower_components" % out_zip.path, "cd %s.dir/bower_components" % out_zip.path, - "for z in %s; do unzip -q $p/$z ; done" % " ".join(sorted([z.path for z in zips])), + "for z in %s; do unzip -q $p/$z ; done" % " ".join(sorted([z.path for z in zips.to_list()])), "cd ..", "find . -exec touch -t 198001010000 '{}' ';'", "zip -Xqr $p/%s bower_components/*" % out_zip.path, @@ -265,10 +265,10 @@ def _bower_component_bundle_impl(ctx): ) ctx.actions.run_shell( - inputs = list(versions), + inputs = versions.to_list(), outputs = [out_versions], mnemonic = "BowerVersions", - command = "(echo '{' ; for j in %s ; do cat $j; echo ',' ; done ; echo \\\"\\\":\\\"\\\"; echo '}') > %s" % (" ".join([v.path for v in versions]), out_versions.path), + command = "(echo '{' ; for j in %s ; do cat $j; echo ',' ; done ; echo \\\"\\\":\\\"\\\"; echo '}') > %s" % (" ".join([v.path for v in versions.to_list()]), out_versions.path), ) return struct( @@ -281,8 +281,8 @@ bower_component_bundle = rule( _bower_component_bundle_impl, attrs = _common_attrs, outputs = { - "zip": "%{name}.zip", "version_json": "%{name}-versions.json", + "zip": "%{name}.zip", }, ) @@ -394,11 +394,6 @@ def _bundle_output_func(name, split): _bundle_rule = rule( _bundle_impl, attrs = { - "deps": attr.label_list(providers = ["transitive_zipfiles"]), - "app": attr.label( - mandatory = True, - allow_single_file = True, - ), "srcs": attr.label_list(allow_files = [ ".js", ".html", @@ -406,12 +401,13 @@ _bundle_rule = rule( ".css", ".ico", ]), - "pkg": attr.string(mandatory = True), - "split": attr.bool(default = True), - "_run_npm": attr.label( - default = Label("//tools/js:run_npm_binary.py"), + "app": attr.label( + mandatory = True, allow_single_file = True, ), + "pkg": attr.string(mandatory = True), + "split": attr.bool(default = True), + "deps": attr.label_list(providers = ["transitive_zipfiles"]), "_bundler_archive": attr.label( default = Label("@polymer-bundler//:%s" % _npm_tarball("polymer-bundler")), allow_single_file = True, @@ -420,13 +416,17 @@ _bundle_rule = rule( default = Label("@crisper//:%s" % _npm_tarball("crisper")), allow_single_file = True, ), + "_run_npm": attr.label( + default = Label("//tools/js:run_npm_binary.py"), + allow_single_file = True, + ), }, outputs = _bundle_output_func, ) def bundle_assets(*args, **kwargs): """Combine html, js, css files and optionally split into js and html bundles.""" - _bundle_rule(*args, pkg = native.package_name(), **kwargs) + _bundle_rule(pkg = native.package_name(), *args, **kwargs) def polygerrit_plugin(name, app, srcs = [], assets = None, plugin_name = None, **kwargs): """Bundles plugin dependencies for deployment. diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl index ccde4675ee..be984f1a7c 100644 --- a/tools/bzl/junit.bzl +++ b/tools/bzl/junit.bzl @@ -50,7 +50,7 @@ def _impl(ctx): classes = ",".join( [_AsClassName(x) for x in ctx.attr.srcs], ) - ctx.file_action(output = ctx.outputs.out, content = _OUTPUT % ( + ctx.actions.write(output = ctx.outputs.out, content = _OUTPUT % ( classes, ctx.attr.outname, )) diff --git a/tools/bzl/maven_jar.bzl b/tools/bzl/maven_jar.bzl index b284d0c944..821e037687 100644 --- a/tools/bzl/maven_jar.bzl +++ b/tools/bzl/maven_jar.bzl @@ -166,15 +166,15 @@ def _maven_jar_impl(ctx): maven_jar = repository_rule( attrs = { "artifact": attr.string(mandatory = True), + "attach_source": attr.bool(default = True), + "exclude": attr.string_list(), + "repository": attr.string(default = MAVEN_CENTRAL), "sha1": attr.string(), "src_sha1": attr.string(), - "_download_script": attr.label(default = Label("//tools:download_file.py")), - "repository": attr.string(default = MAVEN_CENTRAL), - "attach_source": attr.bool(default = True), "unsign": attr.bool(default = False), - "deps": attr.string_list(), "exports": attr.string_list(), - "exclude": attr.string_list(), + "deps": attr.string_list(), + "_download_script": attr.label(default = Label("//tools:download_file.py")), }, local = True, implementation = _maven_jar_impl, diff --git a/tools/bzl/pkg_war.bzl b/tools/bzl/pkg_war.bzl index 1fd1c813ff..1dd6d7ee4c 100644 --- a/tools/bzl/pkg_war.bzl +++ b/tools/bzl/pkg_war.bzl @@ -82,7 +82,7 @@ def _war_impl(ctx): elif hasattr(l, "files"): transitive_lib_deps += l.files - for dep in transitive_lib_deps: + for dep in transitive_lib_deps.to_list(): cmd += _add_file(dep, build_output + "/WEB-INF/lib/") inputs.append(dep) @@ -91,7 +91,7 @@ def _war_impl(ctx): for l in ctx.attr.pgmlibs: transitive_pgmlib_deps += l.java.transitive_runtime_deps - for dep in transitive_pgmlib_deps: + for dep in transitive_pgmlib_deps.to_list(): if dep not in inputs: cmd += _add_file(dep, build_output + "/WEB-INF/pgm-lib/") inputs.append(dep) @@ -104,7 +104,7 @@ def _war_impl(ctx): transitive_context_deps += jar.java.transitive_runtime_deps elif hasattr(jar, "files"): transitive_context_deps += jar.files - for dep in transitive_context_deps: + for dep in transitive_context_deps.to_list(): cmd += _add_context(dep, build_output) inputs.append(dep) diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD index f6016cdb37..b8bfe16492 100644 --- a/tools/eclipse/BUILD +++ b/tools/eclipse/BUILD @@ -1,5 +1,5 @@ -load("//tools/bzl:pkg_war.bzl", "LIBS", "PGMLIBS") load("//tools/bzl:classpath.bzl", "classpath_collector") +load("//tools/bzl:pkg_war.bzl", "LIBS", "PGMLIBS") load( "//tools/bzl:plugins.bzl", "CORE_PLUGINS", diff --git a/tools/util.py b/tools/util.py index 3817f75c4d..172ecfe521 100644 --- a/tools/util.py +++ b/tools/util.py @@ -15,14 +15,12 @@ from os import path REPO_ROOTS = { - 'ECLIPSE': 'https://repo.eclipse.org/content/groups/releases', - 'GERRIT': 'http://gerrit-maven.storage.googleapis.com', - 'GERRIT_API': - 'https://gerrit-api.commondatastorage.googleapis.com/release', - 'MAVEN_CENTRAL': 'http://repo1.maven.org/maven2', - 'MAVEN_LOCAL': 'file://' + path.expanduser('~/.m2/repository'), - 'MAVEN_SNAPSHOT': - 'https://oss.sonatype.org/content/repositories/snapshots', + 'ECLIPSE': 'https://repo.eclipse.org/content/groups/releases', + 'GERRIT': 'http://gerrit-maven.storage.googleapis.com', + 'GERRIT_API': 'https://gerrit-api.commondatastorage.googleapis.com/release', + 'MAVEN_CENTRAL': 'http://repo1.maven.org/maven2', + 'MAVEN_LOCAL': 'file://' + path.expanduser('~/.m2/repository'), + 'MAVEN_SNAPSHOT': 'https://oss.sonatype.org/content/repositories/snapshots', }