Merge "Add "Start review" workflow using work_in_progress"
diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index da30264..a8aedc1 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -2166,14 +2166,23 @@
[[mark-private]]
=== Mark Private
--
-'PUT /changes/link:#change-id[\{change-id\}]/private'
+'POST /changes/link:#change-id[\{change-id\}]/private'
--
-Marks the change to be private. Note users can only mark own changes as private.
+Marks the change to be private. Changes may only be marked private by the
+owner or site administrators.
+
+A message can be specified in the request body inside a
+link:#private-input[PrivateInput] entity.
.Request
----
- PUT /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/private HTTP/1.0
+ POST /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/private HTTP/1.0
+ Content-Type: application/json; charset=UTF-8
+
+ {
+ "message": "After this security fix has been released we can make it public now."
+ }
----
.Response
@@ -2192,9 +2201,17 @@
Marks the change to be non-private. Note users can only unmark own private
changes.
+A message can be specified in the request body inside a
+link:#private-input[PrivateInput] entity.
+
.Request
----
DELETE /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/private HTTP/1.0
+ Content-Type: application/json; charset=UTF-8
+
+ {
+ "message": "This is a security fix that must not be public."
+ }
----
.Response
@@ -2204,6 +2221,20 @@
If the change was already not private, the response is "`409 Conflict`".
+Please note that some proxies prohibit request bodies for DELETE
+requests. In this case, if you want to set a message options, use a
+POST request:
+
+.Request
+----
+ POST /changes/myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940/private.delete HTTP/1.0
+ Content-Type: application/json; charset=UTF-8
+
+ {
+ "message": "This is a security fix that must not be public."
+ }
+----
+
[[ignore]]
=== Ignore
--
@@ -6221,6 +6252,17 @@
identify the accounts that should be should be notified.
|=======================
+[[private-input]]
+=== PrivateInput
+The `PrivateInput` entity contains information for changing the private
+flag on a change.
+
+[options="header",cols="1,^1,5"]
+|=======================
+|Field Name||Description
+|`message` |optional|Message describing why the private flag was changed.
+|=======================
+
[[problem-info]]
=== ProblemInfo
The `ProblemInfo` entity contains a description of a potential consistency problem
diff --git a/WORKSPACE b/WORKSPACE
index f136155..40e4000 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -6,9 +6,9 @@
http_archive(
name = "io_bazel_rules_closure",
- strip_prefix = "rules_closure-0.4.1",
- sha256 = "ba5e2e10cdc4027702f96e9bdc536c6595decafa94847d08ae28c6cb48225124",
- url = "http://bazel-mirror.storage.googleapis.com/github.com/bazelbuild/rules_closure/archive/0.4.1.tar.gz",
+ sha256 = "af1f5a31b8306faed9d09a38c8e2c1d6afc4c4a2dada3b5de11cceae8c7f4596",
+ strip_prefix = "rules_closure-f68d4b5a55c04ee50a3196590dce1ca8e7dbf438",
+ url = "https://bazel-mirror.storage.googleapis.com/github.com/bazelbuild/rules_closure/archive/f68d4b5a55c04ee50a3196590dce1ca8e7dbf438.tar.gz", # 2017-05-05
)
# File is specific to Polymer and copied from the Closure Github -- should be
@@ -24,18 +24,9 @@
# Prevent redundant loading of dependencies.
closure_repositories(
- omit_aopalliance=True,
- omit_args4j=True,
- omit_jsr305=True,
- omit_gson=True,
- omit_guava=True,
- omit_guice=True,
- omit_soy=True,
- omit_icu4j=True,
- omit_asm=True,
- omit_asm_analysis=True,
- omit_asm_commons=True,
- omit_asm_util=True,
+ omit_aopalliance = True,
+ omit_args4j = True,
+ omit_javax_inject = True,
)
ANTLR_VERS = "3.5.2"
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
index a4a3c04..5d0f0ba 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/api/change/ChangeIT.java
@@ -191,29 +191,55 @@
String changeId = result.getChangeId();
assertThat(gApi.changes().id(changeId).get().isPrivate).isNull();
- gApi.changes().id(changeId).setPrivate(true);
+ gApi.changes().id(changeId).setPrivate(true, null);
ChangeInfo info = gApi.changes().id(changeId).get();
assertThat(info.isPrivate).isTrue();
assertThat(Iterables.getLast(info.messages).message).isEqualTo("Set private");
assertThat(Iterables.getLast(info.messages).tag).contains(ChangeMessagesUtil.TAG_SET_PRIVATE);
- gApi.changes().id(changeId).setPrivate(false);
+ gApi.changes().id(changeId).setPrivate(false, null);
info = gApi.changes().id(changeId).get();
assertThat(info.isPrivate).isNull();
assertThat(Iterables.getLast(info.messages).message).isEqualTo("Unset private");
assertThat(Iterables.getLast(info.messages).tag).contains(ChangeMessagesUtil.TAG_UNSET_PRIVATE);
+
+ String msg = "This is a security fix that must not be public.";
+ gApi.changes().id(changeId).setPrivate(true, msg);
+ info = gApi.changes().id(changeId).get();
+ assertThat(info.isPrivate).isTrue();
+ assertThat(Iterables.getLast(info.messages).message).isEqualTo("Set private\n\n" + msg);
+ assertThat(Iterables.getLast(info.messages).tag).contains(ChangeMessagesUtil.TAG_SET_PRIVATE);
+
+ msg = "After this security fix has been released we can make it public now.";
+ gApi.changes().id(changeId).setPrivate(false, msg);
+ info = gApi.changes().id(changeId).get();
+ assertThat(info.isPrivate).isNull();
+ assertThat(Iterables.getLast(info.messages).message).isEqualTo("Unset private\n\n" + msg);
+ assertThat(Iterables.getLast(info.messages).tag).contains(ChangeMessagesUtil.TAG_UNSET_PRIVATE);
}
@Test
- public void setPrivateByOtherUser() throws Exception {
+ public void administratorCanSetUserChangePrivate() throws Exception {
TestRepository<InMemoryRepository> userRepo = cloneProject(project, user);
PushOneCommit.Result result =
pushFactory.create(db, user.getIdent(), userRepo).to("refs/for/master");
- assertThat(gApi.changes().id(result.getChangeId()).get().isPrivate).isNull();
+ String changeId = result.getChangeId();
+ assertThat(gApi.changes().id(changeId).get().isPrivate).isNull();
+
+ gApi.changes().id(changeId).setPrivate(true, null);
+ setApiUser(user);
+ ChangeInfo info = gApi.changes().id(changeId).get();
+ assertThat(info.isPrivate).isTrue();
+ }
+
+ @Test
+ public void cannotSetOtherUsersChangePrivate() throws Exception {
+ PushOneCommit.Result result = createChange();
+ setApiUser(user);
exception.expect(AuthException.class);
exception.expectMessage("not allowed to mark private");
- gApi.changes().id(result.getChangeId()).setPrivate(true);
+ gApi.changes().id(result.getChangeId()).setPrivate(true, null);
}
@Test
@@ -223,7 +249,7 @@
pushFactory.create(db, user.getIdent(), userRepo).to("refs/for/master");
setApiUser(user);
- gApi.changes().id(result.getChangeId()).setPrivate(true);
+ gApi.changes().id(result.getChangeId()).setPrivate(true, null);
// Owner can always access its private changes.
assertThat(gApi.changes().id(result.getChangeId()).get().isPrivate).isTrue();
@@ -246,7 +272,7 @@
@Test
public void privateChangeOfOtherUserCanBeAccessedWithPermission() throws Exception {
PushOneCommit.Result result = createChange();
- gApi.changes().id(result.getChangeId()).setPrivate(true);
+ gApi.changes().id(result.getChangeId()).setPrivate(true, null);
allow(Permission.VIEW_PRIVATE_CHANGES, REGISTERED_USERS, "refs/*");
setApiUser(user);
@@ -596,6 +622,50 @@
}
@Test
+ public void rebaseNotAllowedWithoutPushPermission() throws Exception {
+ // Create two changes both with the same parent
+ PushOneCommit.Result r = createChange();
+ testRepo.reset("HEAD~1");
+ PushOneCommit.Result r2 = createChange();
+
+ // Approve and submit the first change
+ RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
+ revision.review(ReviewInput.approve());
+ revision.submit();
+
+ grant(Permission.REBASE, project, "refs/heads/master", false, REGISTERED_USERS);
+ block(Permission.PUSH, REGISTERED_USERS, "refs/for/*");
+
+ // Rebase the second
+ String changeId = r2.getChangeId();
+ setApiUser(user);
+ exception.expect(AuthException.class);
+ exception.expectMessage("rebase not permitted");
+ gApi.changes().id(changeId).rebase();
+ }
+
+ @Test
+ public void rebaseNotAllowedForOwnerWithoutPushPermission() throws Exception {
+ // Create two changes both with the same parent
+ PushOneCommit.Result r = createChange();
+ testRepo.reset("HEAD~1");
+ PushOneCommit.Result r2 = createChange();
+
+ // Approve and submit the first change
+ RevisionApi revision = gApi.changes().id(r.getChangeId()).current();
+ revision.review(ReviewInput.approve());
+ revision.submit();
+
+ block(Permission.PUSH, REGISTERED_USERS, "refs/for/*");
+
+ // Rebase the second
+ String changeId = r2.getChangeId();
+ exception.expect(AuthException.class);
+ exception.expectMessage("rebase not permitted");
+ gApi.changes().id(changeId).rebase();
+ }
+
+ @Test
public void publish() throws Exception {
PushOneCommit.Result r = createChange("refs/drafts/master");
assertThat(info(r.getChangeId()).status).isEqualTo(ChangeStatus.DRAFT);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/RefAdvertisementIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
index 0abdde6..3b868dd 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/git/RefAdvertisementIT.java
@@ -518,7 +518,7 @@
lsRemoteCommand.call().stream().map(Ref::getName).collect(toList());
assertWithMessage("Precondition violated").that(initialRefNames).contains(change3RefName);
- gApi.changes().id(c3.getId().get()).setPrivate(true);
+ gApi.changes().id(c3.getId().get()).setPrivate(true, null);
List<String> refNames = lsRemoteCommand.call().stream().map(Ref::getName).collect(toList());
assertThat(refNames).doesNotContain(change3RefName);
@@ -538,7 +538,7 @@
lsRemoteCommand.call().stream().map(Ref::getName).collect(toList());
assertWithMessage("Precondition violated").that(initialRefNames).contains(change3RefName);
- gApi.changes().id(c3.getId().get()).setPrivate(true);
+ gApi.changes().id(c3.getId().get()).setPrivate(true, null);
List<String> refNames = lsRemoteCommand.call().stream().map(Ref::getName).collect(toList());
assertThat(refNames).contains(change3RefName);
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
index 04151e9..0ac263f 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/change/SubmitByMergeIfNecessaryIT.java
@@ -30,9 +30,8 @@
import com.google.gerrit.reviewdb.client.Branch;
import com.google.gerrit.reviewdb.client.Project;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.InputStream;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -547,10 +546,10 @@
try (BinaryResult request = submitPreview(change1.getChangeId(), "tgz")) {
assertThat(request.getContentType()).isEqualTo("application/x-gzip");
tempfile = File.createTempFile("test", null);
- request.writeTo(new FileOutputStream(tempfile));
+ request.writeTo(Files.newOutputStream(tempfile.toPath()));
}
- InputStream is = new GZIPInputStream(new FileInputStream(tempfile));
+ InputStream is = new GZIPInputStream(Files.newInputStream(tempfile.toPath()));
List<String> untarredFiles = new ArrayList<>();
try (TarArchiveInputStream tarInputStream =
diff --git a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
index 8d7a452..3dabced 100644
--- a/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
+++ b/gerrit-extension-api/src/main/java/com/google/gerrit/extensions/api/changes/ChangeApi.java
@@ -14,6 +14,7 @@
package com.google.gerrit.extensions.api.changes;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.client.ListChangesOption;
import com.google.gerrit.extensions.common.AccountInfo;
import com.google.gerrit.extensions.common.ChangeInfo;
@@ -85,7 +86,7 @@
void move(MoveInput in) throws RestApiException;
- void setPrivate(boolean value) throws RestApiException;
+ void setPrivate(boolean value, @Nullable String message) throws RestApiException;
void setWorkInProgress(String message) throws RestApiException;
@@ -335,7 +336,7 @@
}
@Override
- public void setPrivate(boolean value) {
+ public void setPrivate(boolean value, @Nullable String message) {
throw new NotImplementedException();
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/DefaultActions.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/DefaultActions.java
index 74668c1..234df60 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/DefaultActions.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/api/DefaultActions.java
@@ -41,6 +41,11 @@
@Override
public void onSuccess(JavaScriptObject in) {
UiResult result = asUiResult(in);
+ if (result == null) {
+ Gerrit.display(target);
+ return;
+ }
+
if (result.alert() != null) {
Window.alert(result.alert());
}
diff --git a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
index f985f31..915867d 100644
--- a/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
+++ b/gerrit-gwtui/src/main/java/com/google/gerrit/client/changes/ChangeApi.java
@@ -122,11 +122,11 @@
}
public static void markPrivate(int id, AsyncCallback<JavaScriptObject> cb) {
- change(id).view("private").put(cb);
+ change(id).view("private").post(PrivateInput.create(), cb);
}
public static void unmarkPrivate(int id, AsyncCallback<JavaScriptObject> cb) {
- change(id).view("private").delete(cb);
+ change(id).view("private.delete").post(PrivateInput.create(), cb);
}
public static RestApi comments(int id) {
@@ -327,6 +327,16 @@
protected CherryPickInput() {}
}
+ private static class PrivateInput extends JavaScriptObject {
+ static PrivateInput create() {
+ return (PrivateInput) createObject();
+ }
+
+ final native void setMessage(String m) /*-{ this.message = m; }-*/;
+
+ protected PrivateInput() {}
+ }
+
private static class RebaseInput extends JavaScriptObject {
final native void setBase(String b) /*-{ this.base = b; }-*/;
diff --git a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
index 651d718..90aedbe 100644
--- a/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
+++ b/gerrit-httpd/src/main/java/com/google/gerrit/httpd/raw/RecompileGwtUiFilter.java
@@ -16,9 +16,10 @@
import com.google.gwtexpui.linker.server.UserAgentRule;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Enumeration;
import java.util.HashSet;
@@ -102,7 +103,7 @@
mkdir(rawtmp.getParentFile());
rawtmp.deleteOnExit();
- try (FileOutputStream rawout = new FileOutputStream(rawtmp);
+ try (OutputStream rawout = Files.newOutputStream(rawtmp.toPath());
InputStream in = zf.getInputStream(ze)) {
final byte[] buf = new byte[4096];
int n;
diff --git a/gerrit-launcher/src/main/java/com/google/gerrit/launcher/GerritLauncher.java b/gerrit-launcher/src/main/java/com/google/gerrit/launcher/GerritLauncher.java
index a7af056..b22ba49 100644
--- a/gerrit-launcher/src/main/java/com/google/gerrit/launcher/GerritLauncher.java
+++ b/gerrit-launcher/src/main/java/com/google/gerrit/launcher/GerritLauncher.java
@@ -20,9 +20,9 @@
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -293,7 +293,7 @@
private static void extractJar(ZipFile zf, ZipEntry ze, SortedMap<String, URL> jars)
throws IOException {
File tmp = createTempFile(safeName(ze), ".jar");
- try (FileOutputStream out = new FileOutputStream(tmp);
+ try (OutputStream out = Files.newOutputStream(tmp.toPath());
InputStream in = zf.getInputStream(ze)) {
byte[] buf = new byte[4096];
int n;
@@ -414,7 +414,7 @@
if (src != null) {
try (InputStream in = src.getLocation().openStream()) {
final File tmp = createTempFile("gerrit_", ".zip");
- try (FileOutputStream out = new FileOutputStream(tmp)) {
+ try (OutputStream out = Files.newOutputStream(tmp.toPath())) {
final byte[] buf = new byte[4096];
int n;
while ((n = in.read(buf, 0, buf.length)) > 0) {
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ProtobufImport.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ProtobufImport.java
index fb524a3..d970856 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ProtobufImport.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/ProtobufImport.java
@@ -39,10 +39,10 @@
import com.google.protobuf.UnknownFieldSet;
import java.io.BufferedInputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.nio.file.Files;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -96,7 +96,7 @@
}
Parser<UnknownFieldSet> parser = UnknownFieldSet.getDefaultInstance().getParserForType();
- try (InputStream in = new BufferedInputStream(new FileInputStream(file))) {
+ try (InputStream in = new BufferedInputStream(Files.newInputStream(file.toPath()))) {
UnknownFieldSet msg;
while ((msg = parser.parseDelimitedFrom(in)) != null) {
Map.Entry<Integer, UnknownFieldSet.Field> e =
diff --git a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/rules/PrologCompiler.java b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/rules/PrologCompiler.java
index 0ea0f1a..4ad7701 100644
--- a/gerrit-pgm/src/main/java/com/google/gerrit/pgm/rules/PrologCompiler.java
+++ b/gerrit-pgm/src/main/java/com/google/gerrit/pgm/rules/PrologCompiler.java
@@ -24,10 +24,9 @@
import com.googlecode.prolog_cafe.compiler.Compiler;
import com.googlecode.prolog_cafe.exceptions.CompileException;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLClassLoader;
@@ -134,7 +133,7 @@
// Any leak of tmp caused by this method failing will be cleaned
// up by our caller when tempDir is recursively deleted.
File tmp = File.createTempFile("rules", ".pl", tempDir);
- try (FileOutputStream out = new FileOutputStream(tmp)) {
+ try (OutputStream out = Files.newOutputStream(tmp.toPath())) {
git.open(blobId).copyTo(out);
}
return tmp;
@@ -230,7 +229,7 @@
jarAdd.setTime(now);
out.putNextEntry(jarAdd);
if (f.isFile()) {
- try (FileInputStream in = new FileInputStream(f)) {
+ try (InputStream in = Files.newInputStream(f.toPath())) {
while (true) {
int nRead = in.read(buffer, 0, buffer.length);
if (nRead <= 0) {
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/ReviewersUtil.java b/gerrit-server/src/main/java/com/google/gerrit/server/ReviewersUtil.java
index 08f879f..410dc5c 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/ReviewersUtil.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/ReviewersUtil.java
@@ -101,7 +101,7 @@
}
}
- // Generate a candidate list at 3x the size of what the user wants to see to
+ // Generate a candidate list at 2x the size of what the user wants to see to
// give the ranking algorithm a good set of candidates it can work with
private static final int CANDIDATE_LIST_MULTIPLIER = 2;
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
index 5338e89..f4ea3b0 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/api/changes/ChangeApiImpl.java
@@ -16,6 +16,7 @@
import static com.google.gerrit.server.api.ApiUtil.asRestApiException;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.extensions.api.changes.AbandonInput;
import com.google.gerrit.extensions.api.changes.AddReviewerInput;
import com.google.gerrit.extensions.api.changes.AddReviewerResult;
@@ -66,16 +67,17 @@
import com.google.gerrit.server.change.Move;
import com.google.gerrit.server.change.Mute;
import com.google.gerrit.server.change.PostHashtags;
+import com.google.gerrit.server.change.PostPrivate;
import com.google.gerrit.server.change.PostReviewers;
import com.google.gerrit.server.change.PublishDraftPatchSet;
import com.google.gerrit.server.change.PutAssignee;
-import com.google.gerrit.server.change.PutPrivate;
import com.google.gerrit.server.change.PutTopic;
import com.google.gerrit.server.change.Rebase;
import com.google.gerrit.server.change.Restore;
import com.google.gerrit.server.change.Revert;
import com.google.gerrit.server.change.Reviewers;
import com.google.gerrit.server.change.Revisions;
+import com.google.gerrit.server.change.SetPrivateOp;
import com.google.gerrit.server.change.SetReadyForReview;
import com.google.gerrit.server.change.SetWorkInProgress;
import com.google.gerrit.server.change.SubmittedTogether;
@@ -129,7 +131,7 @@
private final Check check;
private final Index index;
private final Move move;
- private final PutPrivate putPrivate;
+ private final PostPrivate postPrivate;
private final DeletePrivate deletePrivate;
private final Ignore ignore;
private final Unignore unignore;
@@ -172,7 +174,7 @@
Check check,
Index index,
Move move,
- PutPrivate putPrivate,
+ PostPrivate postPrivate,
DeletePrivate deletePrivate,
Ignore ignore,
Unignore unignore,
@@ -213,7 +215,7 @@
this.check = check;
this.index = index;
this.move = move;
- this.putPrivate = putPrivate;
+ this.postPrivate = postPrivate;
this.deletePrivate = deletePrivate;
this.ignore = ignore;
this.unignore = unignore;
@@ -302,12 +304,13 @@
}
@Override
- public void setPrivate(boolean value) throws RestApiException {
+ public void setPrivate(boolean value, @Nullable String message) throws RestApiException {
try {
+ SetPrivateOp.Input input = new SetPrivateOp.Input(message);
if (value) {
- putPrivate.apply(change, null);
+ postPrivate.apply(change, input);
} else {
- deletePrivate.apply(change, null);
+ deletePrivate.apply(change, input);
}
} catch (Exception e) {
throw asRestApiException("Cannot change private status", e);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeletePrivate.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeletePrivate.java
index a951d66..7819a29 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/DeletePrivate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/DeletePrivate.java
@@ -33,10 +33,7 @@
@Singleton
public class DeletePrivate
- extends RetryingRestModifyView<ChangeResource, DeletePrivate.Input, Response<String>>
- implements UiAction<ChangeResource> {
- public static class Input {}
-
+ extends RetryingRestModifyView<ChangeResource, SetPrivateOp.Input, Response<String>> {
private final ChangeMessagesUtil cmUtil;
private final Provider<ReviewDb> dbProvider;
@@ -49,7 +46,7 @@
@Override
protected Response<String> applyImpl(
- BatchUpdate.Factory updateFactory, ChangeResource rsrc, DeletePrivate.Input input)
+ BatchUpdate.Factory updateFactory, ChangeResource rsrc, SetPrivateOp.Input input)
throws RestApiException, UpdateException {
if (!rsrc.isUserOwner()) {
throw new AuthException("not allowed to unmark private");
@@ -60,7 +57,7 @@
}
ChangeControl control = rsrc.getControl();
- SetPrivateOp op = new SetPrivateOp(cmUtil, false);
+ SetPrivateOp op = new SetPrivateOp(cmUtil, false, input);
try (BatchUpdate u =
updateFactory.create(
dbProvider.get(),
@@ -73,11 +70,20 @@
return Response.none();
}
- @Override
- public Description getDescription(ChangeResource rsrc) {
- return new UiAction.Description()
- .setLabel("Unmark private")
- .setTitle("Unmark change as private")
- .setVisible(rsrc.getChange().isPrivate() && rsrc.isUserOwner());
+ public static class DeletePrivateByPost extends DeletePrivate
+ implements UiAction<ChangeResource> {
+ @Inject
+ DeletePrivateByPost(
+ Provider<ReviewDb> dbProvider, RetryHelper retryHelper, ChangeMessagesUtil cmUtil) {
+ super(dbProvider, retryHelper, cmUtil);
+ }
+
+ @Override
+ public Description getDescription(ChangeResource rsrc) {
+ return new UiAction.Description()
+ .setLabel("Unmark private")
+ .setTitle("Unmark change as private")
+ .setVisible(rsrc.getChange().isPrivate() && rsrc.isUserOwner());
+ }
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
index 5ddf9e9..2315f48 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/Module.java
@@ -28,6 +28,7 @@
import com.google.gerrit.extensions.registration.DynamicMap;
import com.google.gerrit.extensions.restapi.RestApiModule;
import com.google.gerrit.server.account.AccountLoader;
+import com.google.gerrit.server.change.DeletePrivate.DeletePrivateByPost;
import com.google.gerrit.server.change.Reviewed.DeleteReviewed;
import com.google.gerrit.server.change.Reviewed.PutReviewed;
@@ -85,7 +86,8 @@
post(CHANGE_KIND, "index").to(Index.class);
post(CHANGE_KIND, "rebuild.notedb").to(Rebuild.class);
post(CHANGE_KIND, "move").to(Move.class);
- put(CHANGE_KIND, "private").to(PutPrivate.class);
+ post(CHANGE_KIND, "private").to(PostPrivate.class);
+ post(CHANGE_KIND, "private.delete").to(DeletePrivateByPost.class);
delete(CHANGE_KIND, "private").to(DeletePrivate.class);
put(CHANGE_KIND, "ignore").to(Ignore.class);
put(CHANGE_KIND, "unignore").to(Unignore.class);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/PutPrivate.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostPrivate.java
similarity index 72%
rename from gerrit-server/src/main/java/com/google/gerrit/server/change/PutPrivate.java
rename to gerrit-server/src/main/java/com/google/gerrit/server/change/PostPrivate.java
index bd2bf05..a1e673f 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/PutPrivate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/PostPrivate.java
@@ -22,6 +22,8 @@
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil;
+import com.google.gerrit.server.permissions.GlobalPermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.update.BatchUpdate;
import com.google.gerrit.server.update.RetryHelper;
@@ -32,26 +34,30 @@
import com.google.inject.Singleton;
@Singleton
-public class PutPrivate
- extends RetryingRestModifyView<ChangeResource, PutPrivate.Input, Response<String>>
+public class PostPrivate
+ extends RetryingRestModifyView<ChangeResource, SetPrivateOp.Input, Response<String>>
implements UiAction<ChangeResource> {
- public static class Input {}
-
private final ChangeMessagesUtil cmUtil;
private final Provider<ReviewDb> dbProvider;
+ private final PermissionBackend permissionBackend;
@Inject
- PutPrivate(Provider<ReviewDb> dbProvider, RetryHelper retryHelper, ChangeMessagesUtil cmUtil) {
+ PostPrivate(
+ Provider<ReviewDb> dbProvider,
+ RetryHelper retryHelper,
+ ChangeMessagesUtil cmUtil,
+ PermissionBackend permissionBackend) {
super(retryHelper);
this.dbProvider = dbProvider;
this.cmUtil = cmUtil;
+ this.permissionBackend = permissionBackend;
}
@Override
- protected Response<String> applyImpl(
- BatchUpdate.Factory updateFactory, ChangeResource rsrc, Input input)
+ public Response<String> applyImpl(
+ BatchUpdate.Factory updateFactory, ChangeResource rsrc, SetPrivateOp.Input input)
throws RestApiException, UpdateException {
- if (!rsrc.isUserOwner()) {
+ if (!canSetPrivate(rsrc)) {
throw new AuthException("not allowed to mark private");
}
@@ -60,7 +66,7 @@
}
ChangeControl control = rsrc.getControl();
- SetPrivateOp op = new SetPrivateOp(cmUtil, true);
+ SetPrivateOp op = new SetPrivateOp(cmUtil, true, input);
try (BatchUpdate u =
updateFactory.create(
dbProvider.get(),
@@ -82,6 +88,11 @@
.setVisible(
!change.isPrivate()
&& change.getStatus() != Change.Status.MERGED
- && rsrc.isUserOwner());
+ && canSetPrivate(rsrc));
+ }
+
+ private boolean canSetPrivate(ChangeResource rsrc) {
+ PermissionBackend.WithUser user = permissionBackend.user(rsrc.getUser());
+ return rsrc.isUserOwner() || user.testOrFalse(GlobalPermission.ADMINISTRATE_SERVER);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/SetPrivateOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/SetPrivateOp.java
index 1cebcc2..7008eca 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/SetPrivateOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/SetPrivateOp.java
@@ -14,6 +14,7 @@
package com.google.gerrit.server.change;
+import com.google.common.base.Strings;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
@@ -23,13 +24,25 @@
import com.google.gerrit.server.update.ChangeContext;
import com.google.gwtorm.server.OrmException;
-class SetPrivateOp implements BatchUpdateOp {
+public class SetPrivateOp implements BatchUpdateOp {
+ public static class Input {
+ String message;
+
+ public Input() {}
+
+ public Input(String message) {
+ this.message = message;
+ }
+ }
+
private final ChangeMessagesUtil cmUtil;
private final boolean isPrivate;
+ private final Input input;
- SetPrivateOp(ChangeMessagesUtil cmUtil, boolean isPrivate) {
+ SetPrivateOp(ChangeMessagesUtil cmUtil, boolean isPrivate, Input input) {
this.cmUtil = cmUtil;
this.isPrivate = isPrivate;
+ this.input = input;
}
@Override
@@ -48,10 +61,18 @@
private void addMessage(ChangeContext ctx, ChangeUpdate update) throws OrmException {
Change c = ctx.getChange();
+ StringBuilder buf = new StringBuilder(c.isPrivate() ? "Set private" : "Unset private");
+
+ String m = Strings.nullToEmpty(input == null ? null : input.message).trim();
+ if (!m.isEmpty()) {
+ buf.append("\n\n");
+ buf.append(m);
+ }
+
ChangeMessage cmsg =
ChangeMessagesUtil.newMessage(
ctx,
- c.isPrivate() ? "Set private" : "Unset private",
+ buf.toString(),
c.isPrivate()
? ChangeMessagesUtil.TAG_SET_PRIVATE
: ChangeMessagesUtil.TAG_UNSET_PRIVATE);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/change/WorkInProgressOp.java b/gerrit-server/src/main/java/com/google/gerrit/server/change/WorkInProgressOp.java
index 7f6e543..21e5dfa 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/change/WorkInProgressOp.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/change/WorkInProgressOp.java
@@ -61,7 +61,7 @@
StringBuilder buf =
new StringBuilder(c.isWorkInProgress() ? "Set Work In Progress" : "Set Ready For Review");
- String m = Strings.nullToEmpty(in.message).trim();
+ String m = Strings.nullToEmpty(in == null ? null : in.message).trim();
if (!m.isEmpty()) {
buf.append("\n\n");
buf.append(m);
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
index 8fabe44..16c63c8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/ChangeControl.java
@@ -286,6 +286,7 @@
/** Can this user rebase this change? */
private boolean canRebase(ReviewDb db) throws OrmException {
return (isOwner() || getRefControl().canSubmit(isOwner()) || getRefControl().canRebase())
+ && getRefControl().canUpload()
&& !isPatchSetLocked(db);
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index ca719c8..611a1a4 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -986,7 +986,8 @@
return reviewer(who, false);
}
- private Predicate<ChangeData> reviewerDefaultField(String who) throws QueryParseException, OrmException {
+ private Predicate<ChangeData> reviewerDefaultField(String who)
+ throws QueryParseException, OrmException {
return reviewer(who, true);
}
@@ -1232,8 +1233,9 @@
return args.getIdentifiedUser().getAccountId();
}
- public Predicate<ChangeData> reviewerByState(String who, ReviewerStateInternal state,
- boolean forDefaultField) throws QueryParseException, OrmException {
+ public Predicate<ChangeData> reviewerByState(
+ String who, ReviewerStateInternal state, boolean forDefaultField)
+ throws QueryParseException, OrmException {
Predicate<ChangeData> reviewerByEmailPredicate = null;
if (args.index.getSchema().hasField(ChangeField.REVIEWER_BY_EMAIL)) {
Address address = Address.tryParse(who);
@@ -1246,10 +1248,12 @@
try {
Set<Account.Id> accounts = parseAccount(who);
if (!forDefaultField || accounts.size() <= MAX_ACCOUNTS_PER_DEFAULT_FIELD) {
- reviewerPredicate = Predicate.or(
- accounts.stream()
- .map(id -> ReviewerPredicate.forState(args, id, state))
- .collect(toList()));
+ reviewerPredicate =
+ Predicate.or(
+ accounts
+ .stream()
+ .map(id -> ReviewerPredicate.forState(args, id, state))
+ .collect(toList()));
}
} catch (QueryParseException e) {
// Propagate this exception only if we can't use 'who' to query by email
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
index 6601266..ee894c9 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/account/AbstractQueryAccountsTest.java
@@ -98,6 +98,7 @@
@Inject protected AllProjectsName allProjects;
protected LifecycleManager lifecycle;
+ protected Injector injector;
protected ReviewDb db;
protected AccountInfo currentUserInfo;
protected CurrentUser user;
@@ -107,11 +108,14 @@
@Before
public void setUpInjector() throws Exception {
lifecycle = new LifecycleManager();
- Injector injector = createInjector();
+ injector = createInjector();
lifecycle.add(injector);
injector.injectMembers(this);
lifecycle.start();
+ setUpDatabase();
+ }
+ protected void setUpDatabase() throws Exception {
db = schemaFactory.open();
schemaCreator.create(db);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
index 6df03cd..0b01362 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/change/AbstractQueryChangesTest.java
@@ -399,7 +399,7 @@
assertQuery("is:open", change2, change1);
assertQuery("is:private");
- gApi.changes().id(change1.getChangeId()).setPrivate(true);
+ gApi.changes().id(change1.getChangeId()).setPrivate(true, null);
// Change1 is not private, but should be still visible to its owner.
assertQuery("is:open", change1, change2);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java b/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
index a0e5ee0..4b8309a 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/query/group/AbstractQueryGroupsTest.java
@@ -98,6 +98,7 @@
@Inject protected GroupCache groupCache;
protected LifecycleManager lifecycle;
+ protected Injector injector;
protected ReviewDb db;
protected AccountInfo currentUserInfo;
protected CurrentUser user;
@@ -107,11 +108,14 @@
@Before
public void setUpInjector() throws Exception {
lifecycle = new LifecycleManager();
- Injector injector = createInjector();
+ injector = createInjector();
lifecycle.add(injector);
injector.injectMembers(this);
lifecycle.start();
+ setUpDatabase();
+ }
+ protected void setUpDatabase() throws Exception {
db = schemaFactory.open();
schemaCreator.create(db);
diff --git a/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/HookTestCase.java b/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/HookTestCase.java
index 21c8764..3d4a1a0 100644
--- a/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/HookTestCase.java
+++ b/gerrit-server/src/test/java/com/google/gerrit/server/tools/hooks/HookTestCase.java
@@ -54,10 +54,11 @@
import com.google.common.io.ByteStreams;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -119,7 +120,7 @@
try (InputStream in = url.openStream()) {
hook = File.createTempFile("hook_", ".sh");
cleanup.add(hook);
- try (FileOutputStream out = new FileOutputStream(hook)) {
+ try (OutputStream out = Files.newOutputStream(hook.toPath())) {
ByteStreams.copy(in, out);
}
}
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
index 5a47cb0..820052c 100644
--- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
+++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/PluginInstallCommand.java
@@ -25,12 +25,11 @@
import com.google.gerrit.sshd.SshCommand;
import com.google.inject.Inject;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.nio.file.Files;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -54,6 +53,7 @@
@Inject private PluginLoader loader;
+ @SuppressWarnings("resource")
@Override
protected void run() throws UnloggedFailure {
if (!loader.isRemoteAdminEnabled()) {
@@ -80,8 +80,8 @@
data = in;
} else if (new File(source).isFile() && source.equals(new File(source).getAbsolutePath())) {
try {
- data = new FileInputStream(new File(source));
- } catch (FileNotFoundException e) {
+ data = Files.newInputStream(new File(source).toPath());
+ } catch (IOException e) {
throw die("cannot read " + source);
}
} else {
diff --git a/gerrit-war/src/main/java/com/google/gerrit/httpd/UnzippedDistribution.java b/gerrit-war/src/main/java/com/google/gerrit/httpd/UnzippedDistribution.java
index b5a1dae..ec92fba 100644
--- a/gerrit-war/src/main/java/com/google/gerrit/httpd/UnzippedDistribution.java
+++ b/gerrit-war/src/main/java/com/google/gerrit/httpd/UnzippedDistribution.java
@@ -20,10 +20,10 @@
import com.google.gerrit.pgm.init.PluginsDistribution;
import com.google.inject.Singleton;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletContext;
@@ -45,7 +45,7 @@
for (File p : list) {
String pluginJarName = p.getName();
String pluginName = pluginJarName.substring(0, pluginJarName.length() - JAR.length());
- try (InputStream in = new FileInputStream(p)) {
+ try (InputStream in = Files.newInputStream(p.toPath())) {
processor.process(pluginName, in);
}
}
diff --git a/lib/asciidoctor/java/AsciiDoctor.java b/lib/asciidoctor/java/AsciiDoctor.java
index d765cc1..219cc24 100644
--- a/lib/asciidoctor/java/AsciiDoctor.java
+++ b/lib/asciidoctor/java/AsciiDoctor.java
@@ -15,12 +15,12 @@
import com.google.common.io.ByteStreams;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.io.InputStream;
import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -162,7 +162,7 @@
if (bazel) {
renderFiles(inputFiles, null);
} else {
- try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile))) {
+ try (ZipOutputStream zip = new ZipOutputStream(Files.newOutputStream(Paths.get(zipFile)))) {
renderFiles(inputFiles, zip);
File[] cssFiles =
@@ -199,7 +199,7 @@
public static void zipFile(File file, String name, ZipOutputStream zip) throws IOException {
zip.putNextEntry(new ZipEntry(name));
- try (FileInputStream input = new FileInputStream(file)) {
+ try (InputStream input = Files.newInputStream(file.toPath())) {
ByteStreams.copy(input, zip);
}
zip.closeEntry();
diff --git a/lib/asciidoctor/java/DocIndexer.java b/lib/asciidoctor/java/DocIndexer.java
index 395f9fe..fbb7f94 100644
--- a/lib/asciidoctor/java/DocIndexer.java
+++ b/lib/asciidoctor/java/DocIndexer.java
@@ -18,13 +18,13 @@
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.jar.JarEntry;
@@ -81,7 +81,7 @@
return;
}
- try (JarOutputStream jar = new JarOutputStream(new FileOutputStream(outFile))) {
+ try (JarOutputStream jar = new JarOutputStream(Files.newOutputStream(Paths.get(outFile)))) {
byte[] compressedIndex = zip(index());
JarEntry entry = new JarEntry(String.format("%s/%s", Constants.PACKAGE, Constants.INDEX_ZIP));
entry.setSize(compressedIndex.length);
@@ -106,7 +106,7 @@
String title;
try (BufferedReader titleReader =
- new BufferedReader(new InputStreamReader(new FileInputStream(file), UTF_8))) {
+ new BufferedReader(new InputStreamReader(Files.newInputStream(file.toPath()), UTF_8))) {
title = titleReader.readLine();
if (title != null && title.startsWith("[[")) {
// Generally the first line of the txt is the title. In a few cases the
diff --git a/lib/prolog/java/BuckPrologCompiler.java b/lib/prolog/java/BuckPrologCompiler.java
index d3f41c0..cc3e39e 100644
--- a/lib/prolog/java/BuckPrologCompiler.java
+++ b/lib/prolog/java/BuckPrologCompiler.java
@@ -15,9 +15,9 @@
import com.googlecode.prolog_cafe.compiler.Compiler;
import com.googlecode.prolog_cafe.exceptions.CompileException;
import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
@@ -46,7 +46,7 @@
private static void jar(File jar, File classes) throws IOException {
File tmp = File.createTempFile("prolog", ".jar", tmpdir);
try {
- try (JarOutputStream out = new JarOutputStream(new FileOutputStream(tmp))) {
+ try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(tmp.toPath()))) {
add(out, classes, "");
}
if (!tmp.renameTo(jar)) {
@@ -70,7 +70,7 @@
}
JarEntry e = new JarEntry(prefix + name);
- try (FileInputStream in = new FileInputStream(f)) {
+ try (InputStream in = Files.newInputStream(f.toPath())) {
e.setTime(f.lastModified());
out.putNextEntry(e);
byte[] buf = new byte[16 << 10];
diff --git a/polygerrit-ui/.eslintrc.json b/polygerrit-ui/app/.eslintrc.json
similarity index 100%
rename from polygerrit-ui/.eslintrc.json
rename to polygerrit-ui/app/.eslintrc.json
diff --git a/polygerrit-ui/app/BUILD b/polygerrit-ui/app/BUILD
index 7c12fa2..4e99272 100644
--- a/polygerrit-ui/app/BUILD
+++ b/polygerrit-ui/app/BUILD
@@ -34,10 +34,9 @@
name = "closure_lib",
srcs = ["gr-app.js"],
convention = "GOOGLE",
- language = "ECMASCRIPT6",
- suppress = [
- "JSC_BAD_JSDOC_ANNOTATION",
- ],
+ # TODO(davido): Clean up these issues: http://paste.openstack.org/show/608548
+ # and remove this supression
+ suppress = ["JSC_UNUSED_LOCAL_ASSIGNMENT"],
deps = [
"//lib/polymer_externs:polymer_closure",
"@io_bazel_rules_closure//closure/library",
@@ -52,6 +51,7 @@
defs = [
"--polymer_pass",
"--jscomp_off=duplicate",
+ "--force_inject_library=es6_runtime",
],
language = "ECMASCRIPT5",
deps = [":closure_lib"],
@@ -157,3 +157,18 @@
"manual",
],
)
+
+sh_test(
+ name = "lint_test",
+ size = "large",
+ srcs = ["lint_test.sh"],
+ data = [
+ ":pg_code",
+ ".eslintrc.json",
+ ],
+ # Should not run sandboxed.
+ tags = [
+ "local",
+ "manual",
+ ],
+)
diff --git a/polygerrit-ui/app/lint_test.sh b/polygerrit-ui/app/lint_test.sh
new file mode 100755
index 0000000..7ee74d8
--- /dev/null
+++ b/polygerrit-ui/app/lint_test.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+set -ex
+
+eslint_bin=$(which npm)
+if [[ -z "$eslint_bin" ]]; then
+ echo "NPM must be on the path."
+ exit 1
+fi
+
+eslint_bin=$(which eslint)
+eslint_config=$(npm list -g | grep -c eslint-config-google)
+eslint_plugin=$(npm list -g | grep -c eslint-plugin-html)
+if [[ -z "$eslint_bin" ]] || [[ eslint_config -eq "0" ]] || [[ eslint_plugin -eq "0" ]]; then
+ echo "You must install ESLint and its dependencies from NPM."
+ echo "> npm install -g eslint eslint-config-google eslint-plugin-html"
+ echo "For more information, view the README:"
+ echo "https://gerrit.googlesource.com/gerrit/+/master/polygerrit-ui/#Style-guide"
+ exit 1
+fi
+
+${eslint_bin} --ignore-pattern 'bower_components/' --ignore-pattern 'gr-linked-text' --ignore-pattern 'scripts/vendor' --ext .html,.js .
diff --git a/tools/bzl/maven_jar.bzl b/tools/bzl/maven_jar.bzl
index 2dbeae7..55bfae1 100644
--- a/tools/bzl/maven_jar.bzl
+++ b/tools/bzl/maven_jar.bzl
@@ -64,12 +64,13 @@
formatted_deps += " ],"
return formatted_deps
-def _generate_build_file(ctx, binjar, srcjar):
+def _generate_build_files(ctx, binjar, srcjar):
+ header = "# DO NOT EDIT: automatically generated BUILD file for maven_jar rule %s" % ctx.name
srcjar_attr = ""
if srcjar:
srcjar_attr = 'srcjar = "%s",' % srcjar
contents = """
-# DO NOT EDIT: automatically generated BUILD file for maven_jar rule {rule_name}
+{header}
package(default_visibility = ['//visibility:public'])
java_import(
name = 'jar',
@@ -86,10 +87,10 @@
{exports}
)
\n""".format(srcjar_attr = srcjar_attr,
- rule_name = ctx.name,
- binjar = binjar,
- deps = _format_deps("deps", ctx.attr.deps),
- exports = _format_deps("exports", ctx.attr.exports))
+ header = header,
+ binjar = binjar,
+ deps = _format_deps("deps", ctx.attr.deps),
+ exports = _format_deps("exports", ctx.attr.exports))
if srcjar:
contents += """
java_import(
@@ -99,6 +100,18 @@
""".format(srcjar = srcjar)
ctx.file('%s/BUILD' % ctx.path("jar"), contents, False)
+ # Compatibility layer for java_import_external from rules_closure
+ contents = """
+{header}
+package(default_visibility = ['//visibility:public'])
+
+alias(
+ name = "{rule_name}",
+ actual = "@{rule_name}//jar",
+)
+\n""".format(rule_name = ctx.name, header = header)
+ ctx.file("BUILD", contents, False)
+
def _maven_jar_impl(ctx):
"""rule to download a Maven archive."""
coordinates = _create_coordinates(ctx.attr.artifact)
@@ -142,7 +155,7 @@
if out.return_code:
fail("failed %s: %s" % (args, out.stderr))
- _generate_build_file(ctx, binjar, srcjar)
+ _generate_build_files(ctx, binjar, srcjar)
maven_jar = repository_rule(
attrs = {