gerrit/tools/bzl/gwt.bzl
David Ostrovsky e51b745efa Bazel: Allow to consume jgit from development tree
Now that Bazel build for JGit is fully implemented, we can document
the process of routing the JGit dependency to the development tree
instead of consuming it from Central or ~/.m2 local repository:

1. Activate local jgit repository in WORKSPACE file:

  local_repository(
      name = "jgit",
      path = "/home/<user>/projects/jgit",
  )

2. Uncomment alias to jgit repository in lib/jgit/**/BUILD files.
It shouldn't be needed and is tracked under this issue upstream: [1]:

  alias(
      name = "jgit-alias",
      actual = select({
          "@//lib:jgit-dev": "@jgit//org.eclipse.jgit:jgit",
          "//conditions:default": "@jgit_lib//jar",
      }),
      visibility = ["//visibility:public"],
  )

Test plan:

Update local JGit tree, run tests and verify that local JGit tree
modifications are relfected in gerrit build:

  $ bazel build --define jgit-dev=1 headless

To consume JGit from Central, do not pass jgit-dev=1:

  $ bazel test ...

[1] https://github.com/bazelbuild/bazel/issues/2707
Change-Id: I1b0fee7df802f6cbd54acbb0bc73157e2b8bc7cf
2017-03-22 22:27:12 +01:00

309 lines
8.0 KiB
Python

# Copyright (C) 2016 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.
# Port of Buck native gwt_binary() rule. See discussion in context of
# https://github.com/facebook/buck/issues/109
load("//tools/bzl:genrule2.bzl", "genrule2")
load("//tools/bzl:java.bzl", "java_library2")
jar_filetype = FileType([".jar"])
BROWSERS = [
"chrome",
"firefox",
"gecko1_8",
"safari",
"msie",
"ie8",
"ie9",
"ie10",
"edge",
]
ALIASES = {
"chrome": "safari",
"firefox": "gecko1_8",
"msie": "ie10",
"edge": "gecko1_8",
}
MODULE = "com.google.gerrit.GerritGwtUI"
GWT_COMPILER = "com.google.gwt.dev.Compiler"
GWT_JVM_ARGS = ["-Xmx512m"]
GWT_COMPILER_ARGS = [
"-XdisableClassMetadata",
]
GWT_COMPILER_ARGS_RELEASE_MODE = GWT_COMPILER_ARGS + [
"-XdisableCastChecking",
]
PLUGIN_DEPS_NEVERLINK = [
"//gerrit-plugin-api:lib-neverlink",
]
GWT_PLUGIN_DEPS_NEVERLINK = [
"//gerrit-plugin-gwtui:gwtui-api-lib-neverlink",
"//lib/gwt:user-neverlink",
]
GWT_PLUGIN_DEPS = [
"//gerrit-plugin-gwtui:gwtui-api-lib",
]
GWT_TRANSITIVE_DEPS = [
"//lib/gwt:ant",
"//lib/gwt:colt",
"//lib/gwt:javax-validation",
"//lib/gwt:javax-validation_src",
"//lib/gwt:jsinterop-annotations",
"//lib/gwt:jsinterop-annotations_src",
"//lib/gwt:tapestry",
"//lib/gwt:w3c-css-sac",
"//lib/ow2:ow2-asm",
"//lib/ow2:ow2-asm-analysis",
"//lib/ow2:ow2-asm-commons",
"//lib/ow2:ow2-asm-tree",
"//lib/ow2:ow2-asm-util",
]
DEPS = GWT_TRANSITIVE_DEPS + [
"//gerrit-gwtexpui:CSS",
"//lib:gwtjsonrpc",
"//lib/gwt:dev",
"//lib/jgit/org.eclipse.jgit:jgit-source",
]
USER_AGENT_XML = """<module rename-to='gerrit_ui'>
<inherits name='%s'/>
<set-property name='user.agent' value='%s'/>
<set-property name='locale' value='default'/>
</module>
"""
def gwt_module(gwt_xml=None, resources=[], srcs=[], **kwargs):
if gwt_xml:
resources += [gwt_xml]
java_library2(
srcs = srcs,
resources = resources,
**kwargs)
def _gwt_user_agent_module(ctx):
"""Generate user agent specific GWT module."""
if not ctx.attr.user_agent:
return None
ua = ctx.attr.user_agent
impl = ua
if ua in ALIASES:
impl = ALIASES[ua]
# intermediate artifact: user agent speific GWT xml file
gwt_user_agent_xml = ctx.new_file(ctx.label.name + "_gwt.xml")
ctx.file_action(output = gwt_user_agent_xml,
content=USER_AGENT_XML % (MODULE, impl))
# intermediate artifact: user agent specific zip with GWT module
gwt_user_agent_zip = ctx.new_file(ctx.label.name + "_gwt.zip")
gwt = '%s_%s.gwt.xml' % (MODULE.replace('.', '/'), ua)
dir = gwt_user_agent_zip.path + ".dir"
cmd = " && ".join([
"p=$PWD",
"mkdir -p %s" % dir,
"cd %s" % dir,
"mkdir -p $(dirname %s)" % gwt,
"cp $p/%s %s" % (gwt_user_agent_xml.path, gwt),
"$p/%s cC $p/%s $(find . | sed 's|^./||')" % (ctx.executable._zip.path, gwt_user_agent_zip.path)
])
ctx.action(
inputs = [gwt_user_agent_xml] + ctx.files._zip,
outputs = [gwt_user_agent_zip],
command = cmd,
mnemonic = "GenerateUserAgentGWTModule")
return struct(
zip=gwt_user_agent_zip,
module=MODULE + '_' + ua
)
def _gwt_binary_impl(ctx):
module = ctx.attr.module[0]
output_zip = ctx.outputs.output
output_dir = output_zip.path + '.gwt_output'
deploy_dir = output_zip.path + '.gwt_deploy'
deps = _get_transitive_closure(ctx)
paths = []
for dep in deps:
paths.append(dep.path)
gwt_user_agent_modules = []
ua = _gwt_user_agent_module(ctx)
if ua:
paths.append(ua.zip.path)
gwt_user_agent_modules.append(ua.zip)
module = ua.module
cmd = "external/local_jdk/bin/java %s -Dgwt.normalizeTimestamps=true -cp %s %s -war %s -deploy %s " % (
" ".join(ctx.attr.jvm_args),
":".join(paths),
GWT_COMPILER,
output_dir,
deploy_dir,
)
# TODO(davido): clean up command concatenation
cmd += " ".join([
"-style %s" % ctx.attr.style,
"-optimize %s" % ctx.attr.optimize,
"-strict",
" ".join(ctx.attr.compiler_args),
module + "\n",
"rm -rf %s/gwt-unitCache\n" % output_dir,
"root=`pwd`\n",
"cd %s; $root/%s Cc ../%s $(find .)\n" % (
output_dir,
ctx.executable._zip.path,
output_zip.basename,
)
])
ctx.action(
inputs = list(deps) + ctx.files._jdk + ctx.files._zip + gwt_user_agent_modules,
outputs = [output_zip],
mnemonic = "GwtBinary",
progress_message = "GWT compiling " + output_zip.short_path,
command = "set -e\n" + cmd,
)
def _get_transitive_closure(ctx):
deps = set()
for dep in ctx.attr.module_deps:
deps += dep.java.transitive_runtime_deps
deps += dep.java.transitive_source_jars
for dep in ctx.attr.deps:
if hasattr(dep, 'java'):
deps += dep.java.transitive_runtime_deps
elif hasattr(dep, 'files'):
deps += dep.files
return deps
gwt_binary = rule(
attrs = {
"user_agent": attr.string(),
"style": attr.string(default = "OBF"),
"optimize": attr.string(default = "9"),
"deps": attr.label_list(allow_files = jar_filetype),
"module": attr.string_list(default = [MODULE]),
"module_deps": attr.label_list(allow_files = jar_filetype),
"compiler_args": attr.string_list(),
"jvm_args": attr.string_list(),
"_jdk": attr.label(
default = Label("//tools/defaults:jdk"),
),
"_zip": attr.label(
default = Label("@bazel_tools//tools/zip:zipper"),
cfg = "host",
executable = True,
single_file = True,
),
},
outputs = {
"output": "%{name}.zip",
},
implementation = _gwt_binary_impl,
)
def gwt_genrule(suffix = ""):
dbg = 'ui_dbg' + suffix
opt = 'ui_opt' + suffix
module_dep = ':ui_module' + suffix
args = GWT_COMPILER_ARGS_RELEASE_MODE if suffix == "_r" else GWT_COMPILER_ARGS
genrule2(
name = 'ui_optdbg' + suffix,
srcs = [
':' + dbg,
':' + opt,
],
cmd = 'cd $$TMP;' +
'unzip -q $$ROOT/$(location :%s);' % dbg +
'mv' +
' gerrit_ui/gerrit_ui.nocache.js' +
' gerrit_ui/dbg_gerrit_ui.nocache.js;' +
'unzip -qo $$ROOT/$(location :%s);' % opt +
'mkdir -p $$(dirname $@);' +
'zip -qrD $$ROOT/$@ .',
outs = ['ui_optdbg' + suffix + '.zip'],
visibility = ['//visibility:public'],
)
gwt_binary(
name = opt,
module = [MODULE],
module_deps = [module_dep],
deps = DEPS,
compiler_args = args,
jvm_args = GWT_JVM_ARGS,
)
gwt_binary(
name = dbg,
style = 'PRETTY',
optimize = "0",
module_deps = [module_dep],
deps = DEPS,
compiler_args = GWT_COMPILER_ARGS,
jvm_args = GWT_JVM_ARGS,
)
def gen_ui_module(name, suffix = ""):
gwt_module(
name = name + suffix,
srcs = native.glob(['src/main/java/**/*.java']),
gwt_xml = 'src/main/java/%s.gwt.xml' % MODULE.replace('.', '/'),
resources = native.glob(
['src/main/java/**/*'],
exclude = ['src/main/java/**/*.java'] +
['src/main/java/%s.gwt.xml' % MODULE.replace('.', '/')]),
deps = [
'//gerrit-gwtui-common:diffy_logo',
'//gerrit-gwtui-common:client',
'//gerrit-gwtexpui:CSS',
'//lib/codemirror:codemirror' + suffix,
'//lib/gwt:user',
],
visibility = ['//visibility:public'],
)
def gwt_user_agent_permutations():
for ua in BROWSERS:
gwt_binary(
name = "ui_%s" % ua,
user_agent = ua,
style = 'PRETTY',
optimize = "0",
module = [MODULE],
module_deps = [':ui_module'],
deps = DEPS,
compiler_args = GWT_COMPILER_ARGS,
jvm_args = GWT_JVM_ARGS,
)