From b35f03872cd95037cceda728d2d863d92b0b0fea Mon Sep 17 00:00:00 2001 From: eric Date: Sun, 15 Mar 2026 00:59:58 +0100 Subject: [PATCH] test: add more tests --- BUILD.bazel | 8 + MODULE.bazel.lock | 49 ++++-- bun/BUILD.bazel | 13 ++ examples/basic/BUILD.bazel | 8 + examples/basic/README.md | 9 + internal/BUILD.bazel | 21 +++ internal/bun_binary.bzl | 1 + internal/bun_bundle.bzl | 2 - internal/bun_dev.bzl | 1 + internal/bun_script.bzl | 1 + internal/bun_test.bzl | 1 + internal/js_run_devserver.bzl | 1 + internal/workspace.bzl | 149 ++++++++++++++-- js/BUILD.bazel | 9 + npm/BUILD.bazel | 10 ++ result | 1 - tests/binary_test/BUILD.bazel | 24 +++ .../verify_configured_launcher_shape.sh | 16 ++ tests/binary_test/verify_data_shape.sh | 2 +- tests/bun_test_test/BUILD.bazel | 17 +- tests/bun_test_test/configured_suite_shape.sh | 3 +- tests/bundle_test/BUILD.bazel | 121 +++++++++++++ tests/bundle_test/fake_cross_bun.bin | 1 + tests/bundle_test/out.js | 11 ++ tests/bundle_test/out.js.map | 10 ++ tests/bundle_test/sourcemap_bundle__main.js | 11 ++ .../bundle_test/sourcemap_bundle__main.js.map | 10 ++ tests/bundle_test/sourcemap_case/BUILD.bazel | 13 ++ tests/bundle_test/sourcemap_case/entry.ts | 3 + tests/bundle_test/verify_external_shape.sh | 4 +- tests/bundle_test/verify_flag_aquery.sh | 162 ++++++++++++++++++ tests/bundle_test/verify_sourcemap_shape.sh | 60 +++++++ tests/install_test/BUILD.bazel | 24 +++ tests/install_test/determinism.sh | 3 +- tests/install_test/workspace_parity.sh | 26 ++- tests/integration_test/BUILD.bazel | 8 + .../examples_basic_hot_restart_shape_test.sh | 11 ++ tests/js_compat_test/BUILD.bazel | 27 +++ tests/js_compat_test/app/package.json | 4 + .../js_compat_test/verify_workspace_shape.sh | 13 ++ tests/npm_compat_test/BUILD.bazel | 59 +++++++ .../npm_translate_lock_workspace_test.sh | 27 ++- tests/script_test/BUILD.bazel | 51 ++++++ tests/script_test/run_workspace_parallel.sh | 15 ++ tests/script_test/verify_launcher_flags.sh | 12 ++ 45 files changed, 978 insertions(+), 54 deletions(-) delete mode 120000 result create mode 100755 tests/binary_test/verify_configured_launcher_shape.sh create mode 100644 tests/bundle_test/fake_cross_bun.bin create mode 100644 tests/bundle_test/out.js create mode 100644 tests/bundle_test/out.js.map create mode 100644 tests/bundle_test/sourcemap_bundle__main.js create mode 100644 tests/bundle_test/sourcemap_bundle__main.js.map create mode 100644 tests/bundle_test/sourcemap_case/BUILD.bazel create mode 100644 tests/bundle_test/sourcemap_case/entry.ts create mode 100755 tests/bundle_test/verify_flag_aquery.sh create mode 100755 tests/bundle_test/verify_sourcemap_shape.sh create mode 100755 tests/integration_test/examples_basic_hot_restart_shape_test.sh create mode 100644 tests/js_compat_test/app/package.json create mode 100755 tests/js_compat_test/verify_workspace_shape.sh create mode 100644 tests/npm_compat_test/BUILD.bazel create mode 100755 tests/script_test/run_workspace_parallel.sh create mode 100755 tests/script_test/verify_launcher_flags.sh diff --git a/BUILD.bazel b/BUILD.bazel index ffd0fb0..546f681 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1 +1,9 @@ package(default_visibility = ["//visibility:public"]) + +filegroup( + name = "repo_runtime_files", + srcs = [ + "BUILD.bazel", + "MODULE.bazel", + ], +) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c180aff..5a2235f 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -34,9 +34,8 @@ "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.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", "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", @@ -52,8 +51,8 @@ "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.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", - "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "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", @@ -113,8 +112,8 @@ "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.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "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", @@ -284,7 +283,7 @@ }, "//bun:extensions.bzl%bun_install": { "general": { - "bzlTransitiveDigest": "eSFVebwDN61an1dp3505njvMKN961HH+iY2tK6fEBQQ=", + "bzlTransitiveDigest": "lzOUyaXDbkH922ruNkkwEF2cnI4m0XpzrOti0qypwtA=", "usagesDigest": "f9pNm3AOxJDZmpHhL2vrrCo23IW33im/l/VYCTW2BWM=", "recordedInputs": [ "REPO_MAPPING:,bazel_tools bazel_tools" @@ -296,7 +295,14 @@ "package_json": "@@//tests/script_test:vite_app/package.json", "bun_lockfile": "@@//tests/script_test:vite_app/bun.lock", "install_inputs": [], - "isolated_home": true + "isolated_home": true, + "production": false, + "omit": [], + "linker": "", + "backend": "", + "ignore_scripts": false, + "install_flags": [], + "visible_repo_name": "script_test_vite_node_modules" } }, "script_test_vite_monorepo_node_modules": { @@ -305,7 +311,14 @@ "package_json": "@@//tests/script_test:vite_monorepo/package.json", "bun_lockfile": "@@//tests/script_test:vite_monorepo/bun.lock", "install_inputs": [], - "isolated_home": true + "isolated_home": true, + "production": false, + "omit": [], + "linker": "", + "backend": "", + "ignore_scripts": false, + "install_flags": [], + "visible_repo_name": "script_test_vite_monorepo_node_modules" } }, "script_test_paraglide_monorepo_node_modules": { @@ -314,7 +327,14 @@ "package_json": "@@//tests/script_test:paraglide_monorepo/package.json", "bun_lockfile": "@@//tests/script_test:paraglide_monorepo/bun.lock", "install_inputs": [], - "isolated_home": true + "isolated_home": true, + "production": false, + "omit": [], + "linker": "", + "backend": "", + "ignore_scripts": false, + "install_flags": [], + "visible_repo_name": "script_test_paraglide_monorepo_node_modules" } }, "examples_vite_monorepo_node_modules": { @@ -323,7 +343,14 @@ "package_json": "@@//examples/vite_monorepo:package.json", "bun_lockfile": "@@//examples/vite_monorepo:bun.lock", "install_inputs": [], - "isolated_home": true + "isolated_home": true, + "production": false, + "omit": [], + "linker": "", + "backend": "", + "ignore_scripts": false, + "install_flags": [], + "visible_repo_name": "examples_vite_monorepo_node_modules" } } } diff --git a/bun/BUILD.bazel b/bun/BUILD.bazel index 9b8cd59..dbdc256 100644 --- a/bun/BUILD.bazel +++ b/bun/BUILD.bazel @@ -10,6 +10,19 @@ exports_files([ "version.bzl", ]) +filegroup( + name = "repo_runtime_files", + srcs = [ + "BUILD.bazel", + "defs.bzl", + "extensions.bzl", + "repositories.bzl", + "toolchain.bzl", + "version.bzl", + ], + visibility = ["//visibility:public"], +) + bzl_library( name = "toolchain_bzl", srcs = ["toolchain.bzl"], diff --git a/examples/basic/BUILD.bazel b/examples/basic/BUILD.bazel index b17b5c6..e76df4b 100644 --- a/examples/basic/BUILD.bazel +++ b/examples/basic/BUILD.bazel @@ -11,3 +11,11 @@ bun_dev( name = "web_dev", entry_point = "main.ts", ) + +bun_dev( + name = "web_dev_hot_restart", + entry_point = "main.ts", + no_clear_screen = True, + restart_on = ["README.md"], + watch_mode = "hot", +) diff --git a/examples/basic/README.md b/examples/basic/README.md index fc59106..78e243d 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -9,3 +9,12 @@ bazel run //examples/basic:web_dev ``` This starts Bun in watch mode for `main.ts`. + +For the hot-reload launcher variant: + +```bash +bazel run //examples/basic:web_dev_hot_restart +``` + +This starts Bun with `watch_mode = "hot"`, disables screen clearing, and wires +`README.md` through `restart_on` to exercise the custom restart launcher path. diff --git a/internal/BUILD.bazel b/internal/BUILD.bazel index 8ac00ce..32cdaa3 100644 --- a/internal/BUILD.bazel +++ b/internal/BUILD.bazel @@ -18,6 +18,27 @@ exports_files([ "workspace.bzl", ]) +filegroup( + name = "repo_runtime_files", + srcs = [ + "BUILD.bazel", + "bun_binary.bzl", + "bun_build_support.bzl", + "bun_bundle.bzl", + "bun_command.bzl", + "bun_compile.bzl", + "bun_dev.bzl", + "bun_install.bzl", + "bun_script.bzl", + "bun_test.bzl", + "js_compat.bzl", + "js_library.bzl", + "js_run_devserver.bzl", + "workspace.bzl", + ], + visibility = ["//visibility:public"], +) + bzl_library( name = "bun_command_bzl", srcs = ["bun_command.bzl"], diff --git a/internal/bun_binary.bzl b/internal/bun_binary.bzl index f73e656..d160fca 100644 --- a/internal/bun_binary.bzl +++ b/internal/bun_binary.bzl @@ -40,6 +40,7 @@ exec "${bun_bin}" "${bun_args[@]}" "$@" is_executable = True, content = render_workspace_setup( bun_short_path = bun_bin.short_path, + install_metadata_short_path = workspace_info.install_metadata_file.short_path if workspace_info.install_metadata_file else "", primary_source_short_path = entry_point.short_path, working_dir_mode = ctx.attr.working_dir, ) + command, diff --git a/internal/bun_bundle.bzl b/internal/bun_bundle.bzl index cefbc2b..e417d0c 100644 --- a/internal/bun_bundle.bzl +++ b/internal/bun_bundle.bzl @@ -25,8 +25,6 @@ def _bun_bundle_impl(ctx): add_bun_build_common_flags(args, ctx.attr) args.add("--outfile") args.add(output.path) - if ctx.attr.sourcemap: - args.add("--sourcemap") args.add(entry.path) ctx.actions.run( diff --git a/internal/bun_dev.bzl b/internal/bun_dev.bzl index 3ffa480..edddbb0 100644 --- a/internal/bun_dev.bzl +++ b/internal/bun_dev.bzl @@ -127,6 +127,7 @@ done is_executable = True, content = render_workspace_setup( bun_short_path = bun_bin.short_path, + install_metadata_short_path = workspace_info.install_metadata_file.short_path if workspace_info.install_metadata_file else "", primary_source_short_path = entry_point.short_path, working_dir_mode = ctx.attr.working_dir, ) + command, diff --git a/internal/bun_script.bzl b/internal/bun_script.bzl index 1ae4d53..7178c31 100644 --- a/internal/bun_script.bzl +++ b/internal/bun_script.bzl @@ -53,6 +53,7 @@ exec "${bun_bin}" "${bun_args[@]}" "$@" package_dir_hint = package_json.dirname or ".", package_json_short_path = package_json.short_path, primary_source_short_path = package_json.short_path, + install_metadata_short_path = workspace_info.install_metadata_file.short_path if workspace_info.install_metadata_file else "", working_dir_mode = ctx.attr.working_dir, ) + command, ) diff --git a/internal/bun_test.bzl b/internal/bun_test.bzl index 5835f2b..bc0d678 100644 --- a/internal/bun_test.bzl +++ b/internal/bun_test.bzl @@ -81,6 +81,7 @@ exec "${bun_bin}" "${bun_args[@]}" "$@" is_executable = True, content = render_workspace_setup( bun_short_path = bun_bin.short_path, + install_metadata_short_path = workspace_info.install_metadata_file.short_path if workspace_info.install_metadata_file else "", primary_source_short_path = primary_file.short_path, working_dir_mode = "workspace", ) + command, diff --git a/internal/js_run_devserver.bzl b/internal/js_run_devserver.bzl index 96211d9..2db538f 100644 --- a/internal/js_run_devserver.bzl +++ b/internal/js_run_devserver.bzl @@ -31,6 +31,7 @@ def _js_run_devserver_impl(ctx): is_executable = True, content = render_workspace_setup( bun_short_path = bun_bin.short_path, + install_metadata_short_path = workspace_info.install_metadata_file.short_path if workspace_info.install_metadata_file else "", primary_source_short_path = package_json.short_path if package_json else tool_default_info.files_to_run.executable.short_path, package_json_short_path = package_json.short_path if package_json else "", package_dir_hint = ctx.attr.package_dir_hint, diff --git a/internal/workspace.bzl b/internal/workspace.bzl index a7c9691..8544a37 100644 --- a/internal/workspace.bzl +++ b/internal/workspace.bzl @@ -29,6 +29,11 @@ if [[ -n "__PACKAGE_JSON_SHORT_PATH__" ]]; then package_json="${runfiles_dir}/_main/__PACKAGE_JSON_SHORT_PATH__" fi package_rel_dir_hint="__PACKAGE_DIR_HINT__" +install_root_rel_dir_hint="__INSTALL_ROOT_REL_DIR__" +install_metadata="" +if [[ -n "__INSTALL_METADATA_SHORT_PATH__" ]]; then + install_metadata="${runfiles_dir}/_main/__INSTALL_METADATA_SHORT_PATH__" +fi working_dir_mode="__WORKING_DIR_MODE__" normalize_rel_dir() { @@ -111,6 +116,27 @@ find_working_rel_dir_for_path() { rel_dir_from_abs_path "$(dirname "${path}")" } +strip_rel_prefix() { + local child + child="$(normalize_rel_dir "$1")" + local parent + parent="$(normalize_rel_dir "$2")" + + if [[ "${parent}" == "." ]]; then + echo "${child}" + return 0 + fi + if [[ "${child}" == "${parent}" ]]; then + echo "." + return 0 + fi + if [[ "${child}" == "${parent}/"* ]]; then + echo "${child#"${parent}/"}" + return 0 + fi + echo "${child}" +} + select_primary_node_modules() { local selected="" local fallback="" @@ -250,6 +276,15 @@ stage_workspace_view() { materialize_directory_entries "${source_root}/${package_rel_dir}" "${destination_root}/${package_rel_dir}" } +materialize_tree_contents() { + local source_root="$1" + local destination_root="$2" + + rm -rf "${destination_root}" + mkdir -p "${destination_root}" + cp -RL "${source_root}/." "${destination_root}" +} + build_workspace_package_map() { local root="$1" local out="$2" @@ -414,12 +449,18 @@ mirror_install_repo_workspace_node_modules() { build_runtime_path() { local workspace_dir="$1" local package_dir="$2" + local install_root_dir="$3" local entries=() - if [[ -d "${package_dir}/node_modules/.bin" ]]; then - entries+=("${package_dir}/node_modules/.bin") + if [[ -d "${install_root_dir}/node_modules/.bin" ]]; then + entries+=("${install_root_dir}/node_modules/.bin") fi - if [[ -d "${workspace_dir}/node_modules/.bin" && "${workspace_dir}/node_modules/.bin" != "${package_dir}/node_modules/.bin" ]]; then + if [[ -d "${package_dir}/node_modules/.bin" ]]; then + if [[ "${package_dir}/node_modules/.bin" != "${install_root_dir}/node_modules/.bin" ]]; then + entries+=("${package_dir}/node_modules/.bin") + fi + fi + if [[ -d "${workspace_dir}/node_modules/.bin" && "${workspace_dir}/node_modules/.bin" != "${package_dir}/node_modules/.bin" && "${workspace_dir}/node_modules/.bin" != "${install_root_dir}/node_modules/.bin" ]]; then entries+=("${workspace_dir}/node_modules/.bin") fi if [[ -n "${PATH:-}" ]]; then @@ -481,8 +522,66 @@ resolve_execution_rel_dir() { esac } +resolve_install_root_rel_dir() { + if [[ -n "${install_metadata}" && -f "${install_metadata}" ]]; then + local resolved_from_metadata="" + resolved_from_metadata="$( + python3 - "${install_metadata}" "${package_rel_dir}" <<'PY' +import json +import sys + +install_metadata_path = sys.argv[1] +package_rel_dir = sys.argv[2] + +try: + with open(install_metadata_path, "r", encoding="utf-8") as install_metadata_file: + workspace_package_dirs = json.load(install_metadata_file).get("workspace_package_dirs", []) +except Exception: + workspace_package_dirs = [] + +normalized_package_rel_dir = package_rel_dir.strip("./") or "." +matches = [] +for workspace_package_dir in workspace_package_dirs: + normalized_workspace_package_dir = workspace_package_dir.strip("./") + if not normalized_workspace_package_dir: + continue + if normalized_package_rel_dir == normalized_workspace_package_dir: + matches.append((len(normalized_workspace_package_dir), ".")) + continue + suffix = "/" + normalized_workspace_package_dir + if normalized_package_rel_dir.endswith(suffix): + prefix = normalized_package_rel_dir[:-len(suffix)].strip("/") or "." + matches.append((len(normalized_workspace_package_dir), prefix)) + +if matches: + matches.sort(reverse = True) + print(matches[0][1]) +PY + )" + if [[ -n "${resolved_from_metadata}" ]]; then + echo "${resolved_from_metadata}" + return 0 + fi + fi + if [[ -n "${install_root_rel_dir_hint}" && "${install_root_rel_dir_hint}" != "." ]]; then + normalize_rel_dir "${install_root_rel_dir_hint}" + return 0 + fi + if [[ -n "${package_json}" ]]; then + find_package_rel_dir_for_path "${package_json}" + return 0 + fi + if [[ -n "${primary_source}" ]]; then + find_package_rel_dir_for_path "${primary_source}" + return 0 + fi + echo "." +} + package_rel_dir="$(resolve_package_rel_dir)" execution_rel_dir="$(resolve_execution_rel_dir "${package_rel_dir}")" +install_root_rel_dir="$(resolve_install_root_rel_dir)" +package_rel_dir_in_install_root="$(strip_rel_prefix "${package_rel_dir}" "${install_root_rel_dir}")" runtime_workspace="$(mktemp -d)" cleanup_runtime_workspace() { @@ -494,11 +593,31 @@ runtime_package_dir="${runtime_workspace}" if [[ "${package_rel_dir}" != "." ]]; then runtime_package_dir="${runtime_workspace}/${package_rel_dir}" fi +runtime_install_root="${runtime_workspace}" +if [[ "${install_root_rel_dir}" != "." ]]; then + runtime_install_root="${runtime_workspace}/${install_root_rel_dir}" +fi runtime_exec_dir="${runtime_workspace}" if [[ "${execution_rel_dir}" != "." ]]; then runtime_exec_dir="${runtime_workspace}/${execution_rel_dir}" fi +if [[ -n "${primary_source}" ]]; then + materialize_tree_contents "${workspace_root}/${package_rel_dir}" "${runtime_package_dir}" +fi + +if [[ -n "${package_json}" ]]; then + materialize_tree_contents "${workspace_root}/${install_root_rel_dir}" "${runtime_install_root}" +fi + +if [[ -n "${primary_source}" && "${primary_source}" == "${workspace_root}"* ]]; then + primary_source="${runtime_workspace}/$(rel_dir_from_abs_path "${primary_source}")" +fi + +if [[ -n "${package_json}" && "${package_json}" == "${workspace_root}"* ]]; then + package_json="${runtime_workspace}/$(rel_dir_from_abs_path "${package_json}")" +fi + workspace_package_map="${runtime_workspace}/.rules_bun_workspace_packages.tsv" build_workspace_package_map "${runtime_workspace}" "${workspace_package_map}" @@ -506,22 +625,23 @@ primary_node_modules="$(select_primary_node_modules)" install_repo_root="" if [[ -n "${primary_node_modules}" ]]; then install_repo_root="$(dirname "${primary_node_modules}")" - mirror_node_modules_dir "${primary_node_modules}" "${runtime_workspace}/node_modules" + mkdir -p "${runtime_install_root}" + mirror_node_modules_dir "${primary_node_modules}" "${runtime_install_root}/node_modules" fi if [[ -n "${install_repo_root}" ]]; then - resolved_install_node_modules="$(find_install_repo_node_modules "${install_repo_root}" "${package_rel_dir}" || true)" + resolved_install_node_modules="$(find_install_repo_node_modules "${install_repo_root}" "${package_rel_dir_in_install_root}" || true)" if [[ -n "${resolved_install_node_modules}" && "${resolved_install_node_modules}" != "${install_repo_root}/node_modules" ]]; then mirror_node_modules_dir "${resolved_install_node_modules}" "${runtime_package_dir}/node_modules" fi - mirror_install_repo_workspace_node_modules "${install_repo_root}" "${runtime_workspace}" + mirror_install_repo_workspace_node_modules "${install_repo_root}" "${runtime_install_root}" fi -if [[ ! -e "${runtime_package_dir}/node_modules" && -e "${runtime_workspace}/node_modules" && "${runtime_package_dir}" != "${runtime_workspace}" ]]; then - ln -s "${runtime_workspace}/node_modules" "${runtime_package_dir}/node_modules" +if [[ ! -e "${runtime_package_dir}/node_modules" && -e "${runtime_install_root}/node_modules" && "${runtime_package_dir}" != "${runtime_install_root}" ]]; then + ln -s "${runtime_install_root}/node_modules" "${runtime_package_dir}/node_modules" fi -runtime_path="$(build_runtime_path "${runtime_workspace}" "${runtime_package_dir}")" +runtime_path="$(build_runtime_path "${runtime_workspace}" "${runtime_package_dir}" "${runtime_install_root}")" if [[ -n "${runtime_path}" ]]; then export PATH="${runtime_path}" fi @@ -632,7 +752,9 @@ def render_workspace_setup( working_dir_mode, primary_source_short_path = "", package_json_short_path = "", - package_dir_hint = "."): + package_dir_hint = ".", + install_root_rel_dir = ".", + install_metadata_short_path = ""): return _WORKSPACE_SETUP_TEMPLATE.replace("__BUN_SHORT_PATH__", bun_short_path).replace( "__PRIMARY_SOURCE_SHORT_PATH__", primary_source_short_path, @@ -642,8 +764,13 @@ def render_workspace_setup( ).replace( "__PACKAGE_DIR_HINT__", package_dir_hint or ".", + ).replace( + "__INSTALL_ROOT_REL_DIR__", + install_root_rel_dir or ".", + ).replace( + "__INSTALL_METADATA_SHORT_PATH__", + install_metadata_short_path, ).replace( "__WORKING_DIR_MODE__", working_dir_mode, ) - diff --git a/js/BUILD.bazel b/js/BUILD.bazel index fb0947c..e2bec17 100644 --- a/js/BUILD.bazel +++ b/js/BUILD.bazel @@ -4,6 +4,15 @@ package(default_visibility = ["//visibility:public"]) exports_files(["defs.bzl"]) +filegroup( + name = "repo_runtime_files", + srcs = [ + "BUILD.bazel", + "defs.bzl", + ], + visibility = ["//visibility:public"], +) + bzl_library( name = "defs_bzl", srcs = ["defs.bzl"], diff --git a/npm/BUILD.bazel b/npm/BUILD.bazel index 7fbb71a..03dc760 100644 --- a/npm/BUILD.bazel +++ b/npm/BUILD.bazel @@ -7,6 +7,16 @@ exports_files([ "repositories.bzl", ]) +filegroup( + name = "repo_runtime_files", + srcs = [ + "BUILD.bazel", + "extensions.bzl", + "repositories.bzl", + ], + visibility = ["//visibility:public"], +) + bzl_library( name = "extensions_bzl", srcs = ["extensions.bzl"], diff --git a/result b/result deleted file mode 120000 index b202d3d..0000000 --- a/result +++ /dev/null @@ -1 +0,0 @@ -/nix/store/742k6q4hns9h1wj61y90glqwfmn2y7pa-release \ No newline at end of file diff --git a/tests/binary_test/BUILD.bazel b/tests/binary_test/BUILD.bazel index c3cd85b..8b17aba 100644 --- a/tests/binary_test/BUILD.bazel +++ b/tests/binary_test/BUILD.bazel @@ -93,3 +93,27 @@ sh_test( args = ["$(location :runtime_flag_bin)"], data = [":runtime_flag_bin"], ) + +bun_binary( + name = "configured_launcher_bin", + entry_point = "hello.ts", + node_modules = "@script_test_vite_node_modules//:node_modules", + smol = True, + conditions = [ + "browser", + "development", + ], + install_mode = "force", + run_flags = [ + "--hot", + "--console-depth", + "4", + ], +) + +sh_test( + name = "bun_binary_configured_launcher_shape_test", + srcs = ["verify_configured_launcher_shape.sh"], + args = ["$(location :configured_launcher_bin)"], + data = [":configured_launcher_bin"], +) diff --git a/tests/binary_test/verify_configured_launcher_shape.sh b/tests/binary_test/verify_configured_launcher_shape.sh new file mode 100755 index 0000000..cc8e69f --- /dev/null +++ b/tests/binary_test/verify_configured_launcher_shape.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +set -euo pipefail + +binary="$1" + +grep -Fq -- 'install_metadata="${runfiles_dir}/_main/' "${binary}" +grep -Fq -- 'node_modules/.rules_bun/install.json' "${binary}" +grep -Fq -- "--smol" "${binary}" +grep -Fq -- "--conditions" "${binary}" +grep -Fq -- "'browser'" "${binary}" +grep -Fq -- "'development'" "${binary}" +grep -Fq -- "--install" "${binary}" +grep -Fq -- "'force'" "${binary}" +grep -Fq -- "'--hot'" "${binary}" +grep -Fq -- "'--console-depth'" "${binary}" +grep -Fq -- "'4'" "${binary}" diff --git a/tests/binary_test/verify_data_shape.sh b/tests/binary_test/verify_data_shape.sh index 22bcea5..74d5a5a 100755 --- a/tests/binary_test/verify_data_shape.sh +++ b/tests/binary_test/verify_data_shape.sh @@ -4,6 +4,6 @@ set -euo pipefail rule_file="$1" build_file="$2" -grep -Eq 'files = \[bun_bin, entry_point\] \+ ctx\.files\.data' "${rule_file}" +grep -Eq 'extra_files = ctx\.files\.data \+ ctx\.files\.preload \+ ctx\.files\.env_files \+ \[bun_bin\]' "${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 697f54d..ed0f912 100644 --- a/tests/bun_test_test/BUILD.bazel +++ b/tests/bun_test_test/BUILD.bazel @@ -20,7 +20,6 @@ bun_test( timeout_ms = 250, update_snapshots = True, rerun_each = 2, - retry = 3, concurrent = True, randomize = True, seed = 7, @@ -32,6 +31,12 @@ bun_test( test_flags = ["--only-failures"], ) +bun_test( + name = "configured_retry_suite", + srcs = ["passing.test.ts"], + retry = 3, +) + sh_test( name = "bun_test_failing_suite_test", srcs = ["failing_suite_shape.sh"], @@ -63,6 +68,12 @@ sh_test( sh_test( name = "bun_test_configured_suite_shape_test", srcs = ["configured_suite_shape.sh"], - args = ["$(location :configured_suite)"], - data = [":configured_suite"], + args = [ + "$(location :configured_suite)", + "$(location :configured_retry_suite)", + ], + data = [ + ":configured_suite", + ":configured_retry_suite", + ], ) diff --git a/tests/bun_test_test/configured_suite_shape.sh b/tests/bun_test_test/configured_suite_shape.sh index af845b4..85bc65a 100755 --- a/tests/bun_test_test/configured_suite_shape.sh +++ b/tests/bun_test_test/configured_suite_shape.sh @@ -2,6 +2,7 @@ set -euo pipefail launcher="$1" +retry_launcher="$2" grep -Fq -- '--no-install' "${launcher}" grep -Fq -- '--preload' "${launcher}" @@ -10,7 +11,6 @@ grep -Fq -- '--no-env-file' "${launcher}" grep -Fq -- '--timeout' "${launcher}" grep -Fq -- '--update-snapshots' "${launcher}" grep -Fq -- '--rerun-each' "${launcher}" -grep -Fq -- '--retry' "${launcher}" grep -Fq -- '--concurrent' "${launcher}" grep -Fq -- '--randomize' "${launcher}" grep -Fq -- '--seed' "${launcher}" @@ -21,3 +21,4 @@ grep -Fq -- '--reporter-outfile' "${launcher}" grep -Fq -- '--coverage' "${launcher}" grep -Fq -- '--coverage-dir' "${launcher}" grep -Fq -- '--coverage-reporter' "${launcher}" +grep -Fq -- '--retry' "${retry_launcher}" diff --git a/tests/bundle_test/BUILD.bazel b/tests/bundle_test/BUILD.bazel index cdff097..6ac495b 100644 --- a/tests/bundle_test/BUILD.bazel +++ b/tests/bundle_test/BUILD.bazel @@ -39,11 +39,101 @@ bun_build( metafile_md = True, ) +bun_build( + name = "advanced_site_build", + tags = ["manual"], + entry_points = ["site/index.html"], + data = [ + "site/main.ts", + "site/styles.css", + ], + install_mode = "fallback", + target = "node", + format = "cjs", + production = True, + splitting = True, + root = "tests/bundle_test/site", + sourcemap = "linked", + banner = "/* bundle banner */", + footer = "// bundle footer", + public_path = "/static/", + packages = "external", + external = [ + "left-pad", + "react", + ], + entry_naming = "entries/[name]-[hash].[ext]", + chunk_naming = "chunks/[name]-[hash].[ext]", + asset_naming = "assets/[name]-[hash].[ext]", + minify = True, + minify_syntax = True, + minify_whitespace = True, + minify_identifiers = True, + keep_names = True, + css_chunking = True, + conditions = [ + "browser", + "custom", + ], + env = "PUBLIC_*", + define = [ + "process.env.NODE_ENV:\"production\"", + "__DEV__:false", + ], + drop = [ + "console", + "debugger", + ], + feature = [ + "react_fast_refresh", + "server_components", + ], + loader = [ + ".svg:file", + ".txt:text", + ], + jsx_factory = "h", + jsx_fragment = "Fragment", + jsx_import_source = "preact", + jsx_runtime = "automatic", + jsx_side_effects = True, + react_fast_refresh = True, + emit_dce_annotations = True, + no_bundle = True, + build_flags = [ + "--app", + "--server-components", + ], +) + bun_compile( name = "compiled_cli", entry_point = "cli.ts", ) +bun_compile( + name = "compiled_cli_with_flags", + tags = ["manual"], + entry_point = "cli.ts", + bytecode = True, + compile_exec_argv = [ + "--smol", + "--inspect-wait", + ], + compile_executable = "fake_cross_bun.bin", + compile_autoload_dotenv = False, + compile_autoload_bunfig = False, + compile_autoload_tsconfig = True, + compile_autoload_package_json = True, + windows_hide_console = True, + windows_icon = "branding/icon.ico", + windows_title = "Rules Bun Test App", + windows_publisher = "rules_bun", + windows_version = "1.2.3.4", + windows_description = "compile flag coverage", + windows_copyright = "(c) rules_bun", +) + sh_test( name = "bundle_output_test", srcs = ["verify_bundle.sh"], @@ -84,6 +174,20 @@ sh_test( ], ) +sh_test( + name = "bundle_sourcemap_shape_test", + srcs = ["verify_sourcemap_shape.sh"], + env_inherit = ["PATH"], + data = [ + "//:repo_runtime_files", + "//bun:repo_runtime_files", + "//internal:repo_runtime_files", + "BUILD.bazel", + "//tests/bundle_test/sourcemap_case:BUILD.bazel", + "//tests/bundle_test/sourcemap_case:entry.ts", + ], +) + sh_test( name = "bun_build_site_output_test", srcs = ["verify_site_build.sh"], @@ -104,3 +208,20 @@ sh_test( args = ["$(location :compiled_cli)"], data = [":compiled_cli"], ) + +sh_test( + name = "bun_build_compile_flag_shape_test", + srcs = ["verify_flag_aquery.sh"], + env_inherit = ["PATH"], + data = [ + "//:repo_runtime_files", + "//bun:repo_runtime_files", + "//internal:repo_runtime_files", + "BUILD.bazel", + "cli.ts", + "fake_cross_bun.bin", + "site/index.html", + "site/main.ts", + "site/styles.css", + ], +) diff --git a/tests/bundle_test/fake_cross_bun.bin b/tests/bundle_test/fake_cross_bun.bin new file mode 100644 index 0000000..48cdce8 --- /dev/null +++ b/tests/bundle_test/fake_cross_bun.bin @@ -0,0 +1 @@ +placeholder diff --git a/tests/bundle_test/out.js b/tests/bundle_test/out.js new file mode 100644 index 0000000..ca4944e --- /dev/null +++ b/tests/bundle_test/out.js @@ -0,0 +1,11 @@ +// tests/bundle_test/main.ts +function greet(name) { + return `Hello ${name}`; +} +console.log(greet("bundle")); +export { + greet +}; + +//# debugId=A86FEBA7FCC390B664756E2164756E21 +//# sourceMappingURL=out.js.map diff --git a/tests/bundle_test/out.js.map b/tests/bundle_test/out.js.map new file mode 100644 index 0000000..35ba836 --- /dev/null +++ b/tests/bundle_test/out.js.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "sources": ["tests/bundle_test/main.ts"], + "sourcesContent": [ + "export function greet(name: string): string {\n return `Hello ${name}`;\n}\n\nconsole.log(greet(\"bundle\"));\n" + ], + "mappings": ";AAAO,SAAS,KAAK,CAAC,MAAsB;AAAA,EAC1C,OAAO,SAAS;AAAA;AAGlB,QAAQ,IAAI,MAAM,QAAQ,CAAC;", + "debugId": "A86FEBA7FCC390B664756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/tests/bundle_test/sourcemap_bundle__main.js b/tests/bundle_test/sourcemap_bundle__main.js new file mode 100644 index 0000000..344b5f2 --- /dev/null +++ b/tests/bundle_test/sourcemap_bundle__main.js @@ -0,0 +1,11 @@ +// ../../../../../../../Projects/rules_bun/tests/bundle_test/main.ts +function greet(name) { + return `Hello ${name}`; +} +console.log(greet("bundle")); +export { + greet +}; + +//# debugId=D8717FECBBDCEC7764756E2164756E21 +//# sourceMappingURL=sourcemap_bundle__main.js.map diff --git a/tests/bundle_test/sourcemap_bundle__main.js.map b/tests/bundle_test/sourcemap_bundle__main.js.map new file mode 100644 index 0000000..58d0301 --- /dev/null +++ b/tests/bundle_test/sourcemap_bundle__main.js.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "sources": ["../../../../../../../Projects/rules_bun/tests/bundle_test/main.ts"], + "sourcesContent": [ + "export function greet(name: string): string {\n return `Hello ${name}`;\n}\n\nconsole.log(greet(\"bundle\"));\n" + ], + "mappings": ";AAAO,SAAS,KAAK,CAAC,MAAsB;AAAA,EAC1C,OAAO,SAAS;AAAA;AAGlB,QAAQ,IAAI,MAAM,QAAQ,CAAC;", + "debugId": "D8717FECBBDCEC7764756E2164756E21", + "names": [] +} \ No newline at end of file diff --git a/tests/bundle_test/sourcemap_case/BUILD.bazel b/tests/bundle_test/sourcemap_case/BUILD.bazel new file mode 100644 index 0000000..7600ec2 --- /dev/null +++ b/tests/bundle_test/sourcemap_case/BUILD.bazel @@ -0,0 +1,13 @@ +load("//bun:defs.bzl", "bun_bundle") + +exports_files([ + "BUILD.bazel", + "entry.ts", +]) + +bun_bundle( + name = "sourcemap_bundle", + tags = ["manual"], + entry_points = ["entry.ts"], + sourcemap = True, +) diff --git a/tests/bundle_test/sourcemap_case/entry.ts b/tests/bundle_test/sourcemap_case/entry.ts new file mode 100644 index 0000000..c4ac5c3 --- /dev/null +++ b/tests/bundle_test/sourcemap_case/entry.ts @@ -0,0 +1,3 @@ +const message: string = "sourcemap coverage"; + +console.log(message); diff --git a/tests/bundle_test/verify_external_shape.sh b/tests/bundle_test/verify_external_shape.sh index cff7e1c..e0bef6d 100755 --- a/tests/bundle_test/verify_external_shape.sh +++ b/tests/bundle_test/verify_external_shape.sh @@ -4,7 +4,7 @@ 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 'add_bun_build_common_flags\(args, ctx\.attr\)' "${rule_file}" +grep -Eq '"external": attr\.string_list\(' "${rule_file}" grep -Eq 'name = "external_bundle"' "${build_file}" grep -Eq 'external = \["left-pad"\]' "${build_file}" diff --git a/tests/bundle_test/verify_flag_aquery.sh b/tests/bundle_test/verify_flag_aquery.sh new file mode 100755 index 0000000..f9fc033 --- /dev/null +++ b/tests/bundle_test/verify_flag_aquery.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +set -euo pipefail + +if command -v bazel >/dev/null 2>&1; then + bazel_cmd=(bazel) +elif command -v bazelisk >/dev/null 2>&1; then + bazel_cmd=(bazelisk) +else + echo "bazel or bazelisk is required on PATH" >&2 + exit 1 +fi + +find_workspace_root() { + local candidate + local module_path + local script_dir + + for candidate in \ + "${TEST_SRCDIR:-}/${TEST_WORKSPACE:-}" \ + "${TEST_SRCDIR:-}/_main"; do + if [[ -n ${candidate} && -f "${candidate}/MODULE.bazel" ]]; then + printf '%s\n' "${candidate}" + return 0 + fi + done + + if [[ -n ${TEST_SRCDIR:-} ]]; then + module_path="$(find "${TEST_SRCDIR}" -maxdepth 3 -name MODULE.bazel -print -quit 2>/dev/null || true)" + if [[ -n ${module_path} ]]; then + dirname "${module_path}" + return 0 + fi + fi + + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" + candidate="$(cd "${script_dir}/../.." && pwd -P)" + if [[ -f "${candidate}/MODULE.bazel" ]]; then + printf '%s\n' "${candidate}" + return 0 + fi + + echo "Unable to locate rules_bun workspace root" >&2 + exit 1 +} + +rules_bun_root="$(find_workspace_root)" + +run_aquery() { + local mnemonic="$1" + local target="$2" + + ( + cd "${rules_bun_root}" && + "${bazel_cmd[@]}" aquery "mnemonic(\"${mnemonic}\", ${target})" --output=textproto + ) +} + +expect_line() { + local output="$1" + local expected="$2" + + if ! grep -Fq -- "${expected}" <<<"${output}"; then + echo "Expected aquery output to contain: ${expected}" >&2 + exit 1 + fi +} + +build_output="$(run_aquery "BunBuild" "//tests/bundle_test:advanced_site_build")" + +for expected in \ + 'arguments: "--install"' \ + 'arguments: "fallback"' \ + 'arguments: "--target"' \ + 'arguments: "node"' \ + 'arguments: "--format"' \ + 'arguments: "cjs"' \ + 'arguments: "--production"' \ + 'arguments: "--splitting"' \ + 'arguments: "--root"' \ + 'arguments: "tests/bundle_test/site"' \ + 'arguments: "--sourcemap"' \ + 'arguments: "linked"' \ + 'arguments: "--banner"' \ + 'arguments: "/* bundle banner */"' \ + 'arguments: "--footer"' \ + 'arguments: "// bundle footer"' \ + 'arguments: "--public-path"' \ + 'arguments: "/static/"' \ + 'arguments: "--packages"' \ + 'arguments: "external"' \ + 'arguments: "left-pad"' \ + 'arguments: "react"' \ + 'arguments: "--entry-naming"' \ + 'arguments: "entries/[name]-[hash].[ext]"' \ + 'arguments: "--chunk-naming"' \ + 'arguments: "chunks/[name]-[hash].[ext]"' \ + 'arguments: "--asset-naming"' \ + 'arguments: "assets/[name]-[hash].[ext]"' \ + 'arguments: "--minify"' \ + 'arguments: "--minify-syntax"' \ + 'arguments: "--minify-whitespace"' \ + 'arguments: "--minify-identifiers"' \ + 'arguments: "--keep-names"' \ + 'arguments: "--css-chunking"' \ + 'arguments: "--conditions"' \ + 'arguments: "browser"' \ + 'arguments: "custom"' \ + 'arguments: "--env"' \ + 'arguments: "PUBLIC_*"' \ + 'arguments: "process.env.NODE_ENV:\"production\""' \ + 'arguments: "__DEV__:false"' \ + 'arguments: "console"' \ + 'arguments: "debugger"' \ + 'arguments: "react_fast_refresh"' \ + 'arguments: "server_components"' \ + 'arguments: ".svg:file"' \ + 'arguments: ".txt:text"' \ + 'arguments: "--jsx-factory"' \ + 'arguments: "h"' \ + 'arguments: "--jsx-fragment"' \ + 'arguments: "Fragment"' \ + 'arguments: "--jsx-import-source"' \ + 'arguments: "preact"' \ + 'arguments: "--jsx-runtime"' \ + 'arguments: "automatic"' \ + 'arguments: "--jsx-side-effects"' \ + 'arguments: "--react-fast-refresh"' \ + 'arguments: "--emit-dce-annotations"' \ + 'arguments: "--no-bundle"' \ + 'arguments: "--app"' \ + 'arguments: "--server-components"'; do + expect_line "${build_output}" "${expected}" +done + +compile_output="$(run_aquery "BunCompile" "//tests/bundle_test:compiled_cli_with_flags")" + +for expected in \ + 'arguments: "--bytecode"' \ + 'arguments: "--compile-exec-argv"' \ + 'arguments: "--smol"' \ + 'arguments: "--inspect-wait"' \ + 'arguments: "--no-compile-autoload-dotenv"' \ + 'arguments: "--no-compile-autoload-bunfig"' \ + 'arguments: "--compile-autoload-tsconfig"' \ + 'arguments: "--compile-autoload-package-json"' \ + 'arguments: "--compile-executable-path"' \ + 'arguments: "tests/bundle_test/fake_cross_bun.bin"' \ + 'arguments: "--windows-hide-console"' \ + 'arguments: "--windows-icon"' \ + 'arguments: "branding/icon.ico"' \ + 'arguments: "--windows-title"' \ + 'arguments: "Rules Bun Test App"' \ + 'arguments: "--windows-publisher"' \ + 'arguments: "rules_bun"' \ + 'arguments: "--windows-version"' \ + 'arguments: "1.2.3.4"' \ + 'arguments: "--windows-description"' \ + 'arguments: "compile flag coverage"' \ + 'arguments: "--windows-copyright"' \ + 'arguments: "(c) rules_bun"'; do + expect_line "${compile_output}" "${expected}" +done diff --git a/tests/bundle_test/verify_sourcemap_shape.sh b/tests/bundle_test/verify_sourcemap_shape.sh new file mode 100755 index 0000000..0d9f8d8 --- /dev/null +++ b/tests/bundle_test/verify_sourcemap_shape.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash +set -euo pipefail + +if command -v bazel >/dev/null 2>&1; then + bazel_cmd=(bazel) +elif command -v bazelisk >/dev/null 2>&1; then + bazel_cmd=(bazelisk) +else + echo "bazel or bazelisk is required on PATH" >&2 + exit 1 +fi + +find_workspace_root() { + local candidate + local module_path + local script_dir + + for candidate in \ + "${TEST_SRCDIR:-}/${TEST_WORKSPACE:-}" \ + "${TEST_SRCDIR:-}/_main"; do + if [[ -n ${candidate} && -f "${candidate}/MODULE.bazel" ]]; then + printf '%s\n' "${candidate}" + return 0 + fi + done + + if [[ -n ${TEST_SRCDIR:-} ]]; then + module_path="$(find "${TEST_SRCDIR}" -maxdepth 3 -name MODULE.bazel -print -quit 2>/dev/null || true)" + if [[ -n ${module_path} ]]; then + dirname "${module_path}" + return 0 + fi + fi + + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" + candidate="$(cd "${script_dir}/../.." && pwd -P)" + if [[ -f "${candidate}/MODULE.bazel" ]]; then + printf '%s\n' "${candidate}" + return 0 + fi + + echo "Unable to locate rules_bun workspace root" >&2 + exit 1 +} + +rules_bun_root="$(find_workspace_root)" + +bundle_output="$( + cd "${rules_bun_root}" && + "${bazel_cmd[@]}" aquery 'mnemonic("BunBundle", //tests/bundle_test/sourcemap_case:sourcemap_bundle)' --output=textproto +)" + +count="$(grep -Fc 'arguments: "--sourcemap"' <<<"${bundle_output}")" +if [[ ${count} != "1" ]]; then + echo "Expected bun_bundle(sourcemap = True) to emit exactly one --sourcemap flag, got ${count}" >&2 + exit 1 +fi + +grep -Fq 'arguments: "--outfile"' <<<"${bundle_output}" +grep -Fq 'arguments: "tests/bundle_test/sourcemap_case/entry.ts"' <<<"${bundle_output}" diff --git a/tests/install_test/BUILD.bazel b/tests/install_test/BUILD.bazel index 749b29a..8292a7d 100644 --- a/tests/install_test/BUILD.bazel +++ b/tests/install_test/BUILD.bazel @@ -122,6 +122,30 @@ sh_test( }), ) +sh_test( + name = "bun_install_workspace_parity_test", + srcs = ["workspace_parity.sh"], + env_inherit = ["PATH"], + 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"], + }) + [ + "//:repo_runtime_files", + "//bun:repo_runtime_files", + "//internal:repo_runtime_files", + ], +) + sh_test( name = "bun_install_install_flags_shape_test", srcs = ["install_flags_shape.sh"], diff --git a/tests/install_test/determinism.sh b/tests/install_test/determinism.sh index fe382bd..904a353 100755 --- a/tests/install_test/determinism.sh +++ b/tests/install_test/determinism.sh @@ -4,10 +4,11 @@ set -euo pipefail rule_file="$1" grep -Eq 'install", "--frozen-lockfile", "--no-progress"' "${rule_file}" -grep -Eq 'repository_ctx\.file\("package\.json", repository_ctx\.read\(package_json\)\)' "${rule_file}" +grep -Eq 'repository_ctx\.file\("package\.json", _normalized_root_manifest\(repository_ctx, package_json\)\)' "${rule_file}" grep -Eq 'lockfile_name = bun_lockfile\.basename' "${rule_file}" grep -Eq 'if lockfile_name not in \["bun\.lock", "bun\.lockb"\]:' "${rule_file}" grep -Eq 'repository_ctx\.symlink\(bun_lockfile, lockfile_name\)' "${rule_file}" grep -Eq 'glob\(\["\*\*/node_modules/\*\*"\]' "${rule_file}" grep -Eq '_DEFAULT_INSTALL_INPUTS = \[' "${rule_file}" grep -Eq '"install_inputs": attr\.label_list\(allow_files = True\)' "${rule_file}" +grep -Eq '_materialize_install_inputs\(repository_ctx, package_json\)' "${rule_file}" diff --git a/tests/install_test/workspace_parity.sh b/tests/install_test/workspace_parity.sh index 41b35f2..108fef4 100755 --- a/tests/install_test/workspace_parity.sh +++ b/tests/install_test/workspace_parity.sh @@ -3,8 +3,12 @@ set -euo pipefail bun_path="${1:-bun}" -if ! command -v bazel >/dev/null 2>&1; then - echo "bazel is required on PATH" >&2 +if command -v bazel >/dev/null 2>&1; then + bazel_cmd=(bazel) +elif command -v bazelisk >/dev/null 2>&1; then + bazel_cmd=(bazelisk) +else + echo "bazel or bazelisk is required on PATH" >&2 exit 1 fi @@ -199,12 +203,12 @@ chmod +x "${bazel_dir}/node_modules_smoke_test.sh" ( cd "${bazel_dir}" - bazel build @node_modules//:node_modules >/dev/null - bazel test //:node_modules_smoke_test >/dev/null - bazel run //:web_build -- --emptyOutDir >/dev/null + "${bazel_cmd[@]}" build @node_modules//:node_modules >/dev/null + "${bazel_cmd[@]}" test //:node_modules_smoke_test >/dev/null + "${bazel_cmd[@]}" run //:web_build -- --emptyOutDir >/dev/null ) -output_base="$(cd "${bazel_dir}" && bazel info output_base)" +output_base="$(cd "${bazel_dir}" && "${bazel_cmd[@]}" info output_base)" bazel_repo_dir="$(find "${output_base}/external" -maxdepth 1 -type d -name '*+node_modules' | head -n 1)" if [[ -z ${bazel_repo_dir} ]]; then @@ -238,6 +242,8 @@ root = sys.argv[1] def include(rel): if rel == "node_modules" or rel.startswith("node_modules/"): + if rel == "node_modules/.rules_bun" or rel.startswith("node_modules/.rules_bun/"): + return False return True if rel.startswith("packages/") and "/node_modules" in rel: return True @@ -283,6 +289,8 @@ root = sys.argv[1] def include(rel): if rel == "node_modules" or rel.startswith("node_modules/"): + if rel == "node_modules/.rules_bun" or rel.startswith("node_modules/.rules_bun/"): + return False return True if rel.startswith("packages/") and "/node_modules" in rel: return True @@ -343,6 +351,8 @@ for dirpath, dirnames, filenames in os.walk(root, topdown=True, followlinks=Fals for name in dirnames + filenames: full = os.path.join(dirpath, name) rel = os.path.join(rel_dir, name) if rel_dir else name + if rel == ".rules_bun" or rel.startswith(".rules_bun/"): + continue st = os.lstat(full) mode = st.st_mode if stat.S_ISLNK(mode): @@ -379,6 +389,8 @@ for dirpath, dirnames, filenames in os.walk(root, topdown=True, followlinks=Fals for name in dirnames + filenames: full = os.path.join(dirpath, name) rel = os.path.join(rel_dir, name) if rel_dir else name + if rel == ".rules_bun" or rel.startswith(".rules_bun/"): + continue st = os.lstat(full) mode = st.st_mode if stat.S_ISLNK(mode): @@ -411,7 +423,7 @@ rm -rf "${plain_dist_dir}" "${bazel_dist_dir}" ( cd "${bazel_dir}" - bazel run //:web_build -- --emptyOutDir --outDir "${bazel_dist_dir}" >/dev/null + "${bazel_cmd[@]}" run //:web_build -- --emptyOutDir --outDir "${bazel_dist_dir}" >/dev/null ) if [[ ! -d ${plain_dist_dir} ]]; then diff --git a/tests/integration_test/BUILD.bazel b/tests/integration_test/BUILD.bazel index 672d7f0..902db4d 100644 --- a/tests/integration_test/BUILD.bazel +++ b/tests/integration_test/BUILD.bazel @@ -4,6 +4,7 @@ test_suite( name = "examples_test", tests = [ ":examples_basic_run_e2e_test", + ":examples_basic_hot_restart_shape_test", ":examples_workspace_bundle_e2e_test", ":examples_workspace_catalog_shape_test", ":examples_vite_monorepo_catalog_shape_test", @@ -31,6 +32,13 @@ sh_test( data = ["//examples/basic:web_dev"], ) +sh_test( + name = "examples_basic_hot_restart_shape_test", + srcs = ["examples_basic_hot_restart_shape_test.sh"], + args = ["$(location //examples/basic:web_dev_hot_restart)"], + data = ["//examples/basic:web_dev_hot_restart"], +) + sh_test( name = "examples_workspace_bundle_e2e_test", srcs = ["examples_workspace_bundle_e2e_test.sh"], diff --git a/tests/integration_test/examples_basic_hot_restart_shape_test.sh b/tests/integration_test/examples_basic_hot_restart_shape_test.sh new file mode 100755 index 0000000..9656f1c --- /dev/null +++ b/tests/integration_test/examples_basic_hot_restart_shape_test.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +binary="$1" + +grep -Fq -- 'watch_mode="hot"' "${binary}" +grep -Fq -- 'bun_args+=("--hot")' "${binary}" +grep -Fq -- '--no-clear-screen' "${binary}" +grep -Fq -- 'if [[ 1 -eq 0 ]]; then' "${binary}" +grep -Fq -- 'readarray -t restart_paths' "${binary}" +grep -Fq -- 'examples/basic/README.md' "${binary}" diff --git a/tests/js_compat_test/BUILD.bazel b/tests/js_compat_test/BUILD.bazel index 5363bf7..79ff97c 100644 --- a/tests/js_compat_test/BUILD.bazel +++ b/tests/js_compat_test/BUILD.bazel @@ -39,3 +39,30 @@ sh_test( args = ["$(location :compat_devserver)"], data = [":compat_devserver"], ) + +js_run_devserver( + name = "compat_devserver_with_package_json", + tool = ":compat_bin", + package_json = "app/package.json", + working_dir = "package", +) + +js_run_devserver( + name = "compat_devserver_with_package_dir_hint", + tool = ":compat_bin", + package_dir_hint = "app", + working_dir = "package", +) + +sh_test( + name = "js_run_devserver_workspace_shape_test", + srcs = ["verify_workspace_shape.sh"], + args = [ + "$(location :compat_devserver_with_package_json)", + "$(location :compat_devserver_with_package_dir_hint)", + ], + data = [ + ":compat_devserver_with_package_json", + ":compat_devserver_with_package_dir_hint", + ], +) diff --git a/tests/js_compat_test/app/package.json b/tests/js_compat_test/app/package.json new file mode 100644 index 0000000..f46ec7c --- /dev/null +++ b/tests/js_compat_test/app/package.json @@ -0,0 +1,4 @@ +{ + "name": "js-compat-app", + "private": true +} diff --git a/tests/js_compat_test/verify_workspace_shape.sh b/tests/js_compat_test/verify_workspace_shape.sh new file mode 100755 index 0000000..b99865b --- /dev/null +++ b/tests/js_compat_test/verify_workspace_shape.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -euo pipefail + +package_json_launcher="$1" +package_dir_hint_launcher="$2" + +grep -Fq -- 'package_json="${runfiles_dir}/_main/tests/js_compat_test/app/package.json"' "${package_json_launcher}" +grep -Fq -- 'package_rel_dir_hint="."' "${package_json_launcher}" +grep -Fq -- 'working_dir_mode="package"' "${package_json_launcher}" + +grep -Fq -- 'package_json=""' "${package_dir_hint_launcher}" +grep -Fq -- 'package_rel_dir_hint="app"' "${package_dir_hint_launcher}" +grep -Fq -- 'working_dir_mode="package"' "${package_dir_hint_launcher}" diff --git a/tests/npm_compat_test/BUILD.bazel b/tests/npm_compat_test/BUILD.bazel new file mode 100644 index 0000000..2ed0064 --- /dev/null +++ b/tests/npm_compat_test/BUILD.bazel @@ -0,0 +1,59 @@ +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 = "npm_translate_lock_workspace_test", + srcs = ["npm_translate_lock_workspace_test.sh"], + env_inherit = ["PATH"], + 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"], + }) + [ + "//:repo_runtime_files", + "//bun:repo_runtime_files", + "//internal:repo_runtime_files", + "//js:repo_runtime_files", + "//npm:repo_runtime_files", + ], +) diff --git a/tests/npm_compat_test/npm_translate_lock_workspace_test.sh b/tests/npm_compat_test/npm_translate_lock_workspace_test.sh index fed8313..41ad8ca 100755 --- a/tests/npm_compat_test/npm_translate_lock_workspace_test.sh +++ b/tests/npm_compat_test/npm_translate_lock_workspace_test.sh @@ -1,15 +1,17 @@ #!/usr/bin/env bash set -euo pipefail -nix_cmd="${NIX:-/nix/var/nix/profiles/default/bin/nix}" -if [[ ! -x ${nix_cmd} ]]; then - nix_cmd="$(command -v nix || true)" -fi -if [[ -z ${nix_cmd} || ! -x ${nix_cmd} ]]; then - echo "nix is required to launch bazel from the repo dev shell" >&2 +if command -v bazel >/dev/null 2>&1; then + bazel_bin="$(command -v bazel)" +elif command -v bazelisk >/dev/null 2>&1; then + bazel_bin="$(command -v bazelisk)" +else + echo "bazel or bazelisk is required on PATH" >&2 exit 1 fi +bun_path="${1:-bun}" + script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)" rules_bun_root="$(cd "${script_dir}/../.." && pwd -P)" @@ -35,10 +37,7 @@ import isNumber from "is-number"; console.log(`compat:${isNumber(42)}`); JS -( - cd "${rules_bun_root}" && - "${nix_cmd}" develop -c bash -lc 'bun install --cwd "$1" >/dev/null' bash "${fixture_dir}" -) +"${bun_path}" install --cwd "${fixture_dir}" >/dev/null rm -rf "${fixture_dir}/node_modules" cat >"${fixture_dir}/MODULE.bazel" <&2 diff --git a/tests/script_test/BUILD.bazel b/tests/script_test/BUILD.bazel index 9336e2e..e9e89e8 100644 --- a/tests/script_test/BUILD.bazel +++ b/tests/script_test/BUILD.bazel @@ -165,3 +165,54 @@ sh_test( args = ["$(location :workspace_filtered_script)"], data = [":workspace_filtered_script"], ) + +bun_script( + name = "workspace_parallel_script", + script = "say", + package_json = "workspace_run/package.json", + data = [ + "workspace_run/packages/pkg-a/package.json", + "workspace_run/packages/pkg-a/say.ts", + "workspace_run/packages/pkg-b/package.json", + "workspace_run/packages/pkg-b/say.ts", + ], + workspaces = True, + execution_mode = "parallel", +) + +sh_test( + name = "bun_script_workspace_parallel_test", + srcs = ["run_workspace_parallel.sh"], + args = ["$(location :workspace_parallel_script)"], + data = [":workspace_parallel_script"], +) + +bun_script( + name = "workspace_flagged_script", + script = "say", + package_json = "workspace_run/package.json", + data = [ + "workspace_run/packages/pkg-a/package.json", + "workspace_run/packages/pkg-a/say.ts", + "workspace_run/packages/pkg-b/package.json", + "workspace_run/packages/pkg-b/say.ts", + ], + workspaces = True, + execution_mode = "parallel", + no_exit_on_error = True, + shell = "system", +) + +sh_test( + name = "bun_script_workspace_flag_shape_test", + srcs = ["verify_launcher_flags.sh"], + args = [ + "$(location :workspace_flagged_script)", + "--workspaces", + "--parallel", + "--no-exit-on-error", + "--shell", + "system", + ], + data = [":workspace_flagged_script"], +) diff --git a/tests/script_test/run_workspace_parallel.sh b/tests/script_test/run_workspace_parallel.sh new file mode 100755 index 0000000..b59dd92 --- /dev/null +++ b/tests/script_test/run_workspace_parallel.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +set -euo pipefail + +script_bin="$1" +output="$(${script_bin})" + +if [[ ${output} != *"pkg-a"* ]]; then + echo "Expected workspace parallel run output to include pkg-a: ${output}" >&2 + exit 1 +fi + +if [[ ${output} != *"pkg-b"* ]]; then + echo "Expected workspace parallel run output to include pkg-b: ${output}" >&2 + exit 1 +fi diff --git a/tests/script_test/verify_launcher_flags.sh b/tests/script_test/verify_launcher_flags.sh new file mode 100755 index 0000000..515cd41 --- /dev/null +++ b/tests/script_test/verify_launcher_flags.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +binary="$1" +shift + +for expected in "$@"; do + if ! grep -Fq -- "${expected}" "${binary}"; then + echo "Expected ${binary} to contain ${expected}" >&2 + exit 1 + fi +done