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_deploy = //tools/maven:deploy
api_install = //tools/maven:install api_install = //tools/maven:install
docs = //Documentation:html docs = //Documentation:html
download = //tools:download
download_sources = //tools:download_sources
gerrit = //:gerrit gerrit = //:gerrit
eclipse = //tools/eclipse:eclipse
eclipse_project = //tools/eclipse:eclipse_project
release = //:release release = //:release
[buildfile] [buildfile]

View File

@@ -1 +1 @@
5fc60079d9dbaaf8a1e7d542dcb21fd901f68245 4464beabf38ba9c329918b9c7391064bdb2d3fe9

7
BUCK
View File

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

View File

@@ -53,10 +53,10 @@ Eclipse Integration
Generating the Eclipse Project 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 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 Expand the `gerrit` project, right-click on the `buck-out` folder, select
'Properties', and then under 'Attributes' check 'Derived'. 'Properties', and then under 'Attributes' check 'Derived'.
Note that if you make any changes in the project configuration that get Note that if you make any changes in the project configuration
saved to the `.project` file, for example adding Resource Filters on a that get saved to the `.project` file, for example adding Resource
folder, they will be overwritten the next time you run `buck build eclipse`. Filters on a folder, they will be overwritten the next time you run
`tools/eclipse/project.py`.
Refreshing the Classpath Refreshing the Classpath
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
Normally `buck build eclipse` does everything necessary to generate a working Eclipse If an updated classpath is needed, the Eclipse project can be
environment, but if the code doesn't compile and an updated classpath is needed, the refreshed and missing dependency JARs can be downloaded:
Eclipse project can be refreshed and missing dependency JARs can be downloaded by
building the `eclipse_project` and `download` targets:
---- ----
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: 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 Dependency JARs are normally downloaded automatically, but Buck can inspect
its graph and download any missing JAR files. This is useful to enable its graph and download any missing JAR files. This is useful to enable
subsequent builds to run without network access. subsequent builds to run without network access:
Force a download of dependency JARs by building the `download` target:
---- ----
buck build download tools/download_all.py
---- ----
When downloading from behind a proxy (which is common in some corporate 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( python_binary(
name = 'download_file', name = 'download_file',
main = 'download_file.py', main = 'download_file.py',

View File

@@ -1,27 +1,5 @@
include_defs('//tools/build.defs') 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( java_library(
name = 'classpath', name = 'classpath',
deps = LIBS + PGMLIBS + [ deps = LIBS + PGMLIBS + [
@@ -35,37 +13,3 @@ java_library(
'//lib/prolog:compiler_lib', '//lib/prolog:compiler_lib',
] + scan_plugins(), ] + 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 __future__ import print_function
from optparse import OptionParser from optparse import OptionParser
from os import path
from sys import stderr from sys import stderr
from util import check_output from util import check_output
opts = OptionParser() opts = OptionParser()
opts.add_option('--repository', help='maven repository id') opts.add_option('--repository', help='maven repository id')
opts.add_option('--url', help='maven repository url') 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('-a', help='action (valid actions are: install,deploy)')
opts.add_option('-v', help='gerrit version') opts.add_option('-v', help='gerrit version')
opts.add_option('-s', action='append', help='triplet of artifactId:type:path') opts.add_option('-s', action='append', help='triplet of artifactId:type:path')
@@ -35,11 +37,13 @@ common = [
'-Dversion=%s' % args.v, '-Dversion=%s' % args.v,
] ]
self = path.dirname(path.abspath(__file__))
mvn = ['mvn', '--file', path.join(self, 'fake_pom.xml')]
if 'install' == args.a: if 'install' == args.a:
cmd = ['mvn', 'install:install-file'] + common cmd = mvn + ['install:install-file'] + common
elif 'deploy' == args.a: elif 'deploy' == args.a:
cmd = [ cmd = mvn + [
'mvn',
'deploy:deploy-file', 'deploy:deploy-file',
'-DrepositoryId=%s' % args.repository, '-DrepositoryId=%s' % args.repository,
'-Durl=%s' % args.url, '-Durl=%s' % args.url,
@@ -59,3 +63,10 @@ for spec in args.s:
except Exception as e: except Exception as e:
print('%s command failed: %s' % (args.a, e), file=stderr) print('%s command failed: %s' % (args.a, e), file=stderr)
exit(1) 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, url = None,
jar = {}, jar = {},
src = {}): src = {}):
cmd = ['$(exe //tools/maven:mvn)', '-v', version] cmd = ['$(exe //tools/maven:mvn)', '-v', version, '-o', '$OUT']
dep = [] dep = []
for type,d in [('jar', jar), ('java-source', src)]: for type,d in [('jar', jar), ('java-source', src)]:
@@ -30,7 +30,7 @@ def maven_package(
name = 'install', name = 'install',
cmd = ' '.join(cmd + ['-a', 'install']), cmd = ' '.join(cmd + ['-a', 'install']),
deps = dep + ['//tools/maven:mvn'], deps = dep + ['//tools/maven:mvn'],
out = '__fake.install__', out = 'install.info',
) )
if repository and url: if repository and url:
@@ -41,5 +41,5 @@ def maven_package(
'--repository', repository, '--repository', repository,
'--url', url]), '--url', url]),
deps = dep + ['//tools/maven:mvn'], deps = dep + ['//tools/maven:mvn'],
out = '__fake.deploy__', out = 'deploy.info',
) )