Merge branch 'stable-2.9' into stable-2.10

* stable-2.9:
  Consume API version 2.9

Merge made by the 'ours' strategy.

Change-Id: Ife4ea0b62d025dd14ef84004d5be36b3900773e1
diff --git a/.buckconfig b/.buckconfig
new file mode 100644
index 0000000..36c84eb
--- /dev/null
+++ b/.buckconfig
@@ -0,0 +1,14 @@
+[alias]
+  cookbook = //:cookbook-plugin
+  plugin = //:cookbook-plugin
+
+[java]
+  src_roots = java, resources
+
+[project]
+  ignore = .git
+
+[cache]
+  mode = dir
+  dir = buck-out/cache
+
diff --git a/.gitignore b/.gitignore
index fb96bc0..9ab384b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,9 @@
 /target
+/.buckversion
 /.classpath
 /.settings
 /.project
-
+/.buckd
+/buck-cache
+/buck-out
+/bucklets
diff --git a/BUCK b/BUCK
index 0ef0347..066e743 100644
--- a/BUCK
+++ b/BUCK
@@ -1,3 +1,5 @@
+include_defs('//bucklets/gerrit_plugin.bucklet')
+
 MODULE = 'com.googlesource.gerrit.plugins.cookbook.HelloForm'
 
 gerrit_plugin(
@@ -14,3 +16,11 @@
     'Implementation-URL: https://gerrit-review.googlesource.com/#/admin/projects/plugins/cookbook-plugin',
   ]
 )
+
+# TODO(davido): is this needed?
+# requires for bucklets/tools/eclipse/project.py to work
+# not sure, if this does something useful in standalone context
+java_library(
+  name = 'classpath',
+  deps = [':cookbook-plugin__plugin'],
+)
diff --git a/lib/gerrit/BUCK b/lib/gerrit/BUCK
new file mode 100644
index 0000000..11051b2
--- /dev/null
+++ b/lib/gerrit/BUCK
@@ -0,0 +1,20 @@
+include_defs('//bucklets/maven_jar.bucklet')
+
+VER = '2.10-SNAPSHOT'
+REPO = MAVEN_LOCAL
+
+maven_jar(
+  name = 'plugin-api',
+  id = 'com.google.gerrit:gerrit-plugin-api:' + VER,
+  license = 'Apache2.0',
+  attach_source = False,
+  repository = REPO,
+)
+
+maven_jar(
+  name = 'gwtui-api',
+  id = 'com.google.gerrit:gerrit-plugin-gwtui:' + VER,
+  license = 'Apache2.0',
+  attach_source = False,
+  repository = REPO,
+)
diff --git a/lib/gwt/BUCK b/lib/gwt/BUCK
new file mode 100644
index 0000000..e07bf39
--- /dev/null
+++ b/lib/gwt/BUCK
@@ -0,0 +1,43 @@
+include_defs('//bucklets/maven_jar.bucklet')
+
+VER = '2.6.1'
+
+maven_jar(
+  name = 'user',
+  id = 'com.google.gwt:gwt-user:' + VER,
+  sha1 = 'c078b1b8cc0281214b0eb458d2c283d039374fad',
+  license = 'Apache2.0',
+  attach_source = False,
+  deps = [
+    ':javax-validation',
+    ':javax-validation_src',
+  ]
+)
+
+maven_jar(
+  name = 'dev',
+  id = 'com.google.gwt:gwt-dev:' + VER,
+  sha1 = 'db237e4be0aa1fe43425d2c51ab5485dba211ddd',
+  license = 'Apache2.0',
+  attach_source = False,
+  exclude = ['org/eclipse/jetty/*'],
+  deps = [':json'],
+)
+
+maven_jar(
+  name = 'javax-validation',
+  id = 'javax.validation:validation-api:1.0.0.GA',
+  bin_sha1 = 'b6bd7f9d78f6fdaa3c37dae18a4bd298915f328e',
+  src_sha1 = '7a561191db2203550fbfa40d534d4997624cd369',
+  license = 'Apache2.0',
+  visibility = [],
+)
+
+maven_jar(
+  name = 'json',
+  id = 'org.json:json:20140107',
+  sha1 = 'd1ffca6e2482b002702c6a576166fd685e3370e3',
+  license = 'DO_NOT_DISTRIBUTE',
+  attach_source = False,
+  visibility = [],
+)
diff --git a/pom.xml b/pom.xml
index 553a855..9bd7a98 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
   <version>0.1</version>
   <properties>
     <Gerrit-ApiType>plugin</Gerrit-ApiType>
-    <Gerrit-ApiVersion>2.9</Gerrit-ApiVersion>
+    <Gerrit-ApiVersion>2.9-SNAPSHOT</Gerrit-ApiVersion>
   </properties>
 
   <build>
@@ -69,7 +69,7 @@
       <plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>gwt-maven-plugin</artifactId>
-        <version>2.5.1</version>
+        <version>2.6.1</version>
         <configuration>
           <module>com.googlesource.gerrit.plugins.cookbook.HelloForm</module>
           <disableClassMetadata>true</disableClassMetadata>
@@ -103,7 +103,7 @@
     <dependency>
       <groupId>com.google.gwt</groupId>
       <artifactId>gwt-user</artifactId>
-      <version>2.5.1</version>
+      <version>2.6.1</version>
       <scope>provided</scope>
     </dependency>
   </dependencies>
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/DenyUploadExample.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/DenyUploadExample.java
new file mode 100644
index 0000000..a19fab6
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/DenyUploadExample.java
@@ -0,0 +1,44 @@
+// Copyright (C) 2014 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.googlesource.gerrit.plugins.cookbook;
+
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.git.validators.UploadValidationListener;
+import com.google.gerrit.server.validators.ValidationException;
+import com.google.inject.Inject;
+
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.transport.UploadPack;
+
+import java.util.Collection;
+
+public class DenyUploadExample implements UploadValidationListener {
+  @Inject
+  private CurrentUser user;
+
+  @Override
+  public void onPreUpload(Repository repository, Project project,
+      String remoteHost, UploadPack up, Collection<? extends ObjectId> wants,
+      Collection<? extends ObjectId> haves) throws ValidationException {
+    up.sendMessage("Validating project name for " + user.getUserName() + "\n");
+    up.sendMessage("  from host: " + remoteHost + "\n");
+    if (project.getName().equals("deny-upload-project")) {
+      throw new ValidationException(
+          "This error message was sent from cookbook plugin DenyUploadExample.");
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/HelloWeblink.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/HelloWeblink.java
new file mode 100644
index 0000000..3a27191
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/HelloWeblink.java
@@ -0,0 +1,41 @@
+// Copyright (C) 2014 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.googlesource.gerrit.plugins.cookbook;
+
+import com.google.gerrit.extensions.webui.PatchSetWebLink;
+import com.google.gerrit.extensions.webui.ProjectWebLink;
+
+public class HelloWeblink implements PatchSetWebLink, ProjectWebLink {
+  private String name = "HelloLink";
+  private String placeHolderUrlProject =
+      "http://my.hellolink.com/project=%s";
+  private String placeHolderUrlProjectCommit =
+      placeHolderUrlProject + "/commit=%s";
+
+  @Override
+  public String getLinkName() {
+    return name ;
+  }
+
+  @Override
+  public String getPatchSetUrl(String project, String commit) {
+    return String.format(placeHolderUrlProjectCommit, project, commit);
+  }
+
+  @Override
+  public String getProjectUrl(String project) {
+    return String.format(placeHolderUrlProject, project);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/Module.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/Module.java
index ae04cdc..5f88178 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/cookbook/Module.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/Module.java
@@ -19,19 +19,32 @@
 
 import com.google.common.collect.ImmutableList;
 import com.google.gerrit.extensions.annotations.Exports;
+import com.google.gerrit.extensions.common.InheritableBoolean;
+import com.google.gerrit.extensions.events.UsageDataPublishedListener;
 import com.google.gerrit.extensions.registration.DynamicSet;
 import com.google.gerrit.extensions.restapi.RestApiModule;
+import com.google.gerrit.extensions.webui.PatchSetWebLink;
+import com.google.gerrit.extensions.webui.ProjectWebLink;
 import com.google.gerrit.extensions.webui.TopMenu;
-import com.google.gerrit.reviewdb.client.Project.InheritableBoolean;
 import com.google.gerrit.server.config.ProjectConfigEntry;
+import com.google.gerrit.server.git.validators.UploadValidationListener;
+import com.google.gerrit.server.plugins.ServerPluginProvider;
 import com.google.inject.AbstractModule;
 
+import com.googlesource.gerrit.plugins.cookbook.pluginprovider.HelloSshPluginProvider;
+
 public class Module extends AbstractModule {
 
   @Override
   protected void configure() {
     DynamicSet.bind(binder(), TopMenu.class)
         .to(HelloTopMenu.class);
+    DynamicSet.bind(binder(), PatchSetWebLink.class).to(HelloWeblink.class);
+    DynamicSet.bind(binder(), ProjectWebLink.class).to(HelloWeblink.class);
+    DynamicSet.bind(binder(), ServerPluginProvider.class).to(
+        HelloSshPluginProvider.class);
+    DynamicSet.bind(binder(), UsageDataPublishedListener.class).to(UsageDataLogger.class);
+
     install(new RestApiModule() {
       @Override
       protected void configure() {
@@ -40,6 +53,8 @@
         get(REVISION_KIND, "greetings").to(Greetings.class);
       }
     });
+    DynamicSet.bind(binder(), UploadValidationListener.class)
+        .to(DenyUploadExample.class);
     configurePluginParameters();
   }
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/UsageDataLogger.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/UsageDataLogger.java
new file mode 100644
index 0000000..995e68c
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/UsageDataLogger.java
@@ -0,0 +1,40 @@
+// Copyright (C) 2014 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.googlesource.gerrit.plugins.cookbook;
+
+import com.google.gerrit.extensions.events.UsageDataPublishedListener;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class UsageDataLogger implements UsageDataPublishedListener {
+
+  private static final Logger log = LoggerFactory.getLogger(UsageDataLogger.class);
+
+  @Override
+  public void onUsageDataPublished(Event event) {
+    if (log.isInfoEnabled()) {
+      log.info(String.format("Usage data for "
+          + "%s at %s", event.getMetaData().getDescription(), event.getInstant()));
+      log.info(String.format("project name - %s", event.getMetaData().getName()));
+      String unitSymbol = event.getMetaData().getUnitSymbol();
+      for (Data data : event.getData()) {
+        log.info(String.format("%s - %d %s", data.getProjectName(), data.getValue(),
+            unitSymbol));
+      }
+      log.info("");
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshCommand.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshCommand.java
new file mode 100644
index 0000000..b1da6de
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshCommand.java
@@ -0,0 +1,52 @@
+// Copyright (C) 2013 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.googlesource.gerrit.plugins.cookbook.pluginprovider;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.config.SitePaths;
+import com.google.gerrit.sshd.CommandMetaData;
+import com.google.gerrit.sshd.SshCommand;
+import com.google.inject.Inject;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+
+/**
+ * SSH command defined by dynamically registered plugins.
+ *
+ */
+@CommandMetaData(name = "print", description = "Print content of the plugin file")
+public final class HelloSshCommand extends SshCommand {
+  private final String pluginName;
+  private final File pluginDir;
+
+  @Inject
+  public HelloSshCommand(@PluginName String pluginName, SitePaths sitePaths) {
+    this.pluginName = pluginName;
+    this.pluginDir = sitePaths.plugins_dir;
+  }
+
+  @Override
+  public void run() {
+    File pluginFile = new File(pluginDir, pluginName + ".ssh");
+    try {
+      Files.copy(pluginFile.toPath(), out);
+    } catch (IOException e) {
+      throw new RuntimeException("Cannot read plugin content of " + pluginFile,
+          e);
+    }
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshModule.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshModule.java
new file mode 100644
index 0000000..8a9def0
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshModule.java
@@ -0,0 +1,27 @@
+// Copyright (C) 2013 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.googlesource.gerrit.plugins.cookbook.pluginprovider;
+
+import com.google.gerrit.sshd.PluginCommandModule;
+
+/**
+ * SSH Module exported by provided plugins.
+ */
+public class HelloSshModule extends PluginCommandModule {
+  @Override
+  protected void configureCommands() {
+    command(HelloSshCommand.class);
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginContentScanner.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginContentScanner.java
new file mode 100644
index 0000000..794dca0
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginContentScanner.java
@@ -0,0 +1,88 @@
+// Copyright (C) 2014 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.googlesource.gerrit.plugins.cookbook.pluginprovider;
+
+import com.google.common.base.Optional;
+import com.google.gerrit.server.plugins.InvalidPluginException;
+import com.google.gerrit.server.plugins.PluginContentScanner;
+import com.google.gerrit.server.plugins.PluginEntry;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.jar.Manifest;
+
+/**
+ * Plugin scanner is responsible for returning plugin contents.
+ */
+public class HelloSshPluginContentScanner implements PluginContentScanner {
+  private final String pluginName;
+
+  public HelloSshPluginContentScanner(String pluginName) {
+    this.pluginName = pluginName;
+  }
+
+  /**
+   * Scanner for self-registration: not used in this sample.
+   */
+  @Override
+  public Map<Class<? extends Annotation>, Iterable<ExtensionMetaData>> scan(
+      String pluginName, Iterable<Class<? extends Annotation>> annotations)
+      throws InvalidPluginException {
+    return null;
+  }
+
+  /**
+   * Returns the Plugin Manfiest content as it was packaged in a JAR file.
+   */
+  @Override
+  public Manifest getManifest() throws IOException {
+    String manifestString =
+        "PluginName: " + pluginName + "\n" +
+        "Implementation-Version: 1.0\n" +
+        "Gerrit-ReloadMode: restart\n" +
+        "Gerrit-ApiType: Plugin\n" +
+        "Gerrit-SshModule: " + HelloSshModule.class.getName() + "\n";
+    return new Manifest(new ByteArrayInputStream(manifestString.getBytes()));
+  }
+
+  /**
+   * Read static plugin resources: not used in this sample.
+   */
+  @Override
+  public InputStream getInputStream(PluginEntry entry) throws IOException {
+    return null;
+  }
+
+  /**
+   * Return plugin resource entry: not used in this sample.
+   */
+  @Override
+  public Optional<PluginEntry> getEntry(String resourcePath) throws IOException {
+    return Optional.absent();
+  }
+
+  /**
+   * Return full list of plugin resources: not used in this sample.
+   */
+  @Override
+  public Enumeration<PluginEntry> entries() {
+    return Collections.emptyEnumeration();
+  }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginProvider.java b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginProvider.java
new file mode 100644
index 0000000..a7d7268
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/cookbook/pluginprovider/HelloSshPluginProvider.java
@@ -0,0 +1,73 @@
+// Copyright (C) 2014 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.googlesource.gerrit.plugins.cookbook.pluginprovider;
+
+import com.google.gerrit.extensions.annotations.PluginName;
+import com.google.gerrit.server.plugins.InvalidPluginException;
+import com.google.gerrit.server.plugins.ServerPlugin;
+import com.google.gerrit.server.plugins.ServerPluginProvider;
+import com.google.inject.Inject;
+
+import org.eclipse.jgit.internal.storage.file.FileSnapshot;
+
+import java.io.File;
+
+/**
+ * Dynamic provider of Gerrit plugins derived by *.ssh files under $GERRIT_SITE/plugins.
+ *
+ * Example of how to define a dynamic Gerrit plugin provider to register
+ * a new plugin based on the content of *.ssh files.
+ *
+ * This provider allows to define a Gerrit plugin by simply dropping a .ssh file
+ * (e.g. hello.ssh) under $GERRIT_SITE/plugins.
+ * Once the file is created a new plugin is automatically loaded with the name
+ * without extension of the .ssh file (e.g. hello) and a new 'cat' SSH command is
+ * automatically available from the registered plugin.
+ */
+public class HelloSshPluginProvider implements ServerPluginProvider {
+  private static final String SSH_EXT = ".ssh";
+  private final String pluginName;
+
+  @Inject
+  public HelloSshPluginProvider(@PluginName String pluginName) {
+    this.pluginName = pluginName;
+  }
+
+  @Override
+  public boolean handles(File srcFile) {
+    return srcFile.getName().endsWith(SSH_EXT);
+  }
+
+  @Override
+  public String getPluginName(File srcFile) {
+    String srcFileName = srcFile.getName();
+    return srcFileName.substring(0, srcFileName.length() - SSH_EXT.length());
+  }
+
+  @Override
+  public ServerPlugin get(File srcFile, FileSnapshot snapshot,
+      PluginDescription pluginDescriptor) throws InvalidPluginException {
+    String name = getPluginName(srcFile);
+    return new ServerPlugin(name, pluginDescriptor.canonicalUrl,
+        pluginDescriptor.user, srcFile, snapshot,
+        new HelloSshPluginContentScanner(name), pluginDescriptor.dataDir,
+        getClass().getClassLoader());
+  }
+
+  @Override
+  public String getProviderPluginName() {
+    return pluginName;
+  }
+}
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index 6044d40..0fc79fc 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -3,6 +3,47 @@
 
 This plugin is built with Buck.
 
+Two build modes are supported: Standalone and in Gerrit tree. Standalone
+build mode is recommended, as this mode doesn't require local Gerrit
+tree to exist.
+
+Build standalone
+----------------
+
+Clone bucklets library:
+
+```
+  git clone https://gerrit.googlesource.com/bucklets
+
+```
+and link it to cookbook-plugin directory:
+
+```
+  cd cookbook-plugin && ln -s ../bucklets .
+```
+
+Add link to the .buckversion file:
+
+```
+  cd cookbook-plugin && ln -s bucklets/buckversion .buckversion
+```
+
+To build the plugin, issue the following command:
+
+
+```
+  buck build plugin
+```
+
+The output is created in
+
+```
+  buck-out/gen/cookbook-plugin/cookbook-plugin.jar
+```
+
+Build in Gerrit tree
+--------------------
+
 Clone or link this plugin to the plugins directory of Gerrit's source
 tree, and issue the command: