Skip to content

Commit

Permalink
feat: support --noEmit for type-checking as a validation action
Browse files Browse the repository at this point in the history
  • Loading branch information
jacobgardner authored and jbedard committed Sep 4, 2024
1 parent ed84211 commit a2220ed
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 55 deletions.
12 changes: 7 additions & 5 deletions docs/rules.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions e2e/test/common.bats
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ function ts_project() {
local source_map=""
local declaration=""
local composite=""
local tranpsiler=""
while (($# > 0)); do
case "$1" in
--path)
Expand Down Expand Up @@ -215,6 +216,10 @@ function ts_project() {
shift
composite="composite = True,"
;;
--mockTranspiler)
shift;
transpiler="transpiler = mock,"
;;
--)
shift
break
Expand All @@ -238,6 +243,7 @@ function ts_project() {
load("@aspect_rules_ts//ts:defs.bzl", "ts_project")
${npm_link_all_packages}load("@npm//:defs.bzl", "npm_link_all_packages")
${npm_link_all_packages}npm_link_all_packages(name = "node_modules")
load("@aspect_rules_ts//ts/test:mock_transpiler.bzl", "mock")
ts_project(
name = "${name}",
Expand Down
30 changes: 30 additions & 0 deletions e2e/test/validation.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
load "common.bats"

setup() {
cd $BATS_FILE_TMPDIR
}

teardown() {
bazel shutdown
rm -rf $BATS_FILE_TMPDIR/*
}


@test 'When tsc is only used for type-checking with a type-error, should only fail when validations are enabled' {
workspace

echo "export const a: string = 1;" > ./source.ts
tsconfig
ts_project --mockTranspiler --src "source.ts"

run bazel build :foo --norun_validations
assert_success
run cat bazel-bin/source.js
assert_success
# Mock transpiler just copies source input to output
assert_output -p 'export const a: string = 1;'

run bazel build :foo --run_validations
assert_failure
assert_output -p "error TS2322: Type 'number' is not assignable to type 'string'"
}
15 changes: 10 additions & 5 deletions ts/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ def ts_project(
preserve_jsx = False,
composite = False,
incremental = False,
no_emit = False,
emit_declaration_only = False,
transpiler = None,
ts_build_info_file = None,
Expand Down Expand Up @@ -215,6 +216,8 @@ def ts_project(
Instructs Bazel to expect a `.tsbuildinfo` output and a `.d.ts` output for each `.ts` source.
incremental: Whether the `incremental` bit is set in the tsconfig.
Instructs Bazel to expect a `.tsbuildinfo` output.
no_emit: Whether the `noEmit` bit is set in the tsconfig.
Instructs Bazel *not* to expect any outputs. Only a validation action is used.
emit_declaration_only: Whether 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.
Expand Down Expand Up @@ -276,6 +279,7 @@ def ts_project(
source_map = compiler_options.setdefault("sourceMap", source_map)
declaration = compiler_options.setdefault("declaration", declaration)
declaration_map = compiler_options.setdefault("declarationMap", declaration_map)
no_emit = compiler_options.setdefault("noEmit", no_emit)
emit_declaration_only = compiler_options.setdefault("emitDeclarationOnly", emit_declaration_only)
allow_js = compiler_options.setdefault("allowJs", allow_js)
if resolve_json_module != None:
Expand Down Expand Up @@ -309,14 +313,14 @@ def ts_project(
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"

tsc_typings_outs = _lib.calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js)
tsc_typing_maps_outs = _lib.calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js)
tsc_typings_outs = _lib.calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, no_emit)
tsc_typing_maps_outs = _lib.calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js, no_emit)

tsc_js_outs = []
tsc_map_outs = []
if not transpiler or transpiler == "tsc":
tsc_js_outs = _lib.calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, emit_declaration_only)
tsc_map_outs = _lib.calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only)
if no_emit or not transpiler or transpiler == "tsc":
tsc_js_outs = _lib.calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, no_emit, emit_declaration_only)
tsc_map_outs = _lib.calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, no_emit, emit_declaration_only)
tsc_target_name = name
else:
# To stitch together a tree of ts_project where transpiler is a separate rule,
Expand Down Expand Up @@ -401,6 +405,7 @@ def ts_project(
typings_outs = tsc_typings_outs,
typing_maps_outs = tsc_typing_maps_outs,
buildinfo_out = tsbuildinfo_path if composite or incremental else None,
no_emit = no_emit,
emit_declaration_only = emit_declaration_only,
tsc = tsc,
tsc_worker = tsc_worker,
Expand Down
19 changes: 11 additions & 8 deletions ts/private/ts_lib.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ COMPILER_OPTION_ATTRS = {
"declaration_map": attr.bool(
doc = "https://www.typescriptlang.org/tsconfig#declarationMap",
),
"no_emit": attr.bool(
doc = "https://www.typescriptlang.org/tsconfig#noEmit",
),
"emit_declaration_only": attr.bool(
doc = "https://www.typescriptlang.org/tsconfig#emitDeclarationOnly",
),
Expand Down Expand Up @@ -234,8 +237,8 @@ def _validate_tsconfig_dirs(root_dir, out_dir, typings_out_dir):
if typings_out_dir and typings_out_dir.find("../") != -1:
fail("typings_out_dir cannot output to parent directory")

def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, emit_declaration_only):
if emit_declaration_only:
def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, preserve_jsx, no_emit, emit_declaration_only):
if no_emit or emit_declaration_only:
return []

exts = {
Expand All @@ -253,8 +256,8 @@ def _calculate_js_outs(srcs, out_dir, root_dir, allow_js, resolve_json_module, p

return _to_js_out_paths(srcs, out_dir, root_dir, allow_js, resolve_json_module, exts)

def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_declaration_only):
if not source_map or emit_declaration_only:
def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, no_emit, emit_declaration_only):
if no_emit or not source_map or emit_declaration_only:
return []

exts = {
Expand All @@ -269,8 +272,8 @@ def _calculate_map_outs(srcs, out_dir, root_dir, source_map, preserve_jsx, emit_

return _to_js_out_paths(srcs, out_dir, root_dir, False, False, exts)

def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js):
if not (declaration or composite):
def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, composite, allow_js, no_emit):
if no_emit or not (declaration or composite):
return []

exts = {
Expand All @@ -283,8 +286,8 @@ def _calculate_typings_outs(srcs, typings_out_dir, root_dir, declaration, compos

return _to_js_out_paths(srcs, typings_out_dir, root_dir, allow_js, False, exts)

def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js):
if not declaration_map:
def _calculate_typing_maps_outs(srcs, typings_out_dir, root_dir, declaration_map, allow_js, no_emit):
if no_emit or not declaration_map:
return []

exts = {
Expand Down
Loading

0 comments on commit a2220ed

Please sign in to comment.