feat: add phase 6 js_library and ts_library bootstrap
This commit is contained in:
committed by
copilot-swe-agent[bot]
parent
a4f6b55d43
commit
8463e94e00
@@ -34,3 +34,9 @@ Phase 5 bootstrap is in place:
|
||||
- Bundle rule `bun_bundle` (`/internal/bun_bundle.bzl`)
|
||||
- Public export via `bun/defs.bzl`
|
||||
- Focused output/minify tests (`//tests/bundle_test:all`)
|
||||
|
||||
Phase 6 bootstrap is in place:
|
||||
|
||||
- Source grouping rules `js_library` / `ts_library` (`/internal/js_library.bzl`)
|
||||
- Transitive `deps` propagation wired into `bun_bundle` and `bun_test`
|
||||
- Focused dependency-propagation tests (`//tests/library_test:all`)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
load("//internal:bun_binary.bzl", _bun_binary = "bun_binary")
|
||||
load("//internal:bun_bundle.bzl", _bun_bundle = "bun_bundle")
|
||||
load("//internal:bun_test.bzl", _bun_test = "bun_test")
|
||||
load("//internal:js_library.bzl", _js_library = "js_library", _ts_library = "ts_library")
|
||||
load(":toolchain.bzl", _BunToolchainInfo = "BunToolchainInfo", _bun_toolchain = "bun_toolchain")
|
||||
|
||||
visibility("public")
|
||||
@@ -8,5 +9,7 @@ visibility("public")
|
||||
bun_binary = _bun_binary
|
||||
bun_bundle = _bun_bundle
|
||||
bun_test = _bun_test
|
||||
js_library = _js_library
|
||||
ts_library = _ts_library
|
||||
BunToolchainInfo = _BunToolchainInfo
|
||||
bun_toolchain = _bun_toolchain
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Rule for bundling JS/TS sources with Bun."""
|
||||
|
||||
load("//internal:js_library.bzl", "BunSourcesInfo")
|
||||
|
||||
|
||||
def _output_name(target_name, entry):
|
||||
stem = entry.basename.rsplit(".", 1)[0]
|
||||
@@ -13,6 +15,11 @@ def _bun_bundle_impl(ctx):
|
||||
transitive_inputs = []
|
||||
if ctx.attr.node_modules:
|
||||
transitive_inputs.append(ctx.attr.node_modules[DefaultInfo].files)
|
||||
for dep in ctx.attr.deps:
|
||||
if BunSourcesInfo in dep:
|
||||
transitive_inputs.append(dep[BunSourcesInfo].transitive_sources)
|
||||
else:
|
||||
transitive_inputs.append(dep[DefaultInfo].files)
|
||||
|
||||
outputs = []
|
||||
for entry in ctx.files.entry_points:
|
||||
@@ -59,6 +66,7 @@ bun_bundle = rule(
|
||||
allow_files = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"],
|
||||
),
|
||||
"node_modules": attr.label(),
|
||||
"deps": attr.label_list(),
|
||||
"data": attr.label_list(allow_files = True),
|
||||
"target": attr.string(
|
||||
default = "browser",
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"""Rule for running test suites with Bun."""
|
||||
|
||||
load("//internal:js_library.bzl", "BunSourcesInfo")
|
||||
|
||||
|
||||
def _shell_quote(value):
|
||||
return "'" + value.replace("'", "'\"'\"'") + "'"
|
||||
@@ -34,6 +36,11 @@ exec "{bun_bin}" test {src_args} "${{extra_args[@]}}" "$@"
|
||||
transitive_files = []
|
||||
if ctx.attr.node_modules:
|
||||
transitive_files.append(ctx.attr.node_modules[DefaultInfo].files)
|
||||
for dep in ctx.attr.deps:
|
||||
if BunSourcesInfo in dep:
|
||||
transitive_files.append(dep[BunSourcesInfo].transitive_sources)
|
||||
else:
|
||||
transitive_files.append(dep[DefaultInfo].files)
|
||||
|
||||
runfiles = ctx.runfiles(
|
||||
files = [bun_bin] + ctx.files.srcs + ctx.files.data,
|
||||
@@ -56,6 +63,7 @@ bun_test = rule(
|
||||
allow_files = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"],
|
||||
),
|
||||
"node_modules": attr.label(),
|
||||
"deps": attr.label_list(),
|
||||
"data": attr.label_list(allow_files = True),
|
||||
},
|
||||
test = True,
|
||||
|
||||
40
internal/js_library.bzl
Normal file
40
internal/js_library.bzl
Normal file
@@ -0,0 +1,40 @@
|
||||
"""Lightweight JS/TS source grouping rules."""
|
||||
|
||||
BunSourcesInfo = provider(fields = ["transitive_sources"])
|
||||
|
||||
|
||||
def _bun_library_impl(ctx):
|
||||
transitive_sources = [
|
||||
dep[BunSourcesInfo].transitive_sources
|
||||
for dep in ctx.attr.deps
|
||||
if BunSourcesInfo in dep
|
||||
]
|
||||
all_sources = depset(
|
||||
direct = ctx.files.srcs,
|
||||
transitive = transitive_sources,
|
||||
)
|
||||
return [
|
||||
BunSourcesInfo(transitive_sources = all_sources),
|
||||
DefaultInfo(files = all_sources),
|
||||
]
|
||||
|
||||
|
||||
js_library = rule(
|
||||
implementation = _bun_library_impl,
|
||||
attrs = {
|
||||
"srcs": attr.label_list(
|
||||
allow_files = [".js", ".jsx", ".mjs", ".cjs"],
|
||||
),
|
||||
"deps": attr.label_list(),
|
||||
},
|
||||
)
|
||||
|
||||
ts_library = rule(
|
||||
implementation = _bun_library_impl,
|
||||
attrs = {
|
||||
"srcs": attr.label_list(
|
||||
allow_files = [".ts", ".tsx"],
|
||||
),
|
||||
"deps": attr.label_list(),
|
||||
},
|
||||
)
|
||||
41
tests/library_test/BUILD.bazel
Normal file
41
tests/library_test/BUILD.bazel
Normal file
@@ -0,0 +1,41 @@
|
||||
load("//bun:defs.bzl", "bun_bundle", "bun_test", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "helper_lib",
|
||||
srcs = ["helper.ts"],
|
||||
target_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
)
|
||||
|
||||
bun_bundle(
|
||||
name = "bundle_with_deps",
|
||||
entry_points = ["app.ts"],
|
||||
deps = [":helper_lib"],
|
||||
target_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
)
|
||||
|
||||
sh_test(
|
||||
name = "bundle_dep_propagation_test",
|
||||
srcs = ["verify_bundle.sh"],
|
||||
args = ["$(location :bundle_with_deps)"],
|
||||
data = [":bundle_with_deps"],
|
||||
target_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
)
|
||||
|
||||
bun_test(
|
||||
name = "test_with_deps",
|
||||
srcs = ["app.test.ts"],
|
||||
deps = [":helper_lib"],
|
||||
target_compatible_with = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:linux",
|
||||
],
|
||||
)
|
||||
6
tests/library_test/app.test.ts
Normal file
6
tests/library_test/app.test.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { greeting } from "./helper";
|
||||
|
||||
test("uses helper from ts_library dep", () => {
|
||||
expect(greeting("test")).toBe("hello-test");
|
||||
});
|
||||
3
tests/library_test/app.ts
Normal file
3
tests/library_test/app.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { greeting } from "./helper";
|
||||
|
||||
console.log(greeting("bundle"));
|
||||
3
tests/library_test/helper.ts
Normal file
3
tests/library_test/helper.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
export function greeting(name: string): string {
|
||||
return `hello-${name}`;
|
||||
}
|
||||
9
tests/library_test/verify_bundle.sh
Executable file
9
tests/library_test/verify_bundle.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
bundle="$1"
|
||||
|
||||
if [[ ! -s "${bundle}" ]]; then
|
||||
echo "Expected bundled output to exist and be non-empty: ${bundle}" >&2
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user