Skip to content

Commit

Permalink
fix(typescript): add the tsBuildInfoFile option to ts_project (bazel-…
Browse files Browse the repository at this point in the history
…contrib#2138)

Like other options that affect tsc outputs, Bazel needs to know the value from the tsconfig if its set.
Add it to our validator so there's a buildozer command to sync the option value into the BUILD file.

Fixes bazel-contrib#2137
  • Loading branch information
alexeagle authored and mgenov committed Jan 6, 2021
1 parent c985c59 commit 1e66b17
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 5 deletions.
13 changes: 12 additions & 1 deletion packages/typescript/internal/ts_project.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ def _ts_project_impl(ctx):

outputs = json_outs + ctx.outputs.js_outs + ctx.outputs.map_outs + ctx.outputs.typings_outs + ctx.outputs.typing_maps_outs
if ctx.outputs.buildinfo_out:
arguments.add_all([
"--tsBuildInfoFile",
ctx.outputs.buildinfo_out.path,
])
outputs.append(ctx.outputs.buildinfo_out)
runtime_outputs = json_outs + ctx.outputs.js_outs + ctx.outputs.map_outs
typings_outputs = ctx.outputs.typings_outs + ctx.outputs.typing_maps_outs + [s for s in ctx.files.srcs if s.path.endswith(".d.ts")]
Expand Down Expand Up @@ -184,6 +188,7 @@ def _validate_options_impl(ctx):
emit_declaration_only = ctx.attr.emit_declaration_only,
source_map = ctx.attr.source_map,
incremental = ctx.attr.incremental,
ts_build_info_file = ctx.attr.ts_build_info_file,
).to_json()])

run_node(
Expand All @@ -210,6 +215,7 @@ validate_options = rule(
"incremental": attr.bool(),
"source_map": attr.bool(),
"target": attr.string(),
"ts_build_info_file": attr.string(),
"tsconfig": attr.label(mandatory = True, allow_single_file = [".json"]),
"validator": attr.label(default = Label("//packages/typescript/bin:ts_project_options_validator"), executable = True, cfg = "host"),
},
Expand All @@ -236,6 +242,7 @@ def ts_project_macro(
composite = False,
incremental = False,
emit_declaration_only = False,
ts_build_info_file = None,
tsc = None,
validate = True,
declaration_dir = None,
Expand Down Expand Up @@ -394,6 +401,8 @@ def ts_project_macro(
Instructs Bazel to expect a `.tsbuildinfo` output.
emit_declaration_only: if the `emitDeclarationOnly` bit is set in the tsconfig.
Instructs Bazel *not* to expect `.js` or `.js.map` outputs for `.ts` sources.
ts_build_info_file: the user-specified value of `tsBuildInfoFile` from the tsconfig.
Helps Bazel to predict the path where the .tsbuildinfo output is written.
**kwargs: passed through to underlying rule, allows eg. visibility, tags
"""
Expand All @@ -416,12 +425,14 @@ def ts_project_macro(
composite = composite,
incremental = incremental,
emit_declaration_only = emit_declaration_only,
ts_build_info_file = ts_build_info_file,
tsconfig = tsconfig,
extends = extends,
)
extra_deps.append("_validate_%s_options" % name)

typings_out_dir = declaration_dir if declaration_dir else out_dir
tsbuildinfo_path = ts_build_info_file if ts_build_info_file else tsconfig[:-5] + ".tsbuildinfo"

ts_project(
name = name,
Expand All @@ -437,7 +448,7 @@ def ts_project_macro(
map_outs = _out_paths(srcs, out_dir, root_dir, ".js.map") if source_map and not emit_declaration_only else [],
typings_outs = _out_paths(srcs, typings_out_dir, root_dir, ".d.ts") if declaration or composite else [],
typing_maps_outs = _out_paths(srcs, typings_out_dir, root_dir, ".d.ts.map") if declaration_map else [],
buildinfo_out = tsconfig[:-5] + ".tsbuildinfo" if composite or incremental else None,
buildinfo_out = tsbuildinfo_path if composite or incremental else None,
tsc = tsc,
**kwargs
)
34 changes: 30 additions & 4 deletions packages/typescript/internal/ts_project_options_validator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import {relative} from 'path';
import * as ts from 'typescript';

const diagnosticsHost: ts.FormatDiagnosticsHost = {
Expand Down Expand Up @@ -29,14 +30,37 @@ function main([tsconfigPath, output, target, attrsStr]: string[]): 0|1 {

const failures: string[] = [];
const buildozerCmds: string[] = [];

function getTsOption(option) {
if (typeof (options[option]) === 'string') {
// Currently the only string-typed options are filepaths.
// TypeScript will resolve these to a project path
// so when echoing that back to the user, we need to reverse that resolution.
// First turn //path/to/pkg:tsconfig into path/to/pkg
const packageDir = target.substr(2, target.indexOf(':') - 2);
return relative(packageDir, options[option] as string);
}
return options[option];
}

function check(option: string, attr?: string) {
attr = attr || option;
// treat compilerOptions undefined as false
const optionVal = options[option] === undefined ? false : options[option];
if (optionVal !== attrs[attr]) {
const optionVal = getTsOption(option);
const match = optionVal === attrs[attr] ||
(optionVal === undefined && (attrs[attr] === false || attrs[attr] === ''));
if (!match) {
failures.push(
`attribute ${attr}=${attrs[attr]} does not match compilerOptions.${option}=${optionVal}`);
buildozerCmds.push(`set ${attr} ${optionVal ? 'True' : 'False'}`);
if (typeof (optionVal) === 'boolean') {
buildozerCmds.push(`set ${attr} ${optionVal ? 'True' : 'False'}`);
} else if (typeof (optionVal) === 'string') {
buildozerCmds.push(`set ${attr} \"${optionVal}\"`);
} else if (optionVal === undefined) {
// nothing to sync
} else {
throw new Error(`cannot check option ${option} of type ${typeof (option)}`);
}
}
}

Expand All @@ -46,6 +70,7 @@ function main([tsconfigPath, output, target, attrsStr]: string[]): 0|1 {
check('composite');
check('declaration');
check('incremental');
check('tsBuildInfoFile', 'ts_build_info_file');

if (failures.length > 0) {
console.error(`ERROR: ts_project rule ${
Expand All @@ -70,6 +95,7 @@ function main([tsconfigPath, output, target, attrsStr]: string[]): 0|1 {
// incremental: ${attrs.incremental}
// source_map: ${attrs.source_map}
// emit_declaration_only: ${attrs.emit_declaration_only}
// ts_build_info_file: ${attrs.ts_build_info_file}
`,
'utf-8');
return 0;
Expand All @@ -81,4 +107,4 @@ if (require.main === module) {
} catch (e) {
console.error(process.argv[1], e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
load("//packages/typescript:index.bzl", "ts_project")

ts_project(
name = "tsconfig",
composite = True,
ts_build_info_file = "my.tsbuildinfo",
)
1 change: 1 addition & 0 deletions packages/typescript/test/ts_project/tsbuildinfofile/a.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const a: string = '';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"composite": true,
"tsBuildInfoFile": "my.tsbuildinfo",
"types": []
}
}

0 comments on commit 1e66b17

Please sign in to comment.