Skip to content

Commit 20c5c58

Browse files
twheysalexeagle
authored andcommitted
feat(typescript): moved file functions to tslb.bzl
1 parent 96d37b6 commit 20c5c58

File tree

4 files changed

+125
-102
lines changed

4 files changed

+125
-102
lines changed

packages/typescript/index.bzl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ Users should not load files under "/internal"
1919

2020
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_binary")
2121
load("//packages/typescript/internal:ts_config.bzl", "write_tsconfig", _ts_config = "ts_config")
22-
load("//packages/typescript/internal:ts_project.bzl", _lib = "lib", _ts_project = "ts_project")
22+
load("//packages/typescript/internal:ts_project.bzl", _ts_project = "ts_project")
23+
load("//packages/typescript/internal:tslib.bzl", _lib = "lib")
2324
load("//packages/typescript/internal:validate_options.bzl", "validate_options")
2425
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
2526
load("@bazel_skylib//lib:partial.bzl", "partial")
@@ -405,6 +406,8 @@ def ts_project(
405406
files = srcs,
406407
extends = Label("%s//%s:%s" % (native.repository_name(), native.package_name(), name)).relative(extends) if extends else None,
407408
out = "tsconfig_%s.json" % name,
409+
allow_js = allow_js,
410+
resolve_json_module = resolve_json_module,
408411
)
409412

410413
# From here, tsconfig becomes a file, the same as if the

packages/typescript/internal/ts_config.bzl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
"tsconfig.json files using extends"
1616

17+
load(":tslib.bzl", _lib = "lib")
18+
1719
TsConfigInfo = provider(
1820
doc = """Provides TypeScript configuration, in the form of a tsconfig.json file
1921
along with any transitively referenced tsconfig.json files chained by the
@@ -77,6 +79,13 @@ def _relative_path(tsconfig, dest):
7779
result = "./" + result
7880
return result
7981

82+
def _filter_input_files(files, allow_js, resolve_json_module):
83+
return [
84+
f
85+
for f in files
86+
if _lib.is_ts_src(f.basename, allow_js) or _lib.is_json_src(f.basename, resolve_json_module)
87+
]
88+
8089
def _write_tsconfig_rule(ctx):
8190
# TODO: is it useful to expand Make variables in the content?
8291
content = "\n".join(ctx.attr.content)
@@ -85,10 +94,12 @@ def _write_tsconfig_rule(ctx):
8594
"__extends__",
8695
_relative_path(ctx.outputs.out, ctx.file.extends),
8796
)
88-
if ctx.attr.files:
97+
98+
filtered_files = _filter_input_files(ctx.files.files, ctx.attr.allow_js, ctx.attr.resolve_json_module)
99+
if filtered_files:
89100
content = content.replace(
90101
"\"__files__\"",
91-
str([_relative_path(ctx.outputs.out, f) for f in ctx.files.files]),
102+
str([_relative_path(ctx.outputs.out, f) for f in filtered_files]),
92103
)
93104
ctx.actions.write(
94105
output = ctx.outputs.out,
@@ -103,11 +114,13 @@ write_tsconfig_rule = rule(
103114
"extends": attr.label(allow_single_file = True),
104115
"files": attr.label_list(allow_files = True),
105116
"out": attr.output(),
117+
"allow_js": attr.bool(),
118+
"resolve_json_module": attr.bool(),
106119
},
107120
)
108121

109122
# Syntax sugar around skylib's write_file
110-
def write_tsconfig(name, config, files, out, extends = None):
123+
def write_tsconfig(name, config, files, out, extends = None, allow_js = None, resolve_json_module = None):
111124
"""Wrapper around bazel_skylib's write_file which understands tsconfig paths
112125
113126
Args:
@@ -133,4 +146,6 @@ def write_tsconfig(name, config, files, out, extends = None):
133146
extends = extends,
134147
content = [json.encode(amended_config)],
135148
out = out,
149+
allow_js = allow_js,
150+
resolve_json_module = resolve_json_module,
136151
)

packages/typescript/internal/ts_project.bzl

Lines changed: 11 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
load("@rules_nodejs//nodejs:providers.bzl", "DeclarationInfo", "declaration_info", "js_module_info")
44
load("@build_bazel_rules_nodejs//:providers.bzl", "ExternalNpmPackageInfo", "run_node")
55
load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "module_mappings_aspect")
6+
load(":tslib.bzl", _lib = "lib")
67
load(":ts_config.bzl", "TsConfigInfo")
78
load(":validate_options.bzl", "ValidOptionsInfo", _validate_lib = "lib")
89

@@ -50,19 +51,6 @@ _OUTPUTS = {
5051
"typings_outs": attr.output_list(),
5152
}
5253

53-
def _join(*elements):
54-
segments = [f for f in elements if f]
55-
if len(segments):
56-
return "/".join(segments)
57-
return "."
58-
59-
def _relative_to_package(path, ctx):
60-
for prefix in (ctx.bin_dir.path, ctx.label.package):
61-
prefix += "/"
62-
if path.startswith(prefix):
63-
path = path[len(prefix):]
64-
return path
65-
6654
def _declare_outputs(ctx, paths):
6755
return [
6856
ctx.actions.declare_file(path)
@@ -82,7 +70,7 @@ def _calculate_root_dir(ctx):
8270
# a breaking change to restrict it further.
8371
allow_js = True
8472
for src in ctx.files.srcs:
85-
if _is_ts_src(src.path, allow_js):
73+
if _lib.is_ts_src(src.path, allow_js):
8674
if src.is_source:
8775
some_source_path = src.path
8876
else:
@@ -95,26 +83,26 @@ def _calculate_root_dir(ctx):
9583
" found generated file %s and source file %s" %
9684
(some_generated_path, some_source_path))
9785

98-
return _join(
86+
return _lib.join(
9987
root_path,
10088
ctx.label.workspace_root,
10189
ctx.label.package,
10290
ctx.attr.root_dir,
10391
)
10492

10593
def _ts_project_impl(ctx):
106-
srcs = [_relative_to_package(src.path, ctx) for src in ctx.files.srcs]
94+
srcs = [_lib.relative_to_package(src.path, ctx) for src in ctx.files.srcs]
10795

10896
# Recalculate outputs inside the rule implementation.
10997
# The outs are first calculated in the macro in order to try to predetermine outputs so they can be declared as
11098
# outputs on the rule. This provides the benefit of being able to reference an output file with a label.
11199
# However, it is not possible to evaluate files in outputs of other rules such as filegroup, therefore the outs are
112100
# recalculated here.
113101
typings_out_dir = ctx.attr.declaration_dir or ctx.attr.out_dir
114-
js_outs = _declare_outputs(ctx, [] if not ctx.attr.transpile else _calculate_js_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.allow_js, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only))
115-
map_outs = _declare_outputs(ctx, [] if not ctx.attr.transpile else _calculate_map_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.source_map, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only))
116-
typings_outs = _declare_outputs(ctx, _calculate_typings_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration, ctx.attr.composite, ctx.attr.allow_js))
117-
typing_maps_outs = _declare_outputs(ctx, _calculate_typing_maps_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration_map, ctx.attr.allow_js))
102+
js_outs = _declare_outputs(ctx, [] if not ctx.attr.transpile else _lib.calculate_js_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.allow_js, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only))
103+
map_outs = _declare_outputs(ctx, [] if not ctx.attr.transpile else _lib.calculate_map_outs(srcs, ctx.attr.out_dir, ctx.attr.root_dir, ctx.attr.source_map, ctx.attr.preserve_jsx, ctx.attr.emit_declaration_only))
104+
typings_outs = _declare_outputs(ctx, _lib.calculate_typings_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration, ctx.attr.composite, ctx.attr.allow_js))
105+
typing_maps_outs = _declare_outputs(ctx, _lib.calculate_typing_maps_outs(srcs, typings_out_dir, ctx.attr.root_dir, ctx.attr.declaration_map, ctx.attr.allow_js))
118106

119107
arguments = ctx.actions.args()
120108
execution_requirements = {}
@@ -135,15 +123,15 @@ def _ts_project_impl(ctx):
135123
"--project",
136124
ctx.file.tsconfig.path,
137125
"--outDir",
138-
_join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package, ctx.attr.out_dir),
126+
_lib.join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package, ctx.attr.out_dir),
139127
"--rootDir",
140128
_calculate_root_dir(ctx),
141129
])
142130
if len(typings_outs) > 0:
143131
declaration_dir = ctx.attr.declaration_dir if ctx.attr.declaration_dir else ctx.attr.out_dir
144132
arguments.add_all([
145133
"--declarationDir",
146-
_join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package, declaration_dir),
134+
_lib.join(ctx.bin_dir.path, ctx.label.workspace_root, ctx.label.package, declaration_dir),
147135
])
148136

149137
# When users report problems, we can ask them to re-build with
@@ -190,7 +178,7 @@ def _ts_project_impl(ctx):
190178
if len(js_outs):
191179
pkg_len = len(ctx.label.package) + 1 if len(ctx.label.package) else 0
192180
json_outs = [
193-
ctx.actions.declare_file(_join(ctx.attr.out_dir, src.short_path[pkg_len:]))
181+
ctx.actions.declare_file(_lib.join(ctx.attr.out_dir, src.short_path[pkg_len:]))
194182
for src in ctx.files.srcs
195183
if src.basename.endswith(".json") and src.is_source
196184
]
@@ -295,78 +283,3 @@ ts_project = rule(
295283
implementation = _ts_project_impl,
296284
attrs = dict(_ATTRS, **_OUTPUTS),
297285
)
298-
299-
def _is_ts_src(src, allow_js):
300-
if not src.endswith(".d.ts") and (src.endswith(".ts") or src.endswith(".tsx")):
301-
return True
302-
return allow_js and (src.endswith(".js") or src.endswith(".jsx"))
303-
304-
def _is_json_src(src, resolve_json_module):
305-
return resolve_json_module and src.endswith(".json")
306-
307-
def _replace_ext(f, ext_map):
308-
cur_ext = f[f.rindex("."):]
309-
new_ext = ext_map.get(cur_ext)
310-
if new_ext != None:
311-
return new_ext
312-
new_ext = ext_map.get("*")
313-
if new_ext != None:
314-
return new_ext
315-
return None
316-
317-
def _out_paths(srcs, out_dir, root_dir, allow_js, ext_map):
318-
rootdir_replace_pattern = root_dir + "/" if root_dir else ""
319-
outs = []
320-
for f in srcs:
321-
if _is_ts_src(f, allow_js):
322-
out = _join(out_dir, f[:f.rindex(".")].replace(rootdir_replace_pattern, "") + _replace_ext(f, ext_map))
323-
324-
# Don't declare outputs that collide with inputs
325-
# for example, a.js -> a.js
326-
if out != f:
327-
outs.append(out)
328-
return outs
329-
330-
def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, preserve_jsx, emit_declaration_only):
331-
if emit_declaration_only:
332-
return []
333-
334-
exts = {
335-
"*": ".js",
336-
".jsx": ".jsx",
337-
".tsx": ".jsx",
338-
} if preserve_jsx else {"*": ".js"}
339-
return _out_paths(srcs, out_dir, root_dir, allow_js, exts)
340-
341-
def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only):
342-
if not source_map or emit_declaration_only:
343-
return []
344-
345-
exts = {
346-
"*": ".js.map",
347-
".tsx": ".jsx.map",
348-
} if preserve_jsx else {"*": ".js.map"}
349-
return _out_paths(srcs, out_dir, root_dir, False, exts)
350-
351-
def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, include_srcs = True):
352-
if not (declaration or composite):
353-
return []
354-
355-
return _out_paths(srcs, typings_out_dir, root_dir, allow_js, {"*": ".d.ts"})
356-
357-
def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js):
358-
if not declaration_map:
359-
return []
360-
361-
exts = {"*": ".d.ts.map"}
362-
return _out_paths(srcs, typings_out_dir, root_dir, allow_js, exts)
363-
364-
lib = struct(
365-
is_ts_src = _is_ts_src,
366-
is_json_src = _is_json_src,
367-
out_paths = _out_paths,
368-
calculate_js_outs = _calculate_js_outs,
369-
calculate_map_outs = _calculate_map_outs,
370-
calculate_typings_outs = _calculate_typings_outs,
371-
calculate_typing_maps_outs = _calculate_typing_maps_outs,
372-
)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
"Utilities functions for selecting and filtering ts and other files"
2+
3+
def _join(*elements):
4+
segments = [f for f in elements if f]
5+
if len(segments):
6+
return "/".join(segments)
7+
return "."
8+
9+
def _relative_to_package(path, ctx):
10+
for prefix in (ctx.bin_dir.path, ctx.label.package):
11+
prefix += "/"
12+
if path.startswith(prefix):
13+
path = path[len(prefix):]
14+
return path
15+
16+
def _is_ts_src(src, allow_js):
17+
if not src.endswith(".d.ts") and (src.endswith(".ts") or src.endswith(".tsx")):
18+
return True
19+
return allow_js and (src.endswith(".js") or src.endswith(".jsx"))
20+
21+
def _is_json_src(src, resolve_json_module):
22+
return resolve_json_module and src.endswith(".json")
23+
24+
def _replace_ext(f, ext_map):
25+
cur_ext = f[f.rindex("."):]
26+
new_ext = ext_map.get(cur_ext)
27+
if new_ext != None:
28+
return new_ext
29+
new_ext = ext_map.get("*")
30+
if new_ext != None:
31+
return new_ext
32+
return None
33+
34+
35+
def _out_paths(srcs, out_dir, root_dir, allow_js, ext_map):
36+
rootdir_replace_pattern = root_dir + "/" if root_dir else ""
37+
outs = []
38+
for f in srcs:
39+
if _is_ts_src(f, allow_js):
40+
out = _join(out_dir, f[:f.rindex(".")].replace(rootdir_replace_pattern, "") + _replace_ext(f, ext_map))
41+
42+
# Don't declare outputs that collide with inputs
43+
# for example, a.js -> a.js
44+
if out != f:
45+
outs.append(out)
46+
return outs
47+
48+
def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, preserve_jsx, emit_declaration_only):
49+
if emit_declaration_only:
50+
return []
51+
52+
exts = {
53+
"*": ".js",
54+
".jsx": ".jsx",
55+
".tsx": ".jsx",
56+
} if preserve_jsx else {"*": ".js"}
57+
return _out_paths(srcs, out_dir, root_dir, allow_js, exts)
58+
59+
def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only):
60+
if not source_map or emit_declaration_only:
61+
return []
62+
63+
exts = {
64+
"*": ".js.map",
65+
".tsx": ".jsx.map",
66+
} if preserve_jsx else {"*": ".js.map"}
67+
return _out_paths(srcs, out_dir, root_dir, False, exts)
68+
69+
def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, include_srcs = True):
70+
if not (declaration or composite):
71+
return []
72+
73+
return _out_paths(srcs, typings_out_dir, root_dir, allow_js, {"*": ".d.ts"})
74+
75+
def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js):
76+
if not declaration_map:
77+
return []
78+
79+
exts = {"*": ".d.ts.map"}
80+
return _out_paths(srcs, typings_out_dir, root_dir, allow_js, exts)
81+
82+
lib = struct(
83+
join = _join,
84+
relative_to_package = _relative_to_package,
85+
is_ts_src = _is_ts_src,
86+
is_json_src = _is_json_src,
87+
out_paths = _out_paths,
88+
calculate_js_outs = _calculate_js_outs,
89+
calculate_map_outs = _calculate_map_outs,
90+
calculate_typings_outs = _calculate_typings_outs,
91+
calculate_typing_maps_outs = _calculate_typing_maps_outs,
92+
)

0 commit comments

Comments
 (0)