feat: proper windows support

This commit is contained in:
eric
2026-03-15 11:04:44 +01:00
parent 4f8e27cd74
commit 626a6640f8
70 changed files with 3410 additions and 1689 deletions

View File

@@ -1,10 +1,8 @@
"""Compatibility rule for running an executable target as a dev server."""
load("//internal:js_library.bzl", "collect_js_runfiles")
load("//internal:workspace.bzl", "create_bun_workspace_info", "render_workspace_setup", "workspace_runfiles")
def _shell_quote(value):
return "'" + value.replace("'", "'\"'\"'") + "'"
load("//internal:runtime_launcher.bzl", "declare_runtime_wrapper", "runfiles_path", "runtime_launcher_attrs", "write_launcher_spec")
load("//internal:workspace.bzl", "create_bun_workspace_info", "workspace_runfiles")
def _js_run_devserver_impl(ctx):
toolchain = ctx.toolchains["//bun:toolchain_type"]
@@ -21,81 +19,93 @@ def _js_run_devserver_impl(ctx):
extra_files = ctx.files.data + [bun_bin, tool_default_info.files_to_run.executable],
)
tool_workspace = ctx.attr.tool.label.workspace_name or "_main"
tool_path = "{}/{}".format(tool_workspace, tool_default_info.files_to_run.executable.short_path)
default_args = " ".join([_shell_quote(arg) for arg in ctx.attr.args])
launcher = ctx.actions.declare_file(ctx.label.name)
ctx.actions.write(
output = launcher,
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,
working_dir_mode = ctx.attr.working_dir,
) + """
trap cleanup_runtime_workspace EXIT
cd "${runtime_exec_dir}"
tool="${runfiles_dir}/__TOOL_SHORT_PATH__"
exec "${tool}" __DEFAULT_ARGS__ "$@"
""".replace("__TOOL_SHORT_PATH__", tool_path).replace("__DEFAULT_ARGS__", default_args),
)
spec_file = write_launcher_spec(ctx, {
"version": 1,
"kind": "tool_exec",
"bun_short_path": runfiles_path(bun_bin),
"primary_source_short_path": runfiles_path(package_json) if package_json else runfiles_path(tool_default_info.files_to_run.executable),
"package_json_short_path": runfiles_path(package_json) if package_json else "",
"install_metadata_short_path": runfiles_path(workspace_info.install_metadata_file) if workspace_info.install_metadata_file else "",
"install_repo_runfiles_path": workspace_info.install_repo_runfiles_path,
"node_modules_roots": workspace_info.node_modules_roots,
"package_dir_hint": ctx.attr.package_dir_hint,
"working_dir_mode": ctx.attr.working_dir,
"inherit_host_path": ctx.attr.inherit_host_path,
"argv": [],
"args": ctx.attr.args,
"passthrough_args": True,
"tool_short_path": runfiles_path(tool_default_info.files_to_run.executable),
"restart_on": [],
"watch_mode": "",
"reporter": "",
"coverage": False,
"coverage_reporters": [],
"preload_short_paths": [],
"env_file_short_paths": [],
"test_short_paths": [],
})
launcher = declare_runtime_wrapper(ctx, bun_bin, spec_file)
return [
workspace_info,
DefaultInfo(
executable = launcher,
executable = launcher.executable,
runfiles = workspace_runfiles(
ctx,
workspace_info,
direct_files = [launcher, tool_default_info.files_to_run.executable],
direct_files = [launcher.executable, launcher.runner, spec_file, tool_default_info.files_to_run.executable],
transitive_files = dep_runfiles,
).merge(tool_default_info.default_runfiles),
),
]
_JS_RUN_DEVSERVER_ATTRS = runtime_launcher_attrs()
_JS_RUN_DEVSERVER_ATTRS.update({
"tool": attr.label(
mandatory = True,
executable = True,
cfg = "target",
doc = "Executable target to launch as the dev server.",
),
"package_json": attr.label(
allow_single_file = True,
doc = "Optional package.json used to resolve the package working directory.",
),
"package_dir_hint": attr.string(
default = ".",
doc = "Optional package-relative directory hint when package_json is not supplied.",
),
"node_modules": attr.label(
doc = "Optional label providing package files from a node_modules tree, typically produced by bun_install or npm_translate_lock, in runfiles.",
),
"deps": attr.label_list(
doc = "Library dependencies required by the dev server.",
),
"data": attr.label_list(
allow_files = True,
doc = "Additional runtime files required by the dev server.",
),
"working_dir": attr.string(
default = "workspace",
values = ["workspace", "package"],
doc = "Working directory at runtime: Bazel runfiles workspace root or the resolved package directory.",
),
"inherit_host_path": attr.bool(
default = False,
doc = "If true, appends the host PATH after staged node_modules/.bin entries at runtime.",
),
})
js_run_devserver = rule(
implementation = _js_run_devserver_impl,
doc = """Runs an executable target from a staged JS workspace.
This is a Bun-backed compatibility adapter for `rules_js`-style devserver
targets. It stages the same runtime workspace as the Bun rules, then executes
the provided tool with any default arguments.
the provided tool with any default arguments. It is intended for local
development workflows rather than hermetic build execution.
""",
attrs = {
"tool": attr.label(
mandatory = True,
executable = True,
cfg = "target",
doc = "Executable target to launch as the dev server.",
),
"package_json": attr.label(
allow_single_file = True,
doc = "Optional package.json used to resolve the package working directory.",
),
"package_dir_hint": attr.string(
default = ".",
doc = "Optional package-relative directory hint when package_json is not supplied.",
),
"node_modules": attr.label(
doc = "Optional label providing package files from a node_modules tree, typically produced by bun_install or npm_translate_lock, in runfiles.",
),
"deps": attr.label_list(
doc = "Library dependencies required by the dev server.",
),
"data": attr.label_list(
allow_files = True,
doc = "Additional runtime files required by the dev server.",
),
"working_dir": attr.string(
default = "workspace",
values = ["workspace", "package"],
doc = "Working directory at runtime: Bazel runfiles workspace root or the resolved package directory.",
),
},
attrs = _JS_RUN_DEVSERVER_ATTRS,
executable = True,
toolchains = ["//bun:toolchain_type"],
)