Bazel: Implement GWT UI build for the plugins

TEST PLAN:

  $ bazel build plugins/cookbook-plugin

Deploy to the server site and verify that it works.

Change-Id: I98af807f9c92ba4ed7efad332d8fdee407bb8ce6
diff --git a/gerrit-plugin-gwtui/BUILD b/gerrit-plugin-gwtui/BUILD
index ac1909f..18bc038 100644
--- a/gerrit-plugin-gwtui/BUILD
+++ b/gerrit-plugin-gwtui/BUILD
@@ -2,7 +2,7 @@
 load('//tools/bzl:java.bzl', 'java_library2')
 
 SRCS = glob(['src/main/java/com/google/gerrit/**/*.java'])
-DEPS = ['//lib/gwt:user']
+DEPS = ['//lib/gwt:user-neverlink']
 
 java_binary(
   name = 'gwtui-api',
@@ -18,7 +18,16 @@
   srcs = SRCS,
   resources = glob(['src/main/**/*']),
   exported_deps = ['//gerrit-gwtui-common:client-lib'],
-  deps = DEPS + ['//lib/gwt:dev'], # we want this to be exported deps
+  deps = DEPS + ['//lib/gwt:dev'],
+)
+
+java_library2(
+  name = 'gwtui-api-lib-neverlink',
+  srcs = SRCS,
+  resources = glob(['src/main/**/*']),
+  exported_deps = ['//gerrit-gwtui-common:client-lib'],
+  neverlink = 1, # we want this to be exported deps
+  deps = DEPS + ['//lib/gwt:dev'],
 )
 
 java_binary(
diff --git a/lib/gwt/BUILD b/lib/gwt/BUILD
index bf50c80..da6f8eb 100644
--- a/lib/gwt/BUILD
+++ b/lib/gwt/BUILD
@@ -15,6 +15,14 @@
 ]]
 
 java_library(
+  name = 'user-neverlink',
+  exports = ['@user//jar'],
+  visibility = ['//visibility:public'],
+  neverlink = 1,
+  data = ['//lib:LICENSE-Apache2.0'],
+)
+
+java_library(
   name = 'javax-validation_src',
   exports = ['@javax_validation//src'],
   visibility = ['//visibility:public'],
diff --git a/tools/bzl/gwt.bzl b/tools/bzl/gwt.bzl
index ec00613..d14e96a 100644
--- a/tools/bzl/gwt.bzl
+++ b/tools/bzl/gwt.bzl
@@ -48,6 +48,19 @@
   '-XdisableCastChecking',
 ]
 
+PLUGIN_DEPS_NEVERLINK = [
+  '//gerrit-plugin-api:lib-neverlink',
+]
+
+GWT_PLUGIN_DEPS_NEVERLINK = [
+  '//gerrit-plugin-gwtui:gwtui-api-lib-neverlink',
+  '//lib/gwt:user-neverlink',
+]
+
+GWT_PLUGIN_DEPS = [
+  '//gerrit-plugin-gwtui:gwtui-api-lib',
+]
+
 GWT_TRANSITIVE_DEPS = [
   '//lib/gwt:ant',
   '//lib/gwt:colt',
@@ -126,7 +139,7 @@
   )
 
 def _gwt_binary_impl(ctx):
-  module = MODULE
+  module = ctx.attr.module[0]
   output_zip = ctx.outputs.output
   output_dir = output_zip.path + '.gwt_output'
   deploy_dir = output_zip.path + '.gwt_deploy'
@@ -195,6 +208,7 @@
     "style": attr.string(default = "OBF"),
     "optimize": attr.string(default = "9"),
     "deps": attr.label_list(allow_files=jar_filetype),
+    "module": attr.string_list(default = [MODULE]),
     "module_deps": attr.label_list(allow_files=jar_filetype),
     "compiler_args": attr.string_list(),
     "jvm_args": attr.string_list(),
@@ -237,6 +251,7 @@
 
   gwt_binary(
     name = opt,
+    module = [MODULE],
     module_deps = [module_dep],
     deps = DEPS,
     compiler_args = args,
@@ -279,6 +294,7 @@
       user_agent = ua,
       style = 'PRETTY',
       optimize = "0",
+      module = [MODULE],
       module_deps = [':ui_module'],
       deps = DEPS,
       compiler_args = GWT_COMPILER_ARGS,
diff --git a/tools/bzl/plugin.bzl b/tools/bzl/plugin.bzl
index 9b63553..bce8d66 100644
--- a/tools/bzl/plugin.bzl
+++ b/tools/bzl/plugin.bzl
@@ -1,9 +1,14 @@
 load('//tools/bzl:genrule2.bzl', 'genrule2')
+load('//tools/bzl:gwt.bzl', 'GWT_PLUGIN_DEPS',
+     'GWT_PLUGIN_DEPS_NEVERLINK', 'GWT_TRANSITIVE_DEPS',
+     'GWT_COMPILER_ARGS', 'PLUGIN_DEPS_NEVERLINK',
+     'GWT_JVM_ARGS', 'gwt_binary')
 
 def gerrit_plugin(
     name,
     deps = [],
     srcs = [],
+    gwt_module = [],
     resources = [],
     manifest_entries = [],
     **kwargs):
@@ -11,10 +16,14 @@
     name = name + '__plugin',
     srcs = srcs,
     resources = resources,
-    deps = deps + ['//gerrit-plugin-api:lib-neverlink'],
+    deps = deps + GWT_PLUGIN_DEPS_NEVERLINK + PLUGIN_DEPS_NEVERLINK,
     visibility = ['//visibility:public'],
   )
 
+  static_jars = []
+  if gwt_module:
+    static_jars = [':%s-static' % name]
+
   native.java_binary(
     name = '%s__non_stamped' % name,
     deploy_manifest_lines = manifest_entries + [
@@ -24,11 +33,37 @@
     main_class = 'Dummy',
     runtime_deps = [
       ':%s__plugin' % name,
-    ],
+    ] + static_jars,
     visibility = ['//visibility:public'],
     **kwargs
   )
 
+  if gwt_module:
+    native.java_library(
+      name = name + '__gwt_module',
+      resources = list(set(srcs + resources)),
+      runtime_deps = deps + GWT_PLUGIN_DEPS,
+      visibility = ['//visibility:public'],
+    )
+    genrule2(
+      name = '%s-static' % name,
+      cmd = ' && '.join([
+        'mkdir -p $$TMP/static',
+        'unzip -qd $$TMP/static $(location %s__gwt_application)' % name,
+        'cd $$TMP',
+        'zip -qr $$ROOT/$@ .']),
+      tools = [':%s__gwt_application' % name],
+      outs = ['%s-static.jar' % name],
+    )
+    gwt_binary(
+      name = name + '__gwt_application',
+      module = [gwt_module],
+      deps = GWT_PLUGIN_DEPS + GWT_TRANSITIVE_DEPS + ['//lib/gwt:dev'],
+      module_deps = [':%s__gwt_module' % name],
+      compiler_args = GWT_COMPILER_ARGS,
+      jvm_args = GWT_JVM_ARGS,
+    )
+
   # TODO(davido): Remove manual merge of manifest file when this feature
   # request is implemented: https://github.com/bazelbuild/bazel/issues/2009
   genrule2(