blob: 0cc2988de60c6752f244abeb031c40a6287d497b [file] [log] [blame]
# 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",
]
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 = 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.actions.run_shell(
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.actions.run_shell(
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 = depset()
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,
)