Merge branch 'stable-2.14' into stable-2.15

* stable-2.14:
  Upgrade bazlets to latest stable-2.14
  Bazel: Migrate workspace status script to python

Change-Id: I82cdf1b267109a74a7d3cf7723574c08f02ddbb8
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 40e022d..f63f41a 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -123,4 +123,5 @@
 org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
 org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
 org.eclipse.jdt.core.compiler.processAnnotations=enabled
+org.eclipse.jdt.core.compiler.release=disabled
 org.eclipse.jdt.core.compiler.source=1.8
diff --git a/WORKSPACE b/WORKSPACE
index 112a5b9..4c46622 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "e48c6a61d5a3f9ab4589f324fc85b8e3777d8854",
+    commit = "d735ef54dfd38f99106d5635228156139c0b57fd",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/PostVerification.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/PostVerification.java
index cce3202..a937b09 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/PostVerification.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/PostVerification.java
@@ -18,28 +18,20 @@
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.gerrit.common.TimeUtil;
-import com.google.gerrit.common.errors.PermissionDeniedException;
-import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
-import com.google.gerrit.extensions.restapi.AuthException;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestModifyView;
-import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
 import com.google.gerrit.reviewdb.client.LabelId;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
-import com.google.inject.Provider;
 import com.google.inject.Singleton;
 import com.googlesource.gerrit.plugins.verifystatus.common.VerificationInfo;
 import com.googlesource.gerrit.plugins.verifystatus.common.VerifyInput;
 import com.googlesource.gerrit.plugins.verifystatus.server.CiDb;
 import com.googlesource.gerrit.plugins.verifystatus.server.PatchSetVerification;
-import java.io.IOException;
 import java.sql.Timestamp;
 import java.util.List;
 import java.util.Map;
@@ -48,34 +40,19 @@
 import org.slf4j.LoggerFactory;
 
 @Singleton
-@RequiresCapability(SaveReportCapability.ID)
+@RequiresCapability(value = SaveReportCapability.ID, fallBackToAdmin = false)
 public class PostVerification implements RestModifyView<RevisionResource, VerifyInput> {
   private static final Logger log = LoggerFactory.getLogger(PostVerification.class);
   private final SchemaFactory<CiDb> schemaFactory;
-  private final String pluginName;
-  private final Provider<CurrentUser> userProvider;
 
   @Inject
-  PostVerification(
-      @PluginName String pluginName,
-      Provider<CurrentUser> userProvider,
-      SchemaFactory<CiDb> schemaFactory) {
-    this.pluginName = pluginName;
-    this.userProvider = userProvider;
+  PostVerification(SchemaFactory<CiDb> schemaFactory) {
     this.schemaFactory = schemaFactory;
   }
 
   @Override
   public Response<?> apply(RevisionResource revision, VerifyInput input)
-      throws AuthException, BadRequestException, UnprocessableEntityException, OrmException,
-          IOException {
-
-    try {
-      checkPermission();
-    } catch (PermissionDeniedException err) {
-      throw new BadRequestException("fatal: " + err.getMessage());
-    }
-
+      throws BadRequestException, OrmException {
     if (input.verifications == null) {
       throw new BadRequestException("Missing verifications field");
     }
@@ -185,24 +162,4 @@
     }
     return current;
   }
-
-  /**
-   * Assert that the current user is permitted to perform saving of verification reports.
-   *
-   * <p>As the @RequireCapability guards at various entry points of internal commands implicitly add
-   * administrators (which we want to avoid), we also check permissions within QueryShell and grant
-   * access only to those who canPerformRawQuery, regardless of whether they are administrators or
-   * not.
-   *
-   * @throws PermissionDeniedException
-   */
-  private void checkPermission() throws PermissionDeniedException {
-    CapabilityControl ctl = userProvider.get().getCapabilities();
-    if (!ctl.canPerform(SaveReportCapability.getName(pluginName))) {
-      throw new PermissionDeniedException(
-          String.format(
-              "%s does not have \"%s\" capability.",
-              userProvider.get().getUserName(), new SaveReportCapability().getDescription()));
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/SaveCommand.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/SaveCommand.java
index a24126c..97d7114 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/SaveCommand.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/SaveCommand.java
@@ -19,24 +19,20 @@
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
 import com.google.common.collect.Maps;
-import com.google.gerrit.common.errors.PermissionDeniedException;
-import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.restapi.IdString;
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.PatchSet;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
 import com.google.gerrit.server.change.ChangesCollection;
 import com.google.gerrit.server.change.RevisionResource;
 import com.google.gerrit.server.change.Revisions;
+import com.google.gerrit.server.permissions.PermissionBackendException;
 import com.google.gerrit.server.project.ProjectControl;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.gerrit.sshd.commands.PatchSetParser;
 import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
-import com.google.inject.Provider;
 import com.googlesource.gerrit.plugins.verifystatus.common.VerificationInfo;
 import com.googlesource.gerrit.plugins.verifystatus.common.VerifyInput;
 import java.io.IOException;
@@ -48,20 +44,12 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@RequiresCapability(SaveReportCapability.ID)
+@RequiresCapability(value = SaveReportCapability.ID, fallBackToAdmin = false)
 @CommandMetaData(name = "save", description = "Save patchset verification data")
 public class SaveCommand extends SshCommand {
   private static final Logger log = LoggerFactory.getLogger(SaveCommand.class);
 
   private final Set<PatchSet> patchSets = new HashSet<>();
-  private final String pluginName;
-  private final Provider<CurrentUser> userProvider;
-
-  @Inject
-  SaveCommand(@PluginName String pluginName, Provider<CurrentUser> userProvider) {
-    this.pluginName = pluginName;
-    this.userProvider = userProvider;
-  }
 
   @Argument(
       index = 0,
@@ -142,11 +130,6 @@
   @Override
   protected void run() throws UnloggedFailure {
     boolean ok = true;
-    try {
-      checkPermission();
-    } catch (PermissionDeniedException err) {
-      throw new UnloggedFailure("fatal: " + err.getMessage());
-    }
 
     for (PatchSet patchSet : patchSets) {
       try {
@@ -163,7 +146,7 @@
   }
 
   private void applyVerification(PatchSet patchSet, VerifyInput verify)
-      throws RestApiException, OrmException, IOException {
+      throws RestApiException, OrmException, IOException, PermissionBackendException {
     RevisionResource revResource =
         revisions.parse(
             changes.parse(patchSet.getId().getParentKey()),
@@ -176,7 +159,7 @@
     verify.verifications = jobResult;
     try {
       applyVerification(patchSet, verify);
-    } catch (RestApiException | OrmException | IOException e) {
+    } catch (RestApiException | OrmException | IOException | PermissionBackendException e) {
       throw PatchSetParser.error(e.getMessage());
     }
   }
@@ -187,24 +170,4 @@
     } catch (IOException e) {
     }
   }
-
-  /**
-   * Assert that the current user is permitted to perform saving of verification reports.
-   *
-   * <p>As the @RequireCapability guards at various entry points of internal commands implicitly add
-   * administrators (which we want to avoid), we also check permissions within QueryShell and grant
-   * access only to those who canPerformRawQuery, regardless of whether they are administrators or
-   * not.
-   *
-   * @throws PermissionDeniedException
-   */
-  private void checkPermission() throws PermissionDeniedException {
-    CapabilityControl ctl = userProvider.get().getCapabilities();
-    if (!ctl.canPerform(pluginName + "-" + SaveReportCapability.ID)) {
-      throw new PermissionDeniedException(
-          String.format(
-              "%s does not have \"%s\" capability.",
-              userProvider.get().getUserName(), new SaveReportCapability().getDescription()));
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusAdminQueryShell.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusAdminQueryShell.java
index 03fe5b7..3265658 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusAdminQueryShell.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusAdminQueryShell.java
@@ -14,25 +14,18 @@
 
 package com.googlesource.gerrit.plugins.verifystatus;
 
-import com.google.gerrit.common.errors.PermissionDeniedException;
-import com.google.gerrit.extensions.annotations.PluginName;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.account.CapabilityControl;
 import com.google.gerrit.sshd.AdminHighPriorityCommand;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
 import com.google.inject.Inject;
-import com.google.inject.Provider;
 import org.kohsuke.args4j.Option;
 
 /** Opens a query processor. */
 @AdminHighPriorityCommand
-@RequiresCapability(AccessCiDatabaseCapability.ID)
+@RequiresCapability(value = AccessCiDatabaseCapability.ID, fallBackToAdmin = false)
 @CommandMetaData(name = "gsql", description = "Administrative interface to CI database")
 public class VerifyStatusAdminQueryShell extends SshCommand {
-  private final String pluginName;
-  private final Provider<CurrentUser> userProvider;
 
   @Inject private VerifyStatusQueryShell.Factory factory;
 
@@ -42,20 +35,8 @@
   @Option(name = "-c", metaVar = "SQL QUERY", usage = "Query to execute")
   private String query;
 
-  @Inject
-  VerifyStatusAdminQueryShell(@PluginName String pluginName, Provider<CurrentUser> userProvider) {
-    this.pluginName = pluginName;
-    this.userProvider = userProvider;
-  }
-
   @Override
-  protected void run() throws UnloggedFailure {
-    try {
-      checkPermission();
-    } catch (PermissionDeniedException err) {
-      throw new UnloggedFailure("fatal: " + err.getMessage());
-    }
-
+  protected void run() {
     final VerifyStatusQueryShell shell = factory.create(in, out);
     shell.setOutputFormat(format);
     if (query != null) {
@@ -64,24 +45,4 @@
       shell.run();
     }
   }
-
-  /**
-   * Assert that the current user is permitted to perform raw queries.
-   *
-   * <p>As the @RequireCapability guards at various entry points of internal commands implicitly add
-   * administrators (which we want to avoid), we also check permissions within QueryShell and grant
-   * access only to those who canPerformRawQuery, regardless of whether they are administrators or
-   * not.
-   *
-   * @throws PermissionDeniedException
-   */
-  private void checkPermission() throws PermissionDeniedException {
-    CapabilityControl ctl = userProvider.get().getCapabilities();
-    if (!ctl.canPerform(pluginName + "-" + AccessCiDatabaseCapability.ID)) {
-      throw new PermissionDeniedException(
-          String.format(
-              "%s does not have \"%s\" capability.",
-              userProvider.get().getUserName(), new AccessCiDatabaseCapability().getDescription()));
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusQueryShell.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusQueryShell.java
index 1fd180c..3765d33 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusQueryShell.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/VerifyStatusQueryShell.java
@@ -459,6 +459,7 @@
         case JSON_SINGLE:
           collector.add(row);
           break;
+        case PRETTY:
         default:
           final JsonObject obj = new JsonObject();
           obj.addProperty("type", "error");
@@ -491,6 +492,7 @@
         }
         println(collector.toString());
         break;
+      case PRETTY:
       default:
         final JsonObject obj = new JsonObject();
         obj.addProperty("type", "error");
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
index c7b693f..34de386 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/client/VerifyStatusPlugin.java
@@ -38,7 +38,8 @@
                   Plugin.get()
                       .panel(
                           GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
-                          new JobsSummaryPanel.Factory());
+                          new JobsSummaryPanel.Factory(),
+                          "VerifyStatusJobsSummaryPanel");
                 }
                 if (info.showJobsPanel()) {
                   Plugin.get()
@@ -46,13 +47,15 @@
                           info.showJobsBelowRelatedInfoBlock()
                               ? GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_RELATED_INFO_BLOCK
                               : GerritUiExtensionPoint.CHANGE_SCREEN_BELOW_CHANGE_INFO_BLOCK,
-                          new JobsPanel.Factory(info));
+                          new JobsPanel.Factory(info),
+                          "VerifyStatusJobsPanel");
                 }
                 if (info.showJobsDropDownPanel()) {
                   Plugin.get()
                       .panel(
                           GerritUiExtensionPoint.CHANGE_SCREEN_HEADER_RIGHT_OF_POP_DOWNS,
-                          new JobsDropDownPanel.Factory(info));
+                          new JobsDropDownPanel.Factory(info),
+                          "VerifyStatusJobsDropDownPanel");
                 }
               }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/schema/CiDataSourceProvider.java b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/schema/CiDataSourceProvider.java
index c908adc..fcd783f 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/schema/CiDataSourceProvider.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/verifystatus/server/schema/CiDataSourceProvider.java
@@ -150,23 +150,21 @@
       ds.setInitialSize(ds.getMinIdle());
       exportPoolMetrics(ds);
       return intercept(interceptor, ds);
-    } else {
-      // Don't use the connection pool.
-      //
-      try {
-        Properties p = new Properties();
-        p.setProperty("driver", driver);
-        p.setProperty("url", url);
-        if (username != null) {
-          p.setProperty("user", username);
-        }
-        if (password != null) {
-          p.setProperty("password", password);
-        }
-        return intercept(interceptor, new SimpleDataSource(p));
-      } catch (SQLException se) {
-        throw new ProvisionException("Database unavailable", se);
+    }
+    // Don't use the connection pool.
+    try {
+      Properties p = new Properties();
+      p.setProperty("driver", driver);
+      p.setProperty("url", url);
+      if (username != null) {
+        p.setProperty("user", username);
       }
+      if (password != null) {
+        p.setProperty("password", password);
+      }
+      return intercept(interceptor, new SimpleDataSource(p));
+    } catch (SQLException se) {
+      throw new ProvisionException("Database unavailable", se);
     }
   }
 
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index b484ab1..6a18e01 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -27,7 +27,7 @@
 To execute the tests run:
 
 ```
-  bazel test verify_status_tests
+  bazel test verify-status_tests
 ```
 
 ### Build in Gerrit tree
@@ -64,7 +64,7 @@
 To execute the tests run:
 
 ```
-  bazel test plugins/verify-status:verify_status_tests
+  bazel test plugins/verify-status:verify-status_tests
 ```
 
 How to build the Gerrit Plugin API is described in the [Gerrit