gerrit/tools/eclipse/project.py
Luca Milanesio 8f11e6c9fc Fix root path resolution for updated Buck
Since the last Buck upgraded this morning with [1]
the root path resolution is broken.

This is due to the different expansion of the __file__
macro into a deeper structure, including the python
relative path name inside a PEX directory structure.

Example:
gerrit/buck-out/bin/tools/maven/mvn.pex/gerrit-extension-api/pom.xml

In order to go back to the root package structure
and locate the pom.xml file correctly, we need now
to go back until the .buckconfig file is found
(instead of going back exactly 3 times as it was before).

P.S. Without this change the targets api_install
     and war_install are broken on master.

Change-Id: I1a99606ad304c245b21ba501f15c473142a89fc2
2014-06-13 07:15:03 +00:00

179 lines
4.7 KiB
Python
Executable File

#!/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')
args, _ = opts.parse_args()
def gen_project():
p = path.join(ROOT, '.project')
with open(p, 'w') as fd:
print("""\
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>gerrit</name>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>\
""", file=fd)
def gen_classpath():
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 make_classpath():
impl = minidom.getDOMImplementation()
return impl.createDocument(None, 'classpath', None)
def classpathentry(kind, path, src=None, out=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)
doc.documentElement.appendChild(e)
doc = make_classpath()
src = set()
lib = set()
gwt_src = set()
gwt_lib = 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/'):
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 [lib, gwt_lib]:
for j in sorted(libs):
s = None
if j.endswith('.jar'):
s = j[:-4] + '-src.jar'
if not path.exists(s):
s = None
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')
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()
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)