feat: bun_script
This commit is contained in:
@@ -7,6 +7,7 @@ exports_files([
|
||||
"bun_bundle.bzl",
|
||||
"bun_dev.bzl",
|
||||
"bun_install.bzl",
|
||||
"bun_script.bzl",
|
||||
"bun_test.bzl",
|
||||
"js_library.bzl",
|
||||
])
|
||||
@@ -27,6 +28,11 @@ bzl_library(
|
||||
srcs = ["bun_dev.bzl"],
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "bun_script_bzl",
|
||||
srcs = ["bun_script.bzl"],
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
name = "bun_test_bzl",
|
||||
srcs = ["bun_test.bzl"],
|
||||
|
||||
@@ -19,7 +19,6 @@ def _select_bun_binary(repository_ctx):
|
||||
|
||||
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)
|
||||
@@ -60,7 +59,6 @@ stderr:
|
||||
""",
|
||||
)
|
||||
|
||||
|
||||
bun_install_repository = repository_rule(
|
||||
implementation = _bun_install_repository_impl,
|
||||
attrs = {
|
||||
@@ -74,9 +72,6 @@ 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
internal/bun_script.bzl
Normal file
91
internal/bun_script.bzl
Normal file
@@ -0,0 +1,91 @@
|
||||
"""Rule for running package.json scripts with Bun."""
|
||||
|
||||
|
||||
def _shell_quote(value):
|
||||
return "'" + value.replace("'", "'\"'\"'") + "'"
|
||||
|
||||
|
||||
def _bun_script_impl(ctx):
|
||||
toolchain = ctx.toolchains["//bun:toolchain_type"]
|
||||
bun_bin = toolchain.bun.bun_bin
|
||||
package_json = ctx.file.package_json
|
||||
|
||||
launcher = ctx.actions.declare_file(ctx.label.name)
|
||||
ctx.actions.write(
|
||||
output = launcher,
|
||||
is_executable = True,
|
||||
content = """#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
runfiles_dir="${{RUNFILES_DIR:-$0.runfiles}}"
|
||||
workspace_root="${{runfiles_dir}}/_main"
|
||||
bun_bin="${{runfiles_dir}}/_main/{bun_short_path}"
|
||||
package_json="${{runfiles_dir}}/_main/{package_json_short_path}"
|
||||
package_dir="$(dirname "${{package_json}}")"
|
||||
|
||||
working_dir="{working_dir}"
|
||||
if [[ "${{working_dir}}" == "package" ]]; then
|
||||
cd "${{package_dir}}"
|
||||
else
|
||||
cd "${{workspace_root}}"
|
||||
fi
|
||||
|
||||
exec "${{bun_bin}}" --bun run {script} "$@"
|
||||
""".format(
|
||||
bun_short_path = bun_bin.short_path,
|
||||
package_json_short_path = package_json.short_path,
|
||||
working_dir = ctx.attr.working_dir,
|
||||
script = _shell_quote(ctx.attr.script),
|
||||
),
|
||||
)
|
||||
|
||||
transitive_files = []
|
||||
if ctx.attr.node_modules:
|
||||
transitive_files.append(ctx.attr.node_modules[DefaultInfo].files)
|
||||
|
||||
runfiles = ctx.runfiles(
|
||||
files = [bun_bin, package_json] + ctx.files.data,
|
||||
transitive_files = depset(transitive = transitive_files),
|
||||
)
|
||||
|
||||
return [
|
||||
DefaultInfo(
|
||||
executable = launcher,
|
||||
runfiles = runfiles,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
bun_script = rule(
|
||||
implementation = _bun_script_impl,
|
||||
doc = """Runs a named `package.json` script with Bun as an executable target.
|
||||
|
||||
Use this rule to expose existing package scripts such as `dev`, `build`, or
|
||||
`check` via `bazel run` without adding wrapper shell scripts.
|
||||
""",
|
||||
attrs = {
|
||||
"script": attr.string(
|
||||
mandatory = True,
|
||||
doc = "Name of the `package.json` script to execute via `bun run <script>`.",
|
||||
),
|
||||
"package_json": attr.label(
|
||||
mandatory = True,
|
||||
allow_single_file = True,
|
||||
doc = "Label of the `package.json` file containing the named script.",
|
||||
),
|
||||
"node_modules": attr.label(
|
||||
doc = "Optional label providing Bun/npm package files in runfiles.",
|
||||
),
|
||||
"data": attr.label_list(
|
||||
allow_files = True,
|
||||
doc = "Additional runtime files required by the script.",
|
||||
),
|
||||
"working_dir": attr.string(
|
||||
default = "package",
|
||||
values = ["workspace", "package"],
|
||||
doc = "Working directory at runtime: Bazel runfiles `workspace` root or the directory containing `package.json`.",
|
||||
),
|
||||
},
|
||||
executable = True,
|
||||
toolchains = ["//bun:toolchain_type"],
|
||||
)
|
||||
@@ -1,7 +1,9 @@
|
||||
"""Lightweight JS/TS source grouping rules."""
|
||||
|
||||
BunSourcesInfo = provider(fields = ["transitive_sources"])
|
||||
|
||||
BunSourcesInfo = provider(
|
||||
"Provides transitive sources for Bun libraries.",
|
||||
fields = ["transitive_sources"],
|
||||
)
|
||||
|
||||
def _bun_library_impl(ctx):
|
||||
transitive_sources = [
|
||||
@@ -18,7 +20,6 @@ def _bun_library_impl(ctx):
|
||||
DefaultInfo(files = all_sources),
|
||||
]
|
||||
|
||||
|
||||
js_library = rule(
|
||||
implementation = _bun_library_impl,
|
||||
doc = "Aggregates JavaScript sources and transitive Bun source dependencies.",
|
||||
|
||||
Reference in New Issue
Block a user