Bazel: Publish maven artifacts to local and remote repositories

Currently too big files are published, because some unwanted transitive
dependencies are included in the final artifacts. That will be fixed in
follow-up change by using neverlink option in java_library rule or using
provided_deps attribute that will be addded in future releases of Bazel:
[1].

TEST PLAN:

  $ VERBOSE=1 tools/maven/api.sh install bazel
  $ VERBOSE=1 tools/maven/api.sh install buck

* [1] https://github.com/bazelbuild/bazel/issues/1402

Change-Id: Ie73d4ae34d96be7f97f6329c4c30c814f54688d5
diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt
index 5ca6353..97124cb 100644
--- a/Documentation/dev-bazel.txt
+++ b/Documentation/dev-bazel.txt
@@ -7,7 +7,6 @@
 * Version stamping
 * Custom plugins
 * Eclipse project generation.
-* Publishing to maven.
 * Test suites for SSH, acceptance, etc.
 * tag tests as slow, flaky, etc.
 
@@ -81,7 +80,17 @@
   bazel-bin/gerrit-extension-api/extension-api_deploy.jar
 ----
 
-TODO - fix and document deployment to maven
+Install {extension,plugin,gwt}-api to the local maven repository:
+
+----
+  tools/maven/api.sh install bazel
+----
+
+Install gerrit.war to the local maven repository:
+
+----
+  tools/maven/api.sh war_install bazel
+----
 
 === Plugins
 
diff --git a/Documentation/dev-release.txt b/Documentation/dev-release.txt
index 8741d80..023841c 100644
--- a/Documentation/dev-release.txt
+++ b/Documentation/dev-release.txt
@@ -154,7 +154,7 @@
 ----
   buck clean
   buck build --no-cache release docs
-  ./tools/maven/api.sh install
+  ./tools/maven/api.sh install <buck|bazel>
 ----
 
 * Sanity check WAR
@@ -186,13 +186,13 @@
 * Push the WAR to Maven Central:
 +
 ----
-  ./tools/maven/api.sh war_deploy
+  ./tools/maven/api.sh war_deploy <buck|bazel>
 ----
 
 * Push the plugin artifacts to Maven Central:
 +
 ----
-  ./tools/maven/api.sh deploy
+  ./tools/maven/api.sh deploy <buck|bazel>
 ----
 +
 If no artifacts are uploaded, clean the `buck-out` folder and retry:
diff --git a/gerrit-acceptance-framework/BUILD b/gerrit-acceptance-framework/BUILD
index ed04efa..ec79be8 100644
--- a/gerrit-acceptance-framework/BUILD
+++ b/gerrit-acceptance-framework/BUILD
@@ -64,4 +64,5 @@
   title = 'Gerrit Acceptance Test Framework Documentation',
   libs = [':lib'],
   pkgs = ['com.google.gerrit.acceptance'],
+  visibility = ['//visibility:public'],
 )
diff --git a/gerrit-extension-api/BUILD b/gerrit-extension-api/BUILD
index cbe0e26..6f4df01 100644
--- a/gerrit-extension-api/BUILD
+++ b/gerrit-extension-api/BUILD
@@ -55,4 +55,5 @@
   libs = [':api'],
   pkgs = ['com.google.gerrit.extensions'],
   external_docs = [JGIT_DOC_URL, GUAVA_DOC_URL],
+  visibility = ['//visibility:public'],
 )
diff --git a/gerrit-plugin-api/BUILD b/gerrit-plugin-api/BUILD
index e2d8372..e231a02 100644
--- a/gerrit-plugin-api/BUILD
+++ b/gerrit-plugin-api/BUILD
@@ -103,4 +103,5 @@
     '//gerrit-gwtexpui:server',
     '//gerrit-reviewdb:server',
   ],
+  visibility = ['//visibility:public'],
 )
diff --git a/tools/maven/BUCK b/tools/maven/BUCK
index 322b5a2..0541fc0 100644
--- a/tools/maven/BUCK
+++ b/tools/maven/BUCK
@@ -1,6 +1,6 @@
-include_defs('//VERSION')
 include_defs('//tools/maven/package.defs')
 include_defs('//tools/maven/repository.defs')
+include_defs('//version.bzl')
 
 if GERRIT_VERSION.endswith('-SNAPSHOT'):
   URL = MAVEN_SNAPSHOT_URL
diff --git a/tools/maven/BUILD b/tools/maven/BUILD
new file mode 100644
index 0000000..14eb2be
--- /dev/null
+++ b/tools/maven/BUILD
@@ -0,0 +1,31 @@
+load('//:version.bzl', 'GERRIT_VERSION')
+load('//tools/maven:package.bzl', 'maven_package')
+
+MAVEN_REPOSITORY = 'sonatype-nexus-staging'
+# TODO(davido): support snapshot repositories
+MAVEN_RELEASE_URL = 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
+
+maven_package(
+  repository = MAVEN_REPOSITORY,
+  url = MAVEN_RELEASE_URL,
+  version = GERRIT_VERSION,
+  jar = {
+    'gerrit-acceptance-framework': '//gerrit-acceptance-framework:acceptance-framework_deploy.jar',
+    'gerrit-extension-api': '//gerrit-extension-api:extension-api_deploy.jar',
+    'gerrit-plugin-api': '//gerrit-plugin-api:plugin-api_deploy.jar',
+    'gerrit-plugin-gwtui': '//gerrit-plugin-gwtui:gwtui-api_deploy.jar',
+  },
+  src = {
+    'gerrit-acceptance-framework': '//gerrit-acceptance-framework:liblib-src.jar',
+    'gerrit-extension-api': '//gerrit-extension-api:libapi-src.jar',
+    'gerrit-plugin-api': '//gerrit-plugin-api:plugin-api-sources_deploy.jar',
+    'gerrit-plugin-gwtui': '//gerrit-plugin-gwtui:gwtui-api-source_deploy.jar',
+  },
+  doc = {
+    'gerrit-acceptance-framework': '//gerrit-acceptance-framework:acceptance-framework-javadoc',
+    'gerrit-extension-api': '//gerrit-extension-api:extension-api-javadoc',
+    'gerrit-plugin-api': '//gerrit-plugin-api:plugin-api-javadoc',
+    'gerrit-plugin-gwtui': '//gerrit-plugin-gwtui:gwtui-api-javadoc',
+  },
+  war = {'gerrit-war': '//:release'},
+)
diff --git a/tools/maven/api.sh b/tools/maven/api.sh
index c7ce65e..93b5f2e 100755
--- a/tools/maven/api.sh
+++ b/tools/maven/api.sh
@@ -14,16 +14,20 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-if [[ "$#" == "0" ]] ; then
+if [[ "$#" != "2" ]] ; then
   cat <<EOF
-Usage: run "$0 COMMAND" from the top of your workspace, where
-COMMAND is one of
+Usage: run "$0 COMMAND BUILD-TOOL" from the top of your workspace,
+where COMMAND is one of
 
   install
   deploy
   war_install
   war_deploy
 
+and BUILD-TOOL is one of
+
+  buck
+  bazel
 Set VERBOSE in the environment to get more information.
 
 EOF
@@ -54,16 +58,33 @@
     ;;
 esac
 
+case "$2" in
+bazel)
+    buildProc=bazel
+    ;;
+buck)
+    buildProc=buck
+    ;;
+*)
+    echo "unknown build-tool $2. Should be buck or bazel."
+    exit 1
+    ;;
+esac
+
 if [[ "${VERBOSE:-x}" != "x" ]]; then
   set -o xtrace
 fi
 
-buck build //tools/maven:gen_${command} || \
-  { echo "buck failed to build gen_${command}. Use VERBOSE=1 for more info" ; exit 1 ; }
+$buildProc build //tools/maven:gen_${command} || \
+  { echo "$buildProc failed to build gen_${command}. Use VERBOSE=1 for more info" ; exit 1 ; }
 
-script="./buck-out/gen/tools/maven/gen_${command}/${command}.sh"
-
-# The PEX wrapper does some funky exit handling, so even if the script
-# does "exit(0)", the return status is '1'. So we can't tell if the
-# following invocation was successful.
-${script}
+if [[ "$buildProc" = "bazel" ]]; then
+  script="./bazel-genfiles/tools/maven/${command}.sh"
+  ${script}
+else
+  script="./buck-out/gen/tools/maven/gen_${command}/${command}.sh"
+  # The PEX wrapper does some funky exit handling, so even if the script
+  # does "exit(0)", the return status is '1'. So we can't tell if the
+  # following invocation was successful.
+  ${script}
+fi
diff --git a/tools/maven/package.bzl b/tools/maven/package.bzl
new file mode 100644
index 0000000..c996ac5
--- /dev/null
+++ b/tools/maven/package.bzl
@@ -0,0 +1,93 @@
+# Copyright (C) 2016 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.
+
+sh_bang_template = (' && '.join([
+  "echo '#!/bin/bash -eu' > $@",
+  'echo "# this script should run from the root of your workspace." >> $@',
+  'echo "" >> $@',
+  "echo 'if [[ -n \"$$$${VERBOSE:-}\" ]]; then set -x ; fi' >> $@",
+  'echo "" >> $@',
+  'echo %s >> $@',
+  'echo "" >> $@',
+  'echo %s >> $@']))
+
+def maven_package(
+    version,
+    repository = None,
+    url = None,
+    jar = {},
+    src = {},
+    doc = {},
+    war = {}):
+
+  build_cmd = ['bazel', 'build']
+  mvn_cmd = ['python', 'tools/maven/mvn.py', '-v', version]
+  api_cmd = mvn_cmd[:]
+  api_targets = []
+  for type,d in [('jar', jar), ('java-source', src), ('javadoc', doc)]:
+    for a,t in sorted(d.items()):
+      api_cmd.append('-s %s:%s:$(location %s)' % (a,type,t))
+      api_targets.append(t)
+
+  native.genrule(
+    name = 'gen_api_install',
+    cmd = sh_bang_template % (
+      ' '.join(build_cmd + api_targets),
+      ' '.join(api_cmd + ['-a', 'install'])),
+    srcs = api_targets,
+    outs = ['api_install.sh'],
+    executable = True,
+  )
+
+  if repository and url:
+    native.genrule(
+      name = 'gen_api_deploy',
+      cmd = sh_bang_template % (
+        ' '.join(build_cmd + api_targets),
+        ' '.join(api_cmd + ['-a', 'deploy',
+                            '--repository', repository,
+                            '--url', url])),
+      srcs = api_targets,
+      outs = ['api_deploy.sh'],
+      executable = True,
+    )
+
+  war_cmd = mvn_cmd[:]
+  war_targets = []
+  for a,t in sorted(war.items()):
+    war_cmd.append('-s %s:war:$(location %s)' % (a,t))
+    war_targets.append(t)
+
+  native.genrule(
+    name = 'gen_war_install',
+    cmd = sh_bang_template % (' '.join(build_cmd + war_targets),
+                              ' '.join(war_cmd + ['-a', 'install'])),
+    srcs = war_targets,
+    outs = ['war_install.sh'],
+    executable = True,
+  )
+
+  if repository and url:
+    native.genrule(
+      name = 'gen_war_deploy',
+      cmd = sh_bang_template % (
+          ' '.join(build_cmd + war_targets),
+          ' '.join(war_cmd + [
+        '-a', 'deploy',
+        '--repository', repository,
+        '--url', url])),
+      srcs = war_targets,
+      outs = ['war_deploy.sh'],
+      executable = True,
+    )
diff --git a/tools/version.py b/tools/version.py
index 9f03a59..eac2700 100755
--- a/tools/version.py
+++ b/tools/version.py
@@ -53,7 +53,7 @@
   replace_in_file(pom, src_pattern)
 
 src_pattern = re.compile(r"^(GERRIT_VERSION = ')([-.\w]+)(')$", re.MULTILINE)
-replace_in_file('VERSION', src_pattern)
+replace_in_file('version.bzl', src_pattern)
 
 src_pattern = re.compile(r'^(\s*-DarchetypeVersion=)([-.\w]+)(\s*\\)$',
                          re.MULTILINE)
diff --git a/VERSION b/version.bzl
similarity index 100%
rename from VERSION
rename to version.bzl