diff --git a/docs/rules.md b/docs/rules.md index 2ed71fb0..b96db9d5 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -36,12 +36,12 @@ extended configuration file as well, to pass them both to the TypeScript compile
 ts_project_rule(name, deps, srcs, data, allow_js, args, assets, buildinfo_out, composite,
-                declaration, declaration_dir, declaration_map, declaration_transpile,
-                emit_declaration_only, extends, incremental, is_typescript_5_or_greater,
-                isolated_typecheck, js_outs, map_outs, no_emit, out_dir, preserve_jsx,
-                pretranspiled_dts, pretranspiled_js, resolve_json_module, resource_set, root_dir,
-                source_map, supports_workers, transpile, ts_build_info_file, tsc, tsc_worker,
-                tsconfig, typing_maps_outs, typings_outs, validate, validator)
+                copy_data_to_bin, declaration, declaration_dir, declaration_map,
+                declaration_transpile, emit_declaration_only, extends, incremental,
+                is_typescript_5_or_greater, isolated_typecheck, js_outs, map_outs, no_emit, out_dir,
+                preserve_jsx, pretranspiled_dts, pretranspiled_js, resolve_json_module, resource_set,
+                root_dir, source_map, supports_workers, transpile, ts_build_info_file, tsc,
+                tsc_worker, tsconfig, typing_maps_outs, typings_outs, validate, validator)
 
Implementation rule behind the ts_project macro. @@ -64,6 +64,7 @@ for srcs and tsconfig, and pre-declaring output files. | assets | Files which are needed by a downstream build step such as a bundler.

See more details on the `assets` parameter of the `ts_project` macro. | List of labels | optional | `[]` | | buildinfo_out | Location in bazel-out where tsc will write a `.tsbuildinfo` file | Label | optional | `None` | | composite | https://www.typescriptlang.org/tsconfig#composite | Boolean | optional | `False` | +| copy_data_to_bin | When True, data files are copied to the Bazel output tree before being passed as inputs to runfiles. | Boolean | optional | `False` | | declaration | https://www.typescriptlang.org/tsconfig#declaration | Boolean | optional | `False` | | declaration_dir | https://www.typescriptlang.org/tsconfig#declarationDir | String | optional | `""` | | declaration_map | https://www.typescriptlang.org/tsconfig#declarationMap | Boolean | optional | `False` | @@ -125,7 +126,7 @@ ts_project(name, t declaration, source_map, declaration_map, resolve_json_module, preserve_jsx, composite, incremental, no_emit, emit_declaration_only, transpiler, declaration_transpiler, ts_build_info_file, tsc, tsc_worker, validate, validator, declaration_dir, out_dir, - root_dir, supports_workers, kwargs) + root_dir, copy_data_to_bin, supports_workers, kwargs) Compiles one TypeScript project using `tsc --project`. @@ -184,6 +185,7 @@ If you have problems getting your `ts_project` to work correctly, read the dedic | declaration_dir | String specifying a subdirectory under the bazel-out folder where generated declaration outputs are written. Equivalent to the TypeScript --declarationDir option. By default declarations are written to the out_dir. | `None` | | out_dir | String specifying a subdirectory under the bazel-out folder where outputs are written. Equivalent to the TypeScript --outDir option.

Note that Bazel always requires outputs be written under a subdirectory matching the input package, so if your rule appears in `path/to/my/package/BUILD.bazel` and out_dir = "foo" then the .js files will appear in `bazel-out/[arch]/bin/path/to/my/package/foo/*.js`.

By default the out_dir is the package's folder under bazel-out. | `None` | | root_dir | String specifying a subdirectory under the input package which should be consider the root directory of all the input files. Equivalent to the TypeScript --rootDir option. By default it is '.', meaning the source directory where the BUILD file lives. | `None` | +| copy_data_to_bin | When True, `data` files are copied to the Bazel output tree before being passed as inputs to runfiles. Defaults to `transpiler != None` due to backwards compatiblity (see #716/ #411). | `None` | | supports_workers | Whether the "Persistent Worker" protocol is enabled. This uses a custom `tsc` compiler to make rebuilds faster. Note that this causes some known correctness bugs, see https://docs.aspect.build/rules/aspect_rules_ts/docs/troubleshooting. We do not intend to fix these bugs.

Worker mode can be enabled for all `ts_project`s in a build with the global `--@aspect_rules_ts//ts:supports_workers` flag. To enable worker mode for all builds in the workspace, add `build --@aspect_rules_ts//ts:supports_workers` to the .bazelrc.

This is a "tri-state" attribute, accepting values `[-1, 0, 1]`. The behavior is:

- `-1`: use the value of the global `--@aspect_rules_ts//ts:supports_workers` flag. - `0`: Override the global flag, disabling workers for this target. - `1`: Override the global flag, enabling workers for this target. | `-1` | | kwargs | passed through to underlying [`ts_project_rule`](#ts_project_rule), eg. `visibility`, `tags` | none | diff --git a/ts/defs.bzl b/ts/defs.bzl index 0ad506f7..3204d736 100644 --- a/ts/defs.bzl +++ b/ts/defs.bzl @@ -59,6 +59,7 @@ def ts_project( declaration_dir = None, out_dir = None, root_dir = None, + copy_data_to_bin = None, supports_workers = -1, **kwargs): """Compiles one TypeScript project using `tsc --project`. @@ -240,6 +241,9 @@ def ts_project( 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. + copy_data_to_bin: When True, `data` files are copied to the Bazel output tree before being passed as inputs to runfiles. + Defaults to `transpiler != None` due to backwards compatiblity (see #716/ #411). + supports_workers: Whether the "Persistent Worker" protocol is enabled. This uses a custom `tsc` compiler to make rebuilds faster. Note that this causes some known correctness bugs, see @@ -421,6 +425,9 @@ def ts_project( "//conditions:default": False, }) + if copy_data_to_bin == None: + copy_data_to_bin = transpiler != None + ts_project_rule( name = name, srcs = srcs, @@ -460,6 +467,7 @@ def ts_project( is_typescript_5_or_greater = is_typescript_5_or_greater, validate = validate, validator = validator, + copy_data_to_bin = copy_data_to_bin, **kwargs ) diff --git a/ts/private/ts_lib.bzl b/ts/private/ts_lib.bzl index 2dd69f93..55952558 100644 --- a/ts/private/ts_lib.bzl +++ b/ts/private/ts_lib.bzl @@ -116,6 +116,10 @@ https://docs.aspect.build/rulesets/aspect_rules_js/docs/js_library#deps for more default = True, ), "validator": attr.label(mandatory = True, executable = True, cfg = "exec"), + "copy_data_to_bin": attr.bool( + doc = """When True, data files are copied to the Bazel output tree before being passed as inputs to runfiles.""", + default = False, + ), "_options": attr.label( default = "@aspect_rules_ts//ts:options", ), diff --git a/ts/private/ts_project.bzl b/ts/private/ts_project.bzl index 1393019f..80b329e2 100644 --- a/ts/private/ts_project.bzl +++ b/ts/private/ts_project.bzl @@ -325,6 +325,8 @@ See https://github.com/aspect-build/rules_ts/issues/361 for more details. sources = output_sources_depset, data = ctx.attr.data, deps = srcs_tsconfig_deps, + data_files = ctx.files.data, + copy_data_files_to_bin = ctx.attr.copy_data_to_bin, ) providers = [ diff --git a/ts/test/copy_data_to_bin/BUILD.bazel b/ts/test/copy_data_to_bin/BUILD.bazel new file mode 100644 index 00000000..52215ab5 --- /dev/null +++ b/ts/test/copy_data_to_bin/BUILD.bazel @@ -0,0 +1,78 @@ +# Test data file copying behavior. See +# +# https://github.com/aspect-build/rules_ts/issues/411 +# https://github.com/aspect-build/rules_ts/issues/716 +# +# Ideally, the behaviors with and without `transpiler` would align, but that is +# backwards incompatible. + +load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file") +load("@aspect_bazel_lib//lib:testing.bzl", "assert_contains") +load("@aspect_rules_js//js:defs.bzl", "js_binary", "js_run_binary") +load("//ts:defs.bzl", "ts_project") +load("//ts/test:mock_transpiler.bzl", "mock") + +copy_file( + name = "no_transpiler_src", + src = "check_has_data.ts", + out = "no_transpiler.ts", +) + +ts_project( + name = "no_transpiler", + srcs = ["no_transpiler.ts"], + data = ["data.txt"], + tsconfig = {}, +) + +js_binary( + name = "no_transpiler_bin", + data = [":no_transpiler"], + entry_point = "no_transpiler.ts", +) + +js_run_binary( + name = "no_transpiler_gen", + chdir = package_name(), + stdout = "no_transpiler_out.txt", + tool = ":no_transpiler_bin", +) + +assert_contains( + name = "no_transpiler_test", + actual = "no_transpiler_out.txt", + expected = "false", +) + +copy_file( + name = "with_transpiler_src", + src = "check_has_data.ts", + out = "with_transpiler.ts", +) + +ts_project( + name = "with_transpiler", + srcs = ["with_transpiler.ts"], + data = ["data.txt"], + transpiler = mock, + tsconfig = {}, +) + +js_binary( + name = "with_transpiler_bin", + data = [":with_transpiler"], + entry_point = "with_transpiler.js", +) + +js_run_binary( + name = "with_transpiler_gen", + chdir = package_name(), + stdout = "with_transpiler_out.txt", + tool = ":with_transpiler_bin", +) + +assert_contains( + name = "with_transpiler_test", + actual = "with_transpiler_out.txt", + expected = "true", +) diff --git a/ts/test/copy_data_to_bin/check_has_data.ts b/ts/test/copy_data_to_bin/check_has_data.ts new file mode 100644 index 00000000..7235a5d4 --- /dev/null +++ b/ts/test/copy_data_to_bin/check_has_data.ts @@ -0,0 +1,4 @@ +// @ts-ignore +const { readdirSync } = require("node:fs"); + +console.log(readdirSync(".").includes("data.txt")); diff --git a/ts/test/copy_data_to_bin/data.txt b/ts/test/copy_data_to_bin/data.txt new file mode 100644 index 00000000..f7fbb8f1 --- /dev/null +++ b/ts/test/copy_data_to_bin/data.txt @@ -0,0 +1 @@ +irrelevant data in a file