Merge branch 'stable-2.16'

* stable-2.16:
  Consume JGit artifacts from Maven Central
  Consume JGit artifacts from Maven Central
  gr-related-changes: Don't show "Same topic" for only one change
  RelatedChanges: Don't show "Same Topic" for only one change
  ChangeEditApi: Allow to set options on change edit detail request
  JS API: Expose invalidateReposCache method
  restAPI.invalidateGroupsCache: Remove unused parameters
  restAPI.invalidateReposCache: Remove unused parameters
  Add Javadoc to clarify behavior of {Accounts|Changes|Groups}#withOptions
  Update highlight.js to master branch
  Docs: Add use-case for Private changes
  OnlineNoteDbMigrationIT: improve readability of some tests
  Update git submodules
  migrate-to-note-db: add --skip-project option
  OnlineNoteDbMigrationIT: Reuse existing constant
  Do not crash if permitted labels array is empty
  Fix '/' getting typed in search bar when pressed
  Encode project name in download commands
  ProjectResetter: Avoid Repository#getAllRefs
  AbstractDaemonTest: Avoid Repository#getAllRefs
  ChangeUtil: Remove javadoc references to deprecated JGit methods
  Set version to 2.16.4-SNAPSHOT
  AccountManagerIT: Fix failing authentication tests
  ChangeEditApiImpl: Access non-Singleton change edit classes via Provider
  ListChangesOption: Add missing word in Javadoc
  Update git submodules
  Update git submodules
  Fix broken links in gr-icons.html
  Add release notes for Gerrit v2.10.8
  AccountIT#updateDisplayName: Rewrite to work with updated account manager
  Add release notes for Gerrit v2.9.5
  AccountApiImpl: Fix message in exception
  RelatedChangeAndCommitInfo: Use default CommitInfo#toString
  Support Get Related in extension API
  CommitInfo: Use ToStringHelper
  CommitInfo: Handle root commits in toString()
  Implement equals/hashCode/toString in CommitInfo and friends
  Set version to 2.15.9-SNAPSHOT
  AccountIT: Disable failing updateDisplayName test
  Set version to 2.16.3
  Set version to 2.13.12
  Set version to 2.12.9
  Set version to 2.11.12
  Set version to 2.10.8
  Upgrade JGit to 5.1.5.201812261915-r
  Set version to 2.15.8
  Upgrade JGit to 4.9.8.201812241815-r
  Set version to 2.9.5
  Set version to 2.14.18
  Revert "Fix the missing DB entry in Gerrit DB"
  Upgrade JGit to 4.7.7.201812240805-r
  maven_jar: Add repo.eclipse.org to supported repositories
  Update git submodules
  ChangeApi: Add method to list change reviewers
  Bazel: Automatically fix lint errors with buildifier 0.20.0
  Revert "Temp fix for projects list ordering in PolyGerrit"
  Do not center the "By User" column in the Group Audit Log table
  Bazel: Fix more buildifier warnings
  Bazel: Automatically fix lint errors with buildifier 0.20.0
  Fix typo in documentation of edit preferences
  Add MIME type for favicons to list of allowed image types.
  Bazel: Automatically fix lint errors with buildifier
  Mail: Use correct patch set when reading line from file
  Upgrade JGit to 4.5.5.201812240535-r

Change-Id: I15dd15a2e3a1171ddfb792a3f17c43861d434421
This commit is contained in:
David Pursehouse
2019-01-21 13:14:11 +09:00
57 changed files with 420 additions and 245 deletions

4
BUILD
View File

@@ -1,8 +1,8 @@
package(default_visibility = ["//visibility:public"])
load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:genrule2.bzl", "genrule2")
load("//tools/bzl:pkg_war.bzl", "pkg_war") load("//tools/bzl:pkg_war.bzl", "pkg_war")
package(default_visibility = ["//visibility:public"])
config_setting( config_setting(
name = "java9", name = "java9",
values = { values = {

View File

@@ -1,10 +1,8 @@
package(default_visibility = ["//visibility:public"]) load("//tools/bzl:asciidoc.bzl", "documentation_attributes", "genasciidoc", "genasciidoc_zip")
load("//tools/bzl:asciidoc.bzl", "documentation_attributes")
load("//tools/bzl:asciidoc.bzl", "genasciidoc")
load("//tools/bzl:asciidoc.bzl", "genasciidoc_zip")
load("//tools/bzl:license.bzl", "license_map") load("//tools/bzl:license.bzl", "license_map")
package(default_visibility = ["//visibility:public"])
exports_files([ exports_files([
"replace_macros.py", "replace_macros.py",
]) ])

View File

@@ -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] * 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 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 Defaults for preferences that apply for all accounts can be configured
in the `refs/users/default` branch in the `All-Users` repository. in the `refs/users/default` branch in the `All-Users` repository.

View File

@@ -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 View Private Changes] global capability. Private changes are useful in a number
of cases: 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. * You want to check what the change looks like before formal review starts.
By marking the change private without reviewers, nobody can By marking the change private without reviewers, nobody can
prematurely comment on your changes. prematurely comment on your changes.

View File

@@ -1,4 +1,5 @@
load("//tools/bzl:java.bzl", "java_library2") load("//tools/bzl:java.bzl", "java_library2")
load("//tools/bzl:javadoc.bzl", "java_doc")
java_library( java_library(
name = "lib", name = "lib",
@@ -129,8 +130,6 @@ java_library2(
], ],
) )
load("//tools/bzl:javadoc.bzl", "java_doc")
java_doc( java_doc(
name = "framework-javadoc", name = "framework-javadoc",
testonly = True, testonly = True,

View File

@@ -1,5 +1,3 @@
load("//tools/bzl:genrule2.bzl", "genrule2")
ANNOTATIONS = [ ANNOTATIONS = [
"Nullable.java", "Nullable.java",
"audit/Audit.java", "audit/Audit.java",

View File

@@ -1,5 +1,6 @@
load("//lib:guava.bzl", "GUAVA_DOC_URL")
load("//lib/jgit:jgit.bzl", "JGIT_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( java_binary(
name = "extension-api", name = "extension-api",
@@ -34,8 +35,6 @@ java_library(
], ],
) )
load("//tools/bzl:javadoc.bzl", "java_doc")
java_doc( java_doc(
name = "extension-api-javadoc", name = "extension-api-javadoc",
external_docs = [ external_docs = [

View File

@@ -172,16 +172,19 @@ public interface Accounts {
return this; return this;
} }
/** Set an option on the request, appending to existing options. */
public QueryRequest withOption(ListAccountsOption options) { public QueryRequest withOption(ListAccountsOption options) {
this.options.add(options); this.options.add(options);
return this; return this;
} }
/** Set options on the request, appending to existing options. */
public QueryRequest withOptions(ListAccountsOption... options) { public QueryRequest withOptions(ListAccountsOption... options) {
this.options.addAll(Arrays.asList(options)); this.options.addAll(Arrays.asList(options));
return this; return this;
} }
/** Set options on the request, replacing existing options. */
public QueryRequest withOptions(EnumSet<ListAccountsOption> options) { public QueryRequest withOptions(EnumSet<ListAccountsOption> options) {
this.options = options; this.options = options;
return this; return this;

View File

@@ -215,6 +215,11 @@ public interface ChangeApi {
return suggestReviewers().withQuery(query); return suggestReviewers().withQuery(query);
} }
/**
* Retrieve reviewers ({@code ReviewerState.REVIEWER} and {@code ReviewerState.CC}) on the change.
*/
List<ReviewerInfo> reviewers() throws RestApiException;
ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException; ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException;
default ChangeInfo get(Iterable<ListChangesOption> options) throws RestApiException { default ChangeInfo get(Iterable<ListChangesOption> options) throws RestApiException {
@@ -472,6 +477,16 @@ public interface ChangeApi {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@Override
public SuggestedReviewersRequest suggestReviewers(String query) throws RestApiException {
throw new NotImplementedException();
}
@Override
public List<ReviewerInfo> reviewers() throws RestApiException {
throw new NotImplementedException();
}
@Override @Override
public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException { public ChangeInfo get(EnumSet<ListChangesOption> options) throws RestApiException {
throw new NotImplementedException(); throw new NotImplementedException();

View File

@@ -14,11 +14,13 @@
package com.google.gerrit.extensions.api.changes; 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.common.EditInfo;
import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.NotImplementedException; import com.google.gerrit.extensions.restapi.NotImplementedException;
import com.google.gerrit.extensions.restapi.RawInput; import com.google.gerrit.extensions.restapi.RawInput;
import com.google.gerrit.extensions.restapi.RestApiException; import com.google.gerrit.extensions.restapi.RestApiException;
import java.util.EnumSet;
import java.util.Optional; import java.util.Optional;
/** /**
@@ -29,6 +31,33 @@ import java.util.Optional;
*/ */
public interface ChangeEditApi { public interface ChangeEditApi {
abstract class ChangeEditDetailRequest {
private String base;
private EnumSet<ChangeEditDetailOption> options = EnumSet.noneOf(ChangeEditDetailOption.class);
public abstract Optional<EditInfo> 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<ChangeEditDetailOption> options() {
return options;
}
}
ChangeEditDetailRequest detail() throws RestApiException;
/** /**
* Retrieves details regarding the change edit. * Retrieves details regarding the change edit.
* *
@@ -155,6 +184,11 @@ public interface ChangeEditApi {
* interface. * interface.
*/ */
class NotImplemented implements ChangeEditApi { class NotImplemented implements ChangeEditApi {
@Override
public ChangeEditDetailRequest detail() throws RestApiException {
throw new NotImplementedException();
}
@Override @Override
public Optional<EditInfo> get() throws RestApiException { public Optional<EditInfo> get() throws RestApiException {
throw new NotImplementedException(); throw new NotImplementedException();

View File

@@ -94,16 +94,19 @@ public interface Changes {
return this; return this;
} }
/** Set an option on the request, appending to existing options. */
public QueryRequest withOption(ListChangesOption options) { public QueryRequest withOption(ListChangesOption options) {
this.options.add(options); this.options.add(options);
return this; return this;
} }
/** Set options on the request, appending to existing options. */
public QueryRequest withOptions(ListChangesOption... options) { public QueryRequest withOptions(ListChangesOption... options) {
this.options.addAll(Arrays.asList(options)); this.options.addAll(Arrays.asList(options));
return this; return this;
} }
/** Set options on the request, replacing existing options. */
public QueryRequest withOptions(EnumSet<ListChangesOption> options) { public QueryRequest withOptions(EnumSet<ListChangesOption> options) {
this.options = options; this.options = options;
return this; return this;

View File

@@ -253,16 +253,19 @@ public interface Groups {
return this; return this;
} }
/** Set an option on the request, appending to existing options. */
public QueryRequest withOption(ListGroupsOption options) { public QueryRequest withOption(ListGroupsOption options) {
this.options.add(options); this.options.add(options);
return this; return this;
} }
/** Set options on the request, appending to existing options. */
public QueryRequest withOptions(ListGroupsOption... options) { public QueryRequest withOptions(ListGroupsOption... options) {
this.options.addAll(Arrays.asList(options)); this.options.addAll(Arrays.asList(options));
return this; return this;
} }
/** Set options on the request, replacing existing options. */
public QueryRequest withOptions(EnumSet<ListGroupsOption> options) { public QueryRequest withOptions(EnumSet<ListGroupsOption> options) {
this.options = options; this.options = options;
return this; return this;

View File

@@ -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
}

View File

@@ -17,7 +17,7 @@ package com.google.gerrit.extensions.client;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.Set; import java.util.Set;
/** Output options available for retrieval change details. */ /** Output options available for retrieval of change details. */
public enum ListChangesOption { public enum ListChangesOption {
LABELS(0), LABELS(0),
DETAILED_LABELS(8), DETAILED_LABELS(8),

View File

@@ -1,5 +1,3 @@
load("//tools/bzl:genrule2.bzl", "genrule2")
QUERY_PARSE_EXCEPTION_SRCS = [ QUERY_PARSE_EXCEPTION_SRCS = [
"query/QueryParseException.java", "query/QueryParseException.java",
"query/QueryRequiresAuthException.java", "query/QueryRequiresAuthException.java",

View File

@@ -1,3 +1,5 @@
load("//tools/bzl:javadoc.bzl", "java_doc")
CONSTANTS_SRC = [ CONSTANTS_SRC = [
"documentation/Constants.java", "documentation/Constants.java",
] ]
@@ -143,8 +145,6 @@ java_library(
], ],
) )
load("//tools/bzl:javadoc.bzl", "java_doc")
java_doc( java_doc(
name = "doc", name = "doc",
libs = [":server"], libs = [":server"],

View File

@@ -136,21 +136,7 @@ public class AccountManager {
try { try {
Optional<ExternalId> optionalExtId = externalIds.get(who.getExternalIdKey()); Optional<ExternalId> optionalExtId = externalIds.get(who.getExternalIdKey());
if (!optionalExtId.isPresent()) { if (!optionalExtId.isPresent()) {
if (who.getUserName().isPresent()) {
ExternalId.Key key = ExternalId.Key.create(SCHEME_USERNAME, who.getUserName().get());
Optional<ExternalId> 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. // New account, automatically create and return.
logger.atFine().log("External ID not found. Attempting to create new account.");
return create(who); return create(who);
} }
@@ -416,7 +402,6 @@ public class AccountManager {
public AuthResult link(Account.Id to, AuthRequest who) public AuthResult link(Account.Id to, AuthRequest who)
throws AccountException, OrmException, IOException, ConfigInvalidException { throws AccountException, OrmException, IOException, ConfigInvalidException {
Optional<ExternalId> optionalExtId = externalIds.get(who.getExternalIdKey()); Optional<ExternalId> optionalExtId = externalIds.get(who.getExternalIdKey());
logger.atFine().log("Link another authentication identity to an existing account");
if (optionalExtId.isPresent()) { if (optionalExtId.isPresent()) {
ExternalId extId = optionalExtId.get(); ExternalId extId = optionalExtId.get();
if (!extId.accountId().equals(to)) { if (!extId.accountId().equals(to)) {
@@ -425,7 +410,6 @@ public class AccountManager {
} }
update(who, extId); update(who, extId);
} else { } else {
logger.atFine().log("Linking new external ID to the existing account");
ExternalId newExtId = ExternalId newExtId =
ExternalId.createWithEmail(who.getExternalIdKey(), to, who.getEmailAddress()); ExternalId.createWithEmail(who.getExternalIdKey(), to, who.getEmailAddress());
checkEmailNotUsed(newExtId); checkEmailNotUsed(newExtId);

View File

@@ -228,7 +228,7 @@ public class AccountApiImpl implements AccountApi {
accountLoader.fill(); accountLoader.fill();
return ai; return ai;
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot parse change", e); throw asRestApiException("Cannot parse account", e);
} }
} }

View File

@@ -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.RestoreInput;
import com.google.gerrit.extensions.api.changes.RevertInput; import com.google.gerrit.extensions.api.changes.RevertInput;
import com.google.gerrit.extensions.api.changes.ReviewerApi; 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.RevisionApi;
import com.google.gerrit.extensions.api.changes.SubmittedTogetherInfo; import com.google.gerrit.extensions.api.changes.SubmittedTogetherInfo;
import com.google.gerrit.extensions.api.changes.SubmittedTogetherOption; 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.ListChangeComments;
import com.google.gerrit.server.restapi.change.ListChangeDrafts; import com.google.gerrit.server.restapi.change.ListChangeDrafts;
import com.google.gerrit.server.restapi.change.ListChangeRobotComments; 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.MarkAsReviewed;
import com.google.gerrit.server.restapi.change.MarkAsUnreviewed; import com.google.gerrit.server.restapi.change.MarkAsUnreviewed;
import com.google.gerrit.server.restapi.change.Move; import com.google.gerrit.server.restapi.change.Move;
@@ -117,6 +119,7 @@ class ChangeApiImpl implements ChangeApi {
private final ChangeMessageApiImpl.Factory changeMessageApi; private final ChangeMessageApiImpl.Factory changeMessageApi;
private final ChangeMessages changeMessages; private final ChangeMessages changeMessages;
private final SuggestChangeReviewers suggestReviewers; private final SuggestChangeReviewers suggestReviewers;
private final ListReviewers listReviewers;
private final ChangeResource change; private final ChangeResource change;
private final Abandon abandon; private final Abandon abandon;
private final Revert revert; private final Revert revert;
@@ -165,6 +168,7 @@ class ChangeApiImpl implements ChangeApi {
ChangeMessageApiImpl.Factory changeMessageApi, ChangeMessageApiImpl.Factory changeMessageApi,
ChangeMessages changeMessages, ChangeMessages changeMessages,
SuggestChangeReviewers suggestReviewers, SuggestChangeReviewers suggestReviewers,
ListReviewers listReviewers,
Abandon abandon, Abandon abandon,
Revert revert, Revert revert,
Restore restore, Restore restore,
@@ -211,6 +215,7 @@ class ChangeApiImpl implements ChangeApi {
this.changeMessageApi = changeMessageApi; this.changeMessageApi = changeMessageApi;
this.changeMessages = changeMessages; this.changeMessages = changeMessages;
this.suggestReviewers = suggestReviewers; this.suggestReviewers = suggestReviewers;
this.listReviewers = listReviewers;
this.abandon = abandon; this.abandon = abandon;
this.restore = restore; this.restore = restore;
this.updateByMerge = updateByMerge; this.updateByMerge = updateByMerge;
@@ -437,6 +442,15 @@ class ChangeApiImpl implements ChangeApi {
} }
} }
@Override
public List<ReviewerInfo> reviewers() throws RestApiException {
try {
return listReviewers.apply(change);
} catch (Exception e) {
throw asRestApiException("Cannot retrieve reviewers", e);
}
}
@Override @Override
public ChangeInfo get(EnumSet<ListChangesOption> s) throws RestApiException { public ChangeInfo get(EnumSet<ListChangesOption> s) throws RestApiException {
try { try {

View File

@@ -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.ChangeEditApi;
import com.google.gerrit.extensions.api.changes.PublishChangeEditInput; 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.EditInfo;
import com.google.gerrit.extensions.common.Input; import com.google.gerrit.extensions.common.Input;
import com.google.gerrit.extensions.restapi.AuthException; 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.gerrit.server.restapi.change.RebaseChangeEdit;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import java.io.IOException; import java.io.IOException;
import java.util.Optional; import java.util.Optional;
@@ -44,51 +46,79 @@ public class ChangeEditApiImpl implements ChangeEditApi {
ChangeEditApiImpl create(ChangeResource changeResource); ChangeEditApiImpl create(ChangeResource changeResource);
} }
private final ChangeEdits.Detail editDetail; private final Provider<ChangeEdits.Detail> editDetailProvider;
private final ChangeEdits.Post changeEditsPost; private final ChangeEdits.Post changeEditsPost;
private final DeleteChangeEdit deleteChangeEdit; private final DeleteChangeEdit deleteChangeEdit;
private final RebaseChangeEdit rebaseChangeEdit; private final RebaseChangeEdit rebaseChangeEdit;
private final PublishChangeEdit publishChangeEdit; private final PublishChangeEdit publishChangeEdit;
private final ChangeEdits.Get changeEditsGet; private final Provider<ChangeEdits.Get> changeEditsGetProvider;
private final ChangeEdits.Put changeEditsPut; private final ChangeEdits.Put changeEditsPut;
private final ChangeEdits.DeleteContent changeEditDeleteContent; private final ChangeEdits.DeleteContent changeEditDeleteContent;
private final ChangeEdits.GetMessage getChangeEditCommitMessage; private final Provider<ChangeEdits.GetMessage> getChangeEditCommitMessageProvider;
private final ChangeEdits.EditMessage modifyChangeEditCommitMessage; private final ChangeEdits.EditMessage modifyChangeEditCommitMessage;
private final ChangeEdits changeEdits; private final ChangeEdits changeEdits;
private final ChangeResource changeResource; private final ChangeResource changeResource;
@Inject @Inject
public ChangeEditApiImpl( public ChangeEditApiImpl(
ChangeEdits.Detail editDetail, Provider<ChangeEdits.Detail> editDetailProvider,
ChangeEdits.Post changeEditsPost, ChangeEdits.Post changeEditsPost,
DeleteChangeEdit deleteChangeEdit, DeleteChangeEdit deleteChangeEdit,
RebaseChangeEdit rebaseChangeEdit, RebaseChangeEdit rebaseChangeEdit,
PublishChangeEdit publishChangeEdit, PublishChangeEdit publishChangeEdit,
ChangeEdits.Get changeEditsGet, Provider<ChangeEdits.Get> changeEditsGetProvider,
ChangeEdits.Put changeEditsPut, ChangeEdits.Put changeEditsPut,
ChangeEdits.DeleteContent changeEditDeleteContent, ChangeEdits.DeleteContent changeEditDeleteContent,
ChangeEdits.GetMessage getChangeEditCommitMessage, Provider<ChangeEdits.GetMessage> getChangeEditCommitMessageProvider,
ChangeEdits.EditMessage modifyChangeEditCommitMessage, ChangeEdits.EditMessage modifyChangeEditCommitMessage,
ChangeEdits changeEdits, ChangeEdits changeEdits,
@Assisted ChangeResource changeResource) { @Assisted ChangeResource changeResource) {
this.editDetail = editDetail; this.editDetailProvider = editDetailProvider;
this.changeEditsPost = changeEditsPost; this.changeEditsPost = changeEditsPost;
this.deleteChangeEdit = deleteChangeEdit; this.deleteChangeEdit = deleteChangeEdit;
this.rebaseChangeEdit = rebaseChangeEdit; this.rebaseChangeEdit = rebaseChangeEdit;
this.publishChangeEdit = publishChangeEdit; this.publishChangeEdit = publishChangeEdit;
this.changeEditsGet = changeEditsGet; this.changeEditsGetProvider = changeEditsGetProvider;
this.changeEditsPut = changeEditsPut; this.changeEditsPut = changeEditsPut;
this.changeEditDeleteContent = changeEditDeleteContent; this.changeEditDeleteContent = changeEditDeleteContent;
this.getChangeEditCommitMessage = getChangeEditCommitMessage; this.getChangeEditCommitMessageProvider = getChangeEditCommitMessageProvider;
this.modifyChangeEditCommitMessage = modifyChangeEditCommitMessage; this.modifyChangeEditCommitMessage = modifyChangeEditCommitMessage;
this.changeEdits = changeEdits; this.changeEdits = changeEdits;
this.changeResource = changeResource; this.changeResource = changeResource;
} }
@Override
public ChangeEditDetailRequest detail() throws RestApiException {
try {
return new ChangeEditDetailRequest() {
@Override
public Optional<EditInfo> get() throws RestApiException {
return ChangeEditApiImpl.this.get(this);
}
};
} catch (Exception e) {
throw asRestApiException("Cannot retrieve change edit", e);
}
}
private Optional<EditInfo> 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<EditInfo> edit = editDetail.apply(changeResource);
return edit.isNone() ? Optional.empty() : Optional.of(edit.value());
} catch (Exception e) {
throw asRestApiException("Cannot retrieve change edit", e);
}
}
@Override @Override
public Optional<EditInfo> get() throws RestApiException { public Optional<EditInfo> get() throws RestApiException {
try { try {
Response<EditInfo> edit = editDetail.apply(changeResource); Response<EditInfo> edit = editDetailProvider.get().apply(changeResource);
return edit.isNone() ? Optional.empty() : Optional.of(edit.value()); return edit.isNone() ? Optional.empty() : Optional.of(edit.value());
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot retrieve change edit", e); throw asRestApiException("Cannot retrieve change edit", e);
@@ -140,7 +170,7 @@ public class ChangeEditApiImpl implements ChangeEditApi {
public Optional<BinaryResult> getFile(String filePath) throws RestApiException { public Optional<BinaryResult> getFile(String filePath) throws RestApiException {
try { try {
ChangeEditResource changeEditResource = getChangeEditResource(filePath); ChangeEditResource changeEditResource = getChangeEditResource(filePath);
Response<BinaryResult> fileResponse = changeEditsGet.apply(changeEditResource); Response<BinaryResult> fileResponse = changeEditsGetProvider.get().apply(changeEditResource);
return fileResponse.isNone() ? Optional.empty() : Optional.of(fileResponse.value()); return fileResponse.isNone() ? Optional.empty() : Optional.of(fileResponse.value());
} catch (Exception e) { } catch (Exception e) {
throw asRestApiException("Cannot retrieve file of change edit", e); throw asRestApiException("Cannot retrieve file of change edit", e);
@@ -191,7 +221,8 @@ public class ChangeEditApiImpl implements ChangeEditApi {
@Override @Override
public String getCommitMessage() throws RestApiException { public String getCommitMessage() throws RestApiException {
try { try {
try (BinaryResult binaryResult = getChangeEditCommitMessage.apply(changeResource)) { try (BinaryResult binaryResult =
getChangeEditCommitMessageProvider.get().apply(changeResource)) {
return binaryResult.asString(); return binaryResult.asString();
} }
} catch (Exception e) { } catch (Exception e) {

View File

@@ -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. */ /** Get the patch list corresponding to this patch set. */
protected PatchList getPatchList() throws PatchListNotAvailableException { protected PatchList getPatchList() throws PatchListNotAvailableException {
if (patchSet != null) { if (patchSet != null) {

View File

@@ -198,17 +198,6 @@ public class CommentSender extends ReplyToChangeSender {
*/ */
private List<CommentSender.FileCommentGroup> getGroupedInlineComments(Repository repo) { private List<CommentSender.FileCommentGroup> getGroupedInlineComments(Repository repo) {
List<CommentSender.FileCommentGroup> groups = new ArrayList<>(); List<CommentSender.FileCommentGroup> 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 // Loop over the comments and collect them into groups based on the file
// location of the comment. // location of the comment.
@@ -221,6 +210,16 @@ public class CommentSender extends ReplyToChangeSender {
currentGroup = new FileCommentGroup(); currentGroup = new FileCommentGroup();
currentGroup.filename = c.key.filename; currentGroup.filename = c.key.filename;
currentGroup.patchSetId = c.key.patchSetId; 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); groups.add(currentGroup);
if (patchList != null) { if (patchList != null) {
try { try {

View File

@@ -20,6 +20,7 @@ import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.GerritPersonIdentProvider; import com.google.gerrit.server.GerritPersonIdentProvider;
import com.google.gerrit.server.IdentifiedUser; import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.IdentifiedUser.GenericFactory; import com.google.gerrit.server.IdentifiedUser.GenericFactory;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.UsedAt; import com.google.gerrit.server.UsedAt;
import com.google.gerrit.server.account.AccountCache; import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.GroupBackend; import com.google.gerrit.server.account.GroupBackend;
@@ -56,6 +57,7 @@ public class EmailArguments {
final GroupBackend groupBackend; final GroupBackend groupBackend;
final AccountCache accountCache; final AccountCache accountCache;
final PatchListCache patchListCache; final PatchListCache patchListCache;
final PatchSetUtil patchSetUtil;
final ApprovalsUtil approvalsUtil; final ApprovalsUtil approvalsUtil;
final FromAddressGenerator fromAddressGenerator; final FromAddressGenerator fromAddressGenerator;
final EmailSender emailSender; final EmailSender emailSender;
@@ -88,6 +90,7 @@ public class EmailArguments {
GroupBackend groupBackend, GroupBackend groupBackend,
AccountCache accountCache, AccountCache accountCache,
PatchListCache patchListCache, PatchListCache patchListCache,
PatchSetUtil patchSetUtil,
ApprovalsUtil approvalsUtil, ApprovalsUtil approvalsUtil,
FromAddressGenerator fromAddressGenerator, FromAddressGenerator fromAddressGenerator,
EmailSender emailSender, EmailSender emailSender,
@@ -116,6 +119,7 @@ public class EmailArguments {
this.groupBackend = groupBackend; this.groupBackend = groupBackend;
this.accountCache = accountCache; this.accountCache = accountCache;
this.patchListCache = patchListCache; this.patchListCache = patchListCache;
this.patchSetUtil = patchSetUtil;
this.approvalsUtil = approvalsUtil; this.approvalsUtil = approvalsUtil;
this.fromAddressGenerator = fromAddressGenerator; this.fromAddressGenerator = fromAddressGenerator;
this.emailSender = emailSender; this.emailSender = emailSender;

View File

@@ -151,14 +151,24 @@ public class ChangeEdits implements ChildCollection<ChangeResource, ChangeEditRe
private final FileInfoJson fileInfoJson; private final FileInfoJson fileInfoJson;
private final Revisions revisions; private final Revisions revisions;
private String base;
private boolean list;
private boolean downloadCommands;
@Option(name = "--base", metaVar = "revision-id") @Option(name = "--base", metaVar = "revision-id")
String base; public void setBase(String base) {
this.base = base;
}
@Option(name = "--list") @Option(name = "--list")
boolean list; public void setList(boolean list) {
this.list = list;
}
@Option(name = "--download-commands") @Option(name = "--download-commands")
boolean downloadCommands; public void setDownloadCommands(boolean downloadCommands) {
this.downloadCommands = downloadCommands;
}
@Inject @Inject
Detail( Detail(

View File

@@ -31,7 +31,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
@Singleton @Singleton
class ListReviewers implements RestReadView<ChangeResource> { public class ListReviewers implements RestReadView<ChangeResource> {
private final ApprovalsUtil approvalsUtil; private final ApprovalsUtil approvalsUtil;
private final ReviewerJson json; private final ReviewerJson json;
private final ReviewerResource.Factory resourceFactory; private final ReviewerResource.Factory resourceFactory;

View File

@@ -108,11 +108,9 @@ import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.ServerInitiated; 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.AccountProperties;
import com.google.gerrit.server.account.AccountState; import com.google.gerrit.server.account.AccountState;
import com.google.gerrit.server.account.AccountsUpdate; 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.Emails;
import com.google.gerrit.server.account.ProjectWatches; import com.google.gerrit.server.account.ProjectWatches;
import com.google.gerrit.server.account.ProjectWatches.NotifyType; import com.google.gerrit.server.account.ProjectWatches.NotifyType;
@@ -224,8 +222,6 @@ public class AccountIT extends AbstractDaemonTest {
@Inject @Inject
private DynamicSet<AccountActivationValidationListener> accountActivationValidationListeners; private DynamicSet<AccountActivationValidationListener> accountActivationValidationListeners;
@Inject private AccountManager accountManager;
@Inject protected GroupOperations groupOperations; @Inject protected GroupOperations groupOperations;
private AccountIndexedCounter accountIndexedCounter; 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 { private void createDraft(PushOneCommit.Result r, String path, String message) throws Exception {
DraftInput in = new DraftInput(); DraftInput in = new DraftInput();
in.path = path; in.path = path;

View File

@@ -193,25 +193,28 @@ public class AccountManagerIT extends AbstractDaemonTest {
} }
@Test @Test
public void authenticateWhenUsernameExtIdAlreadyExists() throws Exception { public void authenticateWithUsernameAndUpdateDisplayName() throws Exception {
String username = "foo"; String username = "foo";
ExternalId.Key gerritExtIdKey = ExternalId.Key.create(ExternalId.SCHEME_GERRIT, username); String email = "foo@example.com";
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.
Account.Id accountId = new Account.Id(seq.nextAccountId()); Account.Id accountId = new Account.Id(seq.nextAccountId());
ExternalId.Key gerritExtIdKey = ExternalId.Key.create(ExternalId.SCHEME_GERRIT, username);
accountsUpdate.insert( accountsUpdate.insert(
"Create Test Account", "Create Test Account",
accountId, 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); AuthRequest who = AuthRequest.forUser(username);
String newName = "Updated Name";
who.setDisplayName(newName);
AuthResult authResult = accountManager.authenticate(who); AuthResult authResult = accountManager.authenticate(who);
// Expect that the missing SCHEME_GERRIT external ID was created.
assertAuthResultForExistingAccount(authResult, accountId, gerritExtIdKey); assertAuthResultForExistingAccount(authResult, accountId, gerritExtIdKey);
assertExternalIdsWithoutEmail(gerritExtIdKey, usernameExtIdKey);
Optional<AccountState> accountState = accounts.get(accountId);
assertThat(accountState).isPresent();
assertThat(accountState.get().getAccount().getFullName()).isEqualTo(newName);
} }
@Test @Test

View File

@@ -1744,6 +1744,29 @@ public class ChangeIT extends AbstractDaemonTest {
assertThat(rsrc.getETag()).isNotEqualTo(oldETag); 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 @Test
public void notificationsForAddedWorkInProgressReviewers() throws Exception { public void notificationsForAddedWorkInProgressReviewers() throws Exception {
AddReviewerInput in = new AddReviewerInput(); AddReviewerInput in = new AddReviewerInput();

View File

@@ -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.client.ListChangesOption.MESSAGES;
import static com.google.gerrit.extensions.common.testing.EditInfoSubject.assertThat; 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.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 com.google.gerrit.server.group.SystemGroupBackend.REGISTERED_USERS;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS; 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.NotifyHandling;
import com.google.gerrit.extensions.api.changes.PublishChangeEditInput; import com.google.gerrit.extensions.api.changes.PublishChangeEditInput;
import com.google.gerrit.extensions.api.changes.ReviewInput; 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.client.ListChangesOption;
import com.google.gerrit.extensions.common.ApprovalInfo; import com.google.gerrit.extensions.common.ApprovalInfo;
import com.google.gerrit.extensions.common.ChangeInfo; 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.AuthException;
import com.google.gerrit.extensions.restapi.BinaryResult; import com.google.gerrit.extensions.restapi.BinaryResult;
import com.google.gerrit.extensions.restapi.ResourceConflictException; 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.PatchSet;
import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.ChangeMessagesUtil; import com.google.gerrit.server.ChangeMessagesUtil;
@@ -400,7 +401,9 @@ public class ChangeEditIT extends AbstractDaemonTest {
public void retrieveEdit() throws Exception { public void retrieveEdit() throws Exception {
adminRestSession.get(urlEdit(changeId)).assertNoContent(); adminRestSession.get(urlEdit(changeId)).assertNoContent();
createArbitraryEditFor(changeId); createArbitraryEditFor(changeId);
EditInfo editInfo = getEditInfo(changeId, false); Optional<EditInfo> maybeEditInfo = gApi.changes().id(changeId).edit().get();
assertThat(maybeEditInfo).isPresent();
EditInfo editInfo = maybeEditInfo.get();
ChangeInfo changeInfo = get(changeId, CURRENT_REVISION, CURRENT_COMMIT); ChangeInfo changeInfo = get(changeId, CURRENT_REVISION, CURRENT_COMMIT);
assertThat(editInfo.commit.commit).isNotEqualTo(changeInfo.currentRevision); assertThat(editInfo.commit.commit).isNotEqualTo(changeInfo.currentRevision);
assertThat(editInfo).commit().parents().hasSize(1); assertThat(editInfo).commit().parents().hasSize(1);
@@ -414,11 +417,7 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test @Test
public void retrieveFilesInEdit() throws Exception { public void retrieveFilesInEdit() throws Exception {
createEmptyEditFor(changeId); createEmptyEditFor(changeId);
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME, RawInputUtil.create(CONTENT_NEW)); assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2));
EditInfo info = getEditInfo(changeId, true);
assertThat(info.files).isNotNull();
assertThat(info.files.keySet()).containsExactly(Patch.COMMIT_MSG, FILE_NAME, FILE_NAME2);
} }
@Test @Test
@@ -559,8 +558,10 @@ public class ChangeEditIT extends AbstractDaemonTest {
@Test @Test
public void addNewFile() throws Exception { public void addNewFile() throws Exception {
createEmptyEditFor(changeId); createEmptyEditFor(changeId);
assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2));
gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW)); gApi.changes().id(changeId).edit().modifyFile(FILE_NAME3, RawInputUtil.create(CONTENT_NEW));
ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW); ensureSameBytes(getFileContentOfEdit(changeId, FILE_NAME3), CONTENT_NEW);
assertFiles(changeId, ImmutableList.of(COMMIT_MSG, FILE_NAME, FILE_NAME2, FILE_NAME3));
} }
@Test @Test
@@ -767,6 +768,19 @@ public class ChangeEditIT extends AbstractDaemonTest {
assertThat(fileContent).value().bytes().isEqualTo(expectedFileBytes); assertThat(fileContent).value().bytes().isEqualTo(expectedFileBytes);
} }
private void assertFiles(String changeId, List<String> expected) throws Exception {
Optional<EditInfo> 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) { private String urlEdit(String changeId) {
return "/changes/" + changeId + "/edit"; return "/changes/" + changeId + "/edit";
} }
@@ -783,10 +797,6 @@ public class ChangeEditIT extends AbstractDaemonTest {
return urlEdit(changeId) + "/" + fileName + (base ? "?base" : ""); return urlEdit(changeId) + "/" + fileName + (base ? "?base" : "");
} }
private String urlGetFiles(String changeId) {
return urlEdit(changeId) + "?list";
}
private String urlRevisionFiles(String changeId, String revisionId) { private String urlRevisionFiles(String changeId, String revisionId) {
return "/changes/" + changeId + "/revisions/" + revisionId + "/files"; return "/changes/" + changeId + "/revisions/" + revisionId + "/files";
} }
@@ -821,11 +831,6 @@ public class ChangeEditIT extends AbstractDaemonTest {
+ "/diff?context=ALL&intraline"; + "/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> T readContentFromJson(RestResponse r, Class<T> clazz) throws Exception { private <T> T readContentFromJson(RestResponse r, Class<T> clazz) throws Exception {
r.assertOK(); r.assertOK();
try (JsonReader jsonReader = new JsonReader(r.getReader())) { try (JsonReader jsonReader = new JsonReader(r.getReader())) {

View File

@@ -526,18 +526,26 @@ public class CommentsIT extends AbstractDaemonTest {
@Test @Test
public void publishCommentsAllRevisions() throws Exception { 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 = PushOneCommit.Result r2 =
pushFactory pushFactory
.create( .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"); .to("refs/for/master");
addDraft( addDraft(
r1.getChangeId(), r1.getChangeId(),
r1.getCommit().getName(), 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( addDraft(
r1.getChangeId(), r1.getChangeId(),
r1.getCommit().getName(), r1.getCommit().getName(),
@@ -545,7 +553,7 @@ public class CommentsIT extends AbstractDaemonTest {
addDraft( addDraft(
r2.getChangeId(), r2.getChangeId(),
r2.getCommit().getName(), r2.getCommit().getName(),
newDraft(FILE_NAME, Side.REVISION, 1, "join lines")); newDraft(FILE_NAME, Side.REVISION, createLineRange(1, 4, 15), "better now"));
addDraft( addDraft(
r2.getChangeId(), r2.getChangeId(),
r2.getCommit().getName(), r2.getCommit().getName(),
@@ -586,7 +594,7 @@ public class CommentsIT extends AbstractDaemonTest {
assertThat(ps1List).hasSize(2); assertThat(ps1List).hasSize(2);
assertThat(ps1List.get(0).message).isEqualTo("what happened to this?"); assertThat(ps1List.get(0).message).isEqualTo("what happened to this?");
assertThat(ps1List.get(0).side).isEqualTo(Side.PARENT); 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(ps1List.get(1).side).isNull();
assertThat(gApi.changes().id(r2.getChangeId()).revision(r2.getCommit().name()).drafts()) 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).hasSize(4);
assertThat(ps2List.get(0).message).isEqualTo("comment 1 on base"); assertThat(ps2List.get(0).message).isEqualTo("comment 1 on base");
assertThat(ps2List.get(1).message).isEqualTo("comment 2 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"); assertThat(ps2List.get(3).message).isEqualTo("typo: content");
List<Message> messages = email.getMessages(r2.getChangeId(), "comment"); List<Message> messages = email.getMessages(r2.getChangeId(), "comment");
@@ -631,8 +639,8 @@ public class CommentsIT extends AbstractDaemonTest {
+ "#/c/" + "#/c/"
+ c + c
+ "/1/a.txt@1 \n" + "/1/a.txt@1 \n"
+ "PS1, Line 1: ew\n" + "PS1, Line 1: boring\n"
+ "nit: trailing whitespace\n" + "Is it that bad?\n"
+ "\n" + "\n"
+ "\n" + "\n"
+ url + url
@@ -661,8 +669,8 @@ public class CommentsIT extends AbstractDaemonTest {
+ "#/c/" + "#/c/"
+ c + c
+ "/2/a.txt@1 \n" + "/2/a.txt@1 \n"
+ "PS2, Line 1: ew\n" + "PS2, Line 1: interesting\n"
+ "join lines\n" + "better now\n"
+ "\n" + "\n"
+ "\n" + "\n"
+ url + url
@@ -1093,30 +1101,49 @@ public class CommentsIT extends AbstractDaemonTest {
return populate(d, path, side, null, line, message, false); 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) { private DraftInput newDraftOnParent(String path, int parent, int line, String message) {
DraftInput d = new DraftInput(); DraftInput d = new DraftInput();
return populate(d, path, Side.PARENT, Integer.valueOf(parent), line, message, false); return populate(d, path, Side.PARENT, Integer.valueOf(parent), line, message, false);
} }
private static <C extends Comment> C populate( private static <C extends Comment> 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.path = path;
c.side = side; c.side = side;
c.parent = parent; c.parent = parent;
c.line = line != 0 ? line : null; c.line = line != 0 ? line : null;
c.message = message; c.message = message;
c.unresolved = unresolved; c.unresolved = unresolved;
if (line != 0) { if (line != 0) c.range = range;
Comment.Range range = new Comment.Range();
range.startLine = line;
range.startCharacter = 1;
range.endLine = line;
range.endCharacter = 5;
c.range = range;
}
return c; return c;
} }
private static <C extends Comment> 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<CommentInfo, CommentInput> infoToInput(String path) { private static Function<CommentInfo, CommentInput> infoToInput(String path) {
return infoToInput(path, CommentInput::new); return infoToInput(path, CommentInput::new);
} }

View File

@@ -1,7 +1,6 @@
load("//tools/bzl:genrule2.bzl", "genrule2")
# Roboto Mono. Version 2.136 # Roboto Mono. Version 2.136
# https://github.com/google/roboto/releases/tag/v2.136 # https://github.com/google/roboto/releases/tag/v2.136
filegroup( filegroup(
name = "robotofonts", name = "robotofonts",
srcs = [ srcs = [

View File

@@ -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" _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_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. # set this to use a local version.
# "/home/<user>/projects/jgit" # "/home/<user>/projects/jgit"
@@ -67,11 +67,11 @@ def jgit_maven_repos():
def jgit_dep(name): def jgit_dep(name):
mapping = { 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-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: if LOCAL_JGIT_REPO:

View File

@@ -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") load("//tools/bzl:js.bzl", "bower_component", "js_component")
package(default_visibility = ["//visibility:public"])
# For importing new versions of existing bower packages, # For importing new versions of existing bower packages,
# #
# 1) edit the versions of 'seed' components in WORKSPACE as desired # 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 # 4) remove bower_component(name="my_new_dependency", .. ) here
# #
load("//lib/js:bower_components.bzl", "define_bower_components")
define_bower_components() define_bower_components()
js_component( js_component(

View File

@@ -1,7 +1,7 @@
package(default_visibility = ["//visibility:public"])
load("//tools/bzl:maven.bzl", "merge_maven_jars") load("//tools/bzl:maven.bzl", "merge_maven_jars")
package(default_visibility = ["//visibility:public"])
# core and backward-codecs both provide # core and backward-codecs both provide
# META-INF/services/org.apache.lucene.codecs.Codec, so they must be merged. # META-INF/services/org.apache.lucene.codecs.Codec, so they must be merged.
merge_maven_jars( merge_maven_jars(

View File

@@ -12,10 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library") load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
package(default_visibility = ["//visibility:public"])
closure_js_library( closure_js_library(
name = "polymer_closure", name = "polymer_closure",
srcs = ["@polymer_closure//file"], srcs = ["@polymer_closure//file"],

View File

@@ -1,4 +1,5 @@
load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:genrule2.bzl", "genrule2")
load("//tools/bzl:javadoc.bzl", "java_doc")
load( load(
"//tools/bzl:plugins.bzl", "//tools/bzl:plugins.bzl",
"CORE_PLUGINS", "CORE_PLUGINS",
@@ -123,8 +124,6 @@ java_binary(
], ],
) )
load("//tools/bzl:javadoc.bzl", "java_doc")
java_doc( java_doc(
name = "plugin-api-javadoc", name = "plugin-api-javadoc",
libs = PLUGIN_API + [ libs = PLUGIN_API + [

View File

@@ -1,8 +1,8 @@
package(default_visibility = ["//visibility:public"])
load("@io_bazel_rules_go//go:def.bzl", "go_binary") 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:genrule2.bzl", "genrule2")
load("//tools/bzl:js.bzl", "bower_component_bundle")
package(default_visibility = ["//visibility:public"])
bower_component_bundle( bower_component_bundle(
name = "polygerrit_components.bower_components", name = "polygerrit_components.bower_components",

View File

@@ -1,8 +1,8 @@
package(default_visibility = ["//visibility:public"])
load(":rules.bzl", "polygerrit_bundle")
load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:genrule2.bzl", "genrule2")
load("//tools/bzl:js.bzl", "bower_component_bundle") load("//tools/bzl:js.bzl", "bower_component_bundle")
load(":rules.bzl", "polygerrit_bundle")
package(default_visibility = ["//visibility:public"])
polygerrit_bundle( polygerrit_bundle(
name = "polygerrit_ui", name = "polygerrit_ui",

View File

@@ -129,8 +129,7 @@
}, },
_refreshGroupsList() { _refreshGroupsList() {
this.$.restAPI.invalidateGroupsCache(this._filter, this.$.restAPI.invalidateGroupsCache();
this._groupsPerPage, this._offset);
return this._getGroups(this._filter, this._groupsPerPage, return this._getGroups(this._filter, this._groupsPerPage,
this._offset); this._offset);
}, },

View File

@@ -130,8 +130,7 @@
}, },
_refreshReposList() { _refreshReposList() {
this.$.restAPI.invalidateReposCache(this._filter, this.$.restAPI.invalidateReposCache();
this._reposPerPage, this._offset);
return this._getRepos(this._filter, this._reposPerPage, return this._getRepos(this._filter, this._reposPerPage,
this._offset); this._offset);
}, },

View File

@@ -190,7 +190,8 @@
}, },
_getChangesWithSameTopic() { _getChangesWithSameTopic() {
return this.$.restAPI.getChangesWithSameTopic(this.change.topic); return this.$.restAPI.getChangesWithSameTopic(this.change.topic,
this.change._number);
}, },
/** /**

View File

@@ -20,29 +20,29 @@ limitations under the License.
<iron-iconset-svg name="gr-icons" size="24"> <iron-iconset-svg name="gr-icons" size="24">
<svg> <svg>
<defs> <defs>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"/></g> <g id="expand-less"><path d="M12 8l-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/></g> <g id="expand-more"><path d="M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></g> <g id="search"><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></g> <g id="settings"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></g> <g id="create"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></g> <g id="star"><path d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="star-border"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></g> <g id="star-border"><path d="M22 9.24l-7.19-.62L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21 12 17.27 18.18 21l-1.63-7.03L22 9.24zM12 15.4l-3.76 2.27 1-4.28-3.32-2.88 4.38-.38L12 6.1l1.71 4.04 4.38.38-3.32 2.88 1 4.28L12 15.4z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></g> <g id="close"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></g> <g id="chevron-left"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></g> <g id="chevron-right"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g> <g id="more-vert"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/iron-icons.js -->
<g id="deleteEdit"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></g> <g id="deleteEdit"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></g>
<!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/editor-icons.html --> <!-- This SVG is a copy from iron-icons https://github.com/PolymerElements/iron-icons/blob/master/editor-icons.html -->
<g id="publishEdit"><path d="M5 4v2h14V4H5zm0 10h4v6h6v-6h4l-7-7-7 7z"/></g> <g id="publishEdit"><path d="M5 4v2h14V4H5zm0 10h4v6h6v-6h4l-7-7-7 7z"/></g>

View File

@@ -38,6 +38,10 @@
return getRestApi().getVersion(); return getRestApi().getVersion();
}; };
GrPluginRestApi.prototype.invalidateReposCache = function() {
getRestApi().invalidateReposCache();
};
/** /**
* Fetch and return native browser REST API Response. * Fetch and return native browser REST API Response.
* @param {string} method HTTP Method (GET, POST, etc) * @param {string} method HTTP Method (GET, POST, etc)

View File

@@ -1605,7 +1605,7 @@
this._invalidateSharedFetchPromisesPrefix('/groups/?'); this._invalidateSharedFetchPromisesPrefix('/groups/?');
}, },
invalidateReposCache(filter, reposPerPage, opt_offset) { invalidateReposCache() {
this._invalidateSharedFetchPromisesPrefix('/projects/?'); this._invalidateSharedFetchPromisesPrefix('/projects/?');
}, },
@@ -1886,16 +1886,21 @@
}); });
}, },
getChangesWithSameTopic(topic) { getChangesWithSameTopic(topic, changeNum) {
const options = this.listChangesOptionsToHex( const options = this.listChangesOptionsToHex(
this.ListChangesOption.LABELS, this.ListChangesOption.LABELS,
this.ListChangesOption.CURRENT_REVISION, this.ListChangesOption.CURRENT_REVISION,
this.ListChangesOption.CURRENT_COMMIT, this.ListChangesOption.CURRENT_COMMIT,
this.ListChangesOption.DETAILED_LABELS this.ListChangesOption.DETAILED_LABELS
); );
const query = [
'status:open',
'-change:' + changeNum,
'topic:' + topic,
].join(' ');
const params = { const params = {
O: options, O: options,
q: 'status:open topic:' + topic, q: query,
}; };
return this._fetchJSON({ return this._fetchJSON({
url: '/changes/', url: '/changes/',

View File

@@ -956,7 +956,7 @@ limitations under the License.
element._cache.set(url, {}); element._cache.set(url, {});
element.invalidateReposCache('test', 25); element.invalidateReposCache();
assert.isUndefined(element._sharedFetchPromises[url]); assert.isUndefined(element._sharedFetchPromises[url]);
@@ -1043,7 +1043,7 @@ limitations under the License.
element._cache.set(url, {}); element._cache.set(url, {});
element.invalidateGroupsCache('test', 25); element.invalidateGroupsCache();
assert.isUndefined(element._sharedFetchPromises[url]); assert.isUndefined(element._sharedFetchPromises[url]);

View File

@@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
package( package(
default_visibility = ["//visibility:public"], default_visibility = ["//visibility:public"],
) )
load("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_library")
closure_js_library( closure_js_library(
name = "plugin", name = "plugin",
srcs = ["plugin.js"], srcs = ["plugin.js"],

View File

@@ -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("@io_bazel_rules_closure//closure:defs.bzl", "closure_js_binary", "closure_js_library")
load("//tools/bzl:genrule2.bzl", "genrule2")
load( load(
"//tools/bzl:js.bzl", "//tools/bzl:js.bzl",
"bower_component",
"bundle_assets", "bundle_assets",
"js_component",
) )
def polygerrit_bundle(name, srcs, outs, app): def polygerrit_bundle(name, srcs, outs, app):

View File

@@ -41,17 +41,17 @@ def _replace_macros_impl(ctx):
_replace_macros = rule( _replace_macros = rule(
attrs = { attrs = {
"_exe": attr.label(
default = Label("//Documentation:replace_macros.py"),
allow_single_file = True,
),
"src": attr.label( "src": attr.label(
mandatory = True, mandatory = True,
allow_single_file = [".txt"], allow_single_file = [".txt"],
), ),
"suffix": attr.string(mandatory = True),
"searchbox": attr.bool(default = True),
"out": attr.output(mandatory = 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, implementation = _replace_macros_impl,
) )
@@ -108,23 +108,23 @@ def _asciidoc_impl(ctx):
) )
_asciidoc_attrs = { _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( "_exe": attr.label(
default = Label("//java/com/google/gerrit/asciidoctor:asciidoc"), default = Label("//java/com/google/gerrit/asciidoctor:asciidoc"),
cfg = "host", cfg = "host",
allow_files = True, allow_files = True,
executable = 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( _asciidoc = rule(
@@ -279,11 +279,11 @@ _asciidoc_zip = rule(
mandatory = True, mandatory = True,
allow_single_file = [".zip"], allow_single_file = [".zip"],
), ),
"directory": attr.string(mandatory = True),
"resources": attr.label_list( "resources": attr.label_list(
mandatory = True, mandatory = True,
allow_files = True, allow_files = True,
), ),
"directory": attr.string(mandatory = True),
}, },
outputs = { outputs = {
"out": "%{name}.zip", "out": "%{name}.zip",

View File

@@ -8,8 +8,8 @@ def _classpath_collector(ctx):
elif hasattr(d, "files"): elif hasattr(d, "files"):
all += d.files all += d.files
as_strs = [c.path for c in all] as_strs = [c.path for c in all.to_list()]
ctx.file_action( ctx.actions.write(
output = ctx.outputs.runtime, output = ctx.outputs.runtime,
content = "\n".join(sorted(as_strs)), content = "\n".join(sorted(as_strs)),
) )

View File

@@ -23,7 +23,7 @@ def _impl(ctx):
source_jars += l.java.source_jars source_jars += l.java.source_jars
transitive_jar_set += l.java.transitive_deps 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" dir = ctx.outputs.zip.path + ".dir"
source = ctx.outputs.zip.path + ".source" source = ctx.outputs.zip.path + ".source"
external_docs = ["http://docs.oracle.com/javase/8/docs/api"] + ctx.attr.external_docs external_docs = ["http://docs.oracle.com/javase/8/docs/api"] + ctx.attr.external_docs
@@ -32,7 +32,7 @@ def _impl(ctx):
"export TZ", "export TZ",
"rm -rf %s" % source, "rm -rf %s" % source,
"mkdir %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, "rm -rf %s" % dir,
"mkdir %s" % dir, "mkdir %s" % dir,
" ".join([ " ".join([
@@ -56,17 +56,17 @@ def _impl(ctx):
"(cd %s && zip -Xqr ../%s *)" % (dir, ctx.outputs.zip.basename), "(cd %s && zip -Xqr ../%s *)" % (dir, ctx.outputs.zip.basename),
] ]
ctx.actions.run_shell( 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], outputs = [zip_output],
command = " && ".join(cmd), command = " && ".join(cmd),
) )
java_doc = rule( java_doc = rule(
attrs = { attrs = {
"external_docs": attr.string_list(),
"libs": attr.label_list(allow_files = False), "libs": attr.label_list(allow_files = False),
"pkgs": attr.string_list(), "pkgs": attr.string_list(),
"title": attr.string(), "title": attr.string(),
"external_docs": attr.string_list(),
"_jdk": attr.label( "_jdk": attr.label(
default = Label("@bazel_tools//tools/jdk:current_java_runtime"), default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
allow_files = True, allow_files = True,

View File

@@ -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" NPMJS = "NPMJS"
GERRIT = "GERRIT:" 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): def _npm_tarball(name):
return "%s@%s.npm_binary.tgz" % (name, NPM_VERSIONS[name]) return "%s@%s.npm_binary.tgz" % (name, NPM_VERSIONS[name])
@@ -37,9 +37,9 @@ def _npm_binary_impl(ctx):
npm_binary = repository_rule( npm_binary = repository_rule(
attrs = { attrs = {
"repository": attr.string(default = NPMJS),
# Label resolves within repo of the .bzl file. # Label resolves within repo of the .bzl file.
"_download_script": attr.label(default = Label("//tools:download_file.py")), "_download_script": attr.label(default = Label("//tools:download_file.py")),
"repository": attr.string(default = NPMJS),
}, },
local = True, local = True,
implementation = _npm_binary_impl, implementation = _npm_binary_impl,
@@ -120,13 +120,13 @@ def _bash(ctx, cmd):
bower_archive = repository_rule( bower_archive = repository_rule(
_bower_archive, _bower_archive,
attrs = { 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), "package": attr.string(mandatory = True),
"semver": attr.string(), "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 = rule(
_bower_component_impl, _bower_component_impl,
attrs = dict(_common_attrs.items() + { attrs = dict(_common_attrs.items() + {
"zipfile": attr.label(allow_single_file = [".zip"]),
"license": attr.label(allow_single_file = True), "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. # If set, define by hand, and don't regenerate this entry in bower2bazel.
"seed": attr.bool(default = False), "seed": attr.bool(default = False),
"version_json": attr.label(allow_files = [".json"]),
"zipfile": attr.label(allow_single_file = [".zip"]),
}.items()), }.items()),
) )
@@ -247,7 +247,7 @@ def _bower_component_bundle_impl(ctx):
out_versions = ctx.outputs.version_json out_versions = ctx.outputs.version_json
ctx.actions.run_shell( ctx.actions.run_shell(
inputs = list(zips), inputs = zips.to_list(),
outputs = [out_zip], outputs = [out_zip],
command = " && ".join([ command = " && ".join([
"p=$PWD", "p=$PWD",
@@ -256,7 +256,7 @@ def _bower_component_bundle_impl(ctx):
"rm -rf %s.dir" % out_zip.path, "rm -rf %s.dir" % out_zip.path,
"mkdir -p %s.dir/bower_components" % out_zip.path, "mkdir -p %s.dir/bower_components" % out_zip.path,
"cd %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 ..", "cd ..",
"find . -exec touch -t 198001010000 '{}' ';'", "find . -exec touch -t 198001010000 '{}' ';'",
"zip -Xqr $p/%s bower_components/*" % out_zip.path, "zip -Xqr $p/%s bower_components/*" % out_zip.path,
@@ -265,10 +265,10 @@ def _bower_component_bundle_impl(ctx):
) )
ctx.actions.run_shell( ctx.actions.run_shell(
inputs = list(versions), inputs = versions.to_list(),
outputs = [out_versions], outputs = [out_versions],
mnemonic = "BowerVersions", 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( return struct(
@@ -281,8 +281,8 @@ bower_component_bundle = rule(
_bower_component_bundle_impl, _bower_component_bundle_impl,
attrs = _common_attrs, attrs = _common_attrs,
outputs = { outputs = {
"zip": "%{name}.zip",
"version_json": "%{name}-versions.json", "version_json": "%{name}-versions.json",
"zip": "%{name}.zip",
}, },
) )
@@ -394,11 +394,6 @@ def _bundle_output_func(name, split):
_bundle_rule = rule( _bundle_rule = rule(
_bundle_impl, _bundle_impl,
attrs = { attrs = {
"deps": attr.label_list(providers = ["transitive_zipfiles"]),
"app": attr.label(
mandatory = True,
allow_single_file = True,
),
"srcs": attr.label_list(allow_files = [ "srcs": attr.label_list(allow_files = [
".js", ".js",
".html", ".html",
@@ -406,12 +401,13 @@ _bundle_rule = rule(
".css", ".css",
".ico", ".ico",
]), ]),
"pkg": attr.string(mandatory = True), "app": attr.label(
"split": attr.bool(default = True), mandatory = True,
"_run_npm": attr.label(
default = Label("//tools/js:run_npm_binary.py"),
allow_single_file = 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( "_bundler_archive": attr.label(
default = Label("@polymer-bundler//:%s" % _npm_tarball("polymer-bundler")), default = Label("@polymer-bundler//:%s" % _npm_tarball("polymer-bundler")),
allow_single_file = True, allow_single_file = True,
@@ -420,13 +416,17 @@ _bundle_rule = rule(
default = Label("@crisper//:%s" % _npm_tarball("crisper")), default = Label("@crisper//:%s" % _npm_tarball("crisper")),
allow_single_file = True, allow_single_file = True,
), ),
"_run_npm": attr.label(
default = Label("//tools/js:run_npm_binary.py"),
allow_single_file = True,
),
}, },
outputs = _bundle_output_func, outputs = _bundle_output_func,
) )
def bundle_assets(*args, **kwargs): def bundle_assets(*args, **kwargs):
"""Combine html, js, css files and optionally split into js and html bundles.""" """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): def polygerrit_plugin(name, app, srcs = [], assets = None, plugin_name = None, **kwargs):
"""Bundles plugin dependencies for deployment. """Bundles plugin dependencies for deployment.

View File

@@ -50,7 +50,7 @@ def _impl(ctx):
classes = ",".join( classes = ",".join(
[_AsClassName(x) for x in ctx.attr.srcs], [_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, classes,
ctx.attr.outname, ctx.attr.outname,
)) ))

View File

@@ -166,15 +166,15 @@ def _maven_jar_impl(ctx):
maven_jar = repository_rule( maven_jar = repository_rule(
attrs = { attrs = {
"artifact": attr.string(mandatory = True), "artifact": attr.string(mandatory = True),
"attach_source": attr.bool(default = True),
"exclude": attr.string_list(),
"repository": attr.string(default = MAVEN_CENTRAL),
"sha1": attr.string(), "sha1": attr.string(),
"src_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), "unsign": attr.bool(default = False),
"deps": attr.string_list(),
"exports": 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, local = True,
implementation = _maven_jar_impl, implementation = _maven_jar_impl,

View File

@@ -82,7 +82,7 @@ def _war_impl(ctx):
elif hasattr(l, "files"): elif hasattr(l, "files"):
transitive_lib_deps += 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/") cmd += _add_file(dep, build_output + "/WEB-INF/lib/")
inputs.append(dep) inputs.append(dep)
@@ -91,7 +91,7 @@ def _war_impl(ctx):
for l in ctx.attr.pgmlibs: for l in ctx.attr.pgmlibs:
transitive_pgmlib_deps += l.java.transitive_runtime_deps 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: if dep not in inputs:
cmd += _add_file(dep, build_output + "/WEB-INF/pgm-lib/") cmd += _add_file(dep, build_output + "/WEB-INF/pgm-lib/")
inputs.append(dep) inputs.append(dep)
@@ -104,7 +104,7 @@ def _war_impl(ctx):
transitive_context_deps += jar.java.transitive_runtime_deps transitive_context_deps += jar.java.transitive_runtime_deps
elif hasattr(jar, "files"): elif hasattr(jar, "files"):
transitive_context_deps += 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) cmd += _add_context(dep, build_output)
inputs.append(dep) inputs.append(dep)

View File

@@ -1,5 +1,5 @@
load("//tools/bzl:pkg_war.bzl", "LIBS", "PGMLIBS")
load("//tools/bzl:classpath.bzl", "classpath_collector") load("//tools/bzl:classpath.bzl", "classpath_collector")
load("//tools/bzl:pkg_war.bzl", "LIBS", "PGMLIBS")
load( load(
"//tools/bzl:plugins.bzl", "//tools/bzl:plugins.bzl",
"CORE_PLUGINS", "CORE_PLUGINS",

View File

@@ -15,14 +15,12 @@
from os import path from os import path
REPO_ROOTS = { REPO_ROOTS = {
'ECLIPSE': 'https://repo.eclipse.org/content/groups/releases', 'ECLIPSE': 'https://repo.eclipse.org/content/groups/releases',
'GERRIT': 'http://gerrit-maven.storage.googleapis.com', 'GERRIT': 'http://gerrit-maven.storage.googleapis.com',
'GERRIT_API': 'GERRIT_API': 'https://gerrit-api.commondatastorage.googleapis.com/release',
'https://gerrit-api.commondatastorage.googleapis.com/release', 'MAVEN_CENTRAL': 'http://repo1.maven.org/maven2',
'MAVEN_CENTRAL': 'http://repo1.maven.org/maven2', 'MAVEN_LOCAL': 'file://' + path.expanduser('~/.m2/repository'),
'MAVEN_LOCAL': 'file://' + path.expanduser('~/.m2/repository'), 'MAVEN_SNAPSHOT': 'https://oss.sonatype.org/content/repositories/snapshots',
'MAVEN_SNAPSHOT':
'https://oss.sonatype.org/content/repositories/snapshots',
} }