|
| 1 | +load("@build_bazel_rules_nodejs//:providers.bzl", "DeclarationInfo", "JSEcmaScriptModuleInfo", "JSModuleInfo", "JSNamedModuleInfo") |
| 2 | + |
| 3 | +"""Converts a provider name to its actually Starlark provider instance.""" |
| 4 | + |
| 5 | +def _name_to_js_module_provider(name): |
| 6 | + if name == "JSModuleInfo": |
| 7 | + return JSModuleInfo |
| 8 | + elif name == "JSNamedModuleInfo": |
| 9 | + return JSNamedModuleInfo |
| 10 | + elif name == "JSEcmaScriptModuleInfo": |
| 11 | + return JSEcmaScriptModuleInfo |
| 12 | + fail("Unexpected JavaScript module provider.") |
| 13 | + |
| 14 | +"""Implementation of the extract_js_module_output rule.""" |
| 15 | + |
| 16 | +def _extract_js_module_output_impl(ctx): |
| 17 | + js_module_provider = _name_to_js_module_provider(ctx.attr.provider) |
| 18 | + depsets = [] |
| 19 | + for dep in ctx.attr.deps: |
| 20 | + # Include JavaScript sources (including transitive outputs) based on the |
| 21 | + # configured JavaScript module provider. |
| 22 | + if js_module_provider in dep: |
| 23 | + depsets.append(dep[js_module_provider].sources) |
| 24 | + |
| 25 | + # Based on whether declarations should be collected, extract direct |
| 26 | + # and transitive declaration files using the `DeclarationInfo` provider. |
| 27 | + if ctx.attr.include_declarations and DeclarationInfo in dep: |
| 28 | + depsets.append(dep[DeclarationInfo].transitive_declarations) |
| 29 | + |
| 30 | + # Based on whether default files should be collected, extract direct |
| 31 | + # files which are exposed using the `DefaultInfo` provider. Also include |
| 32 | + # data runfiles which are needed for the current target. |
| 33 | + # https://docs.bazel.build/versions/main/skylark/lib/DefaultInfo.html#data_runfiles |
| 34 | + if ctx.attr.include_default_files and DefaultInfo in dep: |
| 35 | + depsets.append(dep[DefaultInfo].files) |
| 36 | + depsets.append(dep[DefaultInfo].data_runfiles.files) |
| 37 | + |
| 38 | + sources = depset(transitive = depsets) |
| 39 | + |
| 40 | + return [DefaultInfo(files = sources)] |
| 41 | + |
| 42 | +""" |
| 43 | + Rule that collects declared JavaScript module output files from a list of dependencies |
| 44 | + based on a configurable JavaScript module provider. The extracted outputs are exposed |
| 45 | + within the `DefaultInfo` provider. Targets defined using this rule can be used as input |
| 46 | + for rules that require JavaScript sources, or if there are multiple JavaScript output |
| 47 | + variants defined for a target while for example only the `JSModule` outputs are of interest. |
| 48 | +
|
| 49 | + As an example: This rule is helpful in combination with `ts_library` and `ng_module` as |
| 50 | + those rule expose multiple output flavors (which are distinguishable by the JavaScript module |
| 51 | + providers as imported from `providers.bzl`). i.e. these rules expose flavors for named AMD |
| 52 | + modules and ECMAScript module output. For reference: |
| 53 | + https://github.com/bazelbuild/rules_nodejs/blob/stable/packages/typescript/internal/build_defs.bzl#L334-L337 |
| 54 | +""" |
| 55 | +extract_js_module_output = rule( |
| 56 | + implementation = _extract_js_module_output_impl, |
| 57 | + attrs = { |
| 58 | + "deps": attr.label_list( |
| 59 | + allow_files = True, |
| 60 | + ), |
| 61 | + "provider": attr.string( |
| 62 | + doc = "JavaScript module info provider that is used for collecting sources from the dependencies.", |
| 63 | + mandatory = True, |
| 64 | + values = ["JSModuleInfo", "JSNamedModuleInfo", "JSEcmaScriptModuleInfo"], |
| 65 | + ), |
| 66 | + "include_declarations": attr.bool( |
| 67 | + mandatory = True, |
| 68 | + doc = "Whether declaration files should be collected from the dependencies.", |
| 69 | + ), |
| 70 | + "include_default_files": attr.bool( |
| 71 | + mandatory = True, |
| 72 | + doc = """ |
| 73 | + Whether files from the `DefaultInfo` provider should be collected. Includes |
| 74 | + data runfiles needed for the default outputs from dependencies. |
| 75 | + """, |
| 76 | + ), |
| 77 | + }, |
| 78 | +) |
0 commit comments