feat: add phase 2 bun_install repository rule bootstrap
This commit is contained in:
committed by
copilot-swe-agent[bot]
parent
14b7e8175a
commit
fe21208ddf
@@ -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`)
|
||||
|
||||
@@ -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",
|
||||
|
||||
1
internal/BUILD.bazel
Normal file
1
internal/BUILD.bazel
Normal file
@@ -0,0 +1 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
21
tests/install_test/BUILD.bazel
Normal file
21
tests/install_test/BUILD.bazel
Normal file
@@ -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",
|
||||
],
|
||||
)
|
||||
22
tests/install_test/clean_install.sh
Executable file
22
tests/install_test/clean_install.sh
Executable file
@@ -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
|
||||
41
tests/install_test/stale_lockfile.sh
Executable file
41
tests/install_test/stale_lockfile.sh
Executable file
@@ -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
|
||||
Reference in New Issue
Block a user