Skip to content

Commit

Permalink
feat(typescript): accept TsConfigInfo in extends
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Eagle committed Aug 27, 2020
1 parent 9d34089 commit 18f0f1c
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 25 deletions.
15 changes: 4 additions & 11 deletions packages/typescript/internal/ts_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -99,29 +99,22 @@ write_tsconfig_rule = rule(
)

# Syntax sugar around skylib's write_file
def write_tsconfig(name, config, files, extends, out):
def write_tsconfig(name, config, files, out, extends = None):
"""Wrapper around bazel_skylib's write_file which understands tsconfig paths
Args:
name: name of the resulting write_file rule
config: tsconfig dictionary
files: list of input .ts files to put in the files[] array
extends: a tsconfig.json file to extend from
out: the file to write
extends: a label for a tsconfig.json file to extend from, if any
"""

# Allow extends to be a list of labels, as this is what ts_project accepts
if type(extends) == type([]):
if len(extends):
extends = extends[0]
else:
extends = None
if extends:
extends = Label(extends)
config["extends"] = "__extends__" #_join(workspace_root, extends.package, extends.name)
config["extends"] = "__extends__"

amended_config = struct(
files = "__files__", #[_join(workspace_root, native.package_name(), f) for f in files],
files = "__files__",
**config
)
write_tsconfig_rule(
Expand Down
35 changes: 28 additions & 7 deletions packages/typescript/internal/ts_project.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,17 @@ def _ts_project_impl(ctx):
deps_depsets.append(dep[DeclarationInfo].transitive_declarations)

inputs = ctx.files.srcs + depset(transitive = deps_depsets).to_list()

# Gather TsConfig info from both the direct (tsconfig) and indirect (extends) attribute
if TsConfigInfo in ctx.attr.tsconfig:
inputs.extend(ctx.attr.tsconfig[TsConfigInfo].deps)
else:
inputs.append(ctx.file.tsconfig)
if ctx.attr.extends:
inputs.extend(ctx.files.extends)
for extend in ctx.attr.extends:
if TsConfigInfo in extend:
inputs.extend(extend[TsConfigInfo].deps)
else:
inputs.extend(extend.files.to_list())

# We do not try to predeclare json_outs, because their output locations generally conflict with their path in the source tree.
# (The exception is when out_dir is used, then the .json output is a different path than the input.)
Expand Down Expand Up @@ -374,7 +379,10 @@ def ts_project_macro(
deps: List of labels of other rules that produce TypeScript typings (.d.ts files)
tsconfig: Label of the tsconfig.json file to use for the compilation, or a target that provides TsConfigInfo.
tsconfig: Label of the tsconfig.json file to use for the compilation
To support "chaining" of more than one extended config, this label could be a target that
provdes `TsConfigInfo` such as `ts_config`.
By default, we assume the tsconfig file is named by adding `.json` to the `name` attribute.
Expand Down Expand Up @@ -407,10 +415,15 @@ def ts_project_macro(
)
```
extends: List of labels of tsconfig file(s) referenced in `extends` section of tsconfig.
extends: Label of the tsconfig file referenced in the `extends` section of tsconfig
Any tsconfig files "chained" by extends clauses must either be transitive deps of the TsConfigInfo
provided to the `tsconfig` attribute, or must be explicitly listed here.
To support "chaining" of more than one extended config, this label could be a target that
provdes `TsConfigInfo` such as `ts_config`.
_DEPRECATED, to be removed in 3.0_:
For backwards compatibility, this accepts a list of Labels of the "chained"
tsconfig files. You should instead use a single Label of a `ts_config` target.
Follow this deprecation: https://github.com/bazelbuild/rules_nodejs/issues/2140
args: List of strings of additional command-line arguments to pass to tsc.
Expand Down Expand Up @@ -460,6 +473,10 @@ def ts_project_macro(
extra_deps = []

if type(tsconfig) == type(dict()):
# Opt-in to #2140 breaking change at the same time you opt-in to experimental tsconfig dict
if type(extends) == type([]):
fail("when tsconfig is a dict, extends should have a single value")

# Copy attributes <-> tsconfig properties
# TODO: fail if compilerOptions includes a conflict with an attribute?
compiler_options = tsconfig.setdefault("compilerOptions", {})
Expand All @@ -482,7 +499,7 @@ def ts_project_macro(
name = "_gen_tsconfig_%s" % name,
config = tsconfig,
files = srcs,
extends = extends,
extends = Label("//%s:%s" % (native.package_name(), name)).relative(extends) if extends else None,
out = "tsconfig_%s.json" % name,
)

Expand Down Expand Up @@ -513,6 +530,10 @@ def ts_project_macro(
typings_out_dir = declaration_dir if declaration_dir else out_dir
tsbuildinfo_path = ts_build_info_file if ts_build_info_file else name + ".tsbuildinfo"

# Backcompat for extends as a list, to cleanup in #2140
if (type(extends) == type("")):
extends = [extends]

ts_project(
name = name,
srcs = srcs,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,50 @@
load("@build_bazel_rules_nodejs//:index.bzl", "generated_file_test")
load("//packages/typescript:index.bzl", "ts_project")
load("//packages/typescript:index.bzl", "ts_config", "ts_project")

# Case one: extend from a single tsconfig
ts_project(
extends = ["//packages/typescript/test/ts_project:tsconfig-base.json"],
name = "case_one",
extends = "//packages/typescript/test/ts_project:tsconfig-base.json",
tsconfig = {
"compilerOptions": {
"declaration": True,
"outDir": "case_one",
"types": [],
},
},
)

ts_config(
name = "tsconfig_chain",
src = "tsconfig-extended.json",
deps = [
"//packages/typescript/test/ts_project:tsconfig",
],
)

# Case two: extend from a chain of tsconfig
ts_project(
name = "case_two",
extends = ":tsconfig_chain",
tsconfig = {
"compilerOptions": {
"declaration": True,
"outDir": "case_two",
"types": [],
},
},
)

generated_file_test(
name = "test_one",
# test the default output of the ts_project
src = "expected.js_",
generated = "case_one/a.js",
)

generated_file_test(
name = "test",
name = "test_two",
# test the default output of the ts_project
src = "expected.js_",
generated = "a.js",
generated = "case_two/a.js",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig-base",
"compilerOptions": {
"declaration": true
},
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Test a tree of tsconfig.json files
load("//packages/typescript:index.bzl", "ts_config", "ts_project")

ts_config(
name = "tsconfig.abcd",
name = "tsconfig",
src = "tsconfig.json",
deps = [
"tsconfig-extended.json",
Expand All @@ -17,6 +17,5 @@ ts_project(
name = "compile_ts",
composite = True,
declaration = True,
# We'll name the tsbuildinfo output after tsconfig[:-5] so fool it for now
tsconfig = "tsconfig.abcd",
tsconfig = "tsconfig",
)

0 comments on commit 18f0f1c

Please sign in to comment.