
This is the second attempt to build JGit from the source using git submodule approach. The first attempt that was abandoned is here: [1]. Using a submodule to bring in the source files vastly simplifies updating JGit. Gerrit developers can bump the SHA-1 of the submodule and not deal with the Maven rebuild process for JGit. This change updates JGit dependency from 5.4.3.201909031940-r to commit 009e07882fee2b0ad2ebe7ba44e2ff52c101f858, and Javadoc version from: 5.4.3.201909031940-r to 5.5.0.201909110433-r. To bump to new Javadoc API _DOC_VERS should be updated in java/com/google/gerrit/extensions/BUILD to point to the desired JGit Javadoc release. JGit sources are imported in Eclipse as source folders. One side effect of this change is that the source code warnings for JGit project are now shown. [1] https://gerrit-review.googlesource.com/c/gerrit/+/61892 Feature: Issue 11737 Change-Id: I16370e57f27e26b2382243ca448484f53dfa96bb
362 lines
13 KiB
Python
Executable File
362 lines
13 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# 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.
|
|
|
|
from __future__ import print_function
|
|
import argparse
|
|
import os
|
|
import subprocess
|
|
import xml.dom.minidom
|
|
import re
|
|
import sys
|
|
|
|
MAIN = '//tools/eclipse:classpath'
|
|
AUTO = '//lib/auto:auto-value'
|
|
JRE = '/'.join([
|
|
'org.eclipse.jdt.launching.JRE_CONTAINER',
|
|
'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
|
|
'JavaSE-1.8',
|
|
])
|
|
# Map of targets to corresponding classpath collector rules
|
|
cp_targets = {
|
|
AUTO: '//tools/eclipse:autovalue_classpath_collect',
|
|
MAIN: '//tools/eclipse:main_classpath_collect',
|
|
}
|
|
|
|
ROOT = os.path.abspath(__file__)
|
|
while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
|
|
ROOT = os.path.dirname(ROOT)
|
|
|
|
opts = argparse.ArgumentParser("Create Eclipse Project")
|
|
opts.add_argument('--plugins', help='create eclipse projects for plugins',
|
|
action='store_true')
|
|
opts.add_argument('--name', help='name of the generated project',
|
|
action='store', default='gerrit', dest='project_name')
|
|
opts.add_argument('-b', '--batch', action='store_true',
|
|
dest='batch', help='Bazel batch option')
|
|
opts.add_argument('-j', '--java', action='store',
|
|
dest='java', help='Post Java 8 support (9)')
|
|
opts.add_argument('-e', '--edge_java', action='store',
|
|
dest='edge_java', help='Post Java 9 support (10|11|...)')
|
|
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()
|
|
|
|
|
|
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)
|
|
|
|
|
|
batch_option = '--batch' if args.batch else None
|
|
custom_java = args.java
|
|
edge_java = args.edge_java
|
|
bazel_exe = find_bazel()
|
|
|
|
|
|
def _build_bazel_cmd(*args):
|
|
build = False
|
|
cmd = [bazel_exe]
|
|
if batch_option:
|
|
cmd.append('--batch')
|
|
for arg in args:
|
|
if arg == "build":
|
|
build = True
|
|
cmd.append(arg)
|
|
if custom_java and not edge_java:
|
|
cmd.append('--host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java)
|
|
cmd.append('--java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java)
|
|
if edge_java and build:
|
|
cmd.append(edge_java)
|
|
return cmd
|
|
|
|
|
|
def retrieve_ext_location():
|
|
return subprocess.check_output(_build_bazel_cmd('info', 'output_base')).strip()
|
|
|
|
|
|
def gen_bazel_path(ext_location):
|
|
bazel = subprocess.check_output(['which', bazel_exe]).strip().decode('UTF-8')
|
|
with open(os.path.join(ROOT, ".bazel_path"), 'w') as fd:
|
|
fd.write("output_base=%s\n" % ext_location)
|
|
fd.write("bazel=%s\n" % bazel)
|
|
fd.write("PATH=%s\n" % os.environ["PATH"])
|
|
|
|
|
|
def _query_classpath(target):
|
|
deps = []
|
|
t = cp_targets[target]
|
|
try:
|
|
subprocess.check_call(_build_bazel_cmd('build', t))
|
|
except subprocess.CalledProcessError:
|
|
exit(1)
|
|
name = 'bazel-bin/tools/eclipse/' + t.split(':')[1] + '.runtime_classpath'
|
|
deps = [line.rstrip('\n') for line in open(name)]
|
|
return deps
|
|
|
|
|
|
def gen_project(name='gerrit', root=ROOT):
|
|
p = os.path.join(root, '.project')
|
|
with open(p, 'w') as fd:
|
|
print("""\
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<projectDescription>
|
|
<name>%(name)s</name>
|
|
<buildSpec>
|
|
<buildCommand>
|
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
|
</buildCommand>
|
|
</buildSpec>
|
|
<natures>
|
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
|
</natures>
|
|
</projectDescription>\
|
|
""" % {"name": name}, file=fd)
|
|
|
|
|
|
def gen_plugin_classpath(root):
|
|
p = os.path.join(root, '.classpath')
|
|
with open(p, 'w') as fd:
|
|
if os.path.exists(os.path.join(root, 'src', 'test', 'java')):
|
|
testpath = """
|
|
<classpathentry excluding="**/BUILD" kind="src" path="src/test/java"\
|
|
out="eclipse-out/test">
|
|
<attributes><attribute name="test" value="true"/></attributes>
|
|
</classpathentry>"""
|
|
else:
|
|
testpath = ""
|
|
print("""\
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<classpath>
|
|
<classpathentry excluding="**/BUILD" kind="src" path="src/main/java"/>%(testpath)s
|
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
|
<classpathentry combineaccessrules="false" kind="src" path="/gerrit"/>
|
|
<classpathentry kind="output" path="eclipse-out/classes"/>
|
|
</classpath>""" % {"testpath": testpath}, file=fd)
|
|
|
|
|
|
def gen_classpath(ext):
|
|
def make_classpath():
|
|
impl = xml.dom.minidom.getDOMImplementation()
|
|
return impl.createDocument(None, 'classpath', None)
|
|
|
|
def import_jgit_sources():
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit/src')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit/resources')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit.archive/src',
|
|
excluding='org/eclipse/jgit/archive/FormatActivator.java')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit.archive/resources')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit.http.server/src')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit.http.server/resources')
|
|
classpathentry('src', 'modules/jgit/org.eclipse.jgit.junit/src')
|
|
|
|
def classpathentry(kind, path, src=None, out=None, exported=None, excluding=None):
|
|
e = doc.createElement('classpathentry')
|
|
e.setAttribute('kind', kind)
|
|
# Excluding the BUILD file, to avoid the Eclipse warnings:
|
|
# "The resource is a duplicate of ..."
|
|
if kind == 'src':
|
|
e.setAttribute('excluding', '**/BUILD' if not excluding else excluding)
|
|
e.setAttribute('path', path)
|
|
if src:
|
|
e.setAttribute('sourcepath', src)
|
|
if out:
|
|
e.setAttribute('output', out)
|
|
if exported:
|
|
e.setAttribute('exported', 'true')
|
|
atts = None
|
|
if out and "test" in out:
|
|
atts = doc.createElement('attributes')
|
|
testAtt = doc.createElement('attribute')
|
|
testAtt.setAttribute('name', 'test')
|
|
testAtt.setAttribute('value', 'true')
|
|
atts.appendChild(testAtt)
|
|
if "apt_generated" in path:
|
|
if not atts:
|
|
atts = doc.createElement('attributes')
|
|
ignoreOptionalProblems = doc.createElement('attribute')
|
|
ignoreOptionalProblems.setAttribute('name', 'ignore_optional_problems')
|
|
ignoreOptionalProblems.setAttribute('value', 'true')
|
|
atts.appendChild(ignoreOptionalProblems)
|
|
optional = doc.createElement('attribute')
|
|
optional.setAttribute('name', 'optional')
|
|
optional.setAttribute('value', 'true')
|
|
atts.appendChild(optional)
|
|
if atts:
|
|
e.appendChild(atts)
|
|
doc.documentElement.appendChild(e)
|
|
|
|
doc = make_classpath()
|
|
src = set()
|
|
lib = set()
|
|
proto = set()
|
|
plugins = set()
|
|
|
|
# Classpath entries are absolute for cross-cell support
|
|
java_library = re.compile('bazel-out/.*?-fastbuild/bin/(.*)/[^/]+[.]jar$')
|
|
proto_library = re.compile('bazel-out/.*?-fastbuild/bin/(.*)proto/(.*)_proto-speed[.]jar$')
|
|
srcs = re.compile('(.*/external/[^/]+)/jar/(.*)[.]jar')
|
|
for p in _query_classpath(MAIN):
|
|
if p.endswith('-src.jar'):
|
|
continue
|
|
|
|
m = java_library.match(p)
|
|
if m:
|
|
src.add(m.group(1))
|
|
# Exceptions: both source and lib
|
|
if p.endswith('libquery_parser.jar') or \
|
|
p.endswith('libgerrit-prolog-common.jar') or \
|
|
p.endswith('com_google_protobuf/libprotobuf_java.jar') or \
|
|
p.endswith('lucene-core-and-backward-codecs__merged.jar'):
|
|
lib.add(p)
|
|
if proto_library.match(p) :
|
|
proto.add(p)
|
|
else:
|
|
# Don't mess up with Bazel internal test runner dependencies.
|
|
# When we use Eclipse we rely on it for running the tests
|
|
if p.endswith(
|
|
"external/bazel_tools/tools/jdk/TestRunner_deploy.jar"):
|
|
continue
|
|
if p.startswith("external"):
|
|
p = os.path.join(ext, p)
|
|
lib.add(p)
|
|
|
|
classpathentry('src', 'java')
|
|
classpathentry('src', 'javatests', out='eclipse-out/test')
|
|
classpathentry('src', 'resources')
|
|
import_jgit_sources()
|
|
for s in sorted(src):
|
|
out = None
|
|
|
|
if s.startswith('lib/'):
|
|
out = 'eclipse-out/lib'
|
|
elif s.startswith('plugins/'):
|
|
if args.plugins:
|
|
plugins.add(s)
|
|
continue
|
|
out = 'eclipse-out/' + s
|
|
|
|
p = os.path.join(s, 'java')
|
|
if os.path.exists(p):
|
|
classpathentry('src', p, out=out + '/main')
|
|
p = os.path.join(s, 'javatests')
|
|
if os.path.exists(p):
|
|
classpathentry('src', p, out=out + '/test')
|
|
continue
|
|
|
|
for env in ['main', 'test']:
|
|
o = None
|
|
if out:
|
|
o = out + '/' + env
|
|
elif env == 'test':
|
|
o = 'eclipse-out/test'
|
|
|
|
for srctype in ['java', 'resources']:
|
|
p = os.path.join(s, 'src', env, srctype)
|
|
if os.path.exists(p):
|
|
classpathentry('src', p, out=o)
|
|
|
|
for libs in [lib]:
|
|
for j in sorted(libs):
|
|
s = None
|
|
m = srcs.match(j)
|
|
if m:
|
|
prefix = m.group(1)
|
|
suffix = m.group(2)
|
|
p = os.path.join(prefix, "jar", "%s-src.jar" % suffix)
|
|
if os.path.exists(p):
|
|
s = p
|
|
if args.plugins:
|
|
classpathentry('lib', j, s, exported=True)
|
|
else:
|
|
classpathentry('lib', j, s)
|
|
|
|
for p in sorted(proto):
|
|
s = p.replace('/proto/lib', '/proto/')
|
|
s = s.replace('/proto/testing/lib', '/proto/testing/')
|
|
s = s.replace('.jar', '-src.jar')
|
|
classpathentry('lib', p, s)
|
|
|
|
classpathentry('con', JRE)
|
|
classpathentry('output', 'eclipse-out/classes')
|
|
classpathentry('src', '.apt_generated')
|
|
classpathentry('src', '.apt_generated_tests', out="eclipse-out/test")
|
|
|
|
p = os.path.join(ROOT, '.classpath')
|
|
with open(p, 'w') as fd:
|
|
doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
|
|
|
|
if args.plugins:
|
|
for plugin in plugins:
|
|
plugindir = os.path.join(ROOT, plugin)
|
|
try:
|
|
gen_project(plugin.replace('plugins/', ""), plugindir)
|
|
gen_plugin_classpath(plugindir)
|
|
except (IOError, OSError) as err:
|
|
print('error generating project for %s: %s' % (plugin, err),
|
|
file=sys.stderr)
|
|
|
|
|
|
def gen_factorypath(ext):
|
|
doc = xml.dom.minidom.getDOMImplementation().createDocument(
|
|
None, 'factorypath', None)
|
|
for jar in _query_classpath(AUTO):
|
|
e = doc.createElement('factorypathentry')
|
|
e.setAttribute('kind', 'EXTJAR')
|
|
e.setAttribute('id', os.path.join(ext, jar))
|
|
e.setAttribute('enabled', 'true')
|
|
e.setAttribute('runInBatchMode', 'false')
|
|
doc.documentElement.appendChild(e)
|
|
|
|
p = os.path.join(ROOT, '.factorypath')
|
|
with open(p, 'w') as fd:
|
|
doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
|
|
|
|
|
|
try:
|
|
ext_location = retrieve_ext_location().decode("utf-8")
|
|
gen_project(args.project_name)
|
|
gen_classpath(ext_location)
|
|
gen_factorypath(ext_location)
|
|
gen_bazel_path(ext_location)
|
|
|
|
try:
|
|
subprocess.check_call(_build_bazel_cmd('build', MAIN))
|
|
except subprocess.CalledProcessError:
|
|
exit(1)
|
|
except KeyboardInterrupt:
|
|
print('Interrupted by user', file=sys.stderr)
|
|
exit(1)
|