Update Buck to latest master

genrule() no longer supports running commands run only for the
side-effect with no output file. Actions like download_sources or
eclipse need to be handled using Python scripts executed from the
user's shell, otherwise Buck fails if caching is enabled.

Change-Id: I361fc20675f211e15e4ab7942ef52778d0a615c2
This commit is contained in:
Shawn Pearce 2013-09-20 10:42:37 -07:00
parent c8f2d3e804
commit a7a3ee1e3a
12 changed files with 197 additions and 263 deletions

View File

@ -3,11 +3,7 @@
api_deploy = //tools/maven:deploy
api_install = //tools/maven:install
docs = //Documentation:html
download = //tools:download
download_sources = //tools:download_sources
gerrit = //:gerrit
eclipse = //tools/eclipse:eclipse
eclipse_project = //tools/eclipse:eclipse_project
release = //:release
[buildfile]

View File

@ -1 +1 @@
5fc60079d9dbaaf8a1e7d542dcb21fd901f68245
4464beabf38ba9c329918b9c7391064bdb2d3fe9

7
BUCK
View File

@ -15,9 +15,12 @@ API_DEPS = [
genrule(
name = 'api',
cmd = '',
cmd = ';'.join(
['cd $TMP'] +
['ln -s $(location %s) .' % n for n in API_DEPS] +
['zip -q0 $OUT *']),
deps = API_DEPS,
out = '__fake.api__',
out = 'api.zip',
)
java_binary(

View File

@ -53,10 +53,10 @@ Eclipse Integration
Generating the Eclipse Project
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Create the Eclipse project by building the `eclipse` target:
Create the Eclipse project:
----
buck build eclipse
tools/eclipse/project.py
----
In Eclipse, choose 'Import existing project' and select the `gerrit` project
@ -65,21 +65,20 @@ from the current working directory.
Expand the `gerrit` project, right-click on the `buck-out` folder, select
'Properties', and then under 'Attributes' check 'Derived'.
Note that if you make any changes in the project configuration that get
saved to the `.project` file, for example adding Resource Filters on a
folder, they will be overwritten the next time you run `buck build eclipse`.
Note that if you make any changes in the project configuration
that get saved to the `.project` file, for example adding Resource
Filters on a folder, they will be overwritten the next time you run
`tools/eclipse/project.py`.
Refreshing the Classpath
~~~~~~~~~~~~~~~~~~~~~~~~
Normally `buck build eclipse` does everything necessary to generate a working Eclipse
environment, but if the code doesn't compile and an updated classpath is needed, the
Eclipse project can be refreshed and missing dependency JARs can be downloaded by
building the `eclipse_project` and `download` targets:
If an updated classpath is needed, the Eclipse project can be
refreshed and missing dependency JARs can be downloaded:
----
buck build eclipse_project download
tools/eclipse/project.py
----
@ -92,7 +91,7 @@ GWT compiler. Additional sources may be obtained, allowing Eclipse to
show documentation or dive into the implementation of a library JAR:
----
buck build download_sources
tools/eclipse/project.py --src
----
@ -250,12 +249,10 @@ Dependencies
Dependency JARs are normally downloaded automatically, but Buck can inspect
its graph and download any missing JAR files. This is useful to enable
subsequent builds to run without network access.
Force a download of dependency JARs by building the `download` target:
subsequent builds to run without network access:
----
buck build download
tools/download_all.py
----
When downloading from behind a proxy (which is common in some corporate

View File

@ -1,22 +1,3 @@
genrule(
name = 'download',
cmd = '$(exe :download_all)',
deps = [':download_all'],
out = '__fake.download__',
)
genrule(
name = 'download_sources',
cmd = '$(exe :download_all) --src',
deps = [':download_all'],
out = '__fake.download__',
)
python_binary(
name = 'download_all',
main = 'download_all.py',
)
python_binary(
name = 'download_file',
main = 'download_file.py',

View File

@ -1,27 +1,5 @@
include_defs('//tools/build.defs')
genrule(
name = 'eclipse',
cmd = '',
deps = [
':_classpath',
':_project',
'//tools:buck.properties',
],
out = '__fake.eclipse__',
)
genrule(
name = 'eclipse_project',
cmd = '',
deps = [
':_classpath_nocompile',
':_project',
'//tools:buck.properties',
],
out = '__fake.eclipse__',
)
java_library(
name = 'classpath',
deps = LIBS + PGMLIBS + [
@ -35,37 +13,3 @@ java_library(
'//lib/prolog:compiler_lib',
] + scan_plugins(),
)
genrule(
name = '_project',
cmd = '$(exe :gen_project)',
deps = [':gen_project'],
out = '__fake.project__',
)
genrule(
name = '_classpath',
cmd = '$(exe :gen_classpath)',
deps = [
':classpath',
':gen_classpath',
],
out = '__fake.classpath__',
)
genrule(
name = '_classpath_nocompile',
cmd = '$(exe :gen_classpath)',
deps = [':gen_classpath'],
out = '__fake.classpath__',
)
python_binary(
name = 'gen_classpath',
main = 'gen_classpath.py',
)
python_binary(
name = 'gen_project',
main = 'gen_project.py',
)

View File

@ -1,118 +0,0 @@
#!/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 os import path
import re
from subprocess import Popen, PIPE
from sys import argv
from xml.dom import minidom
ROOT = path.abspath(__file__)
for _ in range(0, 3):
ROOT = path.dirname(ROOT)
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.6',
])
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)
doc = make_classpath()
src = set()
lib = set()
gwt_src = set()
gwt_lib = set()
def classpathentry(kind, path, src = None):
e = doc.createElement('classpathentry')
e.setAttribute('kind', kind)
e.setAttribute('path', path)
if src:
e.setAttribute('sourcepath', src)
doc.documentElement.appendChild(e)
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):
p = path.join(s, 'java')
if path.exists(p):
classpathentry('src', p)
continue
for env in ['main', 'test']:
for type in ['java', 'resources']:
p = path.join(s, 'src', env, type)
if path.exists(p):
classpathentry('src', p)
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):
classpathentry('lib', path.join(ROOT, s, 'src', 'main', 'java'))
classpathentry('con', JRE)
classpathentry('output', 'buck-out/classes')
p = path.join(ROOT, '.classpath')
with open(p, 'w') as fd:
doc.writexml(fd, addindent = ' ', newl = '\n', encoding='UTF-8')

View File

@ -1,42 +0,0 @@
#!/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 os import path
from sys import argv
ROOT = path.abspath(__file__)
for _ in range(0, 3):
ROOT = path.dirname(ROOT)
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)

156
tools/eclipse/project.py Executable file
View File

@ -0,0 +1,156 @@
#!/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
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.6',
])
ROOT = path.abspath(__file__)
for _ in range(0, 3):
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):
e = doc.createElement('classpathentry')
e.setAttribute('kind', kind)
e.setAttribute('path', path)
if src:
e.setAttribute('sourcepath', src)
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):
p = path.join(s, 'java')
if path.exists(p):
classpathentry('src', p)
continue
for env in ['main', 'test']:
for type in ['java', 'resources']:
p = path.join(s, 'src', env, type)
if path.exists(p):
classpathentry('src', p)
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):
classpathentry('lib', path.join(ROOT, s, 'src', 'main', 'java'))
classpathentry('con', JRE)
classpathentry('output', 'buck-out/classes')
p = path.join(ROOT, '.classpath')
with open(p, 'w') as fd:
doc.writexml(fd, addindent=' ', newl='\n', encoding='UTF-8')
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:
check_call(['buck', 'build'] + MAIN + GWT)
except CalledProcessError as err:
exit(1)

6
tools/maven/fake_pom.xml Normal file
View File

@ -0,0 +1,6 @@
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.gerrit</groupId>
<artifactId>Gerrit-Code-Review-Maven</artifactId>
<version>1</version>
</project>

View File

@ -15,12 +15,14 @@
from __future__ import print_function
from optparse import OptionParser
from os import path
from sys import stderr
from util import check_output
opts = OptionParser()
opts.add_option('--repository', help='maven repository id')
opts.add_option('--url', help='maven repository url')
opts.add_option('-o')
opts.add_option('-a', help='action (valid actions are: install,deploy)')
opts.add_option('-v', help='gerrit version')
opts.add_option('-s', action='append', help='triplet of artifactId:type:path')
@ -35,11 +37,13 @@ common = [
'-Dversion=%s' % args.v,
]
self = path.dirname(path.abspath(__file__))
mvn = ['mvn', '--file', path.join(self, 'fake_pom.xml')]
if 'install' == args.a:
cmd = ['mvn', 'install:install-file'] + common
cmd = mvn + ['install:install-file'] + common
elif 'deploy' == args.a:
cmd = [
'mvn',
cmd = mvn + [
'deploy:deploy-file',
'-DrepositoryId=%s' % args.repository,
'-Durl=%s' % args.url,
@ -59,3 +63,10 @@ for spec in args.s:
except Exception as e:
print('%s command failed: %s' % (args.a, e), file=stderr)
exit(1)
with open(args.o, 'w') as fd:
if args.repository:
print('Repository: %s' % args.repository, file=fd)
if args.url:
print('URL: %s' % args.url, file=fd)
print('Version: %s' % args.v, file=fd)

View File

@ -18,7 +18,7 @@ def maven_package(
url = None,
jar = {},
src = {}):
cmd = ['$(exe //tools/maven:mvn)', '-v', version]
cmd = ['$(exe //tools/maven:mvn)', '-v', version, '-o', '$OUT']
dep = []
for type,d in [('jar', jar), ('java-source', src)]:
@ -30,7 +30,7 @@ def maven_package(
name = 'install',
cmd = ' '.join(cmd + ['-a', 'install']),
deps = dep + ['//tools/maven:mvn'],
out = '__fake.install__',
out = 'install.info',
)
if repository and url:
@ -41,5 +41,5 @@ def maven_package(
'--repository', repository,
'--url', url]),
deps = dep + ['//tools/maven:mvn'],
out = '__fake.deploy__',
out = 'deploy.info',
)