diff --git a/WORKSPACE b/WORKSPACE index eb010a4..19e7f82 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -16,7 +16,7 @@ load("//swc:repositories.bzl", "swc_register_toolchains") swc_register_toolchains( name = "default_swc", - swc_version = "v1.2.119", + swc_version = "v1.2.141", ) load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains") diff --git a/docs/swc.md b/docs/swc.md index 4d816b8..1b6f37d 100644 --- a/docs/swc.md +++ b/docs/swc.md @@ -16,7 +16,7 @@ swc(name = "transpile") ## swc_transpiler
-swc_transpiler(name, args, data, js_outs, map_outs, output_dir, srcs, swc_cli, swcrc) +swc_transpiler(name, args, data, js_outs, map_outs, output_dir, source_maps, srcs, swc_cli, swcrc)Underlying rule for the `swc` macro. @@ -37,6 +37,7 @@ for example to set your own output labels for `js_outs`. | js_outs | list of expected JavaScript output files.
-swc(name, srcs, args, data, output_dir, swcrc, source_maps, source_map_outputs, kwargs) +swc(name, srcs, args, data, output_dir, swcrc, source_maps, kwargs)Execute the swc compiler @@ -63,8 +64,7 @@ Execute the swc compiler | data | runtime dependencies to be propagated in the runfiles |
[]
|
| output_dir | whether to produce a directory output rather than individual files | False
|
| swcrc | label of a configuration file for swc, see https://swc.rs/docs/configuration/swcrc | None
|
-| source_maps | If set, the --source-maps argument is passed to the swc cli with the value. True/False are automaticaly converted to "true"/"false" string values the cli expects. If source_maps is "true" or "both" then source_map_outputs is automatically set to True. | None
|
-| source_map_outputs | if the rule is expected to produce a .js.map file output for each .js file output | False
|
+| source_maps | If set, the --source-maps argument is passed to the swc cli with the value. See https://swc.rs/docs/usage/cli#--source-maps--s True/False are automaticaly converted to "true"/"false" string values the cli expects. | False
|
| kwargs | additional named parameters like tags or visibility | none |
diff --git a/examples/custom_outs/BUILD.bazel b/examples/custom_outs/BUILD.bazel
index 778dd1b..c6001a8 100644
--- a/examples/custom_outs/BUILD.bazel
+++ b/examples/custom_outs/BUILD.bazel
@@ -6,7 +6,7 @@ load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
name = "transpile_" + format,
srcs = ["in.ts"],
args = [
- "-C",
+ "--config",
"module.type=" + format,
],
js_outs = [format + "/out." + ("cjs" if format == "commonjs" else "js")],
diff --git a/examples/filegroup/BUILD.bazel b/examples/filegroup/BUILD.bazel
new file mode 100644
index 0000000..1170b76
--- /dev/null
+++ b/examples/filegroup/BUILD.bazel
@@ -0,0 +1,25 @@
+load("@aspect_rules_swc//swc:swc.bzl", "swc")
+
+filegroup(
+ name = "srcs",
+ srcs = [
+ "a.ts",
+ "b.ts",
+ ],
+)
+
+swc(
+ name = "transpile",
+ srcs = ["srcs"],
+ source_maps = "true",
+)
+
+# Since the srcs were in a filegroup, the swc macro cannot pre-declare the outputs.
+# So there is no label ":a.js" that we can reference from the build file.
+# However, a.js is still produced as one of the default outputs of the transpile rule.
+# We can verify this in an action that depends on the ":transpile" rule and reads the files.
+sh_test(
+ name = "check_outputs",
+ srcs = ["check_outputs.sh"],
+ data = [":transpile"],
+)
diff --git a/examples/filegroup/a.ts b/examples/filegroup/a.ts
new file mode 100644
index 0000000..f6c1fdd
--- /dev/null
+++ b/examples/filegroup/a.ts
@@ -0,0 +1 @@
+export const a: string = "a";
diff --git a/examples/filegroup/b.ts b/examples/filegroup/b.ts
new file mode 100644
index 0000000..bd865e3
--- /dev/null
+++ b/examples/filegroup/b.ts
@@ -0,0 +1 @@
+export const b: string = "b";
diff --git a/examples/filegroup/check_outputs.sh b/examples/filegroup/check_outputs.sh
new file mode 100755
index 0000000..6a4faf9
--- /dev/null
+++ b/examples/filegroup/check_outputs.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+set -o errexit
+
+cd "$TEST_SRCDIR/$TEST_WORKSPACE/$(dirname $TEST_TARGET)"
+grep "export var a" filegroup/a.js
+grep "sourceMappingURL=a.js.map" filegroup/a.js
+grep "../../../../../examples/filegroup/a.ts" filegroup/a.js.map
\ No newline at end of file
diff --git a/swc/BUILD.bazel b/swc/BUILD.bazel
index df8cbed..3100e1d 100644
--- a/swc/BUILD.bazel
+++ b/swc/BUILD.bazel
@@ -63,6 +63,7 @@ bzl_library(
deps = [
"//swc/private:swc",
"@bazel_skylib//lib:paths",
+ "@bazel_skylib//lib:types",
],
)
diff --git a/swc/private/swc.bzl b/swc/private/swc.bzl
index 05c8584..6925c67 100644
--- a/swc/private/swc.bzl
+++ b/swc/private/swc.bzl
@@ -3,11 +3,30 @@
load("@bazel_skylib//lib:paths.bzl", "paths")
_attrs = {
- "srcs": attr.label_list(allow_files = True, mandatory = True, doc = "source files, typically .ts files in the source tree"),
- "args": attr.string_list(doc = "additional arguments to pass to swc cli, see https://swc.rs/docs/usage/cli"),
- "output_dir": attr.bool(doc = "whether to produce a directory output rather than individual files"),
- "data": attr.label_list(default = [], allow_files = True, doc = "runtime dependencies propagated to binaries that depend on this"),
- "swcrc": attr.label(allow_single_file = True, doc = "label of a configuration file for swc, see https://swc.rs/docs/configuration/swcrc"),
+ "srcs": attr.label_list(
+ doc = "source files, typically .ts files in the source tree",
+ allow_files = True,
+ mandatory = True,
+ ),
+ "args": attr.string_list(
+ doc = "additional arguments to pass to swc cli, see https://swc.rs/docs/usage/cli",
+ ),
+ "source_maps": attr.string(
+ doc = "see https://swc.rs/docs/usage/cli#--source-maps--s",
+ values = ["true", "false", "inline", "both"],
+ default = "false",
+ ),
+ "output_dir": attr.bool(
+ doc = "whether to produce a directory output rather than individual files",
+ ),
+ "data": attr.label_list(
+ doc = "runtime dependencies propagated to binaries that depend on this",
+ allow_files = True,
+ ),
+ "swcrc": attr.label(
+ doc = "label of a configuration file for swc, see https://swc.rs/docs/configuration/swcrc",
+ allow_single_file = True,
+ ),
"swc_cli": attr.label(
doc = "binary that executes the swc CLI",
default = "@aspect_rules_swc//swc:cli",
@@ -26,14 +45,41 @@ Can be empty, meaning no source maps should be produced.
If non-empty, there must be one for each entry in srcs, and in the same order."""),
}
+# In theory, swc can transform .js -> .js.
+# But this would cause Bazel outputs to collide with inputs so it requires some re-rooting scheme.
+# TODO: add this if users need it
+_SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".jsx", ".mjs", ".cjs"]
+
+def _is_supported_src(src):
+ return paths.split_extension(src)[-1] in _SUPPORTED_EXTENSIONS
+
+def _declare_outputs(ctx, paths):
+ return [ctx.actions.declare_file(p) for p in paths]
+
+# TODO: aspect_bazel_lib should provide this?
+def _relative_to_package(path, ctx):
+ for prefix in (ctx.bin_dir.path, ctx.label.package):
+ prefix += "/"
+ if path.startswith(prefix):
+ path = path[len(prefix):]
+ return path
+
+def _calculate_js_outs(srcs):
+ return [paths.replace_extension(f, ".js") for f in srcs if _is_supported_src(f)]
+
+def _calculate_map_outs(srcs, source_maps):
+ if source_maps in ["false", "inline"]:
+ return []
+ return [paths.replace_extension(f, ".js.map") for f in srcs if _is_supported_src(f)]
+
def _impl(ctx):
outputs = []
- source_maps = len(ctx.outputs.map_outs) > 0
binding = ctx.toolchains["@aspect_rules_swc//swc:toolchain_type"].swcinfo.binding
args = ctx.actions.args()
# Add user specified arguments *before* rule supplied arguments
args.add_all(ctx.attr.args)
+ args.add_all(["--source-maps", ctx.attr.source_maps])
if ctx.attr.output_dir:
if len(ctx.attr.srcs) != 1:
@@ -63,14 +109,23 @@ def _impl(ctx):
)
else:
- outputs.extend(ctx.outputs.js_outs)
- outputs.extend(ctx.outputs.map_outs)
+ srcs = [_relative_to_package(src.path, ctx) for src in ctx.files.srcs]
+ if len(ctx.attr.js_outs):
+ js_outs = ctx.outputs.js_outs
+ else:
+ js_outs = _declare_outputs(ctx, _calculate_js_outs(srcs))
+ if len(ctx.attr.map_outs):
+ map_outs = ctx.outputs.map_outs
+ else:
+ map_outs = _declare_outputs(ctx, _calculate_map_outs(srcs, ctx.attr.source_maps))
+ outputs.extend(js_outs)
+ outputs.extend(map_outs)
for i, src in enumerate(ctx.files.srcs):
- js_out = ctx.outputs.js_outs[i]
+ js_out = js_outs[i]
inputs = [src] + ctx.toolchains["@aspect_rules_swc//swc:toolchain_type"].swcinfo.tool_files
outs = [js_out]
- if source_maps:
- outs.append(ctx.outputs.map_outs[i])
+ if ctx.attr.source_maps in ["true", "both"]:
+ outs.append(map_outs[i])
# Pass in the swcrc config if it is set
if ctx.file.swcrc:
@@ -119,4 +174,7 @@ swc = struct(
implementation = _impl,
attrs = dict(_attrs, **_outputs),
toolchains = ["@aspect_rules_swc//swc:toolchain_type"],
+ SUPPORTED_EXTENSIONS = _SUPPORTED_EXTENSIONS,
+ calculate_js_outs = _calculate_js_outs,
+ calculate_map_outs = _calculate_map_outs,
)
diff --git a/swc/private/versions.bzl b/swc/private/versions.bzl
index 888f927..eb19328 100644
--- a/swc/private/versions.bzl
+++ b/swc/private/versions.bzl
@@ -1,6 +1,21 @@
"Mirror of release info"
TOOL_VERSIONS = {
+ "v1.2.141": {
+ "android-arm-eabi": "sha384-1Kpl5sj2A50yTtZu5Ae7rGGY+t+0FYvcy/VCUp1IM8lW36RuhERqfahcWdmgtinB",
+ "android-arm64": "sha384-F/kmewGo2LlmyIeEQBnctRBJULmcSbko/5Gz1AJNxATWS1JUEX8C06AhdTpV7dk0",
+ "darwin-arm64": "sha384-UoQMYxodChrzQ785r7bo71aBDUqiu8qE8OSlE+64XrQUk7af0E9QfeA/uOKH81I8",
+ "darwin-x64": "sha384-nzfWWp7SHinJEGXyzeDFcprHs30oGJ4Xb6KV1NDPBMItkP37dGif9KQ4vjIcRiM2",
+ "freebsd-x64": "sha384-oS5YYV3h2CkOdPXy0ERp4/33EMn/iBDA353qp7zlSDsfuFpcCjdauFkMEiAwIipi",
+ "linux-arm-gnueabihf": "sha384-Y0xADrA2UwuwQq0OA3dNdjWLIqq4HwPR0lfhai3Ss+BvMDMpsjtSKLek/shav5++",
+ "linux-arm64-gnu": "sha384-lFM98s0YsVi2LRW5W082i+omOvkeOhiDFHWWdv2N91VGGXrmQxrMbhDgR85aPZBZ",
+ "linux-arm64-musl": "sha384-paCvYozCr4y0XQw4wbp5yi00GaAzMo6pqAxUMkYleY3is8H4obpRr48XCXEJ9ouq",
+ "linux-x64-gnu": "sha384-uNw6WyW05qRZhxam2ls9cQRXi9Cmx1+ItQ1+i2CgXuImHHl3lFhnlMCgvvJTdRyL",
+ "linux-x64-musl": "sha384-uzzI2i5JdE8G/zwvQPGeMbemVIwRnnqWExifbcQGNVYQ614Md26Hhriw4Ej9YFRA",
+ "win32-arm64-msvc": "sha384-iBDJmWJVtxouMntcoGrPqpOEZP5OQrXDWPOE1+kIWSvmlC/JDkNhPL0zyiTxX/Bb",
+ "win32-ia32-msvc": "sha384-p9MgHvIpyHbBoRSbvmAe3llF6xTmjTvfPTjc04xoNgMiIL2wCRG5HaPWNEd/10i0",
+ "win32-x64-msvc": "sha384-4t9URv/+EEfnaU1sp9aFnG/CVWD3/biCq18o/MLvKiZw4ZzcRtyqWZz12aL/HDUY",
+ },
"v1.2.119": {
"android-arm64": "sha384-whzMbD0maV04vzMdOVfPQNDhpe3gWy9Tyg+SsXbzgA5oZDoqTjTM3e2Y5MeKWnz3",
"darwin-arm64": "sha384-2E4E13tCxfatne30Ss2FY+o0T8ebMV4gO999oqWPbehFxcaQI/6+D304xGZPF8/x",
diff --git a/swc/swc.bzl b/swc/swc.bzl
index 0ee3eff..08ae7e2 100644
--- a/swc/swc.bzl
+++ b/swc/swc.bzl
@@ -10,7 +10,7 @@ swc(name = "transpile")
"""
load("//swc/private:swc.bzl", _swc_lib = "swc")
-load("@bazel_skylib//lib:paths.bzl", "paths")
+load("@bazel_skylib//lib:types.bzl", "types")
swc_transpiler = rule(
doc = """Underlying rule for the `swc` macro.
@@ -24,18 +24,7 @@ for example to set your own output labels for `js_outs`.""",
toolchains = _swc_lib.toolchains,
)
-# In theory, swc can transform .js -> .js.
-# But this would cause Bazel outputs to collide with inputs so it requires some re-rooting scheme.
-# TODO: add this if users need it
-_SUPPORTED_EXTENSIONS = [".ts", ".tsx", ".jsx", ".mjs", ".cjs"]
-
-def _is_supported_src(src):
- for e in _SUPPORTED_EXTENSIONS:
- if src.endswith(e):
- return True
- return False
-
-def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = None, source_maps = None, source_map_outputs = False, **kwargs):
+def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = None, source_maps = False, **kwargs):
"""Execute the swc compiler
Args:
@@ -45,14 +34,15 @@ def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = Non
output_dir: whether to produce a directory output rather than individual files
args: additional arguments to pass to swc cli, see https://swc.rs/docs/usage/cli
source_maps: If set, the --source-maps argument is passed to the swc cli with the value.
+ See https://swc.rs/docs/usage/cli#--source-maps--s
True/False are automaticaly converted to "true"/"false" string values the cli expects.
- If source_maps is "true" or "both" then source_map_outputs is automatically set to True.
- source_map_outputs: if the rule is expected to produce a .js.map file output for each .js file output
swcrc: label of a configuration file for swc, see https://swc.rs/docs/configuration/swcrc
**kwargs: additional named parameters like tags or visibility
"""
if srcs == None:
- srcs = native.glob(["**/*" + e for e in _SUPPORTED_EXTENSIONS])
+ srcs = native.glob(["**/*" + e for e in _swc_lib.SUPPORTED_EXTENSIONS])
+ elif not types.is_list(srcs):
+ fail("srcs must be a list, not a " + type(srcs))
# Convert source_maps True/False to "true"/"false" args value
if source_maps == True:
@@ -60,24 +50,13 @@ def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = Non
elif source_maps == False:
source_maps = "false"
- # Detect if we are expecting sourcemap outputs
- if not source_map_outputs:
- source_map_outputs = (source_maps == "true" or source_maps == "both")
-
- # Add the source_maps arg
- if source_maps:
- args = args + ["--source-maps", source_maps]
-
# Determine js & map outputs
js_outs = []
map_outs = []
if not output_dir:
- for f in srcs:
- if _is_supported_src(f):
- js_outs.append(paths.replace_extension(f, ".js"))
- if source_map_outputs:
- map_outs.append(paths.replace_extension(f, ".js.map"))
+ js_outs = _swc_lib.calculate_js_outs(srcs)
+ map_outs = _swc_lib.calculate_map_outs(srcs, source_maps)
swc_transpiler(
name = name,
@@ -85,6 +64,7 @@ def swc(name, srcs = None, args = [], data = [], output_dir = False, swcrc = Non
js_outs = js_outs,
map_outs = map_outs,
output_dir = output_dir,
+ source_maps = source_maps,
args = args,
data = data,
swcrc = swcrc,
diff --git a/swc/tests/versions_test.bzl b/swc/tests/versions_test.bzl
index 79d3887..00cd2ab 100644
--- a/swc/tests/versions_test.bzl
+++ b/swc/tests/versions_test.bzl
@@ -7,7 +7,7 @@ load("//swc/private:versions.bzl", "TOOL_VERSIONS")
def _smoke_test_impl(ctx):
env = unittest.begin(ctx)
- asserts.equals(env, "v1.2.119", TOOL_VERSIONS.keys()[0])
+ asserts.equals(env, "v1.2.141", TOOL_VERSIONS.keys()[0])
return unittest.end(env)
# The unittest library requires that we export the test cases as named test rules,