Update build rules to work with ES6 modules.

This change makes build rules compatible with ES6 modules and
incompatible with html imports.

The build is broken in this change and gerrit-ci fails. The build
repairs after conversion to ES6 modules.

Change-Id: I5da619db6cda06670fffcaefd97a9d3bbe5feb0c
This commit is contained in:
Dmitrii Filippov
2020-03-11 13:33:06 +01:00
parent 445e9249e6
commit c2aac21b17
8 changed files with 50 additions and 342 deletions

View File

@@ -1,184 +0,0 @@
"""This file contains rules to preprocess files before bundling"""
def _update_links_impl(ctx):
"""Wrapper for the links-update command-line tool"""
dir_name = ctx.label.name
output_files = []
input_js_files = []
output_js_files = []
js_files_args = ctx.actions.args()
js_files_args.set_param_file_format("multiline")
js_files_args.use_param_file("%s", use_always = True)
for f in ctx.files.srcs:
output_file = ctx.actions.declare_file(dir_name + "/" + f.path)
output_files.append(output_file)
if f.extension == "html":
input_js_files.append(f)
output_js_files.append(output_file)
js_files_args.add(f)
js_files_args.add(output_file)
else:
ctx.actions.expand_template(
output = output_file,
template = f,
substitutions = {},
)
ctx.actions.run(
executable = ctx.executable._updater,
outputs = output_js_files,
inputs = input_js_files + [ctx.file.redirects],
arguments = [js_files_args, ctx.file.redirects.path],
)
return [DefaultInfo(files = depset(output_files))]
update_links = rule(
implementation = _update_links_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
"redirects": attr.label(allow_single_file = True, mandatory = True),
"_updater": attr.label(
default = ":links-updater-bin",
executable = True,
cfg = "host",
),
},
)
def _get_node_modules_root(node_modules):
if node_modules == None or len(node_modules) == 0:
return None
node_module_root = node_modules[0].label.workspace_root
for target in node_modules:
if target.label.workspace_root != node_module_root:
fail("Only one node_modules workspace can be used")
return node_module_root + "/"
def _get_relative_path(file, root):
root_len = len(root)
if file.path.startswith(root):
return file.path[root_len - 1:]
else:
fail("The file '%s' is not under the root '%s'." % (file.path, root))
def _copy_file(ctx, src, target_name):
output_file = ctx.actions.declare_file(target_name)
ctx.actions.expand_template(
output = output_file,
template = src,
substitutions = {},
)
return output_file
def _get_generated_files(ctx, files, files_root_path, target_dir):
gen_files_for_html = dict()
gen_files_for_js = dict()
copied_files = []
for f in files:
target_name = target_dir + _get_relative_path(f, files_root_path)
if f.extension == "html":
html_output_file = ctx.actions.declare_file(target_name)
js_output_file = ctx.actions.declare_file(target_name + "_gen.js")
gen_files_for_html.update([[f, {"html": html_output_file, "js": js_output_file}]])
elif f.extension == "js":
js_output_file = ctx.actions.declare_file(target_name)
gen_files_for_js.update([[f, {"js": js_output_file}]])
else:
copied_files.append(_copy_file(ctx, f, target_name))
return (gen_files_for_html, gen_files_for_js, copied_files)
def _prepare_for_bundling_impl(ctx):
dir_name = ctx.label.name
all_output_files = []
node_modules_root = _get_node_modules_root(ctx.attr.node_modules)
html_files_dict = dict()
js_files_dict = dict()
root_path = ctx.bin_dir.path + "/" + ctx.attr.root_path
if not root_path.endswith("/"):
root_path = root_path + "/"
gen_files_for_html, gen_files_for_js, copied_files = _get_generated_files(ctx, ctx.files.srcs, root_path, dir_name)
html_files_dict.update(gen_files_for_html)
js_files_dict.update(gen_files_for_js)
all_output_files.extend(copied_files)
gen_files_for_html, gen_files_for_js, copied_files = _get_generated_files(ctx, ctx.files.additional_node_modules_to_preprocess, node_modules_root, dir_name)
html_files_dict.update(gen_files_for_html)
js_files_dict.update(gen_files_for_js)
all_output_files.extend(copied_files)
for f in ctx.files.node_modules:
target_name = dir_name + _get_relative_path(f, node_modules_root)
if html_files_dict.get(f) == None and js_files_dict.get(f) == None:
all_output_files.append(_copy_file(ctx, f, target_name))
preprocessed_output_files = []
html_files_args = ctx.actions.args()
html_files_args.set_param_file_format("multiline")
html_files_args.use_param_file("%s", use_always = True)
for src_path, output_files in html_files_dict.items():
html_files_args.add(src_path)
html_files_args.add(output_files["html"])
html_files_args.add(output_files["js"])
preprocessed_output_files.append(output_files["html"])
preprocessed_output_files.append(output_files["js"])
js_files_args = ctx.actions.args()
js_files_args.set_param_file_format("multiline")
js_files_args.use_param_file("%s", use_always = True)
for src_path, output_files in js_files_dict.items():
js_files_args.add(src_path)
js_files_args.add(output_files["js"])
preprocessed_output_files.append(output_files["js"])
all_output_files.extend(preprocessed_output_files)
ctx.actions.run(
executable = ctx.executable._preprocessor,
outputs = preprocessed_output_files,
inputs = ctx.files.srcs + ctx.files.additional_node_modules_to_preprocess,
arguments = [root_path, html_files_args, js_files_args],
)
entry_point_html = ctx.attr.entry_point
entry_point_js = ctx.attr.entry_point + "_gen.js"
ctx.actions.write(ctx.outputs.html, "<link rel=\"import\" href=\"./%s\" >" % entry_point_html)
ctx.actions.write(ctx.outputs.js, "import \"./%s\";" % entry_point_js)
return [
DefaultInfo(files = depset([ctx.outputs.html, ctx.outputs.js], transitive = [depset(all_output_files)])),
OutputGroupInfo(
js = depset([ctx.outputs.js] + [f for f in all_output_files if f.extension == "js"]),
html = depset([ctx.outputs.html] + [f for f in all_output_files if f.extension == "html"]),
),
]
prepare_for_bundling = rule(
implementation = _prepare_for_bundling_impl,
attrs = {
"srcs": attr.label_list(allow_files = True),
"node_modules": attr.label_list(allow_files = True),
"_preprocessor": attr.label(
default = ":preprocessor-bin",
executable = True,
cfg = "host",
),
"additional_node_modules_to_preprocess": attr.label_list(allow_files = True),
"root_path": attr.string(),
"entry_point": attr.string(
mandatory = True,
doc = "Path relative to root_path",
),
},
outputs = {
"html": "%{name}/entry.html",
"js": "%{name}/entry.js",
},
)