Skip to content

Commit ad856bd

Browse files
committed
Add closure_ts_archive rule
1 parent 5220aff commit ad856bd

3 files changed

Lines changed: 102 additions & 23 deletions

File tree

rules/defs.bzl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
load("//rules/private:closure_ts_compile.bzl", _closure_ts_compile = "closure_ts_compile")
2+
load("//rules/private:closure_ts_archive.bzl", _closure_ts_archive = "closure_ts_archive")
23

34
closure_ts_compile = _closure_ts_compile
5+
closure_ts_archive = _closure_ts_archive
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
"""closure_ts_archive builds zip files of closure js sources"""
2+
3+
load(":closure_ts_compile.bzl", "ClosureTsCompileInfo")
4+
5+
def _get_zip_runfiles_path(path):
6+
if path.startswith("../"):
7+
parts = path.split("/")
8+
path = "/".join(parts[2:])
9+
return path
10+
11+
def _zip_action(ctx):
12+
srcs = ctx.files.srcs
13+
14+
transitive_outs = [dep[ClosureTsCompileInfo].transitive_outs for dep in ctx.attr.deps]
15+
direct_outs = [dep[ClosureTsCompileInfo].direct_outs for dep in ctx.attr.deps]
16+
if ctx.attr.transitive:
17+
inputs = depset(srcs, transitive = transitive_outs)
18+
else:
19+
inputs = depset(srcs, transitive = direct_outs)
20+
21+
def map_zip_runfiles(file):
22+
return "{}={}".format(
23+
_get_zip_runfiles_path(file.short_path),
24+
file.path,
25+
)
26+
27+
manifest = ctx.actions.args()
28+
manifest.use_param_file("@%s", use_always = True)
29+
manifest.set_param_file_format("multiline")
30+
manifest.add_all(inputs, map_each = map_zip_runfiles, allow_closure = True)
31+
32+
zip_cli_args = ctx.actions.args()
33+
zip_cli_args.add("cC")
34+
zip_cli_args.add(ctx.outputs.zip)
35+
36+
ctx.actions.run(
37+
executable = ctx.executable._zipper,
38+
arguments = [zip_cli_args, manifest],
39+
inputs = inputs,
40+
outputs = [ctx.outputs.zip],
41+
use_default_shell_env = True,
42+
mnemonic = "ClosureTsZip",
43+
progress_message = "Building zip: %{label}",
44+
)
45+
46+
def _closure_ts_archive_impl(ctx):
47+
_zip_action(ctx)
48+
49+
return [
50+
DefaultInfo(
51+
files = depset([ctx.outputs.zip]),
52+
),
53+
]
54+
55+
closure_ts_archive = rule(
56+
implementation = _closure_ts_archive_impl,
57+
attrs = {
58+
"srcs": attr.label_list(
59+
doc = "additional sources to add to the archive",
60+
allow_files = True,
61+
),
62+
"deps": attr.label_list(
63+
doc = "closure ts compile dependencies to archive",
64+
providers = [ClosureTsCompileInfo],
65+
),
66+
"transitive": attr.bool(
67+
doc = "archive transitive dependencies into a single archive",
68+
),
69+
"_zipper": attr.label(
70+
cfg = "exec",
71+
executable = True,
72+
default = "@bazel_tools//tools/zip:zipper",
73+
),
74+
},
75+
outputs = {
76+
"zip": "%{name}.js.zip",
77+
},
78+
)

rules/private/closure_ts_compile.bzl

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
load("@bazel_skylib//lib:paths.bzl", "paths")
44

55
ClosureTsCompileInfo = provider(doc = "info about a closure ts compile rule", fields = {
6-
"sources": "DepSet<File>: direct + transitive sources",
6+
"direct_srcs": "DepSet<File>: direct sources",
7+
"transitive_srcs": "DepSet<File>: transitive sources",
8+
"direct_outs": "DepSet<File>: direct outputs",
9+
"transitive_outs": "DepSet<File>: transitive outputs",
710
})
811

912
def _output_for_ts_input(ctx, src):
@@ -13,58 +16,54 @@ def _output_for_ts_input(ctx, src):
1316
def _output_for_externs(ctx):
1417
return ctx.actions.declare_file(ctx.label.name + ".externs.js")
1518

16-
def _tsickle_action(ctx):
17-
direct = ctx.files.srcs
18-
transitive = [dep[ClosureTsCompileInfo].sources for dep in ctx.attr.deps]
19+
def _closure_ts_compile_impl(ctx):
20+
direct_srcs = ctx.files.srcs
21+
transitive_srcs = [dep[ClosureTsCompileInfo].transitive_srcs for dep in ctx.attr.deps]
22+
transitive_outs = [dep[ClosureTsCompileInfo].transitive_outs for dep in ctx.attr.deps]
1923

2024
args = ctx.actions.args()
21-
args.add_all([src.short_path for src in direct])
25+
args.add_all(direct_srcs)
2226

2327
env = {
2428
"BAZEL_BINDIR": ctx.bin_dir.path,
25-
"BAZEL_WORKSPACE": ctx.label.workspace_name,
2629
"BAZEL_PACKAGE": ctx.label.package,
2730
}
2831

2932
direct_ts = []
3033
direct_dts = []
31-
for src in direct:
34+
for src in direct_srcs:
3235
if src.basename.endswith(".d.ts"):
3336
direct_dts.append(src)
3437
else:
3538
direct_ts.append(src)
3639

37-
outputs = [_output_for_ts_input(ctx, f) for f in direct_ts]
40+
direct_outs = [_output_for_ts_input(ctx, f) for f in direct_ts]
3841
if len(direct_dts) > 0:
3942
externs_output = _output_for_externs(ctx)
40-
outputs.append(externs_output)
41-
env["EXTERNS_PATH"] = externs_output.short_path
43+
direct_outs.append(externs_output)
44+
env["EXTERNS_PATH"] = externs_output.short_path.replace("../", "external/")
4245

43-
inputs = depset(direct = direct, transitive = transitive)
46+
all_srcs = depset(direct = direct_srcs, transitive = transitive_srcs)
47+
all_outs = depset(direct = direct_outs, transitive = transitive_outs)
4448

4549
ctx.actions.run(
4650
mnemonic = "TsickleCompile",
4751
executable = ctx.executable._compiler,
4852
arguments = [args],
49-
inputs = inputs,
50-
outputs = outputs,
53+
inputs = all_srcs,
54+
outputs = direct_outs,
5155
env = env,
5256
)
5357

54-
return struct(
55-
inputs = inputs,
56-
outputs = outputs,
57-
)
58-
59-
def _closure_ts_compile_impl(ctx):
60-
result = _tsickle_action(ctx)
61-
6258
return [
6359
DefaultInfo(
64-
files = depset(result.outputs),
60+
files = depset(direct_outs),
6561
),
6662
ClosureTsCompileInfo(
67-
sources = result.inputs,
63+
direct_srcs = direct_srcs,
64+
transitive_srcs = all_srcs,
65+
direct_outs = depset(direct_outs),
66+
transitive_outs = all_outs,
6867
),
6968
]
7069

0 commit comments

Comments
 (0)