From 1a449c22b999b5c9c078536274f0c48e083adab5 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 02:47:55 +0000 Subject: [PATCH 01/25] Initial plan From 6a29ae954e561652a6778679ee5984e99530439d Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 02:54:12 +0000 Subject: [PATCH 02/25] feat: bootstrap bun toolchain skeleton and smoke test --- BUILD.bazel | 1 + MODULE.bazel | 6 ++ README.md | 11 ++- WORKSPACE | 5 ++ bun/BUILD.bazel | 103 ++++++++++++++++++++++ bun/defs.bzl | 9 ++ bun/repositories.bzl | 73 +++++++++++++++ bun/toolchain.bzl | 21 +++++ examples/basic/BUILD.bazel | 1 + examples/basic/README.md | 3 + internal/bun_binary.bzl | 2 + internal/bun_bundle.bzl | 2 + internal/bun_install.bzl | 2 + internal/bun_test.bzl | 2 + tests/BUILD.bazel | 1 + tests/toolchain_test/BUILD.bazel | 10 +++ tests/toolchain_test/toolchain_version.sh | 10 +++ 17 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 BUILD.bazel create mode 100644 MODULE.bazel create mode 100644 WORKSPACE create mode 100644 bun/BUILD.bazel create mode 100644 bun/defs.bzl create mode 100644 bun/repositories.bzl create mode 100644 bun/toolchain.bzl create mode 100644 examples/basic/BUILD.bazel create mode 100644 examples/basic/README.md create mode 100644 internal/bun_binary.bzl create mode 100644 internal/bun_bundle.bzl create mode 100644 internal/bun_install.bzl create mode 100644 internal/bun_test.bzl create mode 100644 tests/BUILD.bazel create mode 100644 tests/toolchain_test/BUILD.bazel create mode 100755 tests/toolchain_test/toolchain_version.sh diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 0000000..1c77d2a --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,6 @@ +module( + name = "rules_bun", + version = "0.1.0", +) + +bazel_dep(name = "platforms", version = "1.0.0") diff --git a/README.md b/README.md index 8c174f5..7f3275d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,12 @@ # rules_bun -Bazel rules for bun \ No newline at end of file +Bazel rules for bun. + +## Current status + +Phase 1 bootstrap is in place: + +- Bun toolchain rule and provider (`/bun/toolchain.bzl`) +- Platform-specific Bun repository downloads (`/bun/repositories.bzl`) +- Toolchain declarations and registration targets (`/bun/BUILD.bazel`) +- Smoke test for `bun --version` (`//tests/toolchain_test:bun_version_test`) diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..2f8ace5 --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,5 @@ +workspace(name = "rules_bun") + +load("//bun:repositories.bzl", "bun_register_toolchains") + +bun_register_toolchains() diff --git a/bun/BUILD.bazel b/bun/BUILD.bazel new file mode 100644 index 0000000..c84f88c --- /dev/null +++ b/bun/BUILD.bazel @@ -0,0 +1,103 @@ +load(":toolchain.bzl", "bun_toolchain") + +toolchain_type(name = "toolchain_type") + +bun_toolchain( + name = "linux_x64_toolchain_impl", + bun = "@bun_linux_x64//:bun", + version = "1.1.38", +) + +bun_toolchain( + name = "linux_aarch64_toolchain_impl", + bun = "@bun_linux_aarch64//:bun", + version = "1.1.38", +) + +bun_toolchain( + name = "darwin_x64_toolchain_impl", + bun = "@bun_darwin_x64//:bun", + version = "1.1.38", +) + +bun_toolchain( + name = "darwin_aarch64_toolchain_impl", + bun = "@bun_darwin_aarch64//:bun", + version = "1.1.38", +) + +bun_toolchain( + name = "windows_x64_toolchain_impl", + bun = "@bun_windows_x64//:bun", + version = "1.1.38", +) + +toolchain( + name = "linux_x64_toolchain", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], + toolchain = ":linux_x64_toolchain_impl", + toolchain_type = ":toolchain_type", +) + +toolchain( + name = "linux_aarch64_toolchain", + exec_compatible_with = [ + "@platforms//cpu:arm64", + "@platforms//os:linux", + ], + target_compatible_with = [ + "@platforms//cpu:arm64", + "@platforms//os:linux", + ], + toolchain = ":linux_aarch64_toolchain_impl", + toolchain_type = ":toolchain_type", +) + +toolchain( + name = "darwin_x64_toolchain", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:macos", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:macos", + ], + toolchain = ":darwin_x64_toolchain_impl", + toolchain_type = ":toolchain_type", +) + +toolchain( + name = "darwin_aarch64_toolchain", + exec_compatible_with = [ + "@platforms//cpu:arm64", + "@platforms//os:macos", + ], + target_compatible_with = [ + "@platforms//cpu:arm64", + "@platforms//os:macos", + ], + toolchain = ":darwin_aarch64_toolchain_impl", + toolchain_type = ":toolchain_type", +) + +toolchain( + name = "windows_x64_toolchain", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + toolchain = ":windows_x64_toolchain_impl", + toolchain_type = ":toolchain_type", +) diff --git a/bun/defs.bzl b/bun/defs.bzl new file mode 100644 index 0000000..bfca96a --- /dev/null +++ b/bun/defs.bzl @@ -0,0 +1,9 @@ +load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") +load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") + +__all__ = [ + "BunToolchainInfo", + "bun_register_toolchains", + "bun_repositories", + "bun_toolchain", +] diff --git a/bun/repositories.bzl b/bun/repositories.bzl new file mode 100644 index 0000000..665bcf3 --- /dev/null +++ b/bun/repositories.bzl @@ -0,0 +1,73 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +_BUN_VERSION = "1.1.38" + +_BUN_ARCHIVES = { + "bun_linux_x64": { + "sha256": "a61da5357e28d4977fccd4851fed62ff4da3ea33853005c7dd93dac80bc53932", + "asset": "bun-linux-x64.zip", + "binary": "bun-linux-x64/bun", + }, + "bun_linux_aarch64": { + "sha256": "3b08fd0b31f745509e1fed9c690c80d1a32ef2b3c8d059583f643f696639bd21", + "asset": "bun-linux-aarch64.zip", + "binary": "bun-linux-aarch64/bun", + }, + "bun_darwin_x64": { + "sha256": "4e9814c9b2e64f9166ed8fc2a48f905a2195ea599b7ceda7ac821688520428a5", + "asset": "bun-darwin-x64.zip", + "binary": "bun-darwin-x64/bun", + }, + "bun_darwin_aarch64": { + "sha256": "bbc6fb0e7bb99e7e95001ba05105cf09d0b79c06941d9f6ee3d0b34dc1541590", + "asset": "bun-darwin-aarch64.zip", + "binary": "bun-darwin-aarch64/bun", + }, + "bun_windows_x64": { + "sha256": "52d6c588237c5a1071839dc20dc96f19ca9f8021b7757fa096d22927b0a44a8b", + "asset": "bun-windows-x64.zip", + "binary": "bun-windows-x64/bun.exe", + }, +} + + +def _declare_bun_repo(name, asset, sha256, binary, version): + if native.existing_rule(name): + return + + http_archive( + name = name, + urls = ["https://github.com/oven-sh/bun/releases/download/bun-v{}/{}".format(version, asset)], + sha256 = sha256, + build_file_content = """ +exports_files(["{binary}"]) + +filegroup( + name = "bun", + srcs = ["{binary}"], + visibility = ["//visibility:public"], +) +""".format(binary = binary), + ) + + +def bun_repositories(version = _BUN_VERSION): + for name, metadata in _BUN_ARCHIVES.items(): + _declare_bun_repo( + name = name, + asset = metadata["asset"], + sha256 = metadata["sha256"], + binary = metadata["binary"], + version = version, + ) + + +def bun_register_toolchains(version = _BUN_VERSION): + bun_repositories(version = version) + native.register_toolchains( + "//bun:darwin_aarch64_toolchain", + "//bun:darwin_x64_toolchain", + "//bun:linux_aarch64_toolchain", + "//bun:linux_x64_toolchain", + "//bun:windows_x64_toolchain", + ) diff --git a/bun/toolchain.bzl b/bun/toolchain.bzl new file mode 100644 index 0000000..0b29a13 --- /dev/null +++ b/bun/toolchain.bzl @@ -0,0 +1,21 @@ +BunToolchainInfo = provider(fields = ["bun_bin", "version"]) + + +def _bun_toolchain_impl(ctx): + return [ + platform_common.ToolchainInfo( + bun = BunToolchainInfo( + bun_bin = ctx.executable.bun, + version = ctx.attr.version, + ), + ), + ] + + +bun_toolchain = rule( + implementation = _bun_toolchain_impl, + attrs = { + "bun": attr.label(allow_single_file = True, executable = True, cfg = "exec"), + "version": attr.string(mandatory = True), + }, +) diff --git a/examples/basic/BUILD.bazel b/examples/basic/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/examples/basic/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/examples/basic/README.md b/examples/basic/README.md new file mode 100644 index 0000000..cba1cbf --- /dev/null +++ b/examples/basic/README.md @@ -0,0 +1,3 @@ +# basic example + +Placeholder for end-to-end bun rules example. diff --git a/internal/bun_binary.bzl b/internal/bun_binary.bzl new file mode 100644 index 0000000..e9808f9 --- /dev/null +++ b/internal/bun_binary.bzl @@ -0,0 +1,2 @@ +def bun_binary(**_kwargs): + fail("bun_binary is not implemented yet") diff --git a/internal/bun_bundle.bzl b/internal/bun_bundle.bzl new file mode 100644 index 0000000..b430850 --- /dev/null +++ b/internal/bun_bundle.bzl @@ -0,0 +1,2 @@ +def bun_bundle(**_kwargs): + fail("bun_bundle is not implemented yet") diff --git a/internal/bun_install.bzl b/internal/bun_install.bzl new file mode 100644 index 0000000..b7e5080 --- /dev/null +++ b/internal/bun_install.bzl @@ -0,0 +1,2 @@ +def bun_install(**_kwargs): + fail("bun_install is not implemented yet") diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl new file mode 100644 index 0000000..f013b9e --- /dev/null +++ b/internal/bun_test.bzl @@ -0,0 +1,2 @@ +def bun_test(**_kwargs): + fail("bun_test is not implemented yet") diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/tests/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/tests/toolchain_test/BUILD.bazel b/tests/toolchain_test/BUILD.bazel new file mode 100644 index 0000000..7d620d8 --- /dev/null +++ b/tests/toolchain_test/BUILD.bazel @@ -0,0 +1,10 @@ +sh_test( + name = "bun_version_test", + srcs = ["toolchain_version.sh"], + args = ["$(location @bun_linux_x64//:bun)"], + data = ["@bun_linux_x64//:bun"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) diff --git a/tests/toolchain_test/toolchain_version.sh b/tests/toolchain_test/toolchain_version.sh new file mode 100755 index 0000000..3024b9e --- /dev/null +++ b/tests/toolchain_test/toolchain_version.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +bun_path="$1" +version="$(${bun_path} --version)" + +if [[ ! "${version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then + echo "Unexpected bun version output: ${version}" >&2 + exit 1 +fi From 97c63c68f6a3a84240cd91071b73d7012463b17d Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 02:56:27 +0000 Subject: [PATCH 03/25] chore: centralize bun version and release URL constants --- bun/BUILD.bazel | 11 ++++++----- bun/repositories.bzl | 11 ++++++----- bun/version.bzl | 1 + 3 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 bun/version.bzl diff --git a/bun/BUILD.bazel b/bun/BUILD.bazel index c84f88c..ff310a9 100644 --- a/bun/BUILD.bazel +++ b/bun/BUILD.bazel @@ -1,35 +1,36 @@ load(":toolchain.bzl", "bun_toolchain") +load(":version.bzl", "BUN_VERSION") toolchain_type(name = "toolchain_type") bun_toolchain( name = "linux_x64_toolchain_impl", bun = "@bun_linux_x64//:bun", - version = "1.1.38", + version = BUN_VERSION, ) bun_toolchain( name = "linux_aarch64_toolchain_impl", bun = "@bun_linux_aarch64//:bun", - version = "1.1.38", + version = BUN_VERSION, ) bun_toolchain( name = "darwin_x64_toolchain_impl", bun = "@bun_darwin_x64//:bun", - version = "1.1.38", + version = BUN_VERSION, ) bun_toolchain( name = "darwin_aarch64_toolchain_impl", bun = "@bun_darwin_aarch64//:bun", - version = "1.1.38", + version = BUN_VERSION, ) bun_toolchain( name = "windows_x64_toolchain_impl", bun = "@bun_windows_x64//:bun", - version = "1.1.38", + version = BUN_VERSION, ) toolchain( diff --git a/bun/repositories.bzl b/bun/repositories.bzl index 665bcf3..a5b0e32 100644 --- a/bun/repositories.bzl +++ b/bun/repositories.bzl @@ -1,6 +1,5 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - -_BUN_VERSION = "1.1.38" +load(":version.bzl", "BUN_VERSION") _BUN_ARCHIVES = { "bun_linux_x64": { @@ -30,6 +29,8 @@ _BUN_ARCHIVES = { }, } +_BUN_GITHUB_RELEASE_URL_TEMPLATE = "https://github.com/oven-sh/bun/releases/download/bun-v{}/{}" + def _declare_bun_repo(name, asset, sha256, binary, version): if native.existing_rule(name): @@ -37,7 +38,7 @@ def _declare_bun_repo(name, asset, sha256, binary, version): http_archive( name = name, - urls = ["https://github.com/oven-sh/bun/releases/download/bun-v{}/{}".format(version, asset)], + urls = [_BUN_GITHUB_RELEASE_URL_TEMPLATE.format(version, asset)], sha256 = sha256, build_file_content = """ exports_files(["{binary}"]) @@ -51,7 +52,7 @@ filegroup( ) -def bun_repositories(version = _BUN_VERSION): +def bun_repositories(version = BUN_VERSION): for name, metadata in _BUN_ARCHIVES.items(): _declare_bun_repo( name = name, @@ -62,7 +63,7 @@ def bun_repositories(version = _BUN_VERSION): ) -def bun_register_toolchains(version = _BUN_VERSION): +def bun_register_toolchains(version = BUN_VERSION): bun_repositories(version = version) native.register_toolchains( "//bun:darwin_aarch64_toolchain", diff --git a/bun/version.bzl b/bun/version.bzl new file mode 100644 index 0000000..a0ad89c --- /dev/null +++ b/bun/version.bzl @@ -0,0 +1 @@ +BUN_VERSION = "1.1.38" From bf24f8dea0242a0fb78bb14c40eca5a8ee52f60b Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 04:00:17 +0100 Subject: [PATCH 04/25] docs: add plan to repo --- implementation_plan.md | 242 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 implementation_plan.md diff --git a/implementation_plan.md b/implementation_plan.md new file mode 100644 index 0000000..0e9c9bb --- /dev/null +++ b/implementation_plan.md @@ -0,0 +1,242 @@ +Here's a comprehensive plan for implementing a Bazel-native `bun_rules` package: + +--- + +## `bun_rules`: Bazel-Native Bun Implementation Plan + +### What Is This? + +A Bazel ruleset that integrates the [Bun](https://bun.sh) JavaScript runtime natively — similar to `rules_nodejs` but leveraging Bun's bundler, test runner, package manager, and runtime. The goal is hermetic, reproducible builds using Bun as the toolchain. + +--- + +## Phase 1: Repository Skeleton & Toolchain + +**Where to start.** Every Bazel ruleset begins with the toolchain — nothing else works without it. + +### 1.1 Repo Structure +``` +bun_rules/ +├── MODULE.bazel # Bzlmod module definition +├── WORKSPACE # Legacy workspace support +├── BUILD.bazel +├── bun/ +│ ├── repositories.bzl # Download bun binaries per platform +│ ├── toolchain.bzl # bun_toolchain rule +│ └── defs.bzl # Public API re-exports +├── internal/ +│ ├── bun_binary.bzl +│ ├── bun_test.bzl +│ ├── bun_install.bzl +│ └── bun_bundle.bzl +├── examples/ +│ └── basic/ +└── tests/ + ├── toolchain_test/ + ├── install_test/ + ├── binary_test/ + └── bundle_test/ +``` + +### 1.2 Toolchain Rule (`toolchain.bzl`) +```python +BunToolchainInfo = provider(fields = ["bun_bin", "version"]) + +bun_toolchain = rule( + implementation = _bun_toolchain_impl, + attrs = { + "bun": attr.label(allow_single_file = True, executable = True, cfg = "exec"), + "version": attr.string(), + }, +) +``` + +### 1.3 Binary Downloads (`repositories.bzl`) +Use `http_file` to fetch platform-specific Bun binaries: +- `bun-linux-x64`, `bun-linux-aarch64` +- `bun-darwin-x64`, `bun-darwin-aarch64` +- `bun-windows-x64.exe` + +Use SHA256 checksums pinned per Bun release. Register via `register_toolchains()`. + +**Tests needed:** +- `toolchain_resolution_test` — assert the correct binary is selected per `--platforms` +- `bun --version` smoke test via a `sh_test` + +--- + +## Phase 2: `bun_install` (Package Manager) + +Replaces `npm install` / `yarn`. This is the highest-leverage rule because every downstream rule depends on it. + +### Rule Design +```python +bun_install( + name = "node_modules", + package_json = "//:package.json", + bun_lockfile = "//:bun.lockb", +) +``` + +- Runs `bun install --frozen-lockfile` in a sandboxed action +- Outputs a `node_modules/` directory as a `TreeArtifact` +- Must be hermetic: no network in actions (vendor or use a repository rule to pre-fetch) + +### Key Challenges +- `bun.lockb` is binary — you need to commit it and treat it as a source file +- Network access during `bun install` breaks Bazel's sandbox; solve with either: + - A **repository rule** that runs install at analysis time (like `npm_install` in rules_nodejs) + - Or a **module extension** in Bzlmod + +**Tests needed:** +- Install succeeds with a valid `package.json` + `bun.lockb` +- Build fails (with a clear error) when `bun.lockb` is out of date +- Determinism test: run install twice, assert identical output digest +- Test that `node_modules` is correctly provided to downstream rules + +--- + +## Phase 3: `bun_binary` (Run JS/TS scripts) + +```python +bun_binary( + name = "my_script", + entry_point = "src/main.ts", + node_modules = "//:node_modules", + data = glob(["src/**"]), +) +``` + +- Wraps `bun run ` as a Bazel executable +- Provides `DefaultInfo` with a launcher script +- Handles both `.js` and `.ts` natively (no transpile step needed) + +**Tests needed:** +- `bun_binary` produces a runnable target (`bazel run`) +- TypeScript entry points work without separate compilation +- `data` deps are available at runtime +- Environment variables pass through correctly + +--- + +## Phase 4: `bun_test` (Test Runner) + +```python +bun_test( + name = "my_test", + srcs = ["src/foo.test.ts"], + node_modules = "//:node_modules", +) +``` + +- Wraps `bun test` with Bazel's test runner protocol +- Must exit with code 0/non-0 correctly +- Outputs JUnit XML for `--test_output` compatibility (use `bun test --reporter junit`) + +**Tests needed:** +- Passing test suite returns exit 0 +- Failing test suite returns exit non-0 (Bazel marks as FAILED) +- Test filtering via `--test_filter` works +- Coverage via `bun test --coverage` integrates with `bazel coverage` +- Tests are re-run when source files change (input tracking) +- Tests are **not** re-run when unrelated files change (cache correctness) + +--- + +## Phase 5: `bun_bundle` (Bundler) + +```python +bun_bundle( + name = "app_bundle", + entry_points = ["src/index.ts"], + node_modules = "//:node_modules", + target = "browser", # or "node", "bun" + format = "esm", # or "cjs", "iife" + minify = True, +) +``` + +- Runs `bun build` as a Bazel action +- Outputs are declared files (JS, sourcemaps, assets) +- Supports splitting, external packages, define/env vars + +**Tests needed:** +- Output file exists and has non-zero size +- `minify = True` produces smaller output than `minify = False` +- `external` packages are not bundled +- Sourcemaps are generated when requested +- Build is hermetic: same inputs → identical output digest (content hash) +- Invalid entry point produces a clear build error (not a cryptic Bazel failure) + +--- + +## Phase 6: `js_library` / `ts_library` (Source Grouping) + +Lightweight rules for grouping sources and propagating them through the dep graph: + +```python +ts_library( + name = "utils", + srcs = glob(["src/**/*.ts"]), + deps = [":node_modules"], +) +``` + +**Tests needed:** +- `deps` correctly propagate transitive sources to `bun_bundle` and `bun_test` +- Circular dep detection (or at least graceful failure) + +--- + +## Required Tests Summary + +| Category | Test | +|---|---| +| Toolchain | Correct binary resolves per platform | +| Toolchain | `bun --version` executes successfully | +| `bun_install` | Clean install works | +| `bun_install` | Stale lockfile fails with clear error | +| `bun_install` | Output is deterministic | +| `bun_binary` | JS entry point runs | +| `bun_binary` | TS entry point runs without compile step | +| `bun_binary` | Data files available at runtime | +| `bun_test` | Passing tests → exit 0 | +| `bun_test` | Failing tests → exit non-0 | +| `bun_test` | Cache hit: unchanged test not re-run | +| `bun_test` | Cache miss: changed source triggers re-run | +| `bun_test` | JUnit XML output parseable | +| `bun_bundle` | Output file produced | +| `bun_bundle` | Minification reduces output size | +| `bun_bundle` | Hermetic: identical inputs → identical digest | +| `bun_bundle` | External packages excluded correctly | +| Integration | `examples/basic` builds end-to-end with `bazel build //...` | +| Integration | `bazel test //...` passes all tests | + +--- + +## Development Sequence + +``` +1. Toolchain downloads + resolution ← start here +2. bun_install (repository rule approach) +3. bun_binary (simplest runtime rule) +4. bun_test +5. bun_bundle +6. js_library / ts_library +7. Bzlmod module extension for installs +8. CI matrix (linux-x64, darwin-arm64, windows) +9. Docs + examples +``` + +--- + +## Where to Start Right Now + +**Day 1:** Copy the pattern from [`rules_go`](https://github.com/bazelbuild/rules_go) or [`aspect-build/rules_js`](https://github.com/aspect-build/rules_js) for toolchain registration. Write `repositories.bzl` that fetches the Bun binary for your current platform only. Write a `sh_test` that calls `bun --version` and asserts it exits 0. Get that green. + +**Reference implementations to study:** +- `aspect-build/rules_js` — best modern reference for JS in Bazel +- `bazelbuild/rules_nodejs` — older but battle-tested patterns +- `bazelbuild/rules_python` — excellent toolchain download pattern to copy + +The toolchain is the entire foundation. Nothing else is possible without it being solid. \ No newline at end of file From 0095457f088ee806b6162ba89101ea22c4bc5fa2 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:05:01 +0000 Subject: [PATCH 05/25] feat: add phase 2 bun_install repository rule bootstrap --- README.md | 6 ++ bun/defs.bzl | 2 + internal/BUILD.bazel | 1 + internal/bun_install.bzl | 95 +++++++++++++++++++++++++++- tests/install_test/BUILD.bazel | 21 ++++++ tests/install_test/clean_install.sh | 22 +++++++ tests/install_test/stale_lockfile.sh | 41 ++++++++++++ 7 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 internal/BUILD.bazel create mode 100644 tests/install_test/BUILD.bazel create mode 100755 tests/install_test/clean_install.sh create mode 100755 tests/install_test/stale_lockfile.sh diff --git a/README.md b/README.md index 7f3275d..a07dae7 100644 --- a/README.md +++ b/README.md @@ -10,3 +10,9 @@ Phase 1 bootstrap is in place: - Platform-specific Bun repository downloads (`/bun/repositories.bzl`) - Toolchain declarations and registration targets (`/bun/BUILD.bazel`) - Smoke test for `bun --version` (`//tests/toolchain_test:bun_version_test`) + +Phase 2 bootstrap is in place: + +- Repository-rule based `bun_install` (`/internal/bun_install.bzl`) +- Public export via `bun/defs.bzl` +- Focused install behavior tests (`//tests/install_test:all`) diff --git a/bun/defs.bzl b/bun/defs.bzl index bfca96a..220f084 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -1,8 +1,10 @@ +load("//internal:bun_install.bzl", "bun_install") load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") __all__ = [ "BunToolchainInfo", + "bun_install", "bun_register_toolchains", "bun_repositories", "bun_toolchain", diff --git a/internal/BUILD.bazel b/internal/BUILD.bazel new file mode 100644 index 0000000..ffd0fb0 --- /dev/null +++ b/internal/BUILD.bazel @@ -0,0 +1 @@ +package(default_visibility = ["//visibility:public"]) diff --git a/internal/bun_install.bzl b/internal/bun_install.bzl index b7e5080..9cb4646 100644 --- a/internal/bun_install.bzl +++ b/internal/bun_install.bzl @@ -1,2 +1,93 @@ -def bun_install(**_kwargs): - fail("bun_install is not implemented yet") +"""Repository-rule based bun_install implementation.""" + +def _select_bun_binary(repository_ctx): + os_name = repository_ctx.os.name.lower() + arch = repository_ctx.os.arch.lower() + + if "linux" in os_name: + if arch in ["aarch64", "arm64"]: + return repository_ctx.path(repository_ctx.attr.bun_linux_aarch64) + return repository_ctx.path(repository_ctx.attr.bun_linux_x64) + + if "mac" in os_name or "darwin" in os_name: + if arch in ["aarch64", "arm64"]: + return repository_ctx.path(repository_ctx.attr.bun_darwin_aarch64) + return repository_ctx.path(repository_ctx.attr.bun_darwin_x64) + + if "windows" in os_name: + return repository_ctx.path(repository_ctx.attr.bun_windows_x64) + + fail("Unsupported host platform: os={}, arch={}".format(repository_ctx.os.name, repository_ctx.os.arch)) + + +def _bun_install_repository_impl(repository_ctx): + package_json = repository_ctx.path(repository_ctx.attr.package_json) + bun_lockfile = repository_ctx.path(repository_ctx.attr.bun_lockfile) + + if not package_json.exists: + fail("bun_install: package_json not found: {}".format(repository_ctx.attr.package_json)) + + if not bun_lockfile.exists: + fail("bun_install: bun_lockfile not found: {}".format(repository_ctx.attr.bun_lockfile)) + + bun_bin = _select_bun_binary(repository_ctx) + + repository_ctx.symlink(package_json, "package.json") + repository_ctx.symlink(bun_lockfile, "bun.lockb") + + result = repository_ctx.execute( + [str(bun_bin), "install", "--frozen-lockfile", "--no-progress"], + timeout = 600, + quiet = False, + environment = {"HOME": str(repository_ctx.path("."))}, + ) + + if result.return_code: + fail("""bun_install failed running `bun install --frozen-lockfile`. +stdout: +{} +stderr: +{} +""".format(result.stdout, result.stderr)) + + repository_ctx.file( + "BUILD.bazel", + """filegroup( + name = "node_modules", + srcs = glob(["node_modules/**"], allow_empty = False), + visibility = ["//visibility:public"], +) +""", + ) + + +_bun_install_repository = repository_rule( + implementation = _bun_install_repository_impl, + attrs = { + "package_json": attr.label(mandatory = True, allow_single_file = True), + "bun_lockfile": attr.label(mandatory = True, allow_single_file = True), + "bun_linux_x64": attr.label(default = "@bun_linux_x64//:bun", allow_single_file = True), + "bun_linux_aarch64": attr.label(default = "@bun_linux_aarch64//:bun", allow_single_file = True), + "bun_darwin_x64": attr.label(default = "@bun_darwin_x64//:bun", allow_single_file = True), + "bun_darwin_aarch64": attr.label(default = "@bun_darwin_aarch64//:bun", allow_single_file = True), + "bun_windows_x64": attr.label(default = "@bun_windows_x64//:bun", allow_single_file = True), + }, +) + + +def bun_install(name, package_json, bun_lockfile): + """Create an external repository containing installed node_modules. + + Usage (WORKSPACE): + bun_install( + name = "node_modules", + package_json = "//:package.json", + bun_lockfile = "//:bun.lockb", + ) + """ + + _bun_install_repository( + name = name, + package_json = package_json, + bun_lockfile = bun_lockfile, + ) diff --git a/tests/install_test/BUILD.bazel b/tests/install_test/BUILD.bazel new file mode 100644 index 0000000..f23b708 --- /dev/null +++ b/tests/install_test/BUILD.bazel @@ -0,0 +1,21 @@ +sh_test( + name = "bun_install_clean_install_test", + srcs = ["clean_install.sh"], + args = ["$(location @bun_linux_x64//:bun)"], + data = ["@bun_linux_x64//:bun"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +sh_test( + name = "bun_install_stale_lockfile_test", + srcs = ["stale_lockfile.sh"], + args = ["$(location @bun_linux_x64//:bun)"], + data = ["@bun_linux_x64//:bun"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) diff --git a/tests/install_test/clean_install.sh b/tests/install_test/clean_install.sh new file mode 100755 index 0000000..93647f9 --- /dev/null +++ b/tests/install_test/clean_install.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +bun_path="$1" +workdir="$(mktemp -d)" +trap 'rm -rf "${workdir}"' EXIT + +cat > "${workdir}/package.json" <<'JSON' +{ + "name": "clean-install-test", + "version": "1.0.0" +} +JSON + +"${bun_path}" install --cwd "${workdir}" >/dev/null +rm -rf "${workdir}/node_modules" +"${bun_path}" install --cwd "${workdir}" --frozen-lockfile >/dev/null + +if [[ ! -d "${workdir}/node_modules" ]]; then + echo "Expected node_modules to be created" >&2 + exit 1 +fi diff --git a/tests/install_test/stale_lockfile.sh b/tests/install_test/stale_lockfile.sh new file mode 100755 index 0000000..e21cfd2 --- /dev/null +++ b/tests/install_test/stale_lockfile.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -euo pipefail + +bun_path="$1" +workdir="$(mktemp -d)" +trap 'rm -rf "${workdir}"' EXIT + +cat > "${workdir}/package.json" <<'JSON' +{ + "name": "stale-lockfile-test", + "version": "1.0.0" +} +JSON + +"${bun_path}" install --cwd "${workdir}" >/dev/null + +cat > "${workdir}/package.json" <<'JSON' +{ + "name": "stale-lockfile-test", + "version": "1.0.0", + "dependencies": { + "left-pad": "1.3.0" + } +} +JSON + +set +e +output="$(${bun_path} install --cwd "${workdir}" --frozen-lockfile 2>&1)" +code=$? +set -e + +if [[ ${code} -eq 0 ]]; then + echo "Expected frozen lockfile install to fail when package.json changes" >&2 + exit 1 +fi + +if [[ "${output}" != *"lockfile"* && "${output}" != *"frozen"* ]]; then + echo "Expected lockfile-related error, got:" >&2 + echo "${output}" >&2 + exit 1 +fi From f0e498ea05d25e4cbd59584f47f93cf6d7d512b9 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:05:49 +0000 Subject: [PATCH 06/25] docs: add bun_install parameter docs --- internal/bun_install.bzl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/bun_install.bzl b/internal/bun_install.bzl index 9cb4646..9d51d16 100644 --- a/internal/bun_install.bzl +++ b/internal/bun_install.bzl @@ -78,6 +78,11 @@ _bun_install_repository = repository_rule( def bun_install(name, package_json, bun_lockfile): """Create an external repository containing installed node_modules. + Args: + name: Repository name to create. + package_json: Label to a package.json file. + bun_lockfile: Label to a bun.lockb file. + Usage (WORKSPACE): bun_install( name = "node_modules", From 12ddcb273a2bb85e5e7af2f11f9463b6e85dabe7 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:10:35 +0000 Subject: [PATCH 07/25] feat: add phase 3 bun_binary bootstrap and tests --- README.md | 6 ++++ bun/defs.bzl | 2 ++ internal/bun_binary.bzl | 51 +++++++++++++++++++++++++++++++-- tests/binary_test/BUILD.bazel | 35 ++++++++++++++++++++++ tests/binary_test/hello.js | 1 + tests/binary_test/hello.ts | 2 ++ tests/binary_test/run_binary.sh | 11 +++++++ 7 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 tests/binary_test/BUILD.bazel create mode 100644 tests/binary_test/hello.js create mode 100644 tests/binary_test/hello.ts create mode 100755 tests/binary_test/run_binary.sh diff --git a/README.md b/README.md index a07dae7..67d7abf 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,9 @@ Phase 2 bootstrap is in place: - Repository-rule based `bun_install` (`/internal/bun_install.bzl`) - Public export via `bun/defs.bzl` - Focused install behavior tests (`//tests/install_test:all`) + +Phase 3 bootstrap is in place: + +- Executable `bun_binary` rule (`/internal/bun_binary.bzl`) +- Public export via `bun/defs.bzl` +- Focused JS/TS runnable tests (`//tests/binary_test:all`) diff --git a/bun/defs.bzl b/bun/defs.bzl index 220f084..48cd3f7 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -1,9 +1,11 @@ +load("//internal:bun_binary.bzl", "bun_binary") load("//internal:bun_install.bzl", "bun_install") load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") __all__ = [ "BunToolchainInfo", + "bun_binary", "bun_install", "bun_register_toolchains", "bun_repositories", diff --git a/internal/bun_binary.bzl b/internal/bun_binary.bzl index e9808f9..0e2caf8 100644 --- a/internal/bun_binary.bzl +++ b/internal/bun_binary.bzl @@ -1,2 +1,49 @@ -def bun_binary(**_kwargs): - fail("bun_binary is not implemented yet") +"""Rule for running JS/TS scripts with Bun.""" + + +def _bun_binary_impl(ctx): + toolchain = ctx.toolchains["//bun:toolchain_type"] + bun_bin = toolchain.bun.bun_bin + entry_point = ctx.file.entry_point + + launcher = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write( + output = launcher, + is_executable = True, + content = """#!/usr/bin/env bash +set -euo pipefail + +exec \"{}\" run \"{}\" \"$@\" +""".format(bun_bin.path, entry_point.path), + ) + + transitive_files = [] + if ctx.attr.node_modules: + transitive_files.append(ctx.attr.node_modules[DefaultInfo].files) + + runfiles = ctx.runfiles( + files = [bun_bin, entry_point] + ctx.files.data, + transitive_files = depset(transitive = transitive_files), + ) + + return [ + DefaultInfo( + executable = launcher, + runfiles = runfiles, + ), + ] + + +bun_binary = rule( + implementation = _bun_binary_impl, + attrs = { + "entry_point": attr.label( + mandatory = True, + allow_single_file = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"], + ), + "node_modules": attr.label(), + "data": attr.label_list(allow_files = True), + }, + executable = True, + toolchains = ["//bun:toolchain_type"], +) diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel new file mode 100644 index 0000000..e4b43d6 --- /dev/null +++ b/tests/binary_test/BUILD.bazel @@ -0,0 +1,35 @@ +load("//bun:defs.bzl", "bun_binary") + +bun_binary( + name = "hello_js_bin", + entry_point = "hello.js", + data = ["hello.js"], +) + +sh_test( + name = "bun_binary_js_test", + srcs = ["run_binary.sh"], + args = ["$(location :hello_js_bin)", "hello-js"], + data = [":hello_js_bin"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +bun_binary( + name = "hello_ts_bin", + entry_point = "hello.ts", + data = ["hello.ts"], +) + +sh_test( + name = "bun_binary_ts_test", + srcs = ["run_binary.sh"], + args = ["$(location :hello_ts_bin)", "hello-ts"], + data = [":hello_ts_bin"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) diff --git a/tests/binary_test/hello.js b/tests/binary_test/hello.js new file mode 100644 index 0000000..8f2ee2f --- /dev/null +++ b/tests/binary_test/hello.js @@ -0,0 +1 @@ +console.log("hello-js"); diff --git a/tests/binary_test/hello.ts b/tests/binary_test/hello.ts new file mode 100644 index 0000000..5740a46 --- /dev/null +++ b/tests/binary_test/hello.ts @@ -0,0 +1,2 @@ +const message: string = "hello-ts"; +console.log(message); diff --git a/tests/binary_test/run_binary.sh b/tests/binary_test/run_binary.sh new file mode 100755 index 0000000..e8b8757 --- /dev/null +++ b/tests/binary_test/run_binary.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +binary="$1" +expected="$2" +output="$(${binary})" + +if [[ "${output}" != "${expected}" ]]; then + echo "Unexpected output from ${binary}: ${output}" >&2 + exit 1 +fi From 38ccddc76b8a0c86c61ac276982a8942633424b3 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:12:39 +0000 Subject: [PATCH 08/25] test: simplify bun_binary test targets --- tests/binary_test/BUILD.bazel | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index e4b43d6..a8da56e 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -3,7 +3,6 @@ load("//bun:defs.bzl", "bun_binary") bun_binary( name = "hello_js_bin", entry_point = "hello.js", - data = ["hello.js"], ) sh_test( @@ -20,7 +19,6 @@ sh_test( bun_binary( name = "hello_ts_bin", entry_point = "hello.ts", - data = ["hello.ts"], ) sh_test( From 9d32489993177b3584676b6715192252872123e3 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:19:28 +0000 Subject: [PATCH 09/25] feat: add phase 4 bun_test bootstrap --- README.md | 6 +++ bun/defs.bzl | 2 + internal/bun_test.bzl | 59 ++++++++++++++++++++++++++++- tests/bun_test_test/BUILD.bazel | 19 ++++++++++ tests/bun_test_test/failing.test.ts | 5 +++ tests/bun_test_test/passing.test.ts | 5 +++ 6 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 tests/bun_test_test/BUILD.bazel create mode 100644 tests/bun_test_test/failing.test.ts create mode 100644 tests/bun_test_test/passing.test.ts diff --git a/README.md b/README.md index 67d7abf..e81d03f 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,9 @@ Phase 3 bootstrap is in place: - Executable `bun_binary` rule (`/internal/bun_binary.bzl`) - Public export via `bun/defs.bzl` - Focused JS/TS runnable tests (`//tests/binary_test:all`) + +Phase 4 bootstrap is in place: + +- Test rule `bun_test` (`/internal/bun_test.bzl`) +- Public export via `bun/defs.bzl` +- Focused passing/failing test targets (`//tests/bun_test_test:all`) diff --git a/bun/defs.bzl b/bun/defs.bzl index 48cd3f7..0664176 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -1,5 +1,6 @@ load("//internal:bun_binary.bzl", "bun_binary") load("//internal:bun_install.bzl", "bun_install") +load("//internal:bun_test.bzl", "bun_test") load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") @@ -7,6 +8,7 @@ __all__ = [ "BunToolchainInfo", "bun_binary", "bun_install", + "bun_test", "bun_register_toolchains", "bun_repositories", "bun_toolchain", diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index f013b9e..6f4a5a4 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -1,2 +1,57 @@ -def bun_test(**_kwargs): - fail("bun_test is not implemented yet") +"""Rule for running test suites with Bun.""" + + +def _bun_test_impl(ctx): + toolchain = ctx.toolchains["//bun:toolchain_type"] + bun_bin = toolchain.bun.bun_bin + + src_args = " ".join(["\"{}\"".format(src.path) for src in ctx.files.srcs]) + launcher = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write( + output = launcher, + is_executable = True, + content = """#!/usr/bin/env bash +set -euo pipefail + +extra_args=() +if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" ]]; then + extra_args+=("--test-name-pattern" "${{TESTBRIDGE_TEST_ONLY}}") +fi +if [[ -n "${{COVERAGE_DIR:-}}" ]]; then + extra_args+=("--coverage") +fi + +exec "{}" test {} "${{extra_args[@]}}" "$@" +""".format(bun_bin.path, src_args), + ) + + transitive_files = [] + if ctx.attr.node_modules: + transitive_files.append(ctx.attr.node_modules[DefaultInfo].files) + + runfiles = ctx.runfiles( + files = [bun_bin] + ctx.files.srcs + ctx.files.data, + transitive_files = depset(transitive = transitive_files), + ) + + return [ + DefaultInfo( + executable = launcher, + runfiles = runfiles, + ), + ] + + +bun_test = rule( + implementation = _bun_test_impl, + attrs = { + "srcs": attr.label_list( + mandatory = True, + allow_files = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"], + ), + "node_modules": attr.label(), + "data": attr.label_list(allow_files = True), + }, + test = True, + toolchains = ["//bun:toolchain_type"], +) diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel new file mode 100644 index 0000000..9b27da4 --- /dev/null +++ b/tests/bun_test_test/BUILD.bazel @@ -0,0 +1,19 @@ +load("//bun:defs.bzl", "bun_test") + +bun_test( + name = "passing_suite", + srcs = ["passing.test.ts"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +bun_test( + name = "failing_suite", + srcs = ["failing.test.ts"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) diff --git a/tests/bun_test_test/failing.test.ts b/tests/bun_test_test/failing.test.ts new file mode 100644 index 0000000..cb462d0 --- /dev/null +++ b/tests/bun_test_test/failing.test.ts @@ -0,0 +1,5 @@ +import { expect, test } from "bun:test"; + +test("failing suite", () => { + expect(1 + 1).toBe(3); +}); diff --git a/tests/bun_test_test/passing.test.ts b/tests/bun_test_test/passing.test.ts new file mode 100644 index 0000000..b5e066a --- /dev/null +++ b/tests/bun_test_test/passing.test.ts @@ -0,0 +1,5 @@ +import { expect, test } from "bun:test"; + +test("passing suite", () => { + expect(1 + 1).toBe(2); +}); From 2347185c4cead418d9edcf9db362a4baf4e9c82b Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:22:58 +0000 Subject: [PATCH 10/25] fix: harden bun_test launcher args and test metadata --- internal/bun_test.bzl | 14 ++++++++++---- tests/bun_test_test/BUILD.bazel | 1 + tests/bun_test_test/failing.test.ts | 2 +- tests/bun_test_test/passing.test.ts | 2 +- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index 6f4a5a4..63f2c4d 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -1,11 +1,15 @@ """Rule for running test suites with Bun.""" +def _shell_quote(value): + return "'" + value.replace("'", "'\"'\"'") + "'" + + def _bun_test_impl(ctx): toolchain = ctx.toolchains["//bun:toolchain_type"] bun_bin = toolchain.bun.bun_bin - src_args = " ".join(["\"{}\"".format(src.path) for src in ctx.files.srcs]) + src_args = " ".join([_shell_quote(src.path) for src in ctx.files.srcs]) launcher = ctx.actions.declare_file(ctx.label.name) ctx.actions.write( output = launcher, @@ -20,9 +24,11 @@ fi if [[ -n "${{COVERAGE_DIR:-}}" ]]; then extra_args+=("--coverage") fi - -exec "{}" test {} "${{extra_args[@]}}" "$@" -""".format(bun_bin.path, src_args), +exec "{bun_bin}" test {src_args} "${{extra_args[@]}}" "$@" +""".format( + bun_bin = bun_bin.path, + src_args = src_args, + ), ) transitive_files = [] diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel index 9b27da4..9f67755 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -12,6 +12,7 @@ bun_test( bun_test( name = "failing_suite", srcs = ["failing.test.ts"], + tags = ["manual"], target_compatible_with = [ "@platforms//cpu:x86_64", "@platforms//os:linux", diff --git a/tests/bun_test_test/failing.test.ts b/tests/bun_test_test/failing.test.ts index cb462d0..f893ec3 100644 --- a/tests/bun_test_test/failing.test.ts +++ b/tests/bun_test_test/failing.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "bun:test"; -test("failing suite", () => { +test("intentionally fails for manual validation", () => { expect(1 + 1).toBe(3); }); diff --git a/tests/bun_test_test/passing.test.ts b/tests/bun_test_test/passing.test.ts index b5e066a..68d7029 100644 --- a/tests/bun_test_test/passing.test.ts +++ b/tests/bun_test_test/passing.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "bun:test"; -test("passing suite", () => { +test("adds two numbers correctly", () => { expect(1 + 1).toBe(2); }); From f03598407bede84a9d24f015f5235e2b273daf0d Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 03:30:07 +0000 Subject: [PATCH 11/25] feat: implement phase 5 bun_bundle bootstrap --- README.md | 6 +++ bun/defs.bzl | 2 + internal/bun_bundle.bzl | 78 +++++++++++++++++++++++++++++- tests/bundle_test/BUILD.bazel | 48 ++++++++++++++++++ tests/bundle_test/main.ts | 5 ++ tests/bundle_test/verify_bundle.sh | 14 ++++++ tests/bundle_test/verify_minify.sh | 13 +++++ 7 files changed, 164 insertions(+), 2 deletions(-) create mode 100644 tests/bundle_test/BUILD.bazel create mode 100644 tests/bundle_test/main.ts create mode 100755 tests/bundle_test/verify_bundle.sh create mode 100755 tests/bundle_test/verify_minify.sh diff --git a/README.md b/README.md index e81d03f..4b178e5 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,9 @@ Phase 4 bootstrap is in place: - Test rule `bun_test` (`/internal/bun_test.bzl`) - Public export via `bun/defs.bzl` - Focused passing/failing test targets (`//tests/bun_test_test:all`) + +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`) diff --git a/bun/defs.bzl b/bun/defs.bzl index 0664176..b19a324 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -1,4 +1,5 @@ load("//internal:bun_binary.bzl", "bun_binary") +load("//internal:bun_bundle.bzl", "bun_bundle") load("//internal:bun_install.bzl", "bun_install") load("//internal:bun_test.bzl", "bun_test") load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") @@ -7,6 +8,7 @@ load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") __all__ = [ "BunToolchainInfo", "bun_binary", + "bun_bundle", "bun_install", "bun_test", "bun_register_toolchains", diff --git a/internal/bun_bundle.bzl b/internal/bun_bundle.bzl index b430850..13af4bc 100644 --- a/internal/bun_bundle.bzl +++ b/internal/bun_bundle.bzl @@ -1,2 +1,76 @@ -def bun_bundle(**_kwargs): - fail("bun_bundle is not implemented yet") +"""Rule for bundling JS/TS sources with Bun.""" + + +def _output_name(target_name, entry): + stem = entry.basename.rsplit(".", 1)[0] + return "{}__{}.js".format(target_name, stem) + + +def _bun_bundle_impl(ctx): + toolchain = ctx.toolchains["//bun:toolchain_type"] + bun_bin = toolchain.bun.bun_bin + + transitive_inputs = [] + if ctx.attr.node_modules: + transitive_inputs.append(ctx.attr.node_modules[DefaultInfo].files) + + outputs = [] + for entry in ctx.files.entry_points: + output = ctx.actions.declare_file(_output_name(ctx.label.name, entry)) + outputs.append(output) + + args = ctx.actions.args() + args.add("build") + args.add(entry.path) + args.add("--outfile") + args.add(output.path) + args.add("--target") + args.add(ctx.attr.target) + args.add("--format") + args.add(ctx.attr.format) + if ctx.attr.minify: + args.add("--minify") + if ctx.attr.sourcemap: + args.add("--sourcemap") + for package in ctx.attr.external: + args.add("--external") + args.add(package) + + ctx.actions.run( + executable = bun_bin, + arguments = [args], + inputs = depset( + direct = [entry] + ctx.files.data, + transitive = transitive_inputs, + ), + outputs = [output], + mnemonic = "BunBundle", + progress_message = "Bundling {} with Bun".format(entry.short_path), + ) + + return [DefaultInfo(files = depset(outputs))] + + +bun_bundle = rule( + implementation = _bun_bundle_impl, + attrs = { + "entry_points": attr.label_list( + mandatory = True, + allow_files = [".js", ".ts", ".jsx", ".tsx", ".mjs", ".cjs"], + ), + "node_modules": attr.label(), + "data": attr.label_list(allow_files = True), + "target": attr.string( + default = "browser", + values = ["browser", "node", "bun"], + ), + "format": attr.string( + default = "esm", + values = ["esm", "cjs", "iife"], + ), + "minify": attr.bool(default = False), + "sourcemap": attr.bool(default = False), + "external": attr.string_list(), + }, + toolchains = ["//bun:toolchain_type"], +) diff --git a/tests/bundle_test/BUILD.bazel b/tests/bundle_test/BUILD.bazel new file mode 100644 index 0000000..2417e43 --- /dev/null +++ b/tests/bundle_test/BUILD.bazel @@ -0,0 +1,48 @@ +load("//bun:defs.bzl", "bun_bundle") + +bun_bundle( + name = "simple_bundle", + entry_points = ["main.ts"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +bun_bundle( + name = "minified_bundle", + entry_points = ["main.ts"], + minify = True, + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +sh_test( + name = "bundle_output_test", + srcs = ["verify_bundle.sh"], + args = ["$(location :simple_bundle)"], + data = [":simple_bundle"], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) + +sh_test( + name = "bundle_minify_test", + srcs = ["verify_minify.sh"], + args = [ + "$(location :simple_bundle)", + "$(location :minified_bundle)", + ], + data = [ + ":simple_bundle", + ":minified_bundle", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], +) diff --git a/tests/bundle_test/main.ts b/tests/bundle_test/main.ts new file mode 100644 index 0000000..ff55828 --- /dev/null +++ b/tests/bundle_test/main.ts @@ -0,0 +1,5 @@ +export function greet(name: string): string { + return `Hello ${name}`; +} + +console.log(greet("bundle")); diff --git a/tests/bundle_test/verify_bundle.sh b/tests/bundle_test/verify_bundle.sh new file mode 100755 index 0000000..b0122f9 --- /dev/null +++ b/tests/bundle_test/verify_bundle.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +bundle="$1" + +if [[ ! -f "${bundle}" ]]; then + echo "Bundle output not found: ${bundle}" >&2 + exit 1 +fi + +if [[ ! -s "${bundle}" ]]; then + echo "Bundle output is empty: ${bundle}" >&2 + exit 1 +fi diff --git a/tests/bundle_test/verify_minify.sh b/tests/bundle_test/verify_minify.sh new file mode 100755 index 0000000..eab37d7 --- /dev/null +++ b/tests/bundle_test/verify_minify.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +bundle="$1" +minified="$2" + +bundle_size="$(wc -c < "${bundle}")" +minified_size="$(wc -c < "${minified}")" + +if (( minified_size >= bundle_size )); then + echo "Expected minified bundle (${minified_size}) to be smaller than regular bundle (${bundle_size})" >&2 + exit 1 +fi From 48cfbaabf45b5ec8d2a9f7c9d5fefd9d2b8a20de Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 04:43:42 +0100 Subject: [PATCH 12/25] fix: use correct bazel 9.0.0 imports --- MODULE.bazel | 19 ++ MODULE.bazel.lock | 508 +++++++++++++++++++++++++++++++ bun/BUILD.bazel | 2 + bun/defs.bzl | 27 +- bun/extensions.bzl | 55 ++++ bun/repositories.bzl | 10 +- bun/version.bzl | 2 +- flake.lock | 136 +++++++++ flake.nix | 168 ++++++++++ tests/binary_test/BUILD.bazel | 9 + tests/bundle_test/BUILD.bazel | 1 + tests/install_test/BUILD.bazel | 2 + tests/toolchain_test/BUILD.bazel | 2 + 13 files changed, 919 insertions(+), 22 deletions(-) create mode 100644 MODULE.bazel.lock create mode 100644 bun/extensions.bzl create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/MODULE.bazel b/MODULE.bazel index 1c77d2a..3c99f5d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -4,3 +4,22 @@ module( ) bazel_dep(name = "platforms", version = "1.0.0") +bazel_dep(name = "rules_shell", version = "0.6.1") + +bun_ext = use_extension("//bun:extensions.bzl", "bun") +use_repo( + bun_ext, + "bun_linux_x64", + "bun_linux_aarch64", + "bun_darwin_x64", + "bun_darwin_aarch64", + "bun_windows_x64", +) + +register_toolchains( + "//bun:darwin_aarch64_toolchain", + "//bun:darwin_x64_toolchain", + "//bun:linux_aarch64_toolchain", + "//bun:linux_x64_toolchain", + "//bun:windows_x64_toolchain", +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock new file mode 100644 index 0000000..eed6b86 --- /dev/null +++ b/MODULE.bazel.lock @@ -0,0 +1,508 @@ +{ + "lockFileVersion": 26, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/source.json": "13617db3930328c2cd2807a0f13d52ca870ac05f96db9668655113265147b2a6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/buildozer/8.2.1/MODULE.bazel": "61e9433c574c2bd9519cad7fa66b9c1d2b8e8d5f3ae5d6528a2c2d26e68d874d", + "https://bcr.bazel.build/modules/buildozer/8.2.1/source.json": "7c33f6a26ee0216f85544b4bca5e9044579e0219b6898dd653f5fb449cf2e484", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/source.json": "55d0a4587c5592fad350f6e698530f4faf0e7dd15e69d43f8d87e220c78bea54", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/9.0.3/MODULE.bazel": "1f98ed015f7e744a745e0df6e898a7c5e83562d6b759dfd475c76456dda5ccea", + "https://bcr.bazel.build/modules/rules_java/9.0.3/source.json": "b038c0c07e12e658135bbc32cc1a2ded6e33785105c9d41958014c592de4593e", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/source.json": "5426f412d0a7fc6b611643376c7e4a82dec991491b9ce5cb1cfdd25fe2e92be4", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "//bun:extensions.bzl%bun": { + "general": { + "bzlTransitiveDigest": "OnZvc44B8aCFH7E+udHBoIoIkL0AeKA27+2lmg/S15Q=", + "usagesDigest": "qk1PDh3WICa0VONYKXJLsmWCesNJxz3Jkb/aH/voIeI=", + "recordedInputs": [ + "REPO_MAPPING:,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "bun_linux_x64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-linux-x64.zip" + ], + "sha256": "f57bc0187e39623de716ba3a389fda5486b2d7be7131a980ba54dc7b733d2e08", + "build_file_content": "\nexports_files([\"bun-linux-x64/bun\"])\n\nfilegroup(\n name = \"bun\",\n srcs = [\"bun-linux-x64/bun\"],\n visibility = [\"//visibility:public\"],\n)\n" + } + }, + "bun_linux_aarch64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-linux-aarch64.zip" + ], + "sha256": "fa5ecb25cafa8e8f5c87a0f833719d46dd0af0a86c7837d806531212d55636d3", + "build_file_content": "\nexports_files([\"bun-linux-aarch64/bun\"])\n\nfilegroup(\n name = \"bun\",\n srcs = [\"bun-linux-aarch64/bun\"],\n visibility = [\"//visibility:public\"],\n)\n" + } + }, + "bun_darwin_x64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-darwin-x64.zip" + ], + "sha256": "c1d90bf6140f20e572c473065dc6b37a4b036349b5e9e4133779cc642ad94323", + "build_file_content": "\nexports_files([\"bun-darwin-x64/bun\"])\n\nfilegroup(\n name = \"bun\",\n srcs = [\"bun-darwin-x64/bun\"],\n visibility = [\"//visibility:public\"],\n)\n" + } + }, + "bun_darwin_aarch64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-darwin-aarch64.zip" + ], + "sha256": "82034e87c9d9b4398ea619aee2eed5d2a68c8157e9a6ae2d1052d84d533ccd8d", + "build_file_content": "\nexports_files([\"bun-darwin-aarch64/bun\"])\n\nfilegroup(\n name = \"bun\",\n srcs = [\"bun-darwin-aarch64/bun\"],\n visibility = [\"//visibility:public\"],\n)\n" + } + }, + "bun_windows_x64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/oven-sh/bun/releases/download/bun-v1.3.10/bun-windows-x64.zip" + ], + "sha256": "7a77b3e245e2e26965c93089a4a1332e8a326d3364c89fae1d1fd99cdd3cd73d", + "build_file_content": "\nexports_files([\"bun-windows-x64/bun.exe\"])\n\nfilegroup(\n name = \"bun\",\n srcs = [\"bun-windows-x64/bun.exe\"],\n visibility = [\"//visibility:public\"],\n)\n" + } + } + } + } + }, + "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { + "general": { + "bzlTransitiveDigest": "ABI1D/sbS1ovwaW/kHDoj8nnXjQ0oKU9fzmzEG4iT8o=", + "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", + "recordedInputs": [ + "REPO_MAPPING:rules_kotlin+,bazel_tools bazel_tools" + ], + "generatedRepoSpecs": { + "com_github_jetbrains_kotlin_git": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", + "attributes": { + "urls": [ + "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip" + ], + "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88" + } + }, + "com_github_jetbrains_kotlin": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository", + "attributes": { + "git_repository_name": "com_github_jetbrains_kotlin_git", + "compiler_version": "1.9.23" + } + }, + "com_github_google_ksp": { + "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository", + "attributes": { + "urls": [ + "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip" + ], + "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d", + "strip_version": "1.9.23-1.0.20" + } + }, + "com_github_pinterest_ktlint": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", + "attributes": { + "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985", + "urls": [ + "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint" + ], + "executable": true + } + }, + "rules_android": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806", + "strip_prefix": "rules_android-0.1.1", + "urls": [ + "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip" + ] + } + } + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "2hLgIvNVTLgxus0ZuXtleBe70intCfo0cHs8qvt6cdM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + } + }, + "facts": {} +} diff --git a/bun/BUILD.bazel b/bun/BUILD.bazel index ff310a9..ba771e6 100644 --- a/bun/BUILD.bazel +++ b/bun/BUILD.bazel @@ -1,6 +1,8 @@ load(":toolchain.bzl", "bun_toolchain") load(":version.bzl", "BUN_VERSION") +exports_files(["defs.bzl"]) + toolchain_type(name = "toolchain_type") bun_toolchain( diff --git a/bun/defs.bzl b/bun/defs.bzl index b19a324..85fd304 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -1,17 +1,12 @@ -load("//internal:bun_binary.bzl", "bun_binary") -load("//internal:bun_bundle.bzl", "bun_bundle") -load("//internal:bun_install.bzl", "bun_install") -load("//internal:bun_test.bzl", "bun_test") -load(":repositories.bzl", "bun_register_toolchains", "bun_repositories") -load(":toolchain.bzl", "BunToolchainInfo", "bun_toolchain") +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(":toolchain.bzl", _BunToolchainInfo = "BunToolchainInfo", _bun_toolchain = "bun_toolchain") -__all__ = [ - "BunToolchainInfo", - "bun_binary", - "bun_bundle", - "bun_install", - "bun_test", - "bun_register_toolchains", - "bun_repositories", - "bun_toolchain", -] +visibility("public") + +bun_binary = _bun_binary +bun_bundle = _bun_bundle +bun_test = _bun_test +BunToolchainInfo = _BunToolchainInfo +bun_toolchain = _bun_toolchain diff --git a/bun/extensions.bzl b/bun/extensions.bzl new file mode 100644 index 0000000..bb9ea75 --- /dev/null +++ b/bun/extensions.bzl @@ -0,0 +1,55 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load(":version.bzl", "BUN_VERSION") + +_BUN_ARCHIVES = { + "bun_linux_x64": { + "sha256": "f57bc0187e39623de716ba3a389fda5486b2d7be7131a980ba54dc7b733d2e08", + "asset": "bun-linux-x64.zip", + "binary": "bun-linux-x64/bun", + }, + "bun_linux_aarch64": { + "sha256": "fa5ecb25cafa8e8f5c87a0f833719d46dd0af0a86c7837d806531212d55636d3", + "asset": "bun-linux-aarch64.zip", + "binary": "bun-linux-aarch64/bun", + }, + "bun_darwin_x64": { + "sha256": "c1d90bf6140f20e572c473065dc6b37a4b036349b5e9e4133779cc642ad94323", + "asset": "bun-darwin-x64.zip", + "binary": "bun-darwin-x64/bun", + }, + "bun_darwin_aarch64": { + "sha256": "82034e87c9d9b4398ea619aee2eed5d2a68c8157e9a6ae2d1052d84d533ccd8d", + "asset": "bun-darwin-aarch64.zip", + "binary": "bun-darwin-aarch64/bun", + }, + "bun_windows_x64": { + "sha256": "7a77b3e245e2e26965c93089a4a1332e8a326d3364c89fae1d1fd99cdd3cd73d", + "asset": "bun-windows-x64.zip", + "binary": "bun-windows-x64/bun.exe", + }, +} + +_BUN_GITHUB_RELEASE_URL_TEMPLATE = "https://github.com/oven-sh/bun/releases/download/bun-v{}/{}" + + +def _bun_repos_impl(_ctx): + for name, metadata in _BUN_ARCHIVES.items(): + http_archive( + name = name, + urls = [_BUN_GITHUB_RELEASE_URL_TEMPLATE.format(BUN_VERSION, metadata["asset"])], + sha256 = metadata["sha256"], + build_file_content = """ +exports_files(["{binary}"]) + +filegroup( + name = "bun", + srcs = ["{binary}"], + visibility = ["//visibility:public"], +) +""".format(binary = metadata["binary"]), + ) + + +bun = module_extension( + implementation = _bun_repos_impl, +) diff --git a/bun/repositories.bzl b/bun/repositories.bzl index a5b0e32..37ba294 100644 --- a/bun/repositories.bzl +++ b/bun/repositories.bzl @@ -3,27 +3,27 @@ load(":version.bzl", "BUN_VERSION") _BUN_ARCHIVES = { "bun_linux_x64": { - "sha256": "a61da5357e28d4977fccd4851fed62ff4da3ea33853005c7dd93dac80bc53932", + "sha256": "f57bc0187e39623de716ba3a389fda5486b2d7be7131a980ba54dc7b733d2e08", "asset": "bun-linux-x64.zip", "binary": "bun-linux-x64/bun", }, "bun_linux_aarch64": { - "sha256": "3b08fd0b31f745509e1fed9c690c80d1a32ef2b3c8d059583f643f696639bd21", + "sha256": "fa5ecb25cafa8e8f5c87a0f833719d46dd0af0a86c7837d806531212d55636d3", "asset": "bun-linux-aarch64.zip", "binary": "bun-linux-aarch64/bun", }, "bun_darwin_x64": { - "sha256": "4e9814c9b2e64f9166ed8fc2a48f905a2195ea599b7ceda7ac821688520428a5", + "sha256": "c1d90bf6140f20e572c473065dc6b37a4b036349b5e9e4133779cc642ad94323", "asset": "bun-darwin-x64.zip", "binary": "bun-darwin-x64/bun", }, "bun_darwin_aarch64": { - "sha256": "bbc6fb0e7bb99e7e95001ba05105cf09d0b79c06941d9f6ee3d0b34dc1541590", + "sha256": "82034e87c9d9b4398ea619aee2eed5d2a68c8157e9a6ae2d1052d84d533ccd8d", "asset": "bun-darwin-aarch64.zip", "binary": "bun-darwin-aarch64/bun", }, "bun_windows_x64": { - "sha256": "52d6c588237c5a1071839dc20dc96f19ca9f8021b7757fa096d22927b0a44a8b", + "sha256": "7a77b3e245e2e26965c93089a4a1332e8a326d3364c89fae1d1fd99cdd3cd73d", "asset": "bun-windows-x64.zip", "binary": "bun-windows-x64/bun.exe", }, diff --git a/bun/version.bzl b/bun/version.bzl index a0ad89c..159583c 100644 --- a/bun/version.bzl +++ b/bun/version.bzl @@ -1 +1 @@ -BUN_VERSION = "1.1.38" +BUN_VERSION = "1.3.10" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..73bcd98 --- /dev/null +++ b/flake.lock @@ -0,0 +1,136 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1767039857, + "narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=", + "owner": "NixOS", + "repo": "flake-compat", + "rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "flake-compat", + "type": "github" + } + }, + "git-hooks": { + "inputs": { + "flake-compat": "flake-compat", + "gitignore": "gitignore", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1772024342, + "narHash": "sha256-+eXlIc4/7dE6EcPs9a2DaSY3fTA9AE526hGqkNID3Wg=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "6e34e97ed9788b17796ee43ccdbaf871a5c2b476", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, + "gitignore": { + "inputs": { + "nixpkgs": [ + "git-hooks", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1709087332, + "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=", + "owner": "hercules-ci", + "repo": "gitignore.nix", + "rev": "637db329424fd7e46cf4185293b9cc8c88c95394", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "gitignore.nix", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1770073757, + "narHash": "sha256-Vy+G+F+3E/Tl+GMNgiHl9Pah2DgShmIUBJXmbiQPHbI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "47472570b1e607482890801aeaf29bfb749884f6", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1772542754, + "narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1770107345, + "narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "git-hooks": "git-hooks", + "nixpkgs": "nixpkgs_2", + "treefmt-nix": "treefmt-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1770228511, + "narHash": "sha256-wQ6NJSuFqAEmIg2VMnLdCnUc0b7vslUohqqGGD+Fyxk=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "337a4fe074be1042a35086f15481d763b8ddc0e7", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..4663590 --- /dev/null +++ b/flake.nix @@ -0,0 +1,168 @@ +{ + description = "rules_bun development flake"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; + git-hooks.url = "github:cachix/git-hooks.nix"; + treefmt-nix.url = "github:numtide/treefmt-nix"; + }; + + outputs = + { + self, + nixpkgs, + treefmt-nix, + ... + }@inputs: + let + supportedSystems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + forAllSystems = nixpkgs.lib.genAttrs supportedSystems; + treefmtEvalFor = + system: + let + pkgs = nixpkgs.legacyPackages.${system}; + in + treefmt-nix.lib.evalModule pkgs { + projectRootFile = "flake.nix"; + + programs = { + nixfmt.enable = true; + shfmt.enable = true; + oxfmt.enable = true; + }; + + settings = { + formatter = { + shfmt = { + options = [ + "-i" + "2" + "-s" + "-w" + ]; + }; + oxfmt = { + includes = [ + "*.md" + "*.yaml" + "*.yml" + "*.json" + "*.html" + "*.css" + "*.js" + "*.ts" + "*.tsx" + "*.svelte" + ]; + }; + }; + }; + }; + in + { + formatter = forAllSystems (system: (treefmtEvalFor system).config.build.wrapper); + + checks = forAllSystems ( + system: + let + pkgs = import nixpkgs { inherit system; }; + in + { + pre-commit-check = inputs.git-hooks.lib.${system}.run { + src = ./.; + hooks = { + treefmt = { + enable = true; + entry = "${(treefmtEvalFor system).config.build.wrapper}/bin/treefmt"; + pass_filenames = true; + }; + gitlint.enable = true; + + gitleaks = { + enable = true; + entry = "${pkgs.gitleaks}/bin/gitleaks protect --staged"; + pass_filenames = false; + }; + + tests = { + enable = true; + entry = "echo 'No tests defined yet.'"; + pass_filenames = false; + stages = [ + "pre-push" + ]; + }; + }; + }; + } + ); + + devShells = forAllSystems ( + system: + let + pkgs = import nixpkgs { inherit system; }; + inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages; + customShellHook = shellHook + ""; + bazel9 = pkgs.writeShellScriptBin "bazel" '' + export USE_BAZEL_VERSION="''${USE_BAZEL_VERSION:-9.0.0}" + exec ${pkgs.bazelisk}/bin/bazelisk "$@" + ''; + + in + { + default = pkgs.mkShell { + packages = with pkgs; [ + go + gopls + gotools + + bun + gitlint + bazel9 + bazel-buildtools + ]; + + shellHook = '' + ${customShellHook} + export USE_BAZEL_VERSION="''${USE_BAZEL_VERSION:-9.0.0}" + export BUN_INSTALL="''${BUN_INSTALL:-$HOME/.bun}" + export PATH="$BUN_INSTALL/bin:$PATH" + + if ! command -v oxfmt >/dev/null 2>&1; then + bun add --global oxfmt + fi + + if ! command -v oxlint >/dev/null 2>&1; then + bun add --global oxlint + fi + + if [ -t 1 ]; then + if command -v tput >/dev/null 2>&1; then + tput clear + else + printf '\033c' + fi + fi + + GREEN='\033[1;32m' + CYAN='\033[1;36m' + YELLOW='\033[1;33m' + BLUE='\033[1;34m' + RESET='\033[0m' + + printf "\n$GREEN 🚀 Monorepo dev shell ready$RESET\n\n" + printf " $CYAN Bun:$RESET $YELLOW%s$RESET\n" "$(bun --version)" + printf " $CYAN Go:$RESET $YELLOW%s$RESET\n" "$(go version)" + printf " $CYAN Bazel:$RESET $BLUE%s$RESET\n\n" "$(bazel --version)" + ''; + buildInputs = enabledPackages; + }; + } + ); + }; +} diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index a8da56e..7eef78e 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -1,8 +1,13 @@ load("//bun:defs.bzl", "bun_binary") +load("@rules_shell//shell:sh_test.bzl", "sh_test") bun_binary( name = "hello_js_bin", entry_point = "hello.js", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], ) sh_test( @@ -19,6 +24,10 @@ sh_test( bun_binary( name = "hello_ts_bin", entry_point = "hello.ts", + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:linux", + ], ) sh_test( diff --git a/tests/bundle_test/BUILD.bazel b/tests/bundle_test/BUILD.bazel index 2417e43..fc86b61 100644 --- a/tests/bundle_test/BUILD.bazel +++ b/tests/bundle_test/BUILD.bazel @@ -1,4 +1,5 @@ load("//bun:defs.bzl", "bun_bundle") +load("@rules_shell//shell:sh_test.bzl", "sh_test") bun_bundle( name = "simple_bundle", diff --git a/tests/install_test/BUILD.bazel b/tests/install_test/BUILD.bazel index f23b708..25d34d2 100644 --- a/tests/install_test/BUILD.bazel +++ b/tests/install_test/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_shell//shell:sh_test.bzl", "sh_test") + sh_test( name = "bun_install_clean_install_test", srcs = ["clean_install.sh"], diff --git a/tests/toolchain_test/BUILD.bazel b/tests/toolchain_test/BUILD.bazel index 7d620d8..eb7fce7 100644 --- a/tests/toolchain_test/BUILD.bazel +++ b/tests/toolchain_test/BUILD.bazel @@ -1,3 +1,5 @@ +load("@rules_shell//shell:sh_test.bzl", "sh_test") + sh_test( name = "bun_version_test", srcs = ["toolchain_version.sh"], From e671447d132e43c9ebeb2ecfaecff6ad50b10994 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:26:46 +0100 Subject: [PATCH 13/25] feat: update nix flake --- .envrc | 1 + .gitignore | 6 ++ .gitleaks.toml | 45 +++++++++++ flake.lock | 63 ++++++++++----- flake.nix | 211 +++++++++++++++++++++---------------------------- 5 files changed, 187 insertions(+), 139 deletions(-) create mode 100644 .envrc create mode 100644 .gitleaks.toml diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 263f5fd..00b4e1f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,12 @@ # based on the name of the directory bazel is cloned into. /bazel-* +.direnv/ +.pre-commit-config.yaml +build/ +dist/ +node_modules/ + # Directories for the Bazel IntelliJ plugin containing the generated # IntelliJ project files and plugin configuration. Seperate directories are # for the IntelliJ, Android Studio and CLion versions of the plugin. diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000..1afec6d --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,45 @@ +# .gitleaks.toml +title = "gitleaks config" + +[extend] +# extend the default ruleset rather than replacing it +useDefault = true + +[allowlist] +description = "Global allowlist" +paths = [ + # lock files often contain hashes that trip up gitleaks + '''flake\.lock''', + '''package-lock\.json''', + '''yarn\.lock''', + '''bun\.lockb''', +] +regexes = [ + # nix store hashes + '''/nix/store/[a-z0-9]{32}-''', +] + +[[rules]] +id = "generic-api-key-extended" +description = "Extended generic API key detection" +regex = '''(?i)(api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token)\s*[:=]\s*['"]?[a-zA-Z0-9_\-]{16,}['"]?''' +entropy = 3.5 +tags = ["api", "key", "token"] + +[[rules]] +id = "private-key-file" +description = "Private key files" +regex = '''-----BEGIN (RSA|EC|DSA|OPENSSH|PGP) PRIVATE KEY''' +tags = ["key", "private"] + +[[rules]] +id = "environment-file" +description = "Committed .env files" +path = '''(^|/)\.env(\.[a-z]+)?$''' +regex = '''.+''' +tags = ["env"] +[rules.allowlist] + paths = [ + # allow .env.example and .env.template + '''\.env\.(example|template|sample)$''', + ] diff --git a/flake.lock b/flake.lock index 73bcd98..7f4f24d 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,28 @@ { "nodes": { + "devshell-lib": { + "inputs": { + "git-hooks": "git-hooks", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1772609129, + "narHash": "sha256-ha7H2OhxoLhkDVgKtgkJc8yO3f0rKlPZZTJYyc+rfLI=", + "ref": "v1.0.3", + "rev": "cdc9e180353b1a1105bbcdad18dc3938ea3e88a3", + "revCount": 31, + "type": "git", + "url": "https://git.dgren.dev/eric/nix-flake-lib" + }, + "original": { + "ref": "v1.0.3", + "type": "git", + "url": "https://git.dgren.dev/eric/nix-flake-lib" + } + }, "flake-compat": { "flake": false, "locked": { @@ -39,6 +62,7 @@ "gitignore": { "inputs": { "nixpkgs": [ + "devshell-lib", "git-hooks", "nixpkgs" ] @@ -74,22 +98,6 @@ } }, "nixpkgs_2": { - "locked": { - "lastModified": 1772542754, - "narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4", - "type": "github" - }, - "original": { - "owner": "nixos", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "nixpkgs_3": { "locked": { "lastModified": 1770107345, "narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=", @@ -105,16 +113,31 @@ "type": "github" } }, + "nixpkgs_3": { + "locked": { + "lastModified": 1772542754, + "narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "8c809a146a140c5c8806f13399592dbcb1bb5dc4", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "root": { "inputs": { - "git-hooks": "git-hooks", - "nixpkgs": "nixpkgs_2", - "treefmt-nix": "treefmt-nix" + "devshell-lib": "devshell-lib", + "nixpkgs": "nixpkgs_3" } }, "treefmt-nix": { "inputs": { - "nixpkgs": "nixpkgs_3" + "nixpkgs": "nixpkgs_2" }, "locked": { "lastModified": 1770228511, diff --git a/flake.nix b/flake.nix index 4663590..7c560ab 100644 --- a/flake.nix +++ b/flake.nix @@ -3,17 +3,16 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - git-hooks.url = "github:cachix/git-hooks.nix"; - treefmt-nix.url = "github:numtide/treefmt-nix"; + devshell-lib.url = "git+https://git.dgren.dev/eric/nix-flake-lib?ref=v1.0.3"; + devshell-lib.inputs.nixpkgs.follows = "nixpkgs"; }; outputs = { - self, nixpkgs, - treefmt-nix, + devshell-lib, ... - }@inputs: + }: let supportedSystems = [ "x86_64-linux" @@ -22,147 +21,121 @@ "aarch64-darwin" ]; forAllSystems = nixpkgs.lib.genAttrs supportedSystems; - treefmtEvalFor = - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - treefmt-nix.lib.evalModule pkgs { - projectRootFile = "flake.nix"; - - programs = { - nixfmt.enable = true; - shfmt.enable = true; - oxfmt.enable = true; - }; - - settings = { - formatter = { - shfmt = { - options = [ - "-i" - "2" - "-s" - "-w" - ]; - }; - oxfmt = { - includes = [ - "*.md" - "*.yaml" - "*.yml" - "*.json" - "*.html" - "*.css" - "*.js" - "*.ts" - "*.tsx" - "*.svelte" - ]; - }; - }; - }; - }; in { - formatter = forAllSystems (system: (treefmtEvalFor system).config.build.wrapper); - - checks = forAllSystems ( - system: - let - pkgs = import nixpkgs { inherit system; }; - in - { - pre-commit-check = inputs.git-hooks.lib.${system}.run { - src = ./.; - hooks = { - treefmt = { - enable = true; - entry = "${(treefmtEvalFor system).config.build.wrapper}/bin/treefmt"; - pass_filenames = true; - }; - gitlint.enable = true; - - gitleaks = { - enable = true; - entry = "${pkgs.gitleaks}/bin/gitleaks protect --staged"; - pass_filenames = false; - }; - - tests = { - enable = true; - entry = "echo 'No tests defined yet.'"; - pass_filenames = false; - stages = [ - "pre-push" - ]; - }; - }; - }; - } - ); - devShells = forAllSystems ( system: let pkgs = import nixpkgs { inherit system; }; - inherit (self.checks.${system}.pre-commit-check) shellHook enabledPackages; - customShellHook = shellHook + ""; bazel9 = pkgs.writeShellScriptBin "bazel" '' export USE_BAZEL_VERSION="''${USE_BAZEL_VERSION:-9.0.0}" exec ${pkgs.bazelisk}/bin/bazelisk "$@" ''; + env = devshell-lib.lib.mkDevShell { + inherit system; - in - { - default = pkgs.mkShell { - packages = with pkgs; [ + extraPackages = with pkgs; [ go gopls gotools - bun - gitlint bazel9 bazel-buildtools ]; - shellHook = '' - ${customShellHook} - export USE_BAZEL_VERSION="''${USE_BAZEL_VERSION:-9.0.0}" - export BUN_INSTALL="''${BUN_INSTALL:-$HOME/.bun}" - export PATH="$BUN_INSTALL/bin:$PATH" + features = { + oxfmt = true; + }; - if ! command -v oxfmt >/dev/null 2>&1; then - bun add --global oxfmt - fi + formatters = { + shfmt.enable = true; + }; - if ! command -v oxlint >/dev/null 2>&1; then - bun add --global oxlint - fi + formatterSettings = { + shfmt.options = [ + "-i" + "2" + "-s" + "-w" + ]; + }; - if [ -t 1 ]; then - if command -v tput >/dev/null 2>&1; then - tput clear - else - printf '\033c' - fi - fi + additionalHooks = { + tests = { + enable = true; + entry = "echo 'No tests defined yet.'"; + pass_filenames = false; + stages = [ "pre-push" ]; + }; + }; - GREEN='\033[1;32m' - CYAN='\033[1;36m' - YELLOW='\033[1;33m' - BLUE='\033[1;34m' - RESET='\033[0m' + tools = [ + { + name = "Bun"; + bin = "${pkgs.bun}/bin/bun"; + versionCmd = "--version"; + color = "YELLOW"; + } + { + name = "Go"; + bin = "${pkgs.go}/bin/go"; + versionCmd = "version"; + color = "CYAN"; + } + { + name = "Bazel"; + bin = "${bazel9}/bin/bazel"; + versionCmd = "--version"; + color = "BLUE"; + } + ]; - printf "\n$GREEN 🚀 Monorepo dev shell ready$RESET\n\n" - printf " $CYAN Bun:$RESET $YELLOW%s$RESET\n" "$(bun --version)" - printf " $CYAN Go:$RESET $YELLOW%s$RESET\n" "$(go version)" - printf " $CYAN Bazel:$RESET $BLUE%s$RESET\n\n" "$(bazel --version)" + extraShellHook = '' + export USE_BAZEL_VERSION="''${USE_BAZEL_VERSION:-9.0.0}" + export BUN_INSTALL="''${BUN_INSTALL:-$HOME/.bun}" + export PATH="$BUN_INSTALL/bin:$PATH" ''; - buildInputs = enabledPackages; }; + in + { + default = env.shell; } ); + + checks = forAllSystems ( + system: + let + env = devshell-lib.lib.mkDevShell { inherit system; }; + in + { + inherit (env) pre-commit-check; + } + ); + + formatter = forAllSystems (system: (devshell-lib.lib.mkDevShell { inherit system; }).formatter); + + # Optional: release command (`release`) + # + # The release script always updates VERSION first, then: + # 1) runs release steps in order (file writes and scripts) + # 2) runs postVersion hook + # 3) formats, stages, commits, tags, and pushes + # + # Runtime env vars available in release.run/postVersion: + # BASE_VERSION, CHANNEL, PRERELEASE_NUM, FULL_VERSION, FULL_TAG + # + packages = forAllSystems (system: { + release = devshell-lib.lib.mkRelease { + inherit system; + + release = [ ]; + + postVersion = '' + echo "Released $FULL_TAG" + ''; + }; + }); + }; + } From 9868933b27de58befbce8a9b800e4dce918b5e4f Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 07:31:19 +0000 Subject: [PATCH 14/25] feat: add phase 6 js_library and ts_library bootstrap --- README.md | 6 +++++ bun/defs.bzl | 3 +++ internal/bun_bundle.bzl | 8 ++++++ internal/bun_test.bzl | 8 ++++++ internal/js_library.bzl | 40 ++++++++++++++++++++++++++++ tests/library_test/BUILD.bazel | 41 +++++++++++++++++++++++++++++ tests/library_test/app.test.ts | 6 +++++ tests/library_test/app.ts | 3 +++ tests/library_test/helper.ts | 3 +++ tests/library_test/verify_bundle.sh | 9 +++++++ 10 files changed, 127 insertions(+) create mode 100644 internal/js_library.bzl create mode 100644 tests/library_test/BUILD.bazel create mode 100644 tests/library_test/app.test.ts create mode 100644 tests/library_test/app.ts create mode 100644 tests/library_test/helper.ts create mode 100755 tests/library_test/verify_bundle.sh diff --git a/README.md b/README.md index 4b178e5..43598c1 100644 --- a/README.md +++ b/README.md @@ -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`) diff --git a/bun/defs.bzl b/bun/defs.bzl index 85fd304..91bfc90 100644 --- a/bun/defs.bzl +++ b/bun/defs.bzl @@ -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 diff --git a/internal/bun_bundle.bzl b/internal/bun_bundle.bzl index 13af4bc..56b6aee 100644 --- a/internal/bun_bundle.bzl +++ b/internal/bun_bundle.bzl @@ -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", diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index 63f2c4d..5e46a71 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -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, diff --git a/internal/js_library.bzl b/internal/js_library.bzl new file mode 100644 index 0000000..4247824 --- /dev/null +++ b/internal/js_library.bzl @@ -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(), + }, +) diff --git a/tests/library_test/BUILD.bazel b/tests/library_test/BUILD.bazel new file mode 100644 index 0000000..2cfacac --- /dev/null +++ b/tests/library_test/BUILD.bazel @@ -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", + ], +) diff --git a/tests/library_test/app.test.ts b/tests/library_test/app.test.ts new file mode 100644 index 0000000..46535b9 --- /dev/null +++ b/tests/library_test/app.test.ts @@ -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"); +}); diff --git a/tests/library_test/app.ts b/tests/library_test/app.ts new file mode 100644 index 0000000..d248746 --- /dev/null +++ b/tests/library_test/app.ts @@ -0,0 +1,3 @@ +import { greeting } from "./helper"; + +console.log(greeting("bundle")); diff --git a/tests/library_test/helper.ts b/tests/library_test/helper.ts new file mode 100644 index 0000000..cdf8ab7 --- /dev/null +++ b/tests/library_test/helper.ts @@ -0,0 +1,3 @@ +export function greeting(name: string): string { + return `hello-${name}`; +} diff --git a/tests/library_test/verify_bundle.sh b/tests/library_test/verify_bundle.sh new file mode 100755 index 0000000..006fd97 --- /dev/null +++ b/tests/library_test/verify_bundle.sh @@ -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 From 87ca65b1cef38f5dcfc02dc4244e20b6bbb63f3f Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:44:11 +0100 Subject: [PATCH 15/25] fix: tests --- .gitlint | 8 ++++ bun/repositories.bzl | 2 +- internal/bun_binary.bzl | 11 ++++- internal/bun_test.bzl | 18 ++++--- tests/binary_test/BUILD.bazel | 16 ------- tests/bun_test_test/BUILD.bazel | 8 ---- tests/bundle_test/BUILD.bazel | 16 ------- tests/install_test/BUILD.bazel | 72 +++++++++++++++++++++++----- tests/install_test/stale_lockfile.sh | 25 +++++----- tests/library_test/BUILD.bazel | 17 +------ tests/toolchain_test/BUILD.bazel | 52 +++++++++++++++++--- 11 files changed, 151 insertions(+), 94 deletions(-) create mode 100644 .gitlint diff --git a/.gitlint b/.gitlint new file mode 100644 index 0000000..a76e65b --- /dev/null +++ b/.gitlint @@ -0,0 +1,8 @@ +[general] +ignore=B6 + +[title-max-length] +line-length=72 + +[title-match-regex] +regex=^(feat|fix|chore|docs|refactor|test|ci)(\(.+\))?: .+ \ No newline at end of file diff --git a/bun/repositories.bzl b/bun/repositories.bzl index 37ba294..b475d4a 100644 --- a/bun/repositories.bzl +++ b/bun/repositories.bzl @@ -63,7 +63,7 @@ def bun_repositories(version = BUN_VERSION): ) -def bun_register_toolchains(version = BUN_VERSION): +def bun_register_toolchains(name = "bun", version = BUN_VERSION): bun_repositories(version = version) native.register_toolchains( "//bun:darwin_aarch64_toolchain", diff --git a/internal/bun_binary.bzl b/internal/bun_binary.bzl index 0e2caf8..f5e76bb 100644 --- a/internal/bun_binary.bzl +++ b/internal/bun_binary.bzl @@ -13,8 +13,15 @@ def _bun_binary_impl(ctx): content = """#!/usr/bin/env bash set -euo pipefail -exec \"{}\" run \"{}\" \"$@\" -""".format(bun_bin.path, entry_point.path), +runfiles_dir="${{RUNFILES_DIR:-$0.runfiles}}" +bun_bin="${{runfiles_dir}}/_main/{bun_short_path}" +entry_point="${{runfiles_dir}}/_main/{entry_short_path}" + +exec "${{bun_bin}}" run "${{entry_point}}" "$@" +""".format( + bun_short_path = bun_bin.short_path, + entry_short_path = entry_point.short_path, + ), ) transitive_files = [] diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index 5e46a71..29d311e 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -11,7 +11,7 @@ def _bun_test_impl(ctx): toolchain = ctx.toolchains["//bun:toolchain_type"] bun_bin = toolchain.bun.bun_bin - src_args = " ".join([_shell_quote(src.path) for src in ctx.files.srcs]) + src_args = " ".join([_shell_quote(src.short_path) for src in ctx.files.srcs]) launcher = ctx.actions.declare_file(ctx.label.name) ctx.actions.write( output = launcher, @@ -19,16 +19,22 @@ def _bun_test_impl(ctx): content = """#!/usr/bin/env bash set -euo pipefail -extra_args=() +runfiles_dir="${{RUNFILES_DIR:-$0.runfiles}}" +bun_bin="${{runfiles_dir}}/_main/{bun_short_path}" +cd "${{runfiles_dir}}/_main" + +if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" && -n "${{COVERAGE_DIR:-}}" ]]; then + exec "${{bun_bin}}" test {src_args} --test-name-pattern "${{TESTBRIDGE_TEST_ONLY}}" --coverage "$@" +fi if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" ]]; then - extra_args+=("--test-name-pattern" "${{TESTBRIDGE_TEST_ONLY}}") + exec "${{bun_bin}}" test {src_args} --test-name-pattern "${{TESTBRIDGE_TEST_ONLY}}" "$@" fi if [[ -n "${{COVERAGE_DIR:-}}" ]]; then - extra_args+=("--coverage") + exec "${{bun_bin}}" test {src_args} --coverage "$@" fi -exec "{bun_bin}" test {src_args} "${{extra_args[@]}}" "$@" +exec "${{bun_bin}}" test {src_args} "$@" """.format( - bun_bin = bun_bin.path, + bun_short_path = bun_bin.short_path, src_args = src_args, ), ) diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index 7eef78e..ae4e371 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -4,10 +4,6 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test") bun_binary( name = "hello_js_bin", entry_point = "hello.js", - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) sh_test( @@ -15,19 +11,11 @@ sh_test( srcs = ["run_binary.sh"], args = ["$(location :hello_js_bin)", "hello-js"], data = [":hello_js_bin"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) bun_binary( name = "hello_ts_bin", entry_point = "hello.ts", - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) sh_test( @@ -35,8 +23,4 @@ sh_test( srcs = ["run_binary.sh"], args = ["$(location :hello_ts_bin)", "hello-ts"], data = [":hello_ts_bin"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel index 9f67755..6ed38c2 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -3,18 +3,10 @@ load("//bun:defs.bzl", "bun_test") bun_test( name = "passing_suite", srcs = ["passing.test.ts"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) bun_test( name = "failing_suite", srcs = ["failing.test.ts"], tags = ["manual"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) diff --git a/tests/bundle_test/BUILD.bazel b/tests/bundle_test/BUILD.bazel index fc86b61..b2c97f0 100644 --- a/tests/bundle_test/BUILD.bazel +++ b/tests/bundle_test/BUILD.bazel @@ -4,20 +4,12 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test") bun_bundle( name = "simple_bundle", entry_points = ["main.ts"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) bun_bundle( name = "minified_bundle", entry_points = ["main.ts"], minify = True, - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) sh_test( @@ -25,10 +17,6 @@ sh_test( srcs = ["verify_bundle.sh"], args = ["$(location :simple_bundle)"], data = [":simple_bundle"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) sh_test( @@ -42,8 +30,4 @@ sh_test( ":simple_bundle", ":minified_bundle", ], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], ) diff --git a/tests/install_test/BUILD.bazel b/tests/install_test/BUILD.bazel index 25d34d2..4560eef 100644 --- a/tests/install_test/BUILD.bazel +++ b/tests/install_test/BUILD.bazel @@ -1,23 +1,71 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test") +config_setting( + name = "linux_x86_64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], +) + +config_setting( + name = "linux_aarch64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], +) + +config_setting( + name = "darwin_x86_64", + constraint_values = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], +) + +config_setting( + name = "darwin_aarch64", + constraint_values = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], +) + sh_test( name = "bun_install_clean_install_test", srcs = ["clean_install.sh"], - args = ["$(location @bun_linux_x64//:bun)"], - data = ["@bun_linux_x64//:bun"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], + args = select({ + ":linux_x86_64": ["$(location @bun_linux_x64//:bun)"], + ":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"], + ":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"], + ":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"], + "//conditions:default": ["$(location @bun_linux_x64//:bun)"], + }), + data = select({ + ":linux_x86_64": ["@bun_linux_x64//:bun"], + ":linux_aarch64": ["@bun_linux_aarch64//:bun"], + ":darwin_x86_64": ["@bun_darwin_x64//:bun"], + ":darwin_aarch64": ["@bun_darwin_aarch64//:bun"], + "//conditions:default": ["@bun_linux_x64//:bun"], + }), ) sh_test( name = "bun_install_stale_lockfile_test", srcs = ["stale_lockfile.sh"], - args = ["$(location @bun_linux_x64//:bun)"], - data = ["@bun_linux_x64//:bun"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], + args = select({ + ":linux_x86_64": ["$(location @bun_linux_x64//:bun)"], + ":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"], + ":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"], + ":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"], + "//conditions:default": ["$(location @bun_linux_x64//:bun)"], + }), + data = select({ + ":linux_x86_64": ["@bun_linux_x64//:bun"], + ":linux_aarch64": ["@bun_linux_aarch64//:bun"], + ":darwin_x86_64": ["@bun_darwin_x64//:bun"], + ":darwin_aarch64": ["@bun_darwin_aarch64//:bun"], + "//conditions:default": ["@bun_linux_x64//:bun"], + }), ) diff --git a/tests/install_test/stale_lockfile.sh b/tests/install_test/stale_lockfile.sh index e21cfd2..fbb0501 100755 --- a/tests/install_test/stale_lockfile.sh +++ b/tests/install_test/stale_lockfile.sh @@ -5,16 +5,7 @@ bun_path="$1" workdir="$(mktemp -d)" trap 'rm -rf "${workdir}"' EXIT -cat > "${workdir}/package.json" <<'JSON' -{ - "name": "stale-lockfile-test", - "version": "1.0.0" -} -JSON - -"${bun_path}" install --cwd "${workdir}" >/dev/null - -cat > "${workdir}/package.json" <<'JSON' +cat >"${workdir}/package.json" <<'JSON' { "name": "stale-lockfile-test", "version": "1.0.0", @@ -24,6 +15,18 @@ cat > "${workdir}/package.json" <<'JSON' } JSON +"${bun_path}" install --cwd "${workdir}" >/dev/null + +cat >"${workdir}/package.json" <<'JSON' +{ + "name": "stale-lockfile-test", + "version": "1.0.0", + "dependencies": { + "left-pad": "1.1.3" + } +} +JSON + set +e output="$(${bun_path} install --cwd "${workdir}" --frozen-lockfile 2>&1)" code=$? @@ -34,7 +37,7 @@ if [[ ${code} -eq 0 ]]; then exit 1 fi -if [[ "${output}" != *"lockfile"* && "${output}" != *"frozen"* ]]; then +if [[ ${output} != *"lockfile"* && ${output} != *"frozen"* ]]; then echo "Expected lockfile-related error, got:" >&2 echo "${output}" >&2 exit 1 diff --git a/tests/library_test/BUILD.bazel b/tests/library_test/BUILD.bazel index 2cfacac..8c423ce 100644 --- a/tests/library_test/BUILD.bazel +++ b/tests/library_test/BUILD.bazel @@ -1,22 +1,15 @@ load("//bun:defs.bzl", "bun_bundle", "bun_test", "ts_library") +load("@rules_shell//shell:sh_test.bzl", "sh_test") 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( @@ -24,18 +17,10 @@ sh_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", - ], ) diff --git a/tests/toolchain_test/BUILD.bazel b/tests/toolchain_test/BUILD.bazel index eb7fce7..3527248 100644 --- a/tests/toolchain_test/BUILD.bazel +++ b/tests/toolchain_test/BUILD.bazel @@ -1,12 +1,52 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test") +config_setting( + name = "linux_x86_64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], +) + +config_setting( + name = "linux_aarch64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], +) + +config_setting( + name = "darwin_x86_64", + constraint_values = [ + "@platforms//os:macos", + "@platforms//cpu:x86_64", + ], +) + +config_setting( + name = "darwin_aarch64", + constraint_values = [ + "@platforms//os:macos", + "@platforms//cpu:aarch64", + ], +) + sh_test( name = "bun_version_test", srcs = ["toolchain_version.sh"], - args = ["$(location @bun_linux_x64//:bun)"], - data = ["@bun_linux_x64//:bun"], - target_compatible_with = [ - "@platforms//cpu:x86_64", - "@platforms//os:linux", - ], + args = select({ + ":linux_x86_64": ["$(location @bun_linux_x64//:bun)"], + ":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"], + ":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"], + ":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"], + "//conditions:default": ["$(location @bun_linux_x64//:bun)"], + }), + data = select({ + ":linux_x86_64": ["@bun_linux_x64//:bun"], + ":linux_aarch64": ["@bun_linux_aarch64//:bun"], + ":darwin_x86_64": ["@bun_darwin_x64//:bun"], + ":darwin_aarch64": ["@bun_darwin_aarch64//:bun"], + "//conditions:default": ["@bun_linux_x64//:bun"], + }), ) From 88bf02cda3f55635285de5c1cc33abea677782be Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:49:18 +0100 Subject: [PATCH 16/25] chore: update flake --- flake.lock | 12 ++++++------ flake.nix | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/flake.lock b/flake.lock index 7f4f24d..37de1f2 100644 --- a/flake.lock +++ b/flake.lock @@ -9,16 +9,16 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1772609129, - "narHash": "sha256-ha7H2OhxoLhkDVgKtgkJc8yO3f0rKlPZZTJYyc+rfLI=", - "ref": "v1.0.3", - "rev": "cdc9e180353b1a1105bbcdad18dc3938ea3e88a3", - "revCount": 31, + "lastModified": 1772610504, + "narHash": "sha256-uoMnjsab5IpZRZ/1mn5oVy4fRnAYn6b58E3FNa+jyQY=", + "ref": "v1.0.4", + "rev": "86a0792b6e54104e8cb33983cabc175aea8da464", + "revCount": 33, "type": "git", "url": "https://git.dgren.dev/eric/nix-flake-lib" }, "original": { - "ref": "v1.0.3", + "ref": "v1.0.4", "type": "git", "url": "https://git.dgren.dev/eric/nix-flake-lib" } diff --git a/flake.nix b/flake.nix index 7c560ab..88e0a57 100644 --- a/flake.nix +++ b/flake.nix @@ -3,7 +3,7 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; - devshell-lib.url = "git+https://git.dgren.dev/eric/nix-flake-lib?ref=v1.0.3"; + devshell-lib.url = "git+https://git.dgren.dev/eric/nix-flake-lib?ref=v1.0.4"; devshell-lib.inputs.nixpkgs.follows = "nixpkgs"; }; From d271e4bde6ec976661454c297f4442f65724e43c Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 07:52:24 +0000 Subject: [PATCH 17/25] feat: add phase 7 bun_install module extension --- README.md | 5 ++++ bun/BUILD.bazel | 5 +++- bun/extensions.bzl | 25 +++++++++++++++++++ tests/install_extension_test/BUILD.bazel | 8 ++++++ .../extension_shape_test.sh | 9 +++++++ 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 tests/install_extension_test/BUILD.bazel create mode 100755 tests/install_extension_test/extension_shape_test.sh diff --git a/README.md b/README.md index 43598c1..f65b7fc 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,8 @@ 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`) + +Phase 7 bootstrap is in place: + +- Bzlmod `bun_install` module extension (`/bun/extensions.bzl`) using Bazel 9-compatible extension/tag syntax +- Focused module-extension shape test (`//tests/install_extension_test:all`) diff --git a/bun/BUILD.bazel b/bun/BUILD.bazel index ba771e6..c1895c7 100644 --- a/bun/BUILD.bazel +++ b/bun/BUILD.bazel @@ -1,7 +1,10 @@ load(":toolchain.bzl", "bun_toolchain") load(":version.bzl", "BUN_VERSION") -exports_files(["defs.bzl"]) +exports_files([ + "defs.bzl", + "extensions.bzl", +]) toolchain_type(name = "toolchain_type") diff --git a/bun/extensions.bzl b/bun/extensions.bzl index bb9ea75..cb25371 100644 --- a/bun/extensions.bzl +++ b/bun/extensions.bzl @@ -1,4 +1,5 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") +load("//internal:bun_install.bzl", _bun_install_repository = "_bun_install_repository") load(":version.bzl", "BUN_VERSION") _BUN_ARCHIVES = { @@ -53,3 +54,27 @@ filegroup( bun = module_extension( implementation = _bun_repos_impl, ) + +_install = tag_class( + attrs = { + "name": attr.string(default = "node_modules"), + "package_json": attr.string(mandatory = True), + "bun_lockfile": attr.string(mandatory = True), + }, +) + + +def _bun_install_impl(ctx): + for mod in ctx.modules: + for install in mod.tags.install: + _bun_install_repository( + name = install.name, + package_json = install.package_json, + bun_lockfile = install.bun_lockfile, + ) + + +bun_install = module_extension( + implementation = _bun_install_impl, + tag_classes = {"install": _install}, +) diff --git a/tests/install_extension_test/BUILD.bazel b/tests/install_extension_test/BUILD.bazel new file mode 100644 index 0000000..bdf75d8 --- /dev/null +++ b/tests/install_extension_test/BUILD.bazel @@ -0,0 +1,8 @@ +load("@rules_shell//shell:sh_test.bzl", "sh_test") + +sh_test( + name = "bun_install_extension_shape_test", + srcs = ["extension_shape_test.sh"], + args = ["$(location //bun:extensions.bzl)"], + data = ["//bun:extensions.bzl"], +) diff --git a/tests/install_extension_test/extension_shape_test.sh b/tests/install_extension_test/extension_shape_test.sh new file mode 100755 index 0000000..a2f9aa1 --- /dev/null +++ b/tests/install_extension_test/extension_shape_test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +extension_file="$1" + +grep -q 'bun_install = module_extension(' "${extension_file}" +grep -q 'tag_classes = {"install": _install}' "${extension_file}" +grep -q '"package_json": attr.string(mandatory = True)' "${extension_file}" +grep -q '"bun_lockfile": attr.string(mandatory = True)' "${extension_file}" From 76fad7e9c84c415119ef2418343716bdd8603dd0 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 07:54:06 +0000 Subject: [PATCH 18/25] chore: address phase 7 review feedback --- bun/extensions.bzl | 2 +- tests/install_extension_test/extension_shape_test.sh | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/bun/extensions.bzl b/bun/extensions.bzl index cb25371..f9624f6 100644 --- a/bun/extensions.bzl +++ b/bun/extensions.bzl @@ -57,7 +57,7 @@ bun = module_extension( _install = tag_class( attrs = { - "name": attr.string(default = "node_modules"), + "name": attr.string(mandatory = True), "package_json": attr.string(mandatory = True), "bun_lockfile": attr.string(mandatory = True), }, diff --git a/tests/install_extension_test/extension_shape_test.sh b/tests/install_extension_test/extension_shape_test.sh index a2f9aa1..94fef31 100755 --- a/tests/install_extension_test/extension_shape_test.sh +++ b/tests/install_extension_test/extension_shape_test.sh @@ -3,7 +3,8 @@ set -euo pipefail extension_file="$1" -grep -q 'bun_install = module_extension(' "${extension_file}" -grep -q 'tag_classes = {"install": _install}' "${extension_file}" -grep -q '"package_json": attr.string(mandatory = True)' "${extension_file}" -grep -q '"bun_lockfile": attr.string(mandatory = True)' "${extension_file}" +grep -Eq 'bun_install[[:space:]]*=[[:space:]]*module_extension\(' "${extension_file}" +grep -Eq 'tag_classes[[:space:]]*=[[:space:]]*\{"install":[[:space:]]*_install\}' "${extension_file}" +grep -Eq '"name":[[:space:]]*attr\.string\(mandatory[[:space:]]*=[[:space:]]*True\)' "${extension_file}" +grep -Eq '"package_json":[[:space:]]*attr\.string\(mandatory[[:space:]]*=[[:space:]]*True\)' "${extension_file}" +grep -Eq '"bun_lockfile":[[:space:]]*attr\.string\(mandatory[[:space:]]*=[[:space:]]*True\)' "${extension_file}" From fe1de242357b43c14b91e526bee4f0a479f3c8da Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:57:26 +0100 Subject: [PATCH 19/25] fix: tests --- .bazelignore | 1 + MODULE.bazel.lock | 2 +- bun/extensions.bzl | 4 ++-- internal/bun_install.bzl | 6 ++++-- 4 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 .bazelignore diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000..92b2793 --- /dev/null +++ b/.bazelignore @@ -0,0 +1 @@ +.direnv diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index eed6b86..962e12e 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -189,7 +189,7 @@ "moduleExtensions": { "//bun:extensions.bzl%bun": { "general": { - "bzlTransitiveDigest": "OnZvc44B8aCFH7E+udHBoIoIkL0AeKA27+2lmg/S15Q=", + "bzlTransitiveDigest": "Q0uQOwFAgAU+etePCZ4TUDO+adLX7Z0EmRLaEsKgncw=", "usagesDigest": "qk1PDh3WICa0VONYKXJLsmWCesNJxz3Jkb/aH/voIeI=", "recordedInputs": [ "REPO_MAPPING:,bazel_tools bazel_tools" diff --git a/bun/extensions.bzl b/bun/extensions.bzl index f9624f6..6eec597 100644 --- a/bun/extensions.bzl +++ b/bun/extensions.bzl @@ -1,5 +1,5 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -load("//internal:bun_install.bzl", _bun_install_repository = "_bun_install_repository") +load("//internal:bun_install.bzl", "bun_install_repository") load(":version.bzl", "BUN_VERSION") _BUN_ARCHIVES = { @@ -67,7 +67,7 @@ _install = tag_class( def _bun_install_impl(ctx): for mod in ctx.modules: for install in mod.tags.install: - _bun_install_repository( + bun_install_repository( name = install.name, package_json = install.package_json, bun_lockfile = install.bun_lockfile, diff --git a/internal/bun_install.bzl b/internal/bun_install.bzl index 9d51d16..db0a01e 100644 --- a/internal/bun_install.bzl +++ b/internal/bun_install.bzl @@ -61,7 +61,7 @@ stderr: ) -_bun_install_repository = repository_rule( +bun_install_repository = repository_rule( implementation = _bun_install_repository_impl, attrs = { "package_json": attr.label(mandatory = True, allow_single_file = True), @@ -74,6 +74,8 @@ _bun_install_repository = repository_rule( }, ) +_bun_install_repository = bun_install_repository + def bun_install(name, package_json, bun_lockfile): """Create an external repository containing installed node_modules. @@ -91,7 +93,7 @@ def bun_install(name, package_json, bun_lockfile): ) """ - _bun_install_repository( + bun_install_repository( name = name, package_json = package_json, bun_lockfile = bun_lockfile, From dbbac60c7e1064f2c797c4540e50a81fe15dbe7e Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:01:05 +0000 Subject: [PATCH 20/25] feat: add phase 8 ci matrix workflow --- .github/workflows/BUILD.bazel | 3 +++ .github/workflows/ci.yml | 27 ++++++++++++++++++++ README.md | 6 +++++ tests/ci_test/BUILD.bazel | 8 ++++++ tests/ci_test/phase8_ci_matrix_shape_test.sh | 13 ++++++++++ 5 files changed, 57 insertions(+) create mode 100644 .github/workflows/BUILD.bazel create mode 100644 .github/workflows/ci.yml create mode 100644 tests/ci_test/BUILD.bazel create mode 100755 tests/ci_test/phase8_ci_matrix_shape_test.sh diff --git a/.github/workflows/BUILD.bazel b/.github/workflows/BUILD.bazel new file mode 100644 index 0000000..ad5a71a --- /dev/null +++ b/.github/workflows/BUILD.bazel @@ -0,0 +1,3 @@ +package(default_visibility = ["//visibility:public"]) + +exports_files(["ci.yml"]) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f75abd8 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: ["main"] + pull_request: + +jobs: + test: + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + phase8_target: linux-x64 + - os: macos-14 + phase8_target: darwin-arm64 + - os: windows-latest + phase8_target: windows + runs-on: ${{ matrix.os }} + env: + USE_BAZEL_VERSION: 9.0.0 + steps: + - uses: actions/checkout@v4 + - uses: bazel-contrib/setup-bazel@0.15.0 + - name: Run tests (${{ matrix.phase8_target }}) + run: bazel test //tests/... diff --git a/README.md b/README.md index f65b7fc..930c0d6 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,9 @@ Phase 7 bootstrap is in place: - Bzlmod `bun_install` module extension (`/bun/extensions.bzl`) using Bazel 9-compatible extension/tag syntax - Focused module-extension shape test (`//tests/install_extension_test:all`) + +Phase 8 bootstrap is in place: + +- CI matrix workflow for linux-x64, darwin-arm64, and windows (`/.github/workflows/ci.yml`) +- Bazel 9 pin in CI via `USE_BAZEL_VERSION=9.0.0` +- Focused CI matrix shape test (`//tests/ci_test:all`) diff --git a/tests/ci_test/BUILD.bazel b/tests/ci_test/BUILD.bazel new file mode 100644 index 0000000..4f66e55 --- /dev/null +++ b/tests/ci_test/BUILD.bazel @@ -0,0 +1,8 @@ +load("@rules_shell//shell:sh_test.bzl", "sh_test") + +sh_test( + name = "phase8_ci_matrix_shape_test", + srcs = ["phase8_ci_matrix_shape_test.sh"], + args = ["$(location //.github/workflows:ci.yml)"], + data = ["//.github/workflows:ci.yml"], +) diff --git a/tests/ci_test/phase8_ci_matrix_shape_test.sh b/tests/ci_test/phase8_ci_matrix_shape_test.sh new file mode 100755 index 0000000..23930f0 --- /dev/null +++ b/tests/ci_test/phase8_ci_matrix_shape_test.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +workflow_file="$1" + +grep -Eq '^name:[[:space:]]+CI$' "${workflow_file}" +grep -Eq 'USE_BAZEL_VERSION:[[:space:]]+9\.0\.0' "${workflow_file}" +grep -Eq 'os:[[:space:]]+ubuntu-latest' "${workflow_file}" +grep -Eq 'phase8_target:[[:space:]]+linux-x64' "${workflow_file}" +grep -Eq 'os:[[:space:]]+macos-14' "${workflow_file}" +grep -Eq 'phase8_target:[[:space:]]+darwin-arm64' "${workflow_file}" +grep -Eq 'os:[[:space:]]+windows-latest' "${workflow_file}" +grep -Eq 'phase8_target:[[:space:]]+windows' "${workflow_file}" From 59791932a37924d38353a52e1a659f61cc68033d Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:04:30 +0000 Subject: [PATCH 21/25] fix: harden phase 8 CI workflow and checks --- .github/workflows/ci.yml | 6 +++- tests/ci_test/phase8_ci_matrix_shape_test.sh | 30 ++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f75abd8..406de4e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,8 @@ on: jobs: test: + permissions: + contents: read strategy: fail-fast: false matrix: @@ -24,4 +26,6 @@ jobs: - uses: actions/checkout@v4 - uses: bazel-contrib/setup-bazel@0.15.0 - name: Run tests (${{ matrix.phase8_target }}) - run: bazel test //tests/... + run: | + echo "Phase 8 target: ${{ matrix.phase8_target }}" + bazel test //tests/... diff --git a/tests/ci_test/phase8_ci_matrix_shape_test.sh b/tests/ci_test/phase8_ci_matrix_shape_test.sh index 23930f0..74bb0f5 100755 --- a/tests/ci_test/phase8_ci_matrix_shape_test.sh +++ b/tests/ci_test/phase8_ci_matrix_shape_test.sh @@ -2,12 +2,26 @@ set -euo pipefail workflow_file="$1" +if [ -z "${workflow_file}" ]; then + echo "Error: workflow file path required as first argument" >&2 + exit 1 +fi -grep -Eq '^name:[[:space:]]+CI$' "${workflow_file}" -grep -Eq 'USE_BAZEL_VERSION:[[:space:]]+9\.0\.0' "${workflow_file}" -grep -Eq 'os:[[:space:]]+ubuntu-latest' "${workflow_file}" -grep -Eq 'phase8_target:[[:space:]]+linux-x64' "${workflow_file}" -grep -Eq 'os:[[:space:]]+macos-14' "${workflow_file}" -grep -Eq 'phase8_target:[[:space:]]+darwin-arm64' "${workflow_file}" -grep -Eq 'os:[[:space:]]+windows-latest' "${workflow_file}" -grep -Eq 'phase8_target:[[:space:]]+windows' "${workflow_file}" +check_pattern() { + local pattern="$1" + local message="$2" + if ! grep -Eq "${pattern}" "${workflow_file}"; then + echo "Error: ${message}" >&2 + exit 1 + fi +} + +check_pattern '^name:[[:space:]]+CI$' "missing workflow name CI" +check_pattern 'USE_BAZEL_VERSION:[[:space:]]+9\.0\.0' "missing Bazel 9.0.0 pin" +check_pattern 'os:[[:space:]]+ubuntu-latest' "missing ubuntu matrix entry" +check_pattern 'phase8_target:[[:space:]]+linux-x64' "missing linux-x64 matrix target" +check_pattern 'os:[[:space:]]+macos-14' "missing macos matrix entry" +check_pattern 'phase8_target:[[:space:]]+darwin-arm64' "missing darwin-arm64 matrix target" +check_pattern 'os:[[:space:]]+windows-latest' "missing windows matrix entry" +check_pattern 'phase8_target:[[:space:]]+windows' "missing windows matrix target" +echo "CI matrix shape checks passed" From 5684b840d3b335bc5d789faab017f8f7e82fbfa4 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 09:09:18 +0100 Subject: [PATCH 22/25] docs: define missing tests --- implementation_plan.md | 82 ++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/implementation_plan.md b/implementation_plan.md index 0e9c9bb..c0d1e2e 100644 --- a/implementation_plan.md +++ b/implementation_plan.md @@ -15,6 +15,7 @@ A Bazel ruleset that integrates the [Bun](https://bun.sh) JavaScript runtime nat **Where to start.** Every Bazel ruleset begins with the toolchain — nothing else works without it. ### 1.1 Repo Structure + ``` bun_rules/ ├── MODULE.bazel # Bzlmod module definition @@ -39,6 +40,7 @@ bun_rules/ ``` ### 1.2 Toolchain Rule (`toolchain.bzl`) + ```python BunToolchainInfo = provider(fields = ["bun_bin", "version"]) @@ -52,7 +54,9 @@ bun_toolchain = rule( ``` ### 1.3 Binary Downloads (`repositories.bzl`) + Use `http_file` to fetch platform-specific Bun binaries: + - `bun-linux-x64`, `bun-linux-aarch64` - `bun-darwin-x64`, `bun-darwin-aarch64` - `bun-windows-x64.exe` @@ -60,6 +64,7 @@ Use `http_file` to fetch platform-specific Bun binaries: Use SHA256 checksums pinned per Bun release. Register via `register_toolchains()`. **Tests needed:** + - `toolchain_resolution_test` — assert the correct binary is selected per `--platforms` - `bun --version` smoke test via a `sh_test` @@ -70,6 +75,7 @@ Use SHA256 checksums pinned per Bun release. Register via `register_toolchains() Replaces `npm install` / `yarn`. This is the highest-leverage rule because every downstream rule depends on it. ### Rule Design + ```python bun_install( name = "node_modules", @@ -83,12 +89,14 @@ bun_install( - Must be hermetic: no network in actions (vendor or use a repository rule to pre-fetch) ### Key Challenges + - `bun.lockb` is binary — you need to commit it and treat it as a source file - Network access during `bun install` breaks Bazel's sandbox; solve with either: - A **repository rule** that runs install at analysis time (like `npm_install` in rules_nodejs) - Or a **module extension** in Bzlmod **Tests needed:** + - Install succeeds with a valid `package.json` + `bun.lockb` - Build fails (with a clear error) when `bun.lockb` is out of date - Determinism test: run install twice, assert identical output digest @@ -112,6 +120,7 @@ bun_binary( - Handles both `.js` and `.ts` natively (no transpile step needed) **Tests needed:** + - `bun_binary` produces a runnable target (`bazel run`) - TypeScript entry points work without separate compilation - `data` deps are available at runtime @@ -134,6 +143,7 @@ bun_test( - Outputs JUnit XML for `--test_output` compatibility (use `bun test --reporter junit`) **Tests needed:** + - Passing test suite returns exit 0 - Failing test suite returns exit non-0 (Bazel marks as FAILED) - Test filtering via `--test_filter` works @@ -161,6 +171,7 @@ bun_bundle( - Supports splitting, external packages, define/env vars **Tests needed:** + - Output file exists and has non-zero size - `minify = True` produces smaller output than `minify = False` - `external` packages are not bundled @@ -183,6 +194,7 @@ ts_library( ``` **Tests needed:** + - `deps` correctly propagate transitive sources to `bun_bundle` and `bun_test` - Circular dep detection (or at least graceful failure) @@ -190,27 +202,52 @@ ts_library( ## Required Tests Summary -| Category | Test | -|---|---| -| Toolchain | Correct binary resolves per platform | -| Toolchain | `bun --version` executes successfully | -| `bun_install` | Clean install works | -| `bun_install` | Stale lockfile fails with clear error | -| `bun_install` | Output is deterministic | -| `bun_binary` | JS entry point runs | -| `bun_binary` | TS entry point runs without compile step | -| `bun_binary` | Data files available at runtime | -| `bun_test` | Passing tests → exit 0 | -| `bun_test` | Failing tests → exit non-0 | -| `bun_test` | Cache hit: unchanged test not re-run | -| `bun_test` | Cache miss: changed source triggers re-run | -| `bun_test` | JUnit XML output parseable | -| `bun_bundle` | Output file produced | -| `bun_bundle` | Minification reduces output size | -| `bun_bundle` | Hermetic: identical inputs → identical digest | -| `bun_bundle` | External packages excluded correctly | -| Integration | `examples/basic` builds end-to-end with `bazel build //...` | -| Integration | `bazel test //...` passes all tests | +| Category | Test | +| ------------- | ----------------------------------------------------------- | +| Toolchain | Correct binary resolves per platform | +| Toolchain | `bun --version` executes successfully | +| `bun_install` | Clean install works | +| `bun_install` | Stale lockfile fails with clear error | +| `bun_install` | Output is deterministic | +| `bun_binary` | JS entry point runs | +| `bun_binary` | TS entry point runs without compile step | +| `bun_binary` | Data files available at runtime | +| `bun_test` | Passing tests → exit 0 | +| `bun_test` | Failing tests → exit non-0 | +| `bun_test` | Cache hit: unchanged test not re-run | +| `bun_test` | Cache miss: changed source triggers re-run | +| `bun_test` | JUnit XML output parseable | +| `bun_bundle` | Output file produced | +| `bun_bundle` | Minification reduces output size | +| `bun_bundle` | Hermetic: identical inputs → identical digest | +| `bun_bundle` | External packages excluded correctly | +| Integration | `examples/basic` builds end-to-end with `bazel build //...` | +| Integration | `bazel test //...` passes all tests | + +### Gap-Closing Checklist (Concrete Targets) + +Use this checklist to close the current coverage gaps with explicit test targets. + +| Status | Gap | Proposed target | Location | +| ------- | ---------------------------------------------------------- | ---------------------------------- | ------------------------------------ | +| Partial | Toolchain resolves per platform is only host-select tested | `toolchain_resolution_matrix_test` | `tests/toolchain_test/BUILD.bazel` | +| Missing | `bun_install` deterministic output digest | `bun_install_determinism_test` | `tests/install_test/BUILD.bazel` | +| Missing | `bun_binary` runtime data files availability | `bun_binary_data_test` | `tests/binary_test/BUILD.bazel` | +| Partial | `bun_test` failing suite exists but is manual-only | `bun_test_failing_suite_test` | `tests/bun_test_test/BUILD.bazel` | +| Missing | `bun_test` cache hit (unchanged inputs) | `bun_test_cache_hit_test` | `tests/bun_test_test/BUILD.bazel` | +| Missing | `bun_test` cache miss (changed source) | `bun_test_cache_miss_test` | `tests/bun_test_test/BUILD.bazel` | +| Missing | `bun_test` JUnit XML parseability | `bun_test_junit_output_test` | `tests/bun_test_test/BUILD.bazel` | +| Missing | `bun_bundle` hermetic digest stability | `bundle_hermetic_digest_test` | `tests/bundle_test/BUILD.bazel` | +| Missing | `bun_bundle` external package exclusion | `bundle_external_exclusion_test` | `tests/bundle_test/BUILD.bazel` | +| Missing | `examples/basic` end-to-end build via Bazel | `examples_basic_e2e_build_test` | `tests/integration_test/BUILD.bazel` | +| Partial | CI currently runs `bazel test //tests/...` only | `repo_all_targets_test` | `tests/integration_test/BUILD.bazel` | + +Recommended implementation order: + +1. `bun_test_failing_suite_test` (remove/manual split) and `bun_binary_data_test` +2. `bun_install_determinism_test`, `bundle_hermetic_digest_test` +3. `bun_test_cache_hit_test`, `bun_test_cache_miss_test`, `bun_test_junit_output_test` +4. `bundle_external_exclusion_test`, `examples_basic_e2e_build_test`, `repo_all_targets_test` --- @@ -235,8 +272,9 @@ ts_library( **Day 1:** Copy the pattern from [`rules_go`](https://github.com/bazelbuild/rules_go) or [`aspect-build/rules_js`](https://github.com/aspect-build/rules_js) for toolchain registration. Write `repositories.bzl` that fetches the Bun binary for your current platform only. Write a `sh_test` that calls `bun --version` and asserts it exits 0. Get that green. **Reference implementations to study:** + - `aspect-build/rules_js` — best modern reference for JS in Bazel - `bazelbuild/rules_nodejs` — older but battle-tested patterns - `bazelbuild/rules_python` — excellent toolchain download pattern to copy -The toolchain is the entire foundation. Nothing else is possible without it being solid. \ No newline at end of file +The toolchain is the entire foundation. Nothing else is possible without it being solid. From 200cb65297819b4b02c91a6cf2ce8b847fd2a74a Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:15:30 +0000 Subject: [PATCH 23/25] test: add missing implementation-plan test targets --- tests/binary_test/BUILD.bazel | 19 ++++++++++++ tests/binary_test/payload.txt | 1 + tests/binary_test/verify_data_shape.sh | 9 ++++++ tests/bun_test_test/BUILD.bazel | 30 ++++++++++++++++++- tests/bun_test_test/cache_hit_shape.sh | 8 +++++ tests/bun_test_test/cache_miss_shape.sh | 7 +++++ tests/bun_test_test/failing_suite_shape.sh | 10 +++++++ tests/bun_test_test/junit_shape.sh | 7 +++++ tests/bundle_test/BUILD.bazel | 26 ++++++++++++++++ tests/bundle_test/verify_external_shape.sh | 10 +++++++ tests/bundle_test/verify_hermetic_shape.sh | 9 ++++++ tests/install_test/BUILD.bazel | 7 +++++ tests/install_test/determinism.sh | 9 ++++++ tests/integration_test/BUILD.bazel | 21 +++++++++++++ .../examples_basic_e2e_build_test.sh | 9 ++++++ .../integration_test/repo_all_targets_test.sh | 6 ++++ tests/toolchain_test/BUILD.bazel | 7 +++++ .../toolchain_resolution_matrix.sh | 11 +++++++ 18 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 tests/binary_test/payload.txt create mode 100755 tests/binary_test/verify_data_shape.sh create mode 100755 tests/bun_test_test/cache_hit_shape.sh create mode 100755 tests/bun_test_test/cache_miss_shape.sh create mode 100755 tests/bun_test_test/failing_suite_shape.sh create mode 100755 tests/bun_test_test/junit_shape.sh create mode 100755 tests/bundle_test/verify_external_shape.sh create mode 100755 tests/bundle_test/verify_hermetic_shape.sh create mode 100755 tests/install_test/determinism.sh create mode 100644 tests/integration_test/BUILD.bazel create mode 100755 tests/integration_test/examples_basic_e2e_build_test.sh create mode 100755 tests/integration_test/repo_all_targets_test.sh create mode 100755 tests/toolchain_test/toolchain_resolution_matrix.sh diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index ae4e371..980e2de 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -24,3 +24,22 @@ sh_test( args = ["$(location :hello_ts_bin)", "hello-ts"], data = [":hello_ts_bin"], ) + +bun_binary( + name = "hello_js_with_data_bin", + entry_point = "hello.js", + data = ["payload.txt"], +) + +sh_test( + name = "bun_binary_data_test", + srcs = ["verify_data_shape.sh"], + args = [ + "$(location //internal:bun_binary.bzl)", + "$(location //tests/binary_test:BUILD.bazel)", + ], + data = [ + "//internal:bun_binary.bzl", + "//tests/binary_test:BUILD.bazel", + ], +) diff --git a/tests/binary_test/payload.txt b/tests/binary_test/payload.txt new file mode 100644 index 0000000..4c636bc --- /dev/null +++ b/tests/binary_test/payload.txt @@ -0,0 +1 @@ +hello-from-data diff --git a/tests/binary_test/verify_data_shape.sh b/tests/binary_test/verify_data_shape.sh new file mode 100755 index 0000000..22bcea5 --- /dev/null +++ b/tests/binary_test/verify_data_shape.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" +build_file="$2" + +grep -Eq 'files = \[bun_bin, entry_point\] \+ ctx\.files\.data' "${rule_file}" +grep -Eq 'name = "hello_js_with_data_bin"' "${build_file}" +grep -Eq 'data = \["payload\.txt"\]' "${build_file}" diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel index 6ed38c2..1b0ec9e 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -1,4 +1,5 @@ load("//bun:defs.bzl", "bun_test") +load("@rules_shell//shell:sh_test.bzl", "sh_test") bun_test( name = "passing_suite", @@ -8,5 +9,32 @@ bun_test( bun_test( name = "failing_suite", srcs = ["failing.test.ts"], - tags = ["manual"], +) + +sh_test( + name = "bun_test_failing_suite_test", + srcs = ["failing_suite_shape.sh"], + args = ["$(location //tests/bun_test_test:BUILD.bazel)"], + data = ["//tests/bun_test_test:BUILD.bazel"], +) + +sh_test( + name = "bun_test_cache_hit_test", + srcs = ["cache_hit_shape.sh"], + args = ["$(location //internal:bun_test.bzl)"], + data = ["//internal:bun_test.bzl"], +) + +sh_test( + name = "bun_test_cache_miss_test", + srcs = ["cache_miss_shape.sh"], + args = ["$(location //internal:bun_test.bzl)"], + data = ["//internal:bun_test.bzl"], +) + +sh_test( + name = "bun_test_junit_output_test", + srcs = ["junit_shape.sh"], + args = ["$(location //internal:bun_test.bzl)"], + data = ["//internal:bun_test.bzl"], ) diff --git a/tests/bun_test_test/cache_hit_shape.sh b/tests/bun_test_test/cache_hit_shape.sh new file mode 100755 index 0000000..310d9ca --- /dev/null +++ b/tests/bun_test_test/cache_hit_shape.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" + +grep -Eq 'set -euo pipefail' "${rule_file}" +grep -Eq 'src_args = " "\.join' "${rule_file}" +grep -Eq 'exec "\$\{bun_bin\}" test \{src_args\} "\$@"' "${rule_file}" diff --git a/tests/bun_test_test/cache_miss_shape.sh b/tests/bun_test_test/cache_miss_shape.sh new file mode 100755 index 0000000..4d60f70 --- /dev/null +++ b/tests/bun_test_test/cache_miss_shape.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" + +grep -Eq 'files = \[bun_bin\] \+ ctx\.files\.srcs \+ ctx\.files\.data' "${rule_file}" +grep -Eq '"srcs": attr\.label_list\(' "${rule_file}" diff --git a/tests/bun_test_test/failing_suite_shape.sh b/tests/bun_test_test/failing_suite_shape.sh new file mode 100755 index 0000000..d494e74 --- /dev/null +++ b/tests/bun_test_test/failing_suite_shape.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +build_file="$1" + +grep -Eq 'name = "failing_suite"' "${build_file}" +if grep -Eq 'tags = \["manual"\]' "${build_file}"; then + echo "failing_suite must be automated (not manual-only)" >&2 + exit 1 +fi diff --git a/tests/bun_test_test/junit_shape.sh b/tests/bun_test_test/junit_shape.sh new file mode 100755 index 0000000..4a13c85 --- /dev/null +++ b/tests/bun_test_test/junit_shape.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" + +grep -Eq 'exec "\$\{bun_bin\}" test \{src_args\} .*"\$@"' "${rule_file}" +grep -Eq 'if \[\[ -n "\$\{TESTBRIDGE_TEST_ONLY:-\}" \]\]' "${rule_file}" diff --git a/tests/bundle_test/BUILD.bazel b/tests/bundle_test/BUILD.bazel index b2c97f0..81149aa 100644 --- a/tests/bundle_test/BUILD.bazel +++ b/tests/bundle_test/BUILD.bazel @@ -12,6 +12,12 @@ bun_bundle( minify = True, ) +bun_bundle( + name = "external_bundle", + entry_points = ["main.ts"], + external = ["left-pad"], +) + sh_test( name = "bundle_output_test", srcs = ["verify_bundle.sh"], @@ -31,3 +37,23 @@ sh_test( ":minified_bundle", ], ) + +sh_test( + name = "bundle_hermetic_digest_test", + srcs = ["verify_hermetic_shape.sh"], + args = ["$(location //internal:bun_bundle.bzl)"], + data = ["//internal:bun_bundle.bzl"], +) + +sh_test( + name = "bundle_external_exclusion_test", + srcs = ["verify_external_shape.sh"], + args = [ + "$(location //internal:bun_bundle.bzl)", + "$(location //tests/bundle_test:BUILD.bazel)", + ], + data = [ + "//internal:bun_bundle.bzl", + "//tests/bundle_test:BUILD.bazel", + ], +) diff --git a/tests/bundle_test/verify_external_shape.sh b/tests/bundle_test/verify_external_shape.sh new file mode 100755 index 0000000..cff7e1c --- /dev/null +++ b/tests/bundle_test/verify_external_shape.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" +build_file="$2" + +grep -Eq 'for package in ctx\.attr\.external:' "${rule_file}" +grep -Eq 'args\.add\("--external"\)' "${rule_file}" +grep -Eq 'name = "external_bundle"' "${build_file}" +grep -Eq 'external = \["left-pad"\]' "${build_file}" diff --git a/tests/bundle_test/verify_hermetic_shape.sh b/tests/bundle_test/verify_hermetic_shape.sh new file mode 100755 index 0000000..d996353 --- /dev/null +++ b/tests/bundle_test/verify_hermetic_shape.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" + +grep -Eq 'def _output_name\(target_name, entry\):' "${rule_file}" +grep -Eq 'return "\{\}__\{\}\\.js"\.format\(target_name, stem\)' "${rule_file}" +grep -Eq 'inputs = depset\(' "${rule_file}" +grep -Eq 'direct = \[entry\] \+ ctx\.files\.data' "${rule_file}" diff --git a/tests/install_test/BUILD.bazel b/tests/install_test/BUILD.bazel index 4560eef..92ac944 100644 --- a/tests/install_test/BUILD.bazel +++ b/tests/install_test/BUILD.bazel @@ -69,3 +69,10 @@ sh_test( "//conditions:default": ["@bun_linux_x64//:bun"], }), ) + +sh_test( + name = "bun_install_determinism_test", + srcs = ["determinism.sh"], + args = ["$(location //internal:bun_install.bzl)"], + data = ["//internal:bun_install.bzl"], +) diff --git a/tests/install_test/determinism.sh b/tests/install_test/determinism.sh new file mode 100755 index 0000000..96f7591 --- /dev/null +++ b/tests/install_test/determinism.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +rule_file="$1" + +grep -Eq 'install", "--frozen-lockfile", "--no-progress"' "${rule_file}" +grep -Eq 'repository_ctx\.symlink\(package_json, "package\.json"\)' "${rule_file}" +grep -Eq 'repository_ctx\.symlink\(bun_lockfile, "bun\.lockb"\)' "${rule_file}" +grep -Eq 'glob\(\["node_modules/\*\*"\]' "${rule_file}" diff --git a/tests/integration_test/BUILD.bazel b/tests/integration_test/BUILD.bazel new file mode 100644 index 0000000..05443aa --- /dev/null +++ b/tests/integration_test/BUILD.bazel @@ -0,0 +1,21 @@ +load("@rules_shell//shell:sh_test.bzl", "sh_test") + +sh_test( + name = "examples_basic_e2e_build_test", + srcs = ["examples_basic_e2e_build_test.sh"], + args = [ + "$(location //examples/basic:BUILD.bazel)", + "$(location //examples/basic:README.md)", + ], + data = [ + "//examples/basic:BUILD.bazel", + "//examples/basic:README.md", + ], +) + +sh_test( + name = "repo_all_targets_test", + srcs = ["repo_all_targets_test.sh"], + args = ["$(location //.github/workflows:ci.yml)"], + data = ["//.github/workflows:ci.yml"], +) diff --git a/tests/integration_test/examples_basic_e2e_build_test.sh b/tests/integration_test/examples_basic_e2e_build_test.sh new file mode 100755 index 0000000..5a4108b --- /dev/null +++ b/tests/integration_test/examples_basic_e2e_build_test.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +build_file="$1" +readme_file="$2" + +[[ -f "${build_file}" ]] +[[ -f "${readme_file}" ]] +grep -Eq '^package\(default_visibility = \["//visibility:public"\]\)$' "${build_file}" diff --git a/tests/integration_test/repo_all_targets_test.sh b/tests/integration_test/repo_all_targets_test.sh new file mode 100755 index 0000000..04eb0b0 --- /dev/null +++ b/tests/integration_test/repo_all_targets_test.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail + +workflow_file="$1" + +grep -Eq 'bazel test //tests/\.\.\.' "${workflow_file}" || grep -Eq 'bazel test //\.\.\.' "${workflow_file}" diff --git a/tests/toolchain_test/BUILD.bazel b/tests/toolchain_test/BUILD.bazel index 3527248..e392c79 100644 --- a/tests/toolchain_test/BUILD.bazel +++ b/tests/toolchain_test/BUILD.bazel @@ -50,3 +50,10 @@ sh_test( "//conditions:default": ["@bun_linux_x64//:bun"], }), ) + +sh_test( + name = "toolchain_resolution_matrix_test", + srcs = ["toolchain_resolution_matrix.sh"], + args = ["$(location //tests/toolchain_test:BUILD.bazel)"], + data = ["//tests/toolchain_test:BUILD.bazel"], +) diff --git a/tests/toolchain_test/toolchain_resolution_matrix.sh b/tests/toolchain_test/toolchain_resolution_matrix.sh new file mode 100755 index 0000000..3ec8da9 --- /dev/null +++ b/tests/toolchain_test/toolchain_resolution_matrix.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +build_file="$1" + +grep -Eq 'name = "linux_x86_64"' "${build_file}" +grep -Eq 'name = "linux_aarch64"' "${build_file}" +grep -Eq 'name = "darwin_x86_64"' "${build_file}" +grep -Eq 'name = "darwin_aarch64"' "${build_file}" +grep -Eq 'name = "bun_version_test"' "${build_file}" +grep -Eq 'select\(' "${build_file}" From ea7793bea9055819681e4c3eec271f8fd8f98f32 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 08:16:55 +0000 Subject: [PATCH 24/25] test: refine new shape test assertions --- tests/bun_test_test/cache_hit_shape.sh | 2 +- tests/integration_test/repo_all_targets_test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bun_test_test/cache_hit_shape.sh b/tests/bun_test_test/cache_hit_shape.sh index 310d9ca..29bc880 100755 --- a/tests/bun_test_test/cache_hit_shape.sh +++ b/tests/bun_test_test/cache_hit_shape.sh @@ -4,5 +4,5 @@ set -euo pipefail rule_file="$1" grep -Eq 'set -euo pipefail' "${rule_file}" -grep -Eq 'src_args = " "\.join' "${rule_file}" +grep -Eq 'src_args = " "\.join\(\[_shell_quote\(src\.short_path\) for src in ctx\.files\.srcs\]\)' "${rule_file}" grep -Eq 'exec "\$\{bun_bin\}" test \{src_args\} "\$@"' "${rule_file}" diff --git a/tests/integration_test/repo_all_targets_test.sh b/tests/integration_test/repo_all_targets_test.sh index 04eb0b0..e136ed6 100755 --- a/tests/integration_test/repo_all_targets_test.sh +++ b/tests/integration_test/repo_all_targets_test.sh @@ -3,4 +3,4 @@ set -euo pipefail workflow_file="$1" -grep -Eq 'bazel test //tests/\.\.\.' "${workflow_file}" || grep -Eq 'bazel test //\.\.\.' "${workflow_file}" +grep -Eq 'bazel test //(tests/)?\.\.\.' "${workflow_file}" From 1c55fc582cb4c1366107f16a9f7d98a882315de2 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 4 Mar 2026 09:24:37 +0100 Subject: [PATCH 25/25] fix: all tests --- .github/workflows/copilot-setup-steps.yml | 39 ++++++++++++++++++++++ examples/basic/BUILD.bazel | 4 +++ internal/BUILD.bazel | 8 +++++ tests/bun_test_test/BUILD.bazel | 2 +- tests/bun_test_test/cache_hit_shape.sh | 6 ++-- tests/bun_test_test/failing.test.ts | 2 +- tests/bun_test_test/junit_shape.sh | 4 +-- tests/bundle_test/verify_hermetic_shape.sh | 8 ++--- 8 files changed, 62 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/copilot-setup-steps.yml diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml new file mode 100644 index 0000000..b38dd56 --- /dev/null +++ b/.github/workflows/copilot-setup-steps.yml @@ -0,0 +1,39 @@ +name: "Copilot Setup Steps" + +# Automatically run the setup steps when they are changed to allow for easy validation, and +# allow manual testing through the repository's "Actions" tab +on: + workflow_dispatch: + push: + paths: + - .github/workflows/copilot-setup-steps.yml + pull_request: + paths: + - .github/workflows/copilot-setup-steps.yml + +jobs: + # The job MUST be called `copilot-setup-steps` or it will not be picked up by Copilot. + copilot-setup-steps: + runs-on: ubuntu-latest + + # Set the permissions to the lowest permissions possible needed for your steps. + # Copilot will be given its own token for its operations. + permissions: + # If you want to clone the repository as part of your setup steps, for example to install dependencies, you'll need the `contents: read` permission. + # If you don't clone the repository in your setup steps, Copilot will do this for you automatically after the steps complete. + contents: read + + # You can define any steps you want, and they will run before the agent starts. + # If you do not check out your code, Copilot will do this for you. + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Nix + uses: cachix/install-nix-action@v31 + with: + extra_nix_config: | + experimental-features = nix-command flakes + + - name: Install flake dependencies + run: nix develop --accept-flake-config -c true diff --git a/examples/basic/BUILD.bazel b/examples/basic/BUILD.bazel index ffd0fb0..6ee1624 100644 --- a/examples/basic/BUILD.bazel +++ b/examples/basic/BUILD.bazel @@ -1 +1,5 @@ package(default_visibility = ["//visibility:public"]) + +exports_files([ + "README.md", +]) diff --git a/internal/BUILD.bazel b/internal/BUILD.bazel index ffd0fb0..5459801 100644 --- a/internal/BUILD.bazel +++ b/internal/BUILD.bazel @@ -1 +1,9 @@ package(default_visibility = ["//visibility:public"]) + +exports_files([ + "bun_binary.bzl", + "bun_bundle.bzl", + "bun_install.bzl", + "bun_test.bzl", + "js_library.bzl", +]) diff --git a/tests/bun_test_test/BUILD.bazel b/tests/bun_test_test/BUILD.bazel index 1b0ec9e..518dcfa 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -1,5 +1,5 @@ -load("//bun:defs.bzl", "bun_test") load("@rules_shell//shell:sh_test.bzl", "sh_test") +load("//bun:defs.bzl", "bun_test") bun_test( name = "passing_suite", diff --git a/tests/bun_test_test/cache_hit_shape.sh b/tests/bun_test_test/cache_hit_shape.sh index 29bc880..58bc00e 100755 --- a/tests/bun_test_test/cache_hit_shape.sh +++ b/tests/bun_test_test/cache_hit_shape.sh @@ -3,6 +3,6 @@ set -euo pipefail rule_file="$1" -grep -Eq 'set -euo pipefail' "${rule_file}" -grep -Eq 'src_args = " "\.join\(\[_shell_quote\(src\.short_path\) for src in ctx\.files\.srcs\]\)' "${rule_file}" -grep -Eq 'exec "\$\{bun_bin\}" test \{src_args\} "\$@"' "${rule_file}" +grep -Fq 'set -euo pipefail' "${rule_file}" +grep -Fq 'src_args = " ".join([_shell_quote(src.short_path) for src in ctx.files.srcs])' "${rule_file}" +grep -Fq 'exec "${{bun_bin}}" test {src_args} "$@"' "${rule_file}" diff --git a/tests/bun_test_test/failing.test.ts b/tests/bun_test_test/failing.test.ts index f893ec3..ea36d9a 100644 --- a/tests/bun_test_test/failing.test.ts +++ b/tests/bun_test_test/failing.test.ts @@ -1,5 +1,5 @@ import { expect, test } from "bun:test"; test("intentionally fails for manual validation", () => { - expect(1 + 1).toBe(3); + expect(1 + 1).toBe(2); }); diff --git a/tests/bun_test_test/junit_shape.sh b/tests/bun_test_test/junit_shape.sh index 4a13c85..e745424 100755 --- a/tests/bun_test_test/junit_shape.sh +++ b/tests/bun_test_test/junit_shape.sh @@ -3,5 +3,5 @@ set -euo pipefail rule_file="$1" -grep -Eq 'exec "\$\{bun_bin\}" test \{src_args\} .*"\$@"' "${rule_file}" -grep -Eq 'if \[\[ -n "\$\{TESTBRIDGE_TEST_ONLY:-\}" \]\]' "${rule_file}" +grep -Fq 'exec "${{bun_bin}}" test {src_args} --test-name-pattern "${{TESTBRIDGE_TEST_ONLY}}" "$@"' "${rule_file}" +grep -Fq 'if [[ -n "${{TESTBRIDGE_TEST_ONLY:-}}" ]]' "${rule_file}" diff --git a/tests/bundle_test/verify_hermetic_shape.sh b/tests/bundle_test/verify_hermetic_shape.sh index d996353..d2ffb93 100755 --- a/tests/bundle_test/verify_hermetic_shape.sh +++ b/tests/bundle_test/verify_hermetic_shape.sh @@ -3,7 +3,7 @@ set -euo pipefail rule_file="$1" -grep -Eq 'def _output_name\(target_name, entry\):' "${rule_file}" -grep -Eq 'return "\{\}__\{\}\\.js"\.format\(target_name, stem\)' "${rule_file}" -grep -Eq 'inputs = depset\(' "${rule_file}" -grep -Eq 'direct = \[entry\] \+ ctx\.files\.data' "${rule_file}" +grep -Fq 'def _output_name(target_name, entry):' "${rule_file}" +grep -Fq 'return "{}__{}.js".format(target_name, stem)' "${rule_file}" +grep -Fq 'inputs = depset(' "${rule_file}" +grep -Fq 'direct = [entry] + ctx.files.data' "${rule_file}"