mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
127 lines
5.1 KiB
Python
127 lines
5.1 KiB
Python
|
|
load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo")
|
||
|
|
|
||
|
|
"""Gets the workspace name of the given rule context."""
|
||
|
|
|
||
|
|
def _get_workspace_name(ctx):
|
||
|
|
if ctx.label.workspace_root:
|
||
|
|
# We need the workspace_name for the target being visited.
|
||
|
|
# Starlark doesn't have this - instead they have a workspace_root
|
||
|
|
# which looks like "external/repo_name" - so grab the second path segment.
|
||
|
|
return ctx.label.workspace_root.split("/")[1]
|
||
|
|
else:
|
||
|
|
return ctx.workspace_name
|
||
|
|
|
||
|
|
"""Implementation of the dev server rule."""
|
||
|
|
|
||
|
|
def _dev_server_rule_impl(ctx):
|
||
|
|
files = depset(ctx.files.srcs)
|
||
|
|
|
||
|
|
# List of files which are required for the devserver to run. This includes the
|
||
|
|
# bazel runfile helpers (to resolve runfiles in bash) and the devserver binary
|
||
|
|
# with its transitive runfiles (in order to be able to run the devserver).
|
||
|
|
required_tools = ctx.files._bash_runfile_helpers + \
|
||
|
|
ctx.files._dev_server_bin + \
|
||
|
|
ctx.attr._dev_server_bin[DefaultInfo].files.to_list() + \
|
||
|
|
ctx.attr._dev_server_bin[DefaultInfo].data_runfiles.files.to_list()
|
||
|
|
|
||
|
|
# Walk through all dependencies specified in the "deps" attribute. These labels need to be
|
||
|
|
# unwrapped in case there are built using TypeScript-specific rules. This is because targets
|
||
|
|
# built using "ts_library" or "ng_module" do not declare the generated JS files as default
|
||
|
|
# rule output.
|
||
|
|
for d in ctx.attr.deps:
|
||
|
|
if JSNamedModuleInfo in d:
|
||
|
|
files = depset(transitive = [files, d[JSNamedModuleInfo].sources])
|
||
|
|
elif hasattr(d, "files"):
|
||
|
|
files = depset(transitive = [files, d.files])
|
||
|
|
|
||
|
|
workspace_name = _get_workspace_name(ctx)
|
||
|
|
root_paths = ["", "/".join([workspace_name, ctx.label.package])] + ctx.attr.additional_root_paths
|
||
|
|
|
||
|
|
# We can't use "ctx.actions.args()" because there is no way to convert the args object
|
||
|
|
# into a string representing the command line arguments. It looks like bazel has some
|
||
|
|
# internal logic to compute the string representation of "ctx.actions.args()".
|
||
|
|
args = '--root_paths="%s" ' % ",".join(root_paths)
|
||
|
|
|
||
|
|
if ctx.attr.historyApiFallback:
|
||
|
|
args += "--historyApiFallback "
|
||
|
|
|
||
|
|
ctx.actions.expand_template(
|
||
|
|
template = ctx.file._launcher_template,
|
||
|
|
output = ctx.outputs.launcher,
|
||
|
|
substitutions = {
|
||
|
|
"TEMPLATED_args": args,
|
||
|
|
},
|
||
|
|
is_executable = True,
|
||
|
|
)
|
||
|
|
|
||
|
|
return [
|
||
|
|
DefaultInfo(runfiles = ctx.runfiles(
|
||
|
|
files = files.to_list() + required_tools,
|
||
|
|
collect_data = True,
|
||
|
|
collect_default = True,
|
||
|
|
)),
|
||
|
|
]
|
||
|
|
|
||
|
|
dev_server_rule = rule(
|
||
|
|
implementation = _dev_server_rule_impl,
|
||
|
|
outputs = {
|
||
|
|
"launcher": "%{name}.sh",
|
||
|
|
},
|
||
|
|
attrs = {
|
||
|
|
"additional_root_paths": attr.string_list(doc = """
|
||
|
|
Additionally paths to serve files from. The paths should be formatted
|
||
|
|
as manifest paths (e.g. "my_workspace/src")
|
||
|
|
"""),
|
||
|
|
"deps": attr.label_list(
|
||
|
|
allow_files = True,
|
||
|
|
doc = """
|
||
|
|
Dependencies that need to be available to the dev-server. This attribute can be
|
||
|
|
used for TypeScript targets which provide multiple flavors of output.
|
||
|
|
""",
|
||
|
|
),
|
||
|
|
"historyApiFallback": attr.bool(
|
||
|
|
default = True,
|
||
|
|
doc = """
|
||
|
|
Whether the devserver should fallback to "/index.html" for non-file requests.
|
||
|
|
This is helpful for single page applications using the HTML history API.
|
||
|
|
""",
|
||
|
|
),
|
||
|
|
"srcs": attr.label_list(allow_files = True, doc = """
|
||
|
|
Sources that should be available to the dev-server. This attribute can be
|
||
|
|
used for explicit files. This attribute only uses the files exposed by the
|
||
|
|
DefaultInfo provider (i.e. TypeScript targets should be added to "deps").
|
||
|
|
"""),
|
||
|
|
"_bash_runfile_helpers": attr.label(default = Label("@bazel_tools//tools/bash/runfiles")),
|
||
|
|
"_dev_server_bin": attr.label(
|
||
|
|
default = Label("//devtools/tools/dev-server:dev-server_bin"),
|
||
|
|
),
|
||
|
|
"_launcher_template": attr.label(allow_single_file = True, default = Label("//devtools/tools/dev-server:launcher_template.sh")),
|
||
|
|
},
|
||
|
|
)
|
||
|
|
|
||
|
|
"""
|
||
|
|
Creates a dev server that can depend on individual bazel targets. The server uses
|
||
|
|
bazel runfile resolution in order to work with Bazel package paths. e.g. developers can
|
||
|
|
request files through their manifest path: "my_workspace/src/dev-app/my-genfile".
|
||
|
|
"""
|
||
|
|
|
||
|
|
def dev_server(name, testonly = False, port = 4200, tags = [], **kwargs):
|
||
|
|
dev_server_rule(
|
||
|
|
name = "%s_launcher" % name,
|
||
|
|
visibility = ["//visibility:private"],
|
||
|
|
tags = tags,
|
||
|
|
testonly = testonly,
|
||
|
|
**kwargs
|
||
|
|
)
|
||
|
|
|
||
|
|
native.sh_binary(
|
||
|
|
name = name,
|
||
|
|
# The "ibazel_notify_changes" tag tells ibazel to not relaunch the executable on file
|
||
|
|
# changes. Rather it will communicate with the server implementation through "stdin".
|
||
|
|
tags = tags + ["ibazel_notify_changes"],
|
||
|
|
srcs = ["%s_launcher.sh" % name],
|
||
|
|
data = [":%s_launcher" % name],
|
||
|
|
args = ["--port=%s" % port],
|
||
|
|
testonly = testonly,
|
||
|
|
)
|