Merge branch 'stable-2.13'

* stable-2.13:
  Build with API version 2.13.6
  Add initialization step to set lfs.plugin value in gerrit.config

Change-Id: I6486a9abe646ed8d081cac63a385bbaad03b5085
diff --git a/.buckconfig b/.buckconfig
deleted file mode 100644
index e78b5d4..0000000
--- a/.buckconfig
+++ /dev/null
@@ -1,13 +0,0 @@
-[alias]
-  lfs = //:lfs
-  plugin = //:lfs
-
-[java]
-  src_roots = java, resources
-
-[project]
-  ignore = .git
-
-[cache]
-  mode = dir
-  dir = buck-out/cache
diff --git a/.gitignore b/.gitignore
index 1c634f0..696ab76 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,8 @@
 /.buckd
 /.watchmanconfig
 /buck-out
+/bazel-bin
+/bazel-genfiles
+/bazel-out
+/bazel-lfs
+/bazel-testlogs
diff --git a/BUCK b/BUCK
deleted file mode 100644
index b0f1d05..0000000
--- a/BUCK
+++ /dev/null
@@ -1,78 +0,0 @@
-include_defs('//bucklets/gerrit_plugin.bucklet')
-include_defs('//bucklets/maven_jar.bucklet')
-
-JGIT_VERSION = '4.5.0.201609210915-r'
-REPO = MAVEN_CENTRAL
-
-gerrit_plugin(
-  name = 'lfs',
-  srcs = glob(['src/main/java/**/*.java']),
-  resources = glob(['src/main/resources/**/*']),
-  deps = [
-    ':jgit-http-apache',
-    ':jgit-lfs',
-    ':jgit-lfs-server',
-  ],
-  provided_deps = [
-    '//lib/httpcomponents:httpcore',
-  ],
-  manifest_entries = [
-    'Gerrit-PluginName: lfs',
-    'Gerrit-Module: com.googlesource.gerrit.plugins.lfs.Module',
-    'Gerrit-HttpModule: com.googlesource.gerrit.plugins.lfs.HttpModule',
-    'Gerrit-SshModule: com.googlesource.gerrit.plugins.lfs.SshModule',
-    'Gerrit-InitStep: com.googlesource.gerrit.plugins.lfs.InitLfs',
-  ],
-)
-
-maven_jar(
-  name = 'jgit-http-apache',
-  id = 'org.eclipse.jgit:org.eclipse.jgit.http.apache:' + JGIT_VERSION,
-  sha1 = 'ce43489af3eb68740d2c5c67939fc15e1d87e082',
-  license = 'jgit',
-  repository = REPO,
-  unsign = True,
-  exclude = [
-    'about.html',
-    'plugin.properties',
-  ],
-)
-
-maven_jar(
-  name = 'jgit-lfs',
-  id = 'org.eclipse.jgit:org.eclipse.jgit.lfs:' + JGIT_VERSION,
-  bin_sha1 = 'f6252a849c8dfcf6ea6526b1891986dd7176735c',
-  src_sha1 = '62d5694f2db58ecef0b227d6943bf1ae26536e24',
-  license = 'jgit',
-  repository = REPO,
-  unsign = True,
-  exclude = [
-    'about.html',
-    'plugin.properties',
-  ],
-)
-
-maven_jar(
-  name = 'jgit-lfs-server',
-  id = 'org.eclipse.jgit:org.eclipse.jgit.lfs.server:' + JGIT_VERSION,
-  bin_sha1 = 'cdcc6bcc5e9db699301b776af22f3dab1cba348b',
-  src_sha1 = 'fe23815a06a10b11b9ec27e4d244f12c771fc6e4',
-  license = 'jgit',
-  repository = REPO,
-  unsign = True,
-  exclude = [
-    'about.html',
-    'plugin.properties',
-  ],
-)
-
-java_test(
-  name = 'lfs_tests',
-  srcs = glob(['src/test/java/**/*.java']),
-  labels = ['lfs'],
-  source_under_test = [':lfs__plugin'],
-  deps = GERRIT_PLUGIN_API + GERRIT_TESTS + [
-    ':lfs__plugin',
-    '//plugins/lfs:jgit-lfs',
-  ],
-)
diff --git a/BUILD b/BUILD
new file mode 100644
index 0000000..0bcbd51
--- /dev/null
+++ b/BUILD
@@ -0,0 +1,35 @@
+load("//tools/bzl:junit.bzl", "junit_tests")
+load(
+    "//tools/bzl:plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+)
+
+gerrit_plugin(
+    name = "lfs",
+    srcs = glob(["src/main/java/**/*.java"]),
+    resources = glob(["src/main/resources/**/*"]),
+    manifest_entries = [
+        "Gerrit-PluginName: lfs",
+        "Gerrit-Module: com.googlesource.gerrit.plugins.lfs.Module",
+        "Gerrit-HttpModule: com.googlesource.gerrit.plugins.lfs.HttpModule",
+        "Gerrit-SshModule: com.googlesource.gerrit.plugins.lfs.SshModule",
+        "Gerrit-InitStep: com.googlesource.gerrit.plugins.lfs.InitLfs",
+    ],
+    deps = [
+        "@jgit_http_apache//jar",
+        "@jgit_lfs//jar",
+        "@jgit_lfs_server//jar",
+    ],
+)
+
+junit_tests(
+    name = "lfs_tests",
+    srcs = glob(["src/test/java/**/*.java"]),
+    tags = ["lfs"],
+    deps = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
+        ":lfs__plugin",
+        "@jgit_lfs//jar",
+    ],
+)
diff --git a/WORKSPACE b/WORKSPACE
new file mode 100644
index 0000000..c707607
--- /dev/null
+++ b/WORKSPACE
@@ -0,0 +1,51 @@
+workspace(name = "lfs")
+
+load("//:bazlets.bzl", "load_bazlets")
+
+load_bazlets(
+    commit = "8a4cbdc993f41fcfe7290e7d1007cfedf8d87c18",
+    #    local_path = "/home/<user>/projects/bazlets",
+)
+
+load("@com_googlesource_gerrit_bazlets//tools:maven_jar.bzl",
+     "maven_jar",
+     "GERRIT")
+
+JGIT_VERS = "4.6.0.201612231935-r.30-gd3148f300"
+
+maven_jar(
+    name = "jgit_http_apache",
+    artifact = "org.eclipse.jgit:org.eclipse.jgit.http.apache:" + JGIT_VERS,
+    sha1 = "b9806f94d6b548c85a9ef96ef647b0f15b64927a",
+    repository = GERRIT,
+)
+
+maven_jar(
+    name = "jgit_lfs",
+    artifact = "org.eclipse.jgit:org.eclipse.jgit.lfs:" + JGIT_VERS,
+    sha1 = "55cf48dd41732ded00d66f2f833e3b7346eb5e37",
+    repository = GERRIT,
+)
+
+maven_jar(
+    name = "jgit_lfs_server",
+    artifact = "org.eclipse.jgit:org.eclipse.jgit.lfs.server:" + JGIT_VERS,
+    sha1 = "4d917afafe7888bba07607bfa7fcb06bb60fe7f1",
+    repository = GERRIT,
+)
+
+# Release Plugin API
+#load("@com_googlesource_gerrit_bazlets//:gerrit_api.bzl",
+#     "gerrit_api")
+
+# Snapshot Plugin API
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_api_maven_local.bzl",
+    "gerrit_api_maven_local",
+)
+
+# Load release Plugin API
+#gerrit_api()
+
+# Load snapshot Plugin API
+gerrit_api_maven_local()
diff --git a/bazlets.bzl b/bazlets.bzl
new file mode 100644
index 0000000..b7ce55a
--- /dev/null
+++ b/bazlets.bzl
@@ -0,0 +1,18 @@
+NAME = "com_googlesource_gerrit_bazlets"
+
+def load_bazlets(
+    commit,
+    local_path = None
+  ):
+  if not local_path:
+      native.git_repository(
+          name = NAME,
+          remote = "https://gerrit.googlesource.com/bazlets",
+          commit = commit,
+      )
+  else:
+      native.local_repository(
+          name = NAME,
+          path = local_path,
+      )
+
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
new file mode 100644
index 0000000..0a5726e
--- /dev/null
+++ b/external_plugin_deps.bzl
@@ -0,0 +1,43 @@
+load("//tools/bzl:maven_jar.bzl", "maven_jar", "GERRIT")
+
+JGIT_VERSION = '4.6.0.201612231935-r.30-gd3148f300'
+REPO = GERRIT
+
+def external_plugin_deps():
+  maven_jar(
+    name = 'jgit_http_apache',
+    artifact = 'org.eclipse.jgit:org.eclipse.jgit.http.apache:' + JGIT_VERSION,
+    sha1 = 'b9806f94d6b548c85a9ef96ef647b0f15b64927a',
+    repository = REPO,
+    unsign = True,
+    exclude = [
+      'about.html',
+      'plugin.properties',
+    ],
+  )
+
+  maven_jar(
+    name = 'jgit_lfs',
+    artifact = 'org.eclipse.jgit:org.eclipse.jgit.lfs:' + JGIT_VERSION,
+    sha1 = '55cf48dd41732ded00d66f2f833e3b7346eb5e37',
+    src_sha1 = 'fce0bceaece4c7885ffcd0d9405a524799b40db1',
+    repository = REPO,
+    unsign = True,
+    exclude = [
+      'about.html',
+      'plugin.properties',
+    ],
+  )
+
+  maven_jar(
+    name = 'jgit_lfs_server',
+    artifact = 'org.eclipse.jgit:org.eclipse.jgit.lfs.server:' + JGIT_VERSION,
+    sha1 = '4d917afafe7888bba07607bfa7fcb06bb60fe7f1',
+    src_sha1 = '1a31427d3a2940c661a16f51d1b2f96b37511fc6',
+    repository = REPO,
+    unsign = True,
+    exclude = [
+      'about.html',
+      'plugin.properties',
+    ],
+  )
diff --git a/lib/gerrit/BUCK b/lib/gerrit/BUCK
deleted file mode 100644
index eb62e9e..0000000
--- a/lib/gerrit/BUCK
+++ /dev/null
@@ -1,13 +0,0 @@
-include_defs('//bucklets/maven_jar.bucklet')
-
-VER = '2.13.6'
-REPO = MAVEN_CENTRAL
-
-maven_jar(
-  name = 'plugin-api',
-  id = 'com.google.gerrit:gerrit-plugin-api:' + VER,
-  sha1 = '1a5d650c72ebc36f4ad522d5481d5ed690bec8bf',
-  attach_source = False,
-  repository = REPO,
-  license = 'Apache2.0',
-)
diff --git a/lib/httpcomponents/BUCK b/lib/httpcomponents/BUCK
deleted file mode 100644
index 60f1699..0000000
--- a/lib/httpcomponents/BUCK
+++ /dev/null
@@ -1,10 +0,0 @@
-include_defs('//bucklets/maven_jar.bucklet')
-
-# httpcore version should match version used in Gerrit
-maven_jar(
-  name = 'httpcore',
-  id = 'org.apache.httpcomponents:httpcore:4.4.1',
-  bin_sha1 = 'f5aa318bda4c6c8d688c9d00b90681dcd82ce636',
-  src_sha1 = '9700be0d0a331691654a8e901943c9a74e33c5fc',
-  license = 'Apache2.0',
-)
\ No newline at end of file
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
index 10605bc..c8e3d69 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
@@ -14,7 +14,6 @@
 
 package com.googlesource.gerrit.plugins.lfs;
 
-import com.google.common.base.Function;
 import com.google.common.collect.Maps;
 import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.RestApiException;
@@ -32,14 +31,6 @@
 
 @Singleton
 class GetLfsGlobalConfig implements RestReadView<ProjectResource> {
-  private static final Function<LfsBackend, LfsBackendType> TO_BACKEND_CFG =
-      new Function<LfsBackend, LfsBackendType>() {
-        @Override
-        public LfsBackendType apply(LfsBackend input) {
-          return input.type;
-        }
-      };
-
   private final LfsConfigurationFactory lfsConfigFactory;
   private final AllProjectsName allProjectsName;
   private final Provider<CurrentUser> self;
@@ -65,7 +56,7 @@
     LfsGlobalConfig globalConfig = lfsConfigFactory.getGlobalConfig();
     info.defaultBackendType = globalConfig.getDefaultBackend().type;
     info.backends = Maps.transformValues(globalConfig.getBackends(),
-        TO_BACKEND_CFG);
+        b -> b.type);
 
     List<LfsProjectConfigSection> configSections =
         lfsConfigFactory.getProjectsConfig().getConfigSections();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
index c107418..5309b4b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/HttpModule.java
@@ -22,11 +22,10 @@
 import com.google.gerrit.httpd.plugins.HttpPluginModule;
 import com.google.inject.Inject;
 
+import com.googlesource.gerrit.plugins.lfs.fs.LfsFsContentServlet;
 import com.googlesource.gerrit.plugins.lfs.fs.LocalLargeFileRepository;
 import com.googlesource.gerrit.plugins.lfs.s3.S3LargeFileRepository;
 
-import org.eclipse.jgit.lfs.server.fs.LfsFsContentServlet;
-
 import java.util.Map;
 
 public class HttpModule extends HttpPluginModule {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
index 67fe512..edc8b77 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
@@ -38,12 +38,16 @@
 import org.eclipse.jgit.lfs.server.LargeFileRepository;
 import org.eclipse.jgit.lfs.server.LfsGerritProtocolServlet;
 import org.eclipse.jgit.lfs.server.LfsObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 @Singleton
 public class LfsApiServlet extends LfsGerritProtocolServlet {
+  private static final Logger log = LoggerFactory.getLogger(LfsApiServlet.class);
+
   private static final long serialVersionUID = 1L;
   private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX);
   private static final String DOWNLOAD = "download";
@@ -123,11 +127,15 @@
     ProjectControl control = state.controlFor(user);
     if ((operation.equals(DOWNLOAD) && !control.isReadable()) ||
         (operation.equals(UPLOAD) && Capable.OK != control.canPushToAtLeastOneRef())) {
-      throw new LfsUnauthorized(
-          String.format("User %s is not authorized to perform %s operation",
-              Strings.isNullOrEmpty(user.getUserName())
-                ? "anonymous" :  user.getUserName(),
-              operation.toLowerCase()));
+      String op = operation.toLowerCase();
+      String project = state.getProject().getName();
+      String userName = Strings.isNullOrEmpty(user.getUserName())
+          ? "anonymous"
+          : user.getUserName();
+      log.debug(String.format(
+          "operation %s unauthorized for user %s on project %s",
+          op, userName, project));
+      throw new LfsUnauthorized(op, project);
     }
   }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGlobalConfig.java
index 2eab3d6..994da0d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGlobalConfig.java
@@ -14,7 +14,6 @@
 
 package com.googlesource.gerrit.plugins.lfs;
 
-import com.google.common.base.Function;
 import com.google.common.collect.FluentIterable;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMap.Builder;
@@ -42,15 +41,10 @@
 
   public Map<String, LfsBackend> getBackends() {
     Builder<String, LfsBackend> builder = ImmutableMap.builder();
-    for (final LfsBackendType type : LfsBackendType.values()) {
+    for (LfsBackendType type : LfsBackendType.values()) {
       Map<String, LfsBackend> backendsOfType =
           FluentIterable.from(cfg.getSubsections(type.name()))
-              .toMap(new Function<String, LfsBackend>() {
-                @Override
-                public LfsBackend apply(String input) {
-                  return new LfsBackend(input, type);
-                }
-              });
+              .toMap(s -> new LfsBackend(s, type));
       builder.putAll(backendsOfType);
     }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/Module.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/Module.java
index bd7519a..c7a33ad 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/Module.java
@@ -19,11 +19,10 @@
 import com.google.gerrit.extensions.config.FactoryModule;
 import com.google.gerrit.extensions.restapi.RestApiModule;
 
+import com.googlesource.gerrit.plugins.lfs.fs.LfsFsContentServlet;
 import com.googlesource.gerrit.plugins.lfs.fs.LocalLargeFileRepository;
 import com.googlesource.gerrit.plugins.lfs.s3.S3LargeFileRepository;
 
-import org.eclipse.jgit.lfs.server.fs.LfsFsContentServlet;
-
 public class Module extends FactoryModule {
 
   @Override
diff --git a/src/main/java/org/eclipse/jgit/lfs/server/fs/LfsFsContentServlet.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsContentServlet.java
similarity index 72%
rename from src/main/java/org/eclipse/jgit/lfs/server/fs/LfsFsContentServlet.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsContentServlet.java
index 90f2778..66d0765 100644
--- a/src/main/java/org/eclipse/jgit/lfs/server/fs/LfsFsContentServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsContentServlet.java
@@ -12,25 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.eclipse.jgit.lfs.server.fs;
-// TODO move file back to com.googlesource.gerrit.plugin.lfs.fs package when
-// https://git.eclipse.org/r/#/c/84933/ is picked up by gerrit
+package com.googlesource.gerrit.plugins.lfs.fs;
 
-import static com.googlesource.gerrit.plugins.lfs.fs.LocalLargeFileRepository.DOWNLOAD;
-import static com.googlesource.gerrit.plugins.lfs.fs.LocalLargeFileRepository.UPLOAD;
+import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD;
+import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD;
 import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION;
 
 import com.google.inject.Inject;
 import com.google.inject.assistedinject.Assisted;
 
-import com.googlesource.gerrit.plugins.lfs.fs.LfsFsRequestAuthorizer;
-import com.googlesource.gerrit.plugins.lfs.fs.LocalLargeFileRepository;
-
 import org.apache.http.HttpStatus;
-import org.eclipse.jgit.lfs.errors.InvalidLongObjectIdException;
 import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
-import org.eclipse.jgit.lfs.lib.Constants;
-import org.eclipse.jgit.lfs.lib.LongObjectId;
+import org.eclipse.jgit.lfs.server.fs.FileLfsServlet;
+import org.eclipse.jgit.lfs.server.fs.ObjectDownloadListener;
+import org.eclipse.jgit.lfs.server.fs.ObjectUploadListener;
 import org.eclipse.jgit.lfs.server.internal.LfsServerText;
 
 import java.io.IOException;
@@ -109,20 +104,4 @@
     req.getInputStream().setReadListener(
         new ObjectUploadListener(repository, context, req, rsp, id));
   }
-
-  private AnyLongObjectId getObjectToTransfer(HttpServletRequest req,
-      HttpServletResponse rsp) throws IOException {
-    String info = req.getPathInfo();
-    if (info.length() != 1 + Constants.LONG_OBJECT_ID_STRING_LENGTH) {
-      sendError(rsp, HttpStatus.SC_UNPROCESSABLE_ENTITY,
-          MessageFormat.format(LfsServerText.get().invalidPathInfo, info));
-      return null;
-    }
-    try {
-      return LongObjectId.fromString(info.substring(1, 65));
-    } catch (InvalidLongObjectIdException e) {
-      sendError(rsp, HttpStatus.SC_UNPROCESSABLE_ENTITY, e.getMessage());
-      return null;
-    }
-  }
 }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
index 71a51af..f96cd7e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
@@ -15,6 +15,8 @@
 package com.googlesource.gerrit.plugins.lfs.fs;
 
 import static com.googlesource.gerrit.plugins.lfs.LfsBackend.DEFAULT;
+import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD;
+import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD;
 
 import com.google.common.base.Strings;
 import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
@@ -43,8 +45,6 @@
   }
 
   public static final String CONTENT_PATH = "content";
-  public static final String UPLOAD = "upload";
-  public static final String DOWNLOAD = "download";
   private static final int DEFAULT_TIMEOUT = 10; //in seconds
 
   private final String servletUrlPattern;
diff --git a/src/main/java/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java b/src/main/java/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
deleted file mode 100644
index 896eb9f..0000000
--- a/src/main/java/org/eclipse/jgit/lfs/errors/LfsUnauthorized.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (C) 2017 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 org.eclipse.jgit.lfs.errors;
-
-
-public class LfsUnauthorized extends LfsException {
-  private static final long serialVersionUID = 1L;
-
-  public LfsUnauthorized(String message) {
-    super(message);
-  }
-}
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index d652cd3..7f44b04 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -1,74 +1,66 @@
 Build
 =====
 
-This plugin can be built with Buck.
-
-Buck
-----
+This @PLUGIN@ plugin is built with Bazel.
 
 Two build modes are supported: Standalone and in Gerrit tree.
 The standalone build mode is recommended, as this mode doesn't require
 the Gerrit tree to exist locally.
 
-
 ### Build standalone
 
-Clone bucklets library:
-
 ```
-  git clone https://gerrit.googlesource.com/bucklets
-
-```
-and link it to %PLUGIN% plugin directory:
-
-```
-  cd %PLUGIN% && ln -s ../bucklets .
-```
-
-Add link to the .buckversion file:
-
-```
-  cd %PLUGIN% && ln -s bucklets/buckversion .buckversion
-```
-
-Add link to the .watchmanconfig file:
-
-```
-  cd %PLUGIN% && ln -s bucklets/watchmanconfig .watchmanconfig
-```
-
-To build the plugin, issue the following command:
-
-```
-  buck build plugin
+  bazel build @PLUGIN@
 ```
 
 The output is created in
 
 ```
-  buck-out/gen/%PLUGIN%.jar
+  bazel-genfiles/@PLUGIN@.jar
+```
+
+To execute the tests run:
+
+```
+  bazel test :@PLUGIN@_tests
 ```
 
 ### Build in Gerrit tree
 
-Clone or link this plugin to the plugins directory of Gerrit's source
-tree, and issue the command:
+Put the external dependency Bazel build file into the Gerrit /plugins directory,
+replacing the existing empty one.
 
 ```
-  buck build plugins/%PLUGIN%
+  cd gerrit/plugins
+  rm external_plugin_deps.bzl
+  ln -s @PLUGIN@/external_plugin_deps.bzl .
+```
+
+Then issue
+
+```
+  bazel build plugins/@PLUGIN@
 ```
 
 The output is created in
 
 ```
-  buck-out/gen/plugins/%PLUGIN%/%PLUGIN%.jar
+  bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
 ```
 
-This project can be imported into the Eclipse IDE:
+This project can be imported into the Eclipse IDE.
+Add the plugin name to the `CUSTOM_PLUGINS` set in
+Gerrit core in `tools/bzl/plugins.bzl`, and execute:
 
 ```
   ./tools/eclipse/project.py
 ```
 
+To execute the tests run:
+
+```
+  bazel test plugins/@PLUGIN@:@PLUGIN@_tests
+```
+
 How to build the Gerrit Plugin API is described in the [Gerrit
-documentation](../../../Documentation/dev-buck.html#_extension_and_plugin_api_jar_files).
+documentation](../../../Documentation/dev-bazel.html#_extension_and_plugin_api_jar_files).
diff --git a/tools/bazel.rc b/tools/bazel.rc
new file mode 100644
index 0000000..2c1da56
--- /dev/null
+++ b/tools/bazel.rc
@@ -0,0 +1,3 @@
+build --workspace_status_command=./tools/workspace-status.sh
+test --build_tests_only
+
diff --git a/tools/bzl/BUILD b/tools/bzl/BUILD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/bzl/BUILD
diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl
new file mode 100644
index 0000000..3af7e58
--- /dev/null
+++ b/tools/bzl/junit.bzl
@@ -0,0 +1,4 @@
+load(
+    "@com_googlesource_gerrit_bazlets//tools:junit.bzl",
+    "junit_tests",
+)
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
new file mode 100644
index 0000000..a2e438f
--- /dev/null
+++ b/tools/bzl/plugin.bzl
@@ -0,0 +1,6 @@
+load(
+    "@com_googlesource_gerrit_bazlets//:gerrit_plugin.bzl",
+    "gerrit_plugin",
+    "PLUGIN_DEPS",
+    "PLUGIN_TEST_DEPS",
+)
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
new file mode 100755
index 0000000..dcb6031
--- /dev/null
+++ b/tools/workspace-status.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# This script will be run by bazel when the build process starts to
+# generate key-value information that represents the status of the
+# workspace. The output should be like
+#
+# KEY1 VALUE1
+# KEY2 VALUE2
+#
+# If the script exits with non-zero code, it's considered as a failure
+# and the output will be discarded.
+
+function rev() {
+  cd $1; git describe --always --match "v[0-9].*" --dirty
+}
+
+echo STABLE_BUILD_LFS_LABEL $(rev .)
+