Skip to content
File

Blob: build/js_file.bzl

2.8 KB
1"""
2Give a collection of js files a JsInfo provider so it can be used as a dependency for aspect_rules.
3"""
4 
5load("@aspect_rules_js//js:providers.bzl", "JsInfo", "js_info")
6load("@bazel_lib//lib:copy_to_bin.bzl", "COPY_FILE_TO_BIN_TOOLCHAINS", "copy_file_to_bin_action")
7 
8_ATTRS = {
9 "srcs": attr.label_list(
10 allow_files = True,
11 ),
12 "deps": attr.label_list(),
13}
14 
15def _gather_sources_and_types(ctx, targets, files):
16 """Gathers sources and types from a list of targets
17 
18 Args:
19 ctx: the rule context
20 
21 targets: List of targets to gather sources and types from their JsInfo providers.
22 
23 These typically come from the `srcs` and/or `data` attributes of a rule
24 
25 files: List of files to gather as sources and types.
26 
27 These typically come from the `srcs` and/or `data` attributes of a rule
28 
29 Returns:
30 Sources & declaration files depsets in the sequence (sources, types)
31 """
32 sources = []
33 types = []
34 
35 for file in files:
36 if file.is_source:
37 file = copy_file_to_bin_action(ctx, file)
38 
39 if file.is_directory:
40 # assume a directory contains types since we can't know that it doesn't
41 types.append(file)
42 sources.append(file)
43 elif (
44 file.path.endswith((".d.ts", ".d.ts.map", ".d.mts", ".d.mts.map", ".d.cts", ".d.cts.map"))
45 ):
46 types.append(file)
47 elif file.path.endswith(".json"):
48 # Any .json can produce types: https://www.typescriptlang.org/tsconfig/#resolveJsonModule
49 # package.json may be required to resolve types with the "typings" key
50 types.append(file)
51 sources.append(file)
52 else:
53 sources.append(file)
54 
55 # sources as depset
56 sources = depset(sources, transitive = [
57 target[JsInfo].sources
58 for target in targets
59 if JsInfo in target
60 ])
61 
62 # types as depset
63 types = depset(types, transitive = [
64 target[JsInfo].types
65 for target in targets
66 if JsInfo in target
67 ])
68 
69 return (sources, types)
70 
71def _js_file_impl(ctx):
72 sources, types = _gather_sources_and_types(
73 ctx = ctx,
74 targets = ctx.attr.srcs,
75 files = ctx.files.srcs,
76 )
77 
78 return [
79 js_info(
80 target = ctx.label,
81 sources = sources,
82 types = types,
83 ),
84 DefaultInfo(
85 files = sources,
86 ),
87 OutputGroupInfo(
88 types = types,
89 ),
90 ]
91 
92js_file_lib = struct(
93 attrs = _ATTRS,
94 implementation = _js_file_impl,
95 provides = [DefaultInfo, JsInfo, OutputGroupInfo],
96)
97 
98js_file = rule(
99 implementation = js_file_lib.implementation,
100 attrs = js_file_lib.attrs,
101 provides = js_file_lib.provides,
102 toolchains = COPY_FILE_TO_BIN_TOOLCHAINS,
103)