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: