#!/usr/bin/python # Copyright (C) 2013 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. # # TODO(sop): Remove hack after Buck supports Eclipse from __future__ import print_function from optparse import OptionParser from os import path from subprocess import Popen, PIPE, CalledProcessError, check_call from xml.dom import minidom import re import sys MAIN = ['//tools/eclipse:classpath'] GWT = ['//gerrit-gwtui:ui_module'] JRE = '/'.join([ 'org.eclipse.jdt.launching.JRE_CONTAINER', 'org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType', 'JavaSE-1.7', ]) ROOT = path.abspath(__file__) while not path.exists(path.join(ROOT, '.buckconfig')): ROOT = path.dirname(ROOT) opts = OptionParser() opts.add_option('--src', action='store_true') opts.add_option('--plugins', help='create eclipse projects for plugins', action='store_true') args, _ = opts.parse_args() def _query_classpath(targets): deps = [] p = Popen(['buck', 'audit', 'classpath'] + targets, stdout=PIPE) for line in p.stdout: deps.append(line.strip()) s = p.wait() if s != 0: exit(s) return deps def gen_project(name='gerrit', root=ROOT): p = path.join(root, '.project') with open(p, 'w') as fd: print("""\ """ + name + """ org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature \ """, file=fd) def gen_plugin_classpath(root): p = path.join(root, '.classpath') with open(p, 'w') as fd: if path.exists(path.join(root, 'src', 'test', 'java')): testpath = """ """ else: testpath = "" print("""\ %(testpath)s """ % {"testpath": testpath}, file=fd) def gen_classpath(): 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) 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() gwt_src = set() gwt_lib = set() plugins = set() java_library = re.compile(r'[^/]+/gen/(.*)/lib__[^/]+__output/[^/]+[.]jar$') for p in _query_classpath(MAIN): if p.endswith('-src.jar'): # gwt_module() depends on -src.jar for Java to JavaScript compiles. gwt_lib.add(p) continue if p.startswith('buck-out/gen/lib/gwt/'): # gwt_module() depends on huge shaded GWT JARs that import # incorrect versions of classes for Gerrit. Collect into # a private grouping for later use. gwt_lib.add(p) continue m = java_library.match(p) if m: src.add(m.group(1)) else: lib.add(p) for p in _query_classpath(GWT): m = java_library.match(p) if m: gwt_src.add(m.group(1)) for s in sorted(src): out = None if s.startswith('lib/'): out = 'buck-out/eclipse/lib' elif s.startswith('plugins/'): if args.plugins: plugins.add(s) continue out = 'buck-out/eclipse/' + s p = path.join(s, 'java') if path.exists(p): classpathentry('src', p, out=out) continue for env in ['main', 'test']: o = None if out: o = out + '/' + env elif env == 'test': o = 'buck-out/eclipse/test' for srctype in ['java', 'resources']: p = path.join(s, 'src', env, srctype) if path.exists(p): classpathentry('src', p, out=o) for libs in [gwt_lib, lib]: for j in sorted(libs): s = None if j.endswith('.jar'): s = j[:-4] + '-src.jar' if not path.exists(s): s = None if args.plugins: classpathentry('lib', j, s, exported=True) else: classpathentry('lib', j, s) for s in sorted(gwt_src): p = path.join(ROOT, s, 'src', 'main', 'java') classpathentry('lib', p, out='buck-out/eclipse/gwtsrc') classpathentry('con', JRE) classpathentry('output', 'buck-out/eclipse/classes') p = 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 = 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(): doc = minidom.getDOMImplementation().createDocument(None, 'factorypath', None) for jar in _query_classpath(['//lib/auto:auto-value']): e = doc.createElement('factorypathentry') e.setAttribute('kind', 'EXTJAR') e.setAttribute('id', path.join(ROOT, jar)) e.setAttribute('enabled', 'true') e.setAttribute('runInBatchMode', 'false') doc.documentElement.appendChild(e) p = path.join(ROOT, '.factorypath') with open(p, 'w') as fd: doc.writexml(fd, addindent='\t', newl='\n', encoding='UTF-8') try: if args.src: try: check_call([path.join(ROOT, 'tools', 'download_all.py'), '--src']) except CalledProcessError as err: exit(1) gen_project() gen_classpath() gen_factorypath() try: targets = ['//tools:buck.properties'] + MAIN + GWT check_call(['buck', 'build'] + targets) except CalledProcessError as err: exit(1) except KeyboardInterrupt: print('Interrupted by user', file=sys.stderr) exit(1)