blob: deeb5d58dd36a1444d756fc28072315462d7a914 [file] [log] [blame]
David Ostrovskyb81b4f72016-05-21 19:55:01 +02001# Copyright (C) 2016 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
David Ostrovsky13a2fc42016-10-30 23:43:42 +010015# Port of Buck native gwt_binary() rule. See discussion in context of
16# https://github.com/facebook/buck/issues/109
David Pursehouse2d085002016-12-11 19:00:10 +090017load("//tools/bzl:genrule2.bzl", "genrule2")
18load("//tools/bzl:java.bzl", "java_library2")
David Ostrovskyb81b4f72016-05-21 19:55:01 +020019
David Pursehouse2d085002016-12-11 19:00:10 +090020jar_filetype = FileType([".jar"])
David Ostrovskyef227122016-11-02 08:14:52 +010021
David Ostrovsky13a2fc42016-10-30 23:43:42 +010022BROWSERS = [
David Pursehouse2d085002016-12-11 19:00:10 +090023 "chrome",
24 "firefox",
25 "gecko1_8",
26 "safari",
27 "msie",
28 "ie8",
29 "ie9",
30 "ie10",
31 "edge",
David Ostrovsky13a2fc42016-10-30 23:43:42 +010032]
David Pursehouse2d085002016-12-11 19:00:10 +090033
David Ostrovsky13a2fc42016-10-30 23:43:42 +010034ALIASES = {
David Pursehouse2d085002016-12-11 19:00:10 +090035 "chrome": "safari",
36 "firefox": "gecko1_8",
37 "msie": "ie10",
38 "edge": "gecko1_8",
David Ostrovsky13a2fc42016-10-30 23:43:42 +010039}
40
David Pursehouse2d085002016-12-11 19:00:10 +090041MODULE = "com.google.gerrit.GerritGwtUI"
David Ostrovskyef227122016-11-02 08:14:52 +010042
43GWT_COMPILER = "com.google.gwt.dev.Compiler"
44
David Pursehouse2d085002016-12-11 19:00:10 +090045GWT_JVM_ARGS = ["-Xmx512m"]
David Ostrovskyef227122016-11-02 08:14:52 +010046
47GWT_COMPILER_ARGS = [
David Pursehouse2d085002016-12-11 19:00:10 +090048 "-XdisableClassMetadata",
David Ostrovskyef227122016-11-02 08:14:52 +010049]
50
51GWT_COMPILER_ARGS_RELEASE_MODE = GWT_COMPILER_ARGS + [
David Pursehouse2d085002016-12-11 19:00:10 +090052 "-XdisableCastChecking",
David Ostrovskyef227122016-11-02 08:14:52 +010053]
54
David Ostrovsky2502fab2016-11-15 14:30:26 -080055PLUGIN_DEPS_NEVERLINK = [
David Pursehouse2d085002016-12-11 19:00:10 +090056 "//gerrit-plugin-api:lib-neverlink",
David Ostrovsky2502fab2016-11-15 14:30:26 -080057]
58
59GWT_PLUGIN_DEPS_NEVERLINK = [
David Pursehouse2d085002016-12-11 19:00:10 +090060 "//gerrit-plugin-gwtui:gwtui-api-lib-neverlink",
61 "//lib/gwt:user-neverlink",
David Ostrovsky2502fab2016-11-15 14:30:26 -080062]
63
64GWT_PLUGIN_DEPS = [
David Pursehouse2d085002016-12-11 19:00:10 +090065 "//gerrit-plugin-gwtui:gwtui-api-lib",
David Ostrovsky2502fab2016-11-15 14:30:26 -080066]
67
David Ostrovskyef227122016-11-02 08:14:52 +010068GWT_TRANSITIVE_DEPS = [
David Pursehouse2d085002016-12-11 19:00:10 +090069 "//lib/gwt:ant",
70 "//lib/gwt:colt",
71 "//lib/gwt:javax-validation",
72 "//lib/gwt:javax-validation_src",
73 "//lib/gwt:jsinterop-annotations",
74 "//lib/gwt:jsinterop-annotations_src",
75 "//lib/gwt:tapestry",
76 "//lib/gwt:w3c-css-sac",
77 "//lib/ow2:ow2-asm",
78 "//lib/ow2:ow2-asm-analysis",
79 "//lib/ow2:ow2-asm-commons",
80 "//lib/ow2:ow2-asm-tree",
81 "//lib/ow2:ow2-asm-util",
David Ostrovskyef227122016-11-02 08:14:52 +010082]
83
84DEPS = GWT_TRANSITIVE_DEPS + [
David Pursehouse2d085002016-12-11 19:00:10 +090085 "//gerrit-gwtexpui:CSS",
86 "//lib:gwtjsonrpc",
87 "//lib/gwt:dev",
David Ostrovskye51b7452016-11-06 18:07:10 +010088 "//lib/jgit/org.eclipse.jgit:jgit-source",
David Ostrovskyef227122016-11-02 08:14:52 +010089]
90
David Ostrovsky13a2fc42016-10-30 23:43:42 +010091USER_AGENT_XML = """<module rename-to='gerrit_ui'>
92<inherits name='%s'/>
93<set-property name='user.agent' value='%s'/>
94<set-property name='locale' value='default'/>
95</module>
96"""
97
David Ostrovskyb81b4f72016-05-21 19:55:01 +020098def gwt_module(gwt_xml=None, resources=[], srcs=[], **kwargs):
99 if gwt_xml:
100 resources += [gwt_xml]
David Ostrovskyb81b4f72016-05-21 19:55:01 +0200101
102 java_library2(
103 srcs = srcs,
104 resources = resources,
105 **kwargs)
David Ostrovskyef227122016-11-02 08:14:52 +0100106
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100107def _gwt_user_agent_module(ctx):
108 """Generate user agent specific GWT module."""
109 if not ctx.attr.user_agent:
110 return None
111
112 ua = ctx.attr.user_agent
113 impl = ua
114 if ua in ALIASES:
115 impl = ALIASES[ua]
116
117 # intermediate artifact: user agent speific GWT xml file
118 gwt_user_agent_xml = ctx.new_file(ctx.label.name + "_gwt.xml")
119 ctx.file_action(output = gwt_user_agent_xml,
120 content=USER_AGENT_XML % (MODULE, impl))
121
122 # intermediate artifact: user agent specific zip with GWT module
123 gwt_user_agent_zip = ctx.new_file(ctx.label.name + "_gwt.zip")
124 gwt = '%s_%s.gwt.xml' % (MODULE.replace('.', '/'), ua)
125 dir = gwt_user_agent_zip.path + ".dir"
126 cmd = " && ".join([
127 "p=$PWD",
128 "mkdir -p %s" % dir,
129 "cd %s" % dir,
130 "mkdir -p $(dirname %s)" % gwt,
131 "cp $p/%s %s" % (gwt_user_agent_xml.path, gwt),
132 "$p/%s cC $p/%s $(find . | sed 's|^./||')" % (ctx.executable._zip.path, gwt_user_agent_zip.path)
133 ])
134 ctx.action(
135 inputs = [gwt_user_agent_xml] + ctx.files._zip,
136 outputs = [gwt_user_agent_zip],
137 command = cmd,
138 mnemonic = "GenerateUserAgentGWTModule")
139
140 return struct(
141 zip=gwt_user_agent_zip,
142 module=MODULE + '_' + ua
143 )
144
145def _gwt_binary_impl(ctx):
David Ostrovsky2502fab2016-11-15 14:30:26 -0800146 module = ctx.attr.module[0]
David Ostrovskyef227122016-11-02 08:14:52 +0100147 output_zip = ctx.outputs.output
148 output_dir = output_zip.path + '.gwt_output'
149 deploy_dir = output_zip.path + '.gwt_deploy'
150
151 deps = _get_transitive_closure(ctx)
152
153 paths = []
154 for dep in deps:
155 paths.append(dep.path)
156
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100157 gwt_user_agent_modules = []
158 ua = _gwt_user_agent_module(ctx)
159 if ua:
160 paths.append(ua.zip.path)
161 gwt_user_agent_modules.append(ua.zip)
162 module = ua.module
163
David Ostrovskyef227122016-11-02 08:14:52 +0100164 cmd = "external/local_jdk/bin/java %s -Dgwt.normalizeTimestamps=true -cp %s %s -war %s -deploy %s " % (
165 " ".join(ctx.attr.jvm_args),
166 ":".join(paths),
167 GWT_COMPILER,
168 output_dir,
169 deploy_dir,
170 )
171 # TODO(davido): clean up command concatenation
172 cmd += " ".join([
173 "-style %s" % ctx.attr.style,
174 "-optimize %s" % ctx.attr.optimize,
175 "-strict",
176 " ".join(ctx.attr.compiler_args),
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100177 module + "\n",
David Ostrovskyef227122016-11-02 08:14:52 +0100178 "rm -rf %s/gwt-unitCache\n" % output_dir,
179 "root=`pwd`\n",
180 "cd %s; $root/%s Cc ../%s $(find .)\n" % (
181 output_dir,
182 ctx.executable._zip.path,
183 output_zip.basename,
184 )
185 ])
186
187 ctx.action(
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100188 inputs = list(deps) + ctx.files._jdk + ctx.files._zip + gwt_user_agent_modules,
David Ostrovskyef227122016-11-02 08:14:52 +0100189 outputs = [output_zip],
190 mnemonic = "GwtBinary",
191 progress_message = "GWT compiling " + output_zip.short_path,
192 command = "set -e\n" + cmd,
193 )
194
195def _get_transitive_closure(ctx):
196 deps = set()
197 for dep in ctx.attr.module_deps:
198 deps += dep.java.transitive_runtime_deps
199 deps += dep.java.transitive_source_jars
200 for dep in ctx.attr.deps:
201 if hasattr(dep, 'java'):
202 deps += dep.java.transitive_runtime_deps
203 elif hasattr(dep, 'files'):
204 deps += dep.files
205
206 return deps
207
208gwt_binary = rule(
David Pursehouse2d085002016-12-11 19:00:10 +0900209 attrs = {
210 "user_agent": attr.string(),
211 "style": attr.string(default = "OBF"),
212 "optimize": attr.string(default = "9"),
213 "deps": attr.label_list(allow_files = jar_filetype),
214 "module": attr.string_list(default = [MODULE]),
215 "module_deps": attr.label_list(allow_files = jar_filetype),
216 "compiler_args": attr.string_list(),
217 "jvm_args": attr.string_list(),
218 "_jdk": attr.label(
219 default = Label("//tools/defaults:jdk"),
220 ),
221 "_zip": attr.label(
222 default = Label("@bazel_tools//tools/zip:zipper"),
223 cfg = "host",
224 executable = True,
225 single_file = True,
226 ),
227 },
228 outputs = {
229 "output": "%{name}.zip",
230 },
231 implementation = _gwt_binary_impl,
David Ostrovskyef227122016-11-02 08:14:52 +0100232)
233
234def gwt_genrule(suffix = ""):
235 dbg = 'ui_dbg' + suffix
236 opt = 'ui_opt' + suffix
237 module_dep = ':ui_module' + suffix
238 args = GWT_COMPILER_ARGS_RELEASE_MODE if suffix == "_r" else GWT_COMPILER_ARGS
239
240 genrule2(
241 name = 'ui_optdbg' + suffix,
242 srcs = [
243 ':' + dbg,
244 ':' + opt,
245 ],
246 cmd = 'cd $$TMP;' +
247 'unzip -q $$ROOT/$(location :%s);' % dbg +
248 'mv' +
249 ' gerrit_ui/gerrit_ui.nocache.js' +
250 ' gerrit_ui/dbg_gerrit_ui.nocache.js;' +
251 'unzip -qo $$ROOT/$(location :%s);' % opt +
252 'mkdir -p $$(dirname $@);' +
Dave Borowitz68ea4b02016-12-20 11:30:46 -0500253 'zip -qrD $$ROOT/$@ .',
David Ostrovsky96edab22016-11-03 22:47:21 +0100254 outs = ['ui_optdbg' + suffix + '.zip'],
David Ostrovskyef227122016-11-02 08:14:52 +0100255 visibility = ['//visibility:public'],
256 )
257
258 gwt_binary(
259 name = opt,
David Ostrovsky2502fab2016-11-15 14:30:26 -0800260 module = [MODULE],
David Ostrovskyef227122016-11-02 08:14:52 +0100261 module_deps = [module_dep],
262 deps = DEPS,
263 compiler_args = args,
264 jvm_args = GWT_JVM_ARGS,
265 )
266
267 gwt_binary(
268 name = dbg,
David Ostrovskyef227122016-11-02 08:14:52 +0100269 style = 'PRETTY',
270 optimize = "0",
271 module_deps = [module_dep],
272 deps = DEPS,
273 compiler_args = GWT_COMPILER_ARGS,
274 jvm_args = GWT_JVM_ARGS,
275 )
276
277def gen_ui_module(name, suffix = ""):
278 gwt_module(
279 name = name + suffix,
280 srcs = native.glob(['src/main/java/**/*.java']),
281 gwt_xml = 'src/main/java/%s.gwt.xml' % MODULE.replace('.', '/'),
282 resources = native.glob(
283 ['src/main/java/**/*'],
284 exclude = ['src/main/java/**/*.java'] +
285 ['src/main/java/%s.gwt.xml' % MODULE.replace('.', '/')]),
286 deps = [
287 '//gerrit-gwtui-common:diffy_logo',
288 '//gerrit-gwtui-common:client',
289 '//gerrit-gwtexpui:CSS',
290 '//lib/codemirror:codemirror' + suffix,
291 '//lib/gwt:user',
292 ],
293 visibility = ['//visibility:public'],
294 )
295
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100296def gwt_user_agent_permutations():
297 for ua in BROWSERS:
298 gwt_binary(
299 name = "ui_%s" % ua,
300 user_agent = ua,
301 style = 'PRETTY',
302 optimize = "0",
David Ostrovsky2502fab2016-11-15 14:30:26 -0800303 module = [MODULE],
David Ostrovsky13a2fc42016-10-30 23:43:42 +0100304 module_deps = [':ui_module'],
305 deps = DEPS,
306 compiler_args = GWT_COMPILER_ARGS,
307 jvm_args = GWT_JVM_ARGS,
308 )