blob: 9ae5cd735fb8f666da4740d352c5c65e3b16452e [file] [log] [blame]
#!/usr/bin/env python
# Copyright (C) 2017 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
# TODO(davido): use Google style for importing instead:
import argparse
from os import path
from subprocess import CalledProcessError, check_call, check_output
from xml.dom import minidom
import re
import sys
JRE = '/'.join([
'org.eclipse.jdt.launching.JRE_CONTAINER',
'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType',
'JavaSE-1.8',
])
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')
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)
batch_option = '--batch' if args.batch else None
def _build_bazel_cmd(*args):
cmd = ['bazel']
if batch_option:
cmd.append('--batch')
for arg in args:
cmd.append(arg)
return cmd
def retrieve_ext_location():
return 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:
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')
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_classpath(ext):
def make_classpath():
impl = minidom.getDOMImplementation()
return impl.createDocument(None, 'classpath', None)
def classpathentry(kind, path, src=None, out=None, exported=None):
e = doc.createElement('classpathentry')
e.setAttribute('kind', kind)
# TODO(davido): Remove this and other exclude BUILD files hack
# when this Bazel bug is fixed:
# https://github.com/bazelbuild/bazel/issues/1083
if kind == 'src':
e.setAttribute('excluding', '**/BUILD')
e.setAttribute('path', path)
if src:
e.setAttribute('sourcepath', src)
if out:
e.setAttribute('output', out)
if exported:
e.setAttribute('exported', 'true')
doc.documentElement.appendChild(e)
doc = make_classpath()
src = set()
lib = set()
java_library = re.compile('bazel-out/(?:.*)-fastbuild/bin(.*)/[^/]+[.]jar$')
srcs = re.compile('(.*/external/[^/]+)/jar/(.*)[.]jar')
for p in _query_classpath():
m = java_library.match(p)
if m:
src.add(m.group(1).lstrip('/'))
else:
if p.startswith("external"):
p = path.join(ext, p)
lib.add(p)
src_paths = {}
for s in sorted(src):
out = None
if s.startswith('lib/'):
out = 'eclipse-out/lib'
p = path.join(s, 'java')
if path.exists(p):
classpathentry('src', p, out=out)
continue
for env in ['main', 'test', 'java', 'javatests']:
o = None
if out:
o = out + '/' + env
elif env == 'test' or env == 'javatests':
o = 'eclipse-out/test'
if s.startswith(env + '/'):
src_paths[env] = o
continue
for srctype in ['java', 'resources']:
p = path.join(s, 'src', env, srctype)
if path.exists(p):
src_paths[p] = o
for s in src_paths:
classpathentry('src', s, out=src_paths[s])
for libs in [lib]:
for j in sorted(libs):
if excluded(j):
continue
s = None
m = srcs.match(j)
if m:
prefix = m.group(1)
suffix = m.group(2)
p = path.join(prefix, "src", "%s-src.jar" % suffix)
if path.exists(p):
s = p
classpathentry('lib', j, s)
classpathentry('con', JRE)
classpathentry('output', 'eclipse-out/classes')
p = path.join(ROOT, '.classpath')
with open(p, 'w') as fd:
doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8')
def excluded(lib):
if args.exclude:
for x in args.exclude:
if x in lib:
return True
return False
try:
name = args.name if args.name else path.basename(ROOT)
gen_project(name)
gen_classpath(retrieve_ext_location().decode('utf-8'))
except KeyboardInterrupt:
print('Interrupted by user', file=sys.stderr)
exit(1)