Merge branch 'stable-2.16' into stable-3.0

* stable-2.16:
  Bazel: Add remaining fixes for --incompatible_disallow_legacy_java_provider
  Bazel: Add fixes for --incompatible_load_python_rules_from_bzl
  Bazel: Export rules_python in plugin API
  Support bazelisk or bazel in tools/eclipse/project.py
  Rework imports in project.py
  Update project.py to use argparse
  Bazel: Add fixes for --incompatible_load_java_rules_from_bzl

Change-Id: I9c47f0de133216d47bc329ca0bdf35cc90a9a63d
diff --git a/gerrit_api.bzl b/gerrit_api.bzl
index 5ffc893..04b7829 100644
--- a/gerrit_api.bzl
+++ b/gerrit_api.bzl
@@ -1,4 +1,5 @@
 load("//:bouncycastle.bzl", "bouncycastle_repos")
+load("//:rules_python.bzl", "rules_python_repos")
 load("//tools:maven_jar.bzl", "maven_jar")
 
 """Bazel rule for building [Gerrit Code Review](https://www.gerritcodereview.com/)
@@ -9,6 +10,7 @@
 
 def gerrit_api():
     bouncycastle_repos()
+    rules_python_repos()
 
     maven_jar(
         name = "gerrit_plugin_api",
diff --git a/gerrit_api_maven_local.bzl b/gerrit_api_maven_local.bzl
index e0d6434..bdeb4ba 100644
--- a/gerrit_api_maven_local.bzl
+++ b/gerrit_api_maven_local.bzl
@@ -1,4 +1,5 @@
 load("//:bouncycastle.bzl", "bouncycastle_repos")
+load("//:rules_python.bzl", "rules_python_repos")
 load("//tools:maven_jar.bzl", "MAVEN_LOCAL", "maven_jar")
 
 """Bazel rule for building [Gerrit Code Review](https://www.gerritcodereview.com/)
@@ -9,6 +10,7 @@
 
 def gerrit_api_maven_local():
     bouncycastle_repos()
+    rules_python_repos()
 
     maven_jar(
         name = "gerrit_plugin_api",
diff --git a/gerrit_plugin.bzl b/gerrit_plugin.bzl
index adb9671..9df7560 100644
--- a/gerrit_plugin.bzl
+++ b/gerrit_plugin.bzl
@@ -1,3 +1,4 @@
+load("@rules_java//java:defs.bzl", "java_binary", "java_library")
 load(
     "//tools:commons.bzl",
     _plugin_deps = "PLUGIN_DEPS",
@@ -29,7 +30,7 @@
     if not dir_name:
         dir_name = name
 
-    native.java_library(
+    java_library(
         name = name + "__plugin",
         srcs = srcs,
         resources = resources,
@@ -37,8 +38,7 @@
         visibility = ["//visibility:public"],
         **kwargs
     )
-
-    native.java_binary(
+    java_binary(
         name = "%s__non_stamped" % name,
         deploy_manifest_lines = manifest_entries + ["Gerrit-ApiType: plugin"],
         main_class = "Dummy",
diff --git a/lib/prolog/BUILD b/lib/prolog/BUILD
index 8f78045..0d6af48 100644
--- a/lib/prolog/BUILD
+++ b/lib/prolog/BUILD
@@ -1,3 +1,5 @@
+load("@rules_java//java:defs.bzl", "java_binary", "java_library")
+
 java_binary(
     name = "compiler-bin",
     main_class = "PrologCompiler",
diff --git a/lib/prolog/prolog.bzl b/lib/prolog/prolog.bzl
index 5d9d3f3..26d54f4 100644
--- a/lib/prolog/prolog.bzl
+++ b/lib/prolog/prolog.bzl
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+load("@rules_java//java:defs.bzl", "java_library")
+
 def prolog_cafe_library(
         name,
         srcs,
@@ -26,7 +28,7 @@
         tools = ["@com_googlesource_gerrit_bazlets//lib/prolog:compiler-bin"],
         outs = [name + ".srcjar"],
     )
-    native.java_library(
+    java_library(
         name = name,
         srcs = [":" + name + "__pl2j"],
         deps = ["@prolog-runtime//jar:neverlink"] + deps,
diff --git a/rules_python.bzl b/rules_python.bzl
new file mode 100644
index 0000000..ad07c37
--- /dev/null
+++ b/rules_python.bzl
@@ -0,0 +1,12 @@
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
+"""Bazel rule for fetching rules python dependency.
+"""
+
+def rules_python_repos():
+    http_archive(
+        name = "rules_python",
+        sha256 = "b5bab4c47e863e0fbb77df4a40c45ca85f98f5a2826939181585644c9f31b97b",
+        strip_prefix = "rules_python-9d68f24659e8ce8b736590ba1e4418af06ec2552",
+        urls = ["https://github.com/bazelbuild/rules_python/archive/9d68f24659e8ce8b736590ba1e4418af06ec2552.tar.gz"],
+    )
diff --git a/tools/classpath.bzl b/tools/classpath.bzl
index 55479c5..682ee3c 100644
--- a/tools/classpath.bzl
+++ b/tools/classpath.bzl
@@ -1,9 +1,9 @@
 def _classpath_collector(ctx):
     all = []
     for d in ctx.attr.deps:
-        if hasattr(d, "java"):
-            all.append(d.java.transitive_runtime_deps)
-            all.append(d.java.compilation_info.runtime_classpath)
+        if JavaInfo in d:
+            all.append(d[JavaInfo].transitive_runtime_deps)
+            all.append(d[JavaInfo].compilation_info.runtime_classpath)
         elif hasattr(d, "files"):
             all.append(d.files)
 
diff --git a/tools/eclipse/BUILD b/tools/eclipse/BUILD
index 9c09be4..789a607 100644
--- a/tools/eclipse/BUILD
+++ b/tools/eclipse/BUILD
@@ -1,3 +1,5 @@
+load("@rules_python//python:defs.bzl", "py_binary")
+
 package(
     default_visibility = ["//visibility:public"],
 )
diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py
index d4a978c..154ae53 100755
--- a/tools/eclipse/project.py
+++ b/tools/eclipse/project.py
@@ -15,16 +15,12 @@
 #
 
 from __future__ import print_function
-# TODO(davido): use Google style for importing instead:
-# import optparse
-# ...
-# optparse.OptionParser
-from optparse import OptionParser
-from os import path
-from subprocess import CalledProcessError, check_call, check_output
-from xml.dom import minidom
+import argparse
+import os
+import subprocess
 import re
 import sys
+import xml.dom.minidom
 
 JRE = '/'.join([
   'org.eclipse.jdt.launching.JRE_CONTAINER',
@@ -32,27 +28,55 @@
   'JavaSE-1.8',
 ])
 
-opts = OptionParser()
-opts.add_option('-r', '--root', help='Root directory entry')
-opts.add_option('-n', '--name', help='Project name')
-opts.add_option('-x', '--exclude', action='append', help='Exclude paths')
-opts.add_option('-b', '--batch', action='store_true',
-                dest='batch', help='Bazel batch option')
-args, _ = opts.parse_args()
+opts = argparse.ArgumentParser("Create Eclipse Project")
+opts.add_argument('-r', '--root', help='Root directory entry')
+opts.add_argument('-n', '--name', help='Project name')
+opts.add_argument('-x', '--exclude', action='append', help='Exclude paths')
+opts.add_argument('-b', '--batch', action='store_true',
+                  dest='batch', help='Bazel batch option')
+opts.add_argument('--bazel',
+                  help=('name of the bazel executable. Defaults to using'
+                        ' bazelisk if found, or bazel if bazelisk is not'
+                        ' found.'),
+                  action='store', default=None, dest='bazel_exe')
+args = opts.parse_args()
 
 if not args.root:
   opts.error('Root option not provided')
   sys.exit(1)
 
 root = args.root
-ROOT = path.abspath(root)
-while not path.exists(path.join(ROOT, 'WORKSPACE')):
-  ROOT = path.dirname(ROOT)
+ROOT = os.path.abspath(root)
+while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
+  ROOT = os.path.dirname(ROOT)
 
 batch_option = '--batch' if args.batch else None
 
+def find_bazel():
+  if args.bazel_exe:
+    try:
+      return subprocess.check_output(
+        ['which', args.bazel_exe]).strip().decode('UTF-8')
+    except subprocess.CalledProcessError:
+      print('Bazel command: %s not found' % args.bazel_exe, file=sys.stderr)
+      sys.exit(1)
+  try:
+    return subprocess.check_output(
+      ['which', 'bazelisk']).strip().decode('UTF-8')
+  except subprocess.CalledProcessError:
+    try:
+      return subprocess.check_output(
+        ['which', 'bazel']).strip().decode('UTF-8')
+    except subprocess.CalledProcessError:
+      print("Neither bazelisk nor bazel found. Please see"
+            " Documentation/dev-bazel for instructions on installing"
+            " one of them.")
+      sys.exit(1)
+
+bazel_exe = find_bazel()
+
 def _build_bazel_cmd(*args):
-  cmd = ['bazel']
+  cmd = [bazel_exe]
   if batch_option:
     cmd.append('--batch')
   for arg in args:
@@ -60,19 +84,19 @@
   return cmd
 
 def retrieve_ext_location():
-  return check_output(_build_bazel_cmd('info', 'output_base')).strip()
+  return subprocess.check_output(_build_bazel_cmd('info', 'output_base')).strip()
 
 def _query_classpath():
   t = '//tools/eclipse:main_classpath_collect'
   try:
-    check_call(_build_bazel_cmd('build', t))
-  except CalledProcessError:
+    subprocess.check_call(_build_bazel_cmd('build', t))
+  except subprocess.CalledProcessError:
     exit(1)
   name = 'bazel-bin/tools/eclipse/' + t.split(':')[1] + '.runtime_classpath'
   return [line.rstrip('\n') for line in open(name)]
 
 def gen_project(name, root=ROOT):
-  p = path.join(root, '.project')
+  p = os.path.join(root, '.project')
   with open(p, 'w') as fd:
     print("""\
 <?xml version="1.0" encoding="UTF-8"?>
@@ -91,7 +115,7 @@
 
 def gen_classpath(ext):
   def make_classpath():
-    impl = minidom.getDOMImplementation()
+    impl = xml.dom.minidom.getDOMImplementation()
     return impl.createDocument(None, 'classpath', None)
 
   def classpathentry(kind, path, src=None, out=None, exported=None):
@@ -123,7 +147,7 @@
       src.add(m.group(1).lstrip('/'))
     else:
       if ext is not None and p.startswith("external"):
-        p = path.join(ext, p)
+        p = os.path.join(ext, p)
         lib.add(p)
 
   src_paths = {}
@@ -133,8 +157,8 @@
     if s.startswith('lib/'):
       out = 'eclipse-out/lib'
 
-    p = path.join(s, 'java')
-    if path.exists(p):
+    p = os.path.join(s, 'java')
+    if os.path.exists(p):
       classpathentry('src', p, out=out)
       continue
 
@@ -150,8 +174,8 @@
         continue
 
       for srctype in ['java', 'resources']:
-        p = path.join(s, 'src', env, srctype)
-        if path.exists(p):
+        p = os.path.join(s, 'src', env, srctype)
+        if os.path.exists(p):
           src_paths[p] = o
 
   for s in src_paths:
@@ -166,15 +190,15 @@
       if m:
         prefix = m.group(1)
         suffix = m.group(2)
-        p = path.join(prefix, "src", "%s-src.jar" % suffix)
-        if path.exists(p):
+        p = os.path.join(prefix, "src", "%s-src.jar" % suffix)
+        if os.path.exists(p):
           s = p
       classpathentry('lib', j, s)
 
   classpathentry('con', JRE)
   classpathentry('output', 'eclipse-out/classes')
 
-  p = path.join(ROOT, '.classpath')
+  p = os.path.join(ROOT, '.classpath')
   with open(p, 'w') as fd:
     doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
 
@@ -186,7 +210,7 @@
   return False
 
 try:
-  name = args.name if args.name else path.basename(ROOT)
+  name = args.name if args.name else os.path.basename(ROOT)
   gen_project(name)
   gen_classpath(retrieve_ext_location().decode('utf-8'))
 
diff --git a/tools/java.bzl b/tools/java.bzl
index 7c41fbe..8996b69 100644
--- a/tools/java.bzl
+++ b/tools/java.bzl
@@ -15,11 +15,13 @@
 # Syntactic sugar for native java_library() rule:
 #   accept exported_deps attributes
 
+load("@rules_java//java:defs.bzl", "java_library")
+
 def java_library2(deps = [], exported_deps = [], exports = [], **kwargs):
     if exported_deps:
         deps = deps + exported_deps
         exports = exports + exported_deps
-    native.java_library(
+    java_library(
         deps = deps,
         exports = exports,
         **kwargs
diff --git a/tools/javadoc.bzl b/tools/javadoc.bzl
index 2503594..0f1bfd9 100644
--- a/tools/javadoc.bzl
+++ b/tools/javadoc.bzl
@@ -17,8 +17,10 @@
 def _impl(ctx):
     zip_output = ctx.outputs.zip
 
-    transitive_jars = depset(transitive = [l.java.transitive_deps for l in ctx.attr.libs])
-    source_jars = depset(transitive = [l.java.source_jars for l in ctx.attr.libs])
+    transitive_jars = depset(transitive = [j[JavaInfo].transitive_deps for j in ctx.attr.libs])
+    # TODO(davido): Remove list to depset conversion on source_jars, when this issue is fixed:
+    # https://github.com/bazelbuild/bazel/issues/4221
+    source_jars = depset(transitive = [depset(j[JavaInfo].source_jars) for j in ctx.attr.libs])
 
     transitive_jar_paths = [j.path for j in transitive_jars.to_list()]
     dir = ctx.outputs.zip.path + ".dir"
diff --git a/tools/junit.bzl b/tools/junit.bzl
index b4cd558..58869ff 100644
--- a/tools/junit.bzl
+++ b/tools/junit.bzl
@@ -18,6 +18,8 @@
 
 # See https://github.com/bazelbuild/bazel/issues/1017 for background.
 
+load("@rules_java//java:defs.bzl", "java_test")
+
 _OUTPUT = """import org.junit.runners.Suite;
 import org.junit.runner.RunWith;
 
@@ -71,7 +73,7 @@
         srcs = srcs,
         outname = s_name,
     )
-    native.java_test(
+    java_test(
         name = name,
         test_class = s_name,
         srcs = srcs + [":" + s_name],
diff --git a/tools/pkg_war.bzl b/tools/pkg_war.bzl
index ce094ff..931450b 100644
--- a/tools/pkg_war.bzl
+++ b/tools/pkg_war.bzl
@@ -56,8 +56,8 @@
 
     transitive_libs = []
     for l in ctx.attr.libs:
-        if hasattr(l, "java"):
-            transitive_libs.append(l.java.transitive_runtime_deps)
+        if JavaInfo in l:
+            transitive_libs.append(l[JavaInfo].transitive_runtime_deps)
         elif hasattr(l, "files"):
             transitive_libs.append(l.files)
 
@@ -74,8 +74,8 @@
     transitive_context_libs = []
     if ctx.attr.context:
         for jar in ctx.attr.context:
-            if hasattr(jar, "java"):
-                transitive_context_libs.append(jar.java.transitive_runtime_deps)
+            if JavaInfo in jar:
+                transitive_context_libs.append(jar[JavaInfo].transitive_runtime_deps)
             elif hasattr(jar, "files"):
                 transitive_context_libs.append(jar.files)
     transitive_context_deps = depset(transitive = transitive_context_libs)
diff --git a/tools/sonar/BUILD b/tools/sonar/BUILD
index 30222ca..06a7cd1 100644
--- a/tools/sonar/BUILD
+++ b/tools/sonar/BUILD
@@ -1,3 +1,5 @@
+load("@rules_python//python:defs.bzl", "py_binary")
+
 package(
     default_visibility = ["//visibility:public"],
 )