parent
090824526b
commit
a3f1e2cb42
|
@ -12,11 +12,13 @@ from source downstream. Alternately, this API is available from the
|
|||
used in a downstream project.
|
||||
"""
|
||||
|
||||
load("//packages/bazel:index.bzl",
|
||||
load(
|
||||
"//packages/bazel:index.bzl",
|
||||
_ng_module = "ng_module",
|
||||
_ng_package = "ng_package",
|
||||
_protractor_web_test = "protractor_web_test",
|
||||
_protractor_web_test_suite = "protractor_web_test_suite")
|
||||
_protractor_web_test_suite = "protractor_web_test_suite",
|
||||
)
|
||||
load("//tools:ng_setup_workspace.bzl", _ng_setup_workspace = "ng_setup_workspace")
|
||||
|
||||
ng_module = _ng_module
|
||||
|
|
|
@ -10,9 +10,11 @@ Users should not load files under "/src"
|
|||
load("//packages/bazel/src:ng_module.bzl", _ng_module = "ng_module")
|
||||
load("//packages/bazel/src:ng_setup_workspace.bzl", _ng_setup_workspace = "ng_setup_workspace")
|
||||
load("//packages/bazel/src/ng_package:ng_package.bzl", _ng_package = "ng_package")
|
||||
load("//packages/bazel/src/protractor:protractor_web_test.bzl",
|
||||
_protractor_web_test = "protractor_web_test",
|
||||
_protractor_web_test_suite = "protractor_web_test_suite")
|
||||
load(
|
||||
"//packages/bazel/src/protractor:protractor_web_test.bzl",
|
||||
_protractor_web_test = "protractor_web_test",
|
||||
_protractor_web_test_suite = "protractor_web_test_suite",
|
||||
)
|
||||
|
||||
ng_module = _ng_module
|
||||
ng_package = _ng_package
|
||||
|
|
|
@ -28,75 +28,78 @@ ESM5Info = provider(
|
|||
)
|
||||
|
||||
def _map_closure_path(file):
|
||||
result = file.short_path[:-len(".closure.js")]
|
||||
# short_path is meant to be used when accessing runfiles in a binary, where
|
||||
# the CWD is inside the current repo. Therefore files in external repo have a
|
||||
# short_path of ../external/wkspc/path/to/package
|
||||
# We want to strip the first two segments from such paths.
|
||||
if (result.startswith("../")):
|
||||
result = "/".join(result.split("/")[2:])
|
||||
return result + ".js"
|
||||
result = file.short_path[:-len(".closure.js")]
|
||||
|
||||
# short_path is meant to be used when accessing runfiles in a binary, where
|
||||
# the CWD is inside the current repo. Therefore files in external repo have a
|
||||
# short_path of ../external/wkspc/path/to/package
|
||||
# We want to strip the first two segments from such paths.
|
||||
if (result.startswith("../")):
|
||||
result = "/".join(result.split("/")[2:])
|
||||
return result + ".js"
|
||||
|
||||
def _join(array):
|
||||
return "/".join([p for p in array if p])
|
||||
return "/".join([p for p in array if p])
|
||||
|
||||
def _esm5_outputs_aspect(target, ctx):
|
||||
if not hasattr(target, "typescript"):
|
||||
return []
|
||||
if not hasattr(target, "typescript"):
|
||||
return []
|
||||
|
||||
# We create a new tsconfig.json file that will have our compilation settings
|
||||
tsconfig = ctx.actions.declare_file("%s_esm5.tsconfig.json" % target.label.name)
|
||||
# We create a new tsconfig.json file that will have our compilation settings
|
||||
tsconfig = ctx.actions.declare_file("%s_esm5.tsconfig.json" % target.label.name)
|
||||
|
||||
workspace = target.label.workspace_root if target.label.workspace_root else ""
|
||||
workspace = target.label.workspace_root if target.label.workspace_root else ""
|
||||
|
||||
# re-root the outputs under a ".esm5" directory so the path don't collide
|
||||
out_dir = ctx.label.name + ".esm5"
|
||||
if workspace:
|
||||
out_dir = out_dir + "/" + workspace
|
||||
# re-root the outputs under a ".esm5" directory so the path don't collide
|
||||
out_dir = ctx.label.name + ".esm5"
|
||||
if workspace:
|
||||
out_dir = out_dir + "/" + workspace
|
||||
|
||||
outputs = [ctx.actions.declare_file(_join([out_dir, _map_closure_path(f)]))
|
||||
for f in target.typescript.replay_params.outputs
|
||||
if not f.short_path.endswith(".externs.js")]
|
||||
outputs = [
|
||||
ctx.actions.declare_file(_join([out_dir, _map_closure_path(f)]))
|
||||
for f in target.typescript.replay_params.outputs
|
||||
if not f.short_path.endswith(".externs.js")
|
||||
]
|
||||
|
||||
ctx.actions.run(
|
||||
executable = ctx.executable._modify_tsconfig,
|
||||
inputs = [target.typescript.replay_params.tsconfig],
|
||||
outputs = [tsconfig],
|
||||
arguments = [
|
||||
target.typescript.replay_params.tsconfig.path,
|
||||
tsconfig.path,
|
||||
_join([workspace, target.label.package, ctx.label.name + ".esm5"]),
|
||||
ctx.bin_dir.path
|
||||
],
|
||||
)
|
||||
ctx.actions.run(
|
||||
executable = ctx.executable._modify_tsconfig,
|
||||
inputs = [target.typescript.replay_params.tsconfig],
|
||||
outputs = [tsconfig],
|
||||
arguments = [
|
||||
target.typescript.replay_params.tsconfig.path,
|
||||
tsconfig.path,
|
||||
_join([workspace, target.label.package, ctx.label.name + ".esm5"]),
|
||||
ctx.bin_dir.path,
|
||||
],
|
||||
)
|
||||
|
||||
ctx.actions.run(
|
||||
progress_message = "Compiling TypeScript (ES5 with ES Modules) %s" % target.label,
|
||||
inputs = target.typescript.replay_params.inputs + [tsconfig],
|
||||
outputs = outputs,
|
||||
arguments = [tsconfig.path],
|
||||
executable = target.typescript.replay_params.compiler,
|
||||
execution_requirements = {
|
||||
# TODO(alexeagle): enable worker mode for these compilations
|
||||
"supports-workers": "0",
|
||||
},
|
||||
)
|
||||
ctx.actions.run(
|
||||
progress_message = "Compiling TypeScript (ES5 with ES Modules) %s" % target.label,
|
||||
inputs = target.typescript.replay_params.inputs + [tsconfig],
|
||||
outputs = outputs,
|
||||
arguments = [tsconfig.path],
|
||||
executable = target.typescript.replay_params.compiler,
|
||||
execution_requirements = {
|
||||
# TODO(alexeagle): enable worker mode for these compilations
|
||||
"supports-workers": "0",
|
||||
},
|
||||
)
|
||||
|
||||
root_dir = _join([
|
||||
ctx.bin_dir.path,
|
||||
workspace,
|
||||
target.label.package,
|
||||
ctx.label.name + ".esm5",
|
||||
])
|
||||
root_dir = _join([
|
||||
ctx.bin_dir.path,
|
||||
workspace,
|
||||
target.label.package,
|
||||
ctx.label.name + ".esm5",
|
||||
])
|
||||
|
||||
transitive_output={root_dir: depset(outputs)}
|
||||
for dep in ctx.rule.attr.deps:
|
||||
if ESM5Info in dep:
|
||||
transitive_output.update(dep[ESM5Info].transitive_output)
|
||||
transitive_output = {root_dir: depset(outputs)}
|
||||
for dep in ctx.rule.attr.deps:
|
||||
if ESM5Info in dep:
|
||||
transitive_output.update(dep[ESM5Info].transitive_output)
|
||||
|
||||
return [ESM5Info(
|
||||
transitive_output = transitive_output,
|
||||
)]
|
||||
return [ESM5Info(
|
||||
transitive_output = transitive_output,
|
||||
)]
|
||||
|
||||
# Downstream rules can use this aspect to access the ESM5 output flavor.
|
||||
# Only terminal rules (those which expect never to be used in deps[]) should do
|
||||
|
@ -104,12 +107,13 @@ def _esm5_outputs_aspect(target, ctx):
|
|||
esm5_outputs_aspect = aspect(
|
||||
implementation = _esm5_outputs_aspect,
|
||||
# Recurse to the deps of any target we visit
|
||||
attr_aspects = ['deps'],
|
||||
attr_aspects = ["deps"],
|
||||
attrs = {
|
||||
"_modify_tsconfig": attr.label(
|
||||
default = Label("//packages/bazel/src:modify_tsconfig"),
|
||||
executable = True,
|
||||
cfg = "host"),
|
||||
cfg = "host",
|
||||
),
|
||||
# We must list tsc_wrapped here to ensure it's built before the action runs
|
||||
# For some reason, having the compiler output as an input to the action above
|
||||
# is not sufficient.
|
||||
|
@ -128,43 +132,44 @@ esm5_outputs_aspect = aspect(
|
|||
)
|
||||
|
||||
def esm5_root_dir(ctx):
|
||||
return ctx.label.name + ".esm5"
|
||||
return ctx.label.name + ".esm5"
|
||||
|
||||
def flatten_esm5(ctx):
|
||||
"""Merge together the .esm5 folders from the dependencies.
|
||||
"""Merge together the .esm5 folders from the dependencies.
|
||||
|
||||
Two different dependencies A and B may have outputs like
|
||||
`bazel-bin/path/to/A.esm5/path/to/lib.js`
|
||||
`bazel-bin/path/to/B.esm5/path/to/main.js`
|
||||
Two different dependencies A and B may have outputs like
|
||||
`bazel-bin/path/to/A.esm5/path/to/lib.js`
|
||||
`bazel-bin/path/to/B.esm5/path/to/main.js`
|
||||
|
||||
In order to run rollup on this app, in case main.js contains `import from './lib'`
|
||||
they need to be together in the same root directory, so if we depend on both A and B
|
||||
we need the outputs to be
|
||||
`bazel-bin/path/to/my_rule.esm5/path/to/lib.js`
|
||||
`bazel-bin/path/to/my_rule.esm5/path/to/main.js`
|
||||
In order to run rollup on this app, in case main.js contains `import from './lib'`
|
||||
they need to be together in the same root directory, so if we depend on both A and B
|
||||
we need the outputs to be
|
||||
`bazel-bin/path/to/my_rule.esm5/path/to/lib.js`
|
||||
`bazel-bin/path/to/my_rule.esm5/path/to/main.js`
|
||||
|
||||
Args:
|
||||
ctx: the skylark rule execution context
|
||||
Args:
|
||||
ctx: the skylark rule execution context
|
||||
|
||||
Returns:
|
||||
list of flattened files
|
||||
"""
|
||||
esm5_sources = []
|
||||
result = []
|
||||
for dep in ctx.attr.deps:
|
||||
if ESM5Info in dep:
|
||||
transitive_output = dep[ESM5Info].transitive_output
|
||||
esm5_sources.extend(transitive_output.values())
|
||||
for f in depset(transitive = esm5_sources).to_list():
|
||||
path = f.short_path[f.short_path.find(".esm5") + len(".esm5"):]
|
||||
if (path.startswith("../")):
|
||||
path = "external/" + path[3:]
|
||||
rerooted_file = ctx.actions.declare_file("/".join([esm5_root_dir(ctx), path]))
|
||||
result.append(rerooted_file)
|
||||
# print("copy", f.short_path, "to", rerooted_file.short_path)
|
||||
ctx.actions.expand_template(
|
||||
output = rerooted_file,
|
||||
template = f,
|
||||
substitutions = {},
|
||||
)
|
||||
return result
|
||||
Returns:
|
||||
list of flattened files
|
||||
"""
|
||||
esm5_sources = []
|
||||
result = []
|
||||
for dep in ctx.attr.deps:
|
||||
if ESM5Info in dep:
|
||||
transitive_output = dep[ESM5Info].transitive_output
|
||||
esm5_sources.extend(transitive_output.values())
|
||||
for f in depset(transitive = esm5_sources).to_list():
|
||||
path = f.short_path[f.short_path.find(".esm5") + len(".esm5"):]
|
||||
if (path.startswith("../")):
|
||||
path = "external/" + path[3:]
|
||||
rerooted_file = ctx.actions.declare_file("/".join([esm5_root_dir(ctx), path]))
|
||||
result.append(rerooted_file)
|
||||
|
||||
# print("copy", f.short_path, "to", rerooted_file.short_path)
|
||||
ctx.actions.expand_template(
|
||||
output = rerooted_file,
|
||||
template = f,
|
||||
substitutions = {},
|
||||
)
|
||||
return result
|
||||
|
|
|
@ -5,270 +5,272 @@
|
|||
"""Run Angular's AOT template compiler
|
||||
"""
|
||||
|
||||
load(":rules_typescript.bzl",
|
||||
"tsc_wrapped_tsconfig",
|
||||
load(
|
||||
":rules_typescript.bzl",
|
||||
"COMMON_ATTRIBUTES",
|
||||
"COMMON_OUTPUTS",
|
||||
"compile_ts",
|
||||
"DEPS_ASPECTS",
|
||||
"compile_ts",
|
||||
"ts_providers_dict_to_struct",
|
||||
"tsc_wrapped_tsconfig",
|
||||
)
|
||||
|
||||
def compile_strategy(ctx):
|
||||
"""Detect which strategy should be used to implement ng_module.
|
||||
"""Detect which strategy should be used to implement ng_module.
|
||||
|
||||
Depending on the value of the 'compile' define flag or the '_global_mode' attribute, ng_module
|
||||
can be implemented in various ways. This function reads the configuration passed by the user and
|
||||
determines which mode is active.
|
||||
Depending on the value of the 'compile' define flag or the '_global_mode' attribute, ng_module
|
||||
can be implemented in various ways. This function reads the configuration passed by the user and
|
||||
determines which mode is active.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
one of 'legacy', 'local', 'jit', or 'global' depending on the configuration in ctx
|
||||
"""
|
||||
Returns:
|
||||
one of 'legacy', 'local', 'jit', or 'global' depending on the configuration in ctx
|
||||
"""
|
||||
|
||||
strategy = 'legacy'
|
||||
if 'compile' in ctx.var:
|
||||
strategy = ctx.var['compile']
|
||||
strategy = "legacy"
|
||||
if "compile" in ctx.var:
|
||||
strategy = ctx.var["compile"]
|
||||
|
||||
if strategy not in ['legacy', 'local', 'jit']:
|
||||
fail("Unknown --define=compile value '%s'" % strategy)
|
||||
if strategy not in ["legacy", "local", "jit"]:
|
||||
fail("Unknown --define=compile value '%s'" % strategy)
|
||||
|
||||
if strategy == 'legacy' and hasattr(ctx.attr, '_global_mode') and ctx.attr._global_mode:
|
||||
strategy = 'global'
|
||||
if strategy == "legacy" and hasattr(ctx.attr, "_global_mode") and ctx.attr._global_mode:
|
||||
strategy = "global"
|
||||
|
||||
return strategy
|
||||
return strategy
|
||||
|
||||
def _compiler_name(ctx):
|
||||
"""Selects a user-visible name depending on the current compilation strategy.
|
||||
"""Selects a user-visible name depending on the current compilation strategy.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
the name of the current compiler to be displayed in build output
|
||||
"""
|
||||
Returns:
|
||||
the name of the current compiler to be displayed in build output
|
||||
"""
|
||||
|
||||
strategy = compile_strategy(ctx)
|
||||
if strategy == 'legacy':
|
||||
return 'ngc'
|
||||
elif strategy == 'global':
|
||||
return 'ngc.ivy'
|
||||
elif strategy == 'local':
|
||||
return 'ngtsc'
|
||||
elif strategy == 'jit':
|
||||
return 'tsc'
|
||||
else:
|
||||
fail('unreachable')
|
||||
strategy = compile_strategy(ctx)
|
||||
if strategy == "legacy":
|
||||
return "ngc"
|
||||
elif strategy == "global":
|
||||
return "ngc.ivy"
|
||||
elif strategy == "local":
|
||||
return "ngtsc"
|
||||
elif strategy == "jit":
|
||||
return "tsc"
|
||||
else:
|
||||
fail("unreachable")
|
||||
|
||||
def _enable_ivy_value(ctx):
|
||||
"""Determines the value of the enableIvy option in the generated tsconfig.
|
||||
"""Determines the value of the enableIvy option in the generated tsconfig.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
the value of enableIvy that needs to be set in angularCompilerOptions in the generated tsconfig
|
||||
"""
|
||||
Returns:
|
||||
the value of enableIvy that needs to be set in angularCompilerOptions in the generated tsconfig
|
||||
"""
|
||||
|
||||
strategy = compile_strategy(ctx)
|
||||
if strategy == 'legacy':
|
||||
return False
|
||||
elif strategy == 'global':
|
||||
return True
|
||||
elif strategy == 'local':
|
||||
return 'ngtsc'
|
||||
elif strategy == 'jit':
|
||||
return 'tsc'
|
||||
else:
|
||||
fail('unreachable')
|
||||
strategy = compile_strategy(ctx)
|
||||
if strategy == "legacy":
|
||||
return False
|
||||
elif strategy == "global":
|
||||
return True
|
||||
elif strategy == "local":
|
||||
return "ngtsc"
|
||||
elif strategy == "jit":
|
||||
return "tsc"
|
||||
else:
|
||||
fail("unreachable")
|
||||
|
||||
def _include_ng_files(ctx):
|
||||
"""Determines whether Angular outputs will be produced by the current compilation strategy.
|
||||
"""Determines whether Angular outputs will be produced by the current compilation strategy.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
true iff the current compilation strategy will produce View Engine compilation outputs (such as
|
||||
factory files), false otherwise
|
||||
"""
|
||||
Returns:
|
||||
true iff the current compilation strategy will produce View Engine compilation outputs (such as
|
||||
factory files), false otherwise
|
||||
"""
|
||||
|
||||
strategy = compile_strategy(ctx)
|
||||
return strategy == 'legacy' or strategy == 'global'
|
||||
strategy = compile_strategy(ctx)
|
||||
return strategy == "legacy" or strategy == "global"
|
||||
|
||||
def _basename_of(ctx, file):
|
||||
ext_len = len(".ts")
|
||||
if file.short_path.endswith(".ng.html"):
|
||||
ext_len = len(".ng.html")
|
||||
elif file.short_path.endswith(".html"):
|
||||
ext_len = len(".html")
|
||||
return file.short_path[len(ctx.label.package) + 1:-ext_len]
|
||||
ext_len = len(".ts")
|
||||
if file.short_path.endswith(".ng.html"):
|
||||
ext_len = len(".ng.html")
|
||||
elif file.short_path.endswith(".html"):
|
||||
ext_len = len(".html")
|
||||
return file.short_path[len(ctx.label.package) + 1:-ext_len]
|
||||
|
||||
# Return true if run with bazel (the open-sourced version of blaze), false if
|
||||
# run with blaze.
|
||||
def _is_bazel():
|
||||
return not hasattr(native, "genmpm")
|
||||
return not hasattr(native, "genmpm")
|
||||
|
||||
def _flat_module_out_file(ctx):
|
||||
"""Provide a default for the flat_module_out_file attribute.
|
||||
"""Provide a default for the flat_module_out_file attribute.
|
||||
|
||||
We cannot use the default="" parameter of ctx.attr because the value is calculated
|
||||
from other attributes (name)
|
||||
We cannot use the default="" parameter of ctx.attr because the value is calculated
|
||||
from other attributes (name)
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
a basename used for the flat module out (no extension)
|
||||
"""
|
||||
if hasattr(ctx.attr, "flat_module_out_file") and ctx.attr.flat_module_out_file:
|
||||
return ctx.attr.flat_module_out_file
|
||||
return "%s_public_index" % ctx.label.name
|
||||
Returns:
|
||||
a basename used for the flat module out (no extension)
|
||||
"""
|
||||
if hasattr(ctx.attr, "flat_module_out_file") and ctx.attr.flat_module_out_file:
|
||||
return ctx.attr.flat_module_out_file
|
||||
return "%s_public_index" % ctx.label.name
|
||||
|
||||
def _should_produce_flat_module_outs(ctx):
|
||||
"""Should we produce flat module outputs.
|
||||
"""Should we produce flat module outputs.
|
||||
|
||||
We only produce flat module outs when we expect the ng_module is meant to be published,
|
||||
based on the presence of the module_name attribute.
|
||||
We only produce flat module outs when we expect the ng_module is meant to be published,
|
||||
based on the presence of the module_name attribute.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
true iff we should run the bundle_index_host to produce flat module metadata and bundle index
|
||||
"""
|
||||
return _is_bazel() and ctx.attr.module_name
|
||||
Returns:
|
||||
true iff we should run the bundle_index_host to produce flat module metadata and bundle index
|
||||
"""
|
||||
return _is_bazel() and ctx.attr.module_name
|
||||
|
||||
# Calculate the expected output of the template compiler for every source in
|
||||
# in the library. Most of these will be produced as empty files but it is
|
||||
# unknown, without parsing, which will be empty.
|
||||
def _expected_outs(ctx):
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
|
||||
devmode_js_files = []
|
||||
closure_js_files = []
|
||||
declaration_files = []
|
||||
summary_files = []
|
||||
metadata_files = []
|
||||
devmode_js_files = []
|
||||
closure_js_files = []
|
||||
declaration_files = []
|
||||
summary_files = []
|
||||
metadata_files = []
|
||||
|
||||
factory_basename_set = depset([_basename_of(ctx, src) for src in ctx.files.factories])
|
||||
factory_basename_set = depset([_basename_of(ctx, src) for src in ctx.files.factories])
|
||||
|
||||
for src in ctx.files.srcs + ctx.files.assets:
|
||||
package_prefix = ctx.label.package + "/" if ctx.label.package else ""
|
||||
for src in ctx.files.srcs + ctx.files.assets:
|
||||
package_prefix = ctx.label.package + "/" if ctx.label.package else ""
|
||||
|
||||
# Strip external repository name from path if src is from external repository
|
||||
# If src is from external repository, it's short_path will be ../<external_repo_name>/...
|
||||
short_path = src.short_path if src.short_path[0:2] != ".." else "/".join(src.short_path.split("/")[2:])
|
||||
# Strip external repository name from path if src is from external repository
|
||||
# If src is from external repository, it's short_path will be ../<external_repo_name>/...
|
||||
short_path = src.short_path if src.short_path[0:2] != ".." else "/".join(src.short_path.split("/")[2:])
|
||||
|
||||
if short_path.endswith(".ts") and not short_path.endswith(".d.ts"):
|
||||
basename = short_path[len(package_prefix):-len(".ts")]
|
||||
if include_ng_files and (len(factory_basename_set) == 0 or basename in factory_basename_set):
|
||||
devmode_js = [
|
||||
".ngfactory.js",
|
||||
".ngsummary.js",
|
||||
".js",
|
||||
]
|
||||
summaries = [".ngsummary.json"]
|
||||
metadata = [".metadata.json"]
|
||||
else:
|
||||
devmode_js = [".js"]
|
||||
summaries = []
|
||||
metadata = []
|
||||
elif include_ng_files and short_path.endswith(".css"):
|
||||
basename = short_path[len(package_prefix):-len(".css")]
|
||||
devmode_js = [
|
||||
".css.shim.ngstyle.js",
|
||||
".css.ngstyle.js",
|
||||
]
|
||||
summaries = []
|
||||
metadata = []
|
||||
if short_path.endswith(".ts") and not short_path.endswith(".d.ts"):
|
||||
basename = short_path[len(package_prefix):-len(".ts")]
|
||||
if include_ng_files and (len(factory_basename_set) == 0 or basename in factory_basename_set):
|
||||
devmode_js = [
|
||||
".ngfactory.js",
|
||||
".ngsummary.js",
|
||||
".js",
|
||||
]
|
||||
summaries = [".ngsummary.json"]
|
||||
metadata = [".metadata.json"]
|
||||
else:
|
||||
devmode_js = [".js"]
|
||||
summaries = []
|
||||
metadata = []
|
||||
elif include_ng_files and short_path.endswith(".css"):
|
||||
basename = short_path[len(package_prefix):-len(".css")]
|
||||
devmode_js = [
|
||||
".css.shim.ngstyle.js",
|
||||
".css.ngstyle.js",
|
||||
]
|
||||
summaries = []
|
||||
metadata = []
|
||||
else:
|
||||
continue
|
||||
|
||||
filter_summaries = ctx.attr.filter_summaries
|
||||
closure_js = [f.replace(".js", ".closure.js") for f in devmode_js if not filter_summaries or not f.endswith(".ngsummary.js")]
|
||||
declarations = [f.replace(".js", ".d.ts") for f in devmode_js]
|
||||
|
||||
devmode_js_files += [ctx.actions.declare_file(basename + ext) for ext in devmode_js]
|
||||
closure_js_files += [ctx.actions.declare_file(basename + ext) for ext in closure_js]
|
||||
declaration_files += [ctx.actions.declare_file(basename + ext) for ext in declarations]
|
||||
summary_files += [ctx.actions.declare_file(basename + ext) for ext in summaries]
|
||||
if not _is_bazel():
|
||||
metadata_files += [ctx.actions.declare_file(basename + ext) for ext in metadata]
|
||||
|
||||
# We do this just when producing a flat module index for a publishable ng_module
|
||||
if include_ng_files and _should_produce_flat_module_outs(ctx):
|
||||
flat_module_out = _flat_module_out_file(ctx)
|
||||
devmode_js_files.append(ctx.actions.declare_file("%s.js" % flat_module_out))
|
||||
closure_js_files.append(ctx.actions.declare_file("%s.closure.js" % flat_module_out))
|
||||
bundle_index_typings = ctx.actions.declare_file("%s.d.ts" % flat_module_out)
|
||||
declaration_files.append(bundle_index_typings)
|
||||
metadata_files.append(ctx.actions.declare_file("%s.metadata.json" % flat_module_out))
|
||||
else:
|
||||
continue
|
||||
bundle_index_typings = None
|
||||
|
||||
filter_summaries = ctx.attr.filter_summaries
|
||||
closure_js = [f.replace(".js", ".closure.js") for f in devmode_js if not filter_summaries or not f.endswith(".ngsummary.js")]
|
||||
declarations = [f.replace(".js", ".d.ts") for f in devmode_js]
|
||||
# TODO(alxhub): i18n is only produced by the legacy compiler currently. This should be re-enabled
|
||||
# when ngtsc can extract messages
|
||||
if include_ng_files:
|
||||
i18n_messages_files = [ctx.new_file(ctx.genfiles_dir, ctx.label.name + "_ngc_messages.xmb")]
|
||||
else:
|
||||
i18n_messages_files = []
|
||||
|
||||
devmode_js_files += [ctx.actions.declare_file(basename + ext) for ext in devmode_js]
|
||||
closure_js_files += [ctx.actions.declare_file(basename + ext) for ext in closure_js]
|
||||
declaration_files += [ctx.actions.declare_file(basename + ext) for ext in declarations]
|
||||
summary_files += [ctx.actions.declare_file(basename + ext) for ext in summaries]
|
||||
if not _is_bazel():
|
||||
metadata_files += [ctx.actions.declare_file(basename + ext) for ext in metadata]
|
||||
|
||||
# We do this just when producing a flat module index for a publishable ng_module
|
||||
if include_ng_files and _should_produce_flat_module_outs(ctx):
|
||||
flat_module_out = _flat_module_out_file(ctx)
|
||||
devmode_js_files.append(ctx.actions.declare_file("%s.js" % flat_module_out))
|
||||
closure_js_files.append(ctx.actions.declare_file("%s.closure.js" % flat_module_out))
|
||||
bundle_index_typings = ctx.actions.declare_file("%s.d.ts" % flat_module_out)
|
||||
declaration_files.append(bundle_index_typings)
|
||||
metadata_files.append(ctx.actions.declare_file("%s.metadata.json" % flat_module_out))
|
||||
else:
|
||||
bundle_index_typings = None
|
||||
|
||||
# TODO(alxhub): i18n is only produced by the legacy compiler currently. This should be re-enabled
|
||||
# when ngtsc can extract messages
|
||||
if include_ng_files:
|
||||
i18n_messages_files = [ctx.new_file(ctx.genfiles_dir, ctx.label.name + "_ngc_messages.xmb")]
|
||||
else:
|
||||
i18n_messages_files = []
|
||||
|
||||
return struct(
|
||||
closure_js = closure_js_files,
|
||||
devmode_js = devmode_js_files,
|
||||
declarations = declaration_files,
|
||||
summaries = summary_files,
|
||||
metadata = metadata_files,
|
||||
bundle_index_typings = bundle_index_typings,
|
||||
i18n_messages = i18n_messages_files,
|
||||
)
|
||||
return struct(
|
||||
closure_js = closure_js_files,
|
||||
devmode_js = devmode_js_files,
|
||||
declarations = declaration_files,
|
||||
summaries = summary_files,
|
||||
metadata = metadata_files,
|
||||
bundle_index_typings = bundle_index_typings,
|
||||
i18n_messages = i18n_messages_files,
|
||||
)
|
||||
|
||||
def _ngc_tsconfig(ctx, files, srcs, **kwargs):
|
||||
outs = _expected_outs(ctx)
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
if "devmode_manifest" in kwargs:
|
||||
expected_outs = outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
else:
|
||||
expected_outs = outs.closure_js
|
||||
outs = _expected_outs(ctx)
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
if "devmode_manifest" in kwargs:
|
||||
expected_outs = outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
else:
|
||||
expected_outs = outs.closure_js
|
||||
|
||||
angular_compiler_options = {
|
||||
"enableResourceInlining": ctx.attr.inline_resources,
|
||||
"generateCodeForLibraries": False,
|
||||
"allowEmptyCodegenFiles": True,
|
||||
# Summaries are only enabled if Angular outputs are to be produced.
|
||||
"enableSummariesForJit": include_ng_files,
|
||||
"enableIvy": _enable_ivy_value(ctx),
|
||||
"fullTemplateTypeCheck": ctx.attr.type_check,
|
||||
# FIXME: wrong place to de-dupe
|
||||
"expectedOut": depset([o.path for o in expected_outs]).to_list()
|
||||
}
|
||||
angular_compiler_options = {
|
||||
"enableResourceInlining": ctx.attr.inline_resources,
|
||||
"generateCodeForLibraries": False,
|
||||
"allowEmptyCodegenFiles": True,
|
||||
# Summaries are only enabled if Angular outputs are to be produced.
|
||||
"enableSummariesForJit": include_ng_files,
|
||||
"enableIvy": _enable_ivy_value(ctx),
|
||||
"fullTemplateTypeCheck": ctx.attr.type_check,
|
||||
# FIXME: wrong place to de-dupe
|
||||
"expectedOut": depset([o.path for o in expected_outs]).to_list(),
|
||||
}
|
||||
|
||||
if _should_produce_flat_module_outs(ctx):
|
||||
angular_compiler_options["flatModuleId"] = ctx.attr.module_name
|
||||
angular_compiler_options["flatModuleOutFile"] = _flat_module_out_file(ctx)
|
||||
angular_compiler_options["flatModulePrivateSymbolPrefix"] = "_".join(
|
||||
[ctx.workspace_name] + ctx.label.package.split("/") + [ctx.label.name, ""])
|
||||
if _should_produce_flat_module_outs(ctx):
|
||||
angular_compiler_options["flatModuleId"] = ctx.attr.module_name
|
||||
angular_compiler_options["flatModuleOutFile"] = _flat_module_out_file(ctx)
|
||||
angular_compiler_options["flatModulePrivateSymbolPrefix"] = "_".join(
|
||||
[ctx.workspace_name] + ctx.label.package.split("/") + [ctx.label.name, ""],
|
||||
)
|
||||
|
||||
return dict(tsc_wrapped_tsconfig(ctx, files, srcs, **kwargs), **{
|
||||
"angularCompilerOptions": angular_compiler_options
|
||||
})
|
||||
return dict(tsc_wrapped_tsconfig(ctx, files, srcs, **kwargs), **{
|
||||
"angularCompilerOptions": angular_compiler_options,
|
||||
})
|
||||
|
||||
def _collect_summaries_aspect_impl(target, ctx):
|
||||
results = depset(target.angular.summaries if hasattr(target, "angular") else [])
|
||||
results = depset(target.angular.summaries if hasattr(target, "angular") else [])
|
||||
|
||||
# If we are visiting empty-srcs ts_library, this is a re-export
|
||||
srcs = ctx.rule.attr.srcs if hasattr(ctx.rule.attr, "srcs") else []
|
||||
# If we are visiting empty-srcs ts_library, this is a re-export
|
||||
srcs = ctx.rule.attr.srcs if hasattr(ctx.rule.attr, "srcs") else []
|
||||
|
||||
# "re-export" rules should expose all the files of their deps
|
||||
if not srcs and hasattr(ctx.rule.attr, "deps"):
|
||||
for dep in ctx.rule.attr.deps:
|
||||
if (hasattr(dep, "angular")):
|
||||
results = depset(dep.angular.summaries, transitive = [results])
|
||||
# "re-export" rules should expose all the files of their deps
|
||||
if not srcs and hasattr(ctx.rule.attr, "deps"):
|
||||
for dep in ctx.rule.attr.deps:
|
||||
if (hasattr(dep, "angular")):
|
||||
results = depset(dep.angular.summaries, transitive = [results])
|
||||
|
||||
return struct(collect_summaries_aspect_result = results)
|
||||
return struct(collect_summaries_aspect_result = results)
|
||||
|
||||
_collect_summaries_aspect = aspect(
|
||||
implementation = _collect_summaries_aspect_impl,
|
||||
|
@ -278,177 +280,197 @@ _collect_summaries_aspect = aspect(
|
|||
# Extra options passed to Node when running ngc.
|
||||
_EXTRA_NODE_OPTIONS_FLAGS = [
|
||||
# Expose the v8 garbage collection API to JS.
|
||||
"--node_options=--expose-gc"
|
||||
"--node_options=--expose-gc",
|
||||
]
|
||||
|
||||
def ngc_compile_action(ctx, label, inputs, outputs, messages_out, tsconfig_file,
|
||||
node_opts, locale=None, i18n_args=[]):
|
||||
"""Helper function to create the ngc action.
|
||||
def ngc_compile_action(
|
||||
ctx,
|
||||
label,
|
||||
inputs,
|
||||
outputs,
|
||||
messages_out,
|
||||
tsconfig_file,
|
||||
node_opts,
|
||||
locale = None,
|
||||
i18n_args = []):
|
||||
"""Helper function to create the ngc action.
|
||||
|
||||
This is exposed for google3 to wire up i18n replay rules, and is not intended
|
||||
as part of the public API.
|
||||
This is exposed for google3 to wire up i18n replay rules, and is not intended
|
||||
as part of the public API.
|
||||
|
||||
Args:
|
||||
ctx: skylark context
|
||||
label: the label of the ng_module being compiled
|
||||
inputs: passed to the ngc action's inputs
|
||||
outputs: passed to the ngc action's outputs
|
||||
messages_out: produced xmb files
|
||||
tsconfig_file: tsconfig file with settings used for the compilation
|
||||
node_opts: list of strings, extra nodejs options.
|
||||
locale: i18n locale, or None
|
||||
i18n_args: additional command-line arguments to ngc
|
||||
Args:
|
||||
ctx: skylark context
|
||||
label: the label of the ng_module being compiled
|
||||
inputs: passed to the ngc action's inputs
|
||||
outputs: passed to the ngc action's outputs
|
||||
messages_out: produced xmb files
|
||||
tsconfig_file: tsconfig file with settings used for the compilation
|
||||
node_opts: list of strings, extra nodejs options.
|
||||
locale: i18n locale, or None
|
||||
i18n_args: additional command-line arguments to ngc
|
||||
|
||||
Returns:
|
||||
the parameters of the compilation which will be used to replay the ngc action for i18N.
|
||||
"""
|
||||
Returns:
|
||||
the parameters of the compilation which will be used to replay the ngc action for i18N.
|
||||
"""
|
||||
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
|
||||
mnemonic = "AngularTemplateCompile"
|
||||
progress_message = "Compiling Angular templates (%s) %s" % (_compiler_name(ctx), label)
|
||||
mnemonic = "AngularTemplateCompile"
|
||||
progress_message = "Compiling Angular templates (%s) %s" % (_compiler_name(ctx), label)
|
||||
|
||||
if locale:
|
||||
mnemonic = "AngularI18NMerging"
|
||||
supports_workers = "0"
|
||||
progress_message = ("Recompiling Angular templates (ngc) %s for locale %s" %
|
||||
(label, locale))
|
||||
else:
|
||||
supports_workers = str(int(ctx.attr._supports_workers))
|
||||
if locale:
|
||||
mnemonic = "AngularI18NMerging"
|
||||
supports_workers = "0"
|
||||
progress_message = ("Recompiling Angular templates (ngc) %s for locale %s" %
|
||||
(label, locale))
|
||||
else:
|
||||
supports_workers = str(int(ctx.attr._supports_workers))
|
||||
|
||||
arguments = (list(_EXTRA_NODE_OPTIONS_FLAGS) +
|
||||
["--node_options=%s" % opt for opt in node_opts])
|
||||
# One at-sign makes this a params-file, enabling the worker strategy.
|
||||
# Two at-signs escapes the argument so it's passed through to ngc
|
||||
# rather than the contents getting expanded.
|
||||
if supports_workers == "1":
|
||||
arguments += ["@@" + tsconfig_file.path]
|
||||
else:
|
||||
arguments += ["-p", tsconfig_file.path]
|
||||
arguments = (list(_EXTRA_NODE_OPTIONS_FLAGS) +
|
||||
["--node_options=%s" % opt for opt in node_opts])
|
||||
|
||||
arguments += i18n_args
|
||||
# One at-sign makes this a params-file, enabling the worker strategy.
|
||||
# Two at-signs escapes the argument so it's passed through to ngc
|
||||
# rather than the contents getting expanded.
|
||||
if supports_workers == "1":
|
||||
arguments += ["@@" + tsconfig_file.path]
|
||||
else:
|
||||
arguments += ["-p", tsconfig_file.path]
|
||||
|
||||
ctx.actions.run(
|
||||
progress_message = progress_message,
|
||||
mnemonic = mnemonic,
|
||||
inputs = inputs,
|
||||
outputs = outputs,
|
||||
arguments = arguments,
|
||||
executable = ctx.executable.compiler,
|
||||
execution_requirements = {
|
||||
"supports-workers": supports_workers,
|
||||
},
|
||||
)
|
||||
arguments += i18n_args
|
||||
|
||||
if include_ng_files and messages_out != None:
|
||||
ctx.actions.run(
|
||||
inputs = list(inputs),
|
||||
outputs = messages_out,
|
||||
executable = ctx.executable._ng_xi18n,
|
||||
arguments = (_EXTRA_NODE_OPTIONS_FLAGS +
|
||||
[tsconfig_file.path] +
|
||||
# The base path is bin_dir because of the way the ngc
|
||||
# compiler host is configured. So we need to explicitly
|
||||
# point to genfiles/ to redirect the output.
|
||||
["../genfiles/" + messages_out[0].short_path]),
|
||||
progress_message = "Extracting Angular 2 messages (ng_xi18n)",
|
||||
mnemonic = "Angular2MessageExtractor")
|
||||
|
||||
if not locale and not ctx.attr.no_i18n:
|
||||
return struct(
|
||||
label = label,
|
||||
tsconfig = tsconfig_file,
|
||||
progress_message = progress_message,
|
||||
mnemonic = mnemonic,
|
||||
inputs = inputs,
|
||||
outputs = outputs,
|
||||
compiler = ctx.executable.compiler,
|
||||
arguments = arguments,
|
||||
executable = ctx.executable.compiler,
|
||||
execution_requirements = {
|
||||
"supports-workers": supports_workers,
|
||||
},
|
||||
)
|
||||
|
||||
return None
|
||||
if include_ng_files and messages_out != None:
|
||||
ctx.actions.run(
|
||||
inputs = list(inputs),
|
||||
outputs = messages_out,
|
||||
executable = ctx.executable._ng_xi18n,
|
||||
arguments = (_EXTRA_NODE_OPTIONS_FLAGS +
|
||||
[tsconfig_file.path] +
|
||||
# The base path is bin_dir because of the way the ngc
|
||||
# compiler host is configured. So we need to explicitly
|
||||
# point to genfiles/ to redirect the output.
|
||||
["../genfiles/" + messages_out[0].short_path]),
|
||||
progress_message = "Extracting Angular 2 messages (ng_xi18n)",
|
||||
mnemonic = "Angular2MessageExtractor",
|
||||
)
|
||||
|
||||
if not locale and not ctx.attr.no_i18n:
|
||||
return struct(
|
||||
label = label,
|
||||
tsconfig = tsconfig_file,
|
||||
inputs = inputs,
|
||||
outputs = outputs,
|
||||
compiler = ctx.executable.compiler,
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def _compile_action(ctx, inputs, outputs, messages_out, tsconfig_file, node_opts):
|
||||
# Give the Angular compiler all the user-listed assets
|
||||
file_inputs = list(ctx.files.assets)
|
||||
# Give the Angular compiler all the user-listed assets
|
||||
file_inputs = list(ctx.files.assets)
|
||||
|
||||
# The compiler only needs to see TypeScript sources from the npm dependencies,
|
||||
# but may need to look at package.json and ngsummary.json files as well.
|
||||
if hasattr(ctx.attr, "node_modules"):
|
||||
file_inputs += [f for f in ctx.files.node_modules
|
||||
if f.path.endswith(".ts") or f.path.endswith(".json")]
|
||||
# The compiler only needs to see TypeScript sources from the npm dependencies,
|
||||
# but may need to look at package.json and ngsummary.json files as well.
|
||||
if hasattr(ctx.attr, "node_modules"):
|
||||
file_inputs += [
|
||||
f
|
||||
for f in ctx.files.node_modules
|
||||
if f.path.endswith(".ts") or f.path.endswith(".json")
|
||||
]
|
||||
|
||||
# If the user supplies a tsconfig.json file, the Angular compiler needs to read it
|
||||
if hasattr(ctx.attr, "tsconfig") and ctx.file.tsconfig:
|
||||
file_inputs.append(ctx.file.tsconfig)
|
||||
# If the user supplies a tsconfig.json file, the Angular compiler needs to read it
|
||||
if hasattr(ctx.attr, "tsconfig") and ctx.file.tsconfig:
|
||||
file_inputs.append(ctx.file.tsconfig)
|
||||
|
||||
# Collect the inputs and summary files from our deps
|
||||
action_inputs = depset(file_inputs,
|
||||
transitive = [inputs] + [dep.collect_summaries_aspect_result for dep in ctx.attr.deps
|
||||
if hasattr(dep, "collect_summaries_aspect_result")])
|
||||
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts)
|
||||
|
||||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js, outs.i18n_messages, tsconfig_file, node_opts)
|
||||
|
||||
def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
_compile_action(ctx, inputs, compile_action_outputs, None, tsconfig_file, node_opts)
|
||||
|
||||
def _ts_expected_outs(ctx, label):
|
||||
# rules_typescript expects a function with two arguments, but our
|
||||
# implementation doesn't use the label
|
||||
_ignored = [label]
|
||||
return _expected_outs(ctx)
|
||||
|
||||
def ng_module_impl(ctx, ts_compile_actions):
|
||||
"""Implementation function for the ng_module rule.
|
||||
|
||||
This is exposed so that google3 can have its own entry point that re-uses this
|
||||
and is not meant as a public API.
|
||||
|
||||
Args:
|
||||
ctx: the skylark rule context
|
||||
ts_compile_actions: generates all the actions to run an ngc compilation
|
||||
|
||||
Returns:
|
||||
the result of the ng_module rule as a dict, suitable for
|
||||
conversion by ts_providers_dict_to_struct
|
||||
"""
|
||||
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
|
||||
providers = ts_compile_actions(
|
||||
ctx, is_library=True, compile_action=_prodmode_compile_action,
|
||||
devmode_compile_action=_devmode_compile_action,
|
||||
tsc_wrapped_tsconfig=_ngc_tsconfig,
|
||||
outputs = _ts_expected_outs)
|
||||
|
||||
outs = _expected_outs(ctx)
|
||||
|
||||
if include_ng_files:
|
||||
providers["angular"] = {
|
||||
"summaries": outs.summaries,
|
||||
"metadata": outs.metadata
|
||||
}
|
||||
providers["ngc_messages"] = outs.i18n_messages
|
||||
|
||||
if include_ng_files and _should_produce_flat_module_outs(ctx):
|
||||
if len(outs.metadata) > 1:
|
||||
fail("expecting exactly one metadata output for " + str(ctx.label))
|
||||
|
||||
providers["angular"]["flat_module_metadata"] = struct(
|
||||
module_name = ctx.attr.module_name,
|
||||
metadata_file = outs.metadata[0],
|
||||
typings_file = outs.bundle_index_typings,
|
||||
flat_module_out_file = _flat_module_out_file(ctx),
|
||||
# Collect the inputs and summary files from our deps
|
||||
action_inputs = depset(
|
||||
file_inputs,
|
||||
transitive = [inputs] + [
|
||||
dep.collect_summaries_aspect_result
|
||||
for dep in ctx.attr.deps
|
||||
if hasattr(dep, "collect_summaries_aspect_result")
|
||||
],
|
||||
)
|
||||
|
||||
return providers
|
||||
return ngc_compile_action(ctx, ctx.label, action_inputs, outputs, messages_out, tsconfig_file, node_opts)
|
||||
|
||||
def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
return _compile_action(ctx, inputs, outputs + outs.closure_js, outs.i18n_messages, tsconfig_file, node_opts)
|
||||
|
||||
def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts):
|
||||
outs = _expected_outs(ctx)
|
||||
compile_action_outputs = outputs + outs.devmode_js + outs.declarations + outs.summaries + outs.metadata
|
||||
_compile_action(ctx, inputs, compile_action_outputs, None, tsconfig_file, node_opts)
|
||||
|
||||
def _ts_expected_outs(ctx, label):
|
||||
# rules_typescript expects a function with two arguments, but our
|
||||
# implementation doesn't use the label
|
||||
_ignored = [label]
|
||||
return _expected_outs(ctx)
|
||||
|
||||
def ng_module_impl(ctx, ts_compile_actions):
|
||||
"""Implementation function for the ng_module rule.
|
||||
|
||||
This is exposed so that google3 can have its own entry point that re-uses this
|
||||
and is not meant as a public API.
|
||||
|
||||
Args:
|
||||
ctx: the skylark rule context
|
||||
ts_compile_actions: generates all the actions to run an ngc compilation
|
||||
|
||||
Returns:
|
||||
the result of the ng_module rule as a dict, suitable for
|
||||
conversion by ts_providers_dict_to_struct
|
||||
"""
|
||||
|
||||
include_ng_files = _include_ng_files(ctx)
|
||||
|
||||
providers = ts_compile_actions(
|
||||
ctx,
|
||||
is_library = True,
|
||||
compile_action = _prodmode_compile_action,
|
||||
devmode_compile_action = _devmode_compile_action,
|
||||
tsc_wrapped_tsconfig = _ngc_tsconfig,
|
||||
outputs = _ts_expected_outs,
|
||||
)
|
||||
|
||||
outs = _expected_outs(ctx)
|
||||
|
||||
if include_ng_files:
|
||||
providers["angular"] = {
|
||||
"summaries": outs.summaries,
|
||||
"metadata": outs.metadata,
|
||||
}
|
||||
providers["ngc_messages"] = outs.i18n_messages
|
||||
|
||||
if include_ng_files and _should_produce_flat_module_outs(ctx):
|
||||
if len(outs.metadata) > 1:
|
||||
fail("expecting exactly one metadata output for " + str(ctx.label))
|
||||
|
||||
providers["angular"]["flat_module_metadata"] = struct(
|
||||
module_name = ctx.attr.module_name,
|
||||
metadata_file = outs.metadata[0],
|
||||
typings_file = outs.bundle_index_typings,
|
||||
flat_module_out_file = _flat_module_out_file(ctx),
|
||||
)
|
||||
|
||||
return providers
|
||||
|
||||
def _ng_module_impl(ctx):
|
||||
return ts_providers_dict_to_struct(ng_module_impl(ctx, compile_ts))
|
||||
return ts_providers_dict_to_struct(ng_module_impl(ctx, compile_ts))
|
||||
|
||||
NG_MODULE_ATTRIBUTES = {
|
||||
"srcs": attr.label_list(allow_files = [".ts"]),
|
||||
|
@ -457,9 +479,8 @@ NG_MODULE_ATTRIBUTES = {
|
|||
# https://github.com/bazelbuild/skydoc/issues/21
|
||||
"deps": attr.label_list(
|
||||
doc = "Targets that are imported by this target",
|
||||
aspects = list(DEPS_ASPECTS) + [_collect_summaries_aspect]
|
||||
aspects = list(DEPS_ASPECTS) + [_collect_summaries_aspect],
|
||||
),
|
||||
|
||||
"assets": attr.label_list(
|
||||
doc = ".html and .css files needed by the Angular compiler",
|
||||
allow_files = [
|
||||
|
@ -468,31 +489,24 @@ NG_MODULE_ATTRIBUTES = {
|
|||
".html",
|
||||
],
|
||||
),
|
||||
|
||||
"factories": attr.label_list(
|
||||
allow_files = [".ts", ".html"],
|
||||
mandatory = False),
|
||||
|
||||
mandatory = False,
|
||||
),
|
||||
"filter_summaries": attr.bool(default = False),
|
||||
|
||||
"type_check": attr.bool(default = True),
|
||||
|
||||
"inline_resources": attr.bool(default = True),
|
||||
|
||||
"no_i18n": attr.bool(default = False),
|
||||
|
||||
"compiler": attr.label(
|
||||
default = Label("//packages/bazel/src/ngc-wrapped"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
|
||||
"_ng_xi18n": attr.label(
|
||||
default = Label("//packages/bazel/src/ngc-wrapped:xi18n"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
|
||||
"_supports_workers": attr.bool(default = True),
|
||||
}
|
||||
|
||||
|
@ -503,9 +517,8 @@ NG_MODULE_RULE_ATTRS = dict(dict(COMMON_ATTRIBUTES, **NG_MODULE_ATTRIBUTES), **{
|
|||
# The default assumes the user specified a target "node_modules" in their
|
||||
# root BUILD file.
|
||||
"node_modules": attr.label(
|
||||
default = Label("@//:node_modules")
|
||||
default = Label("@//:node_modules"),
|
||||
),
|
||||
|
||||
"entry_point": attr.string(),
|
||||
|
||||
# Default is %{name}_public_index
|
||||
|
|
|
@ -14,41 +14,46 @@ specification of this format at https://goo.gl/jB3GVv
|
|||
"""
|
||||
|
||||
load("@build_bazel_rules_nodejs//:internal/collect_es6_sources.bzl", "collect_es6_sources")
|
||||
load("@build_bazel_rules_nodejs//:internal/rollup/rollup_bundle.bzl",
|
||||
"write_rollup_config",
|
||||
"rollup_module_mappings_aspect",
|
||||
"run_uglify",
|
||||
"ROLLUP_ATTRS")
|
||||
load("@build_bazel_rules_nodejs//:internal/npm_package/npm_package.bzl",
|
||||
"NPM_PACKAGE_ATTRS",
|
||||
"NPM_PACKAGE_OUTPUTS",
|
||||
"create_package")
|
||||
load(
|
||||
"@build_bazel_rules_nodejs//:internal/rollup/rollup_bundle.bzl",
|
||||
"ROLLUP_ATTRS",
|
||||
"rollup_module_mappings_aspect",
|
||||
"run_uglify",
|
||||
"write_rollup_config",
|
||||
)
|
||||
load(
|
||||
"@build_bazel_rules_nodejs//:internal/npm_package/npm_package.bzl",
|
||||
"NPM_PACKAGE_ATTRS",
|
||||
"NPM_PACKAGE_OUTPUTS",
|
||||
"create_package",
|
||||
)
|
||||
load("@build_bazel_rules_nodejs//:internal/node.bzl", "sources_aspect")
|
||||
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "flatten_esm5", "esm5_root_dir")
|
||||
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5")
|
||||
|
||||
# Convert from some-dash-case to someCamelCase
|
||||
def _convert_dash_case_to_camel_case(s):
|
||||
parts = s.split("-")
|
||||
# First letter in the result is always unchanged
|
||||
return s[0] + "".join([p.title() for p in parts])[1:]
|
||||
parts = s.split("-")
|
||||
|
||||
# First letter in the result is always unchanged
|
||||
return s[0] + "".join([p.title() for p in parts])[1:]
|
||||
|
||||
# Convert from a package name on npm to an identifier that's a legal global symbol
|
||||
# @angular/core -> ng.core
|
||||
# @angular/platform-browser-dynamic/testing -> ng.platformBrowserDynamic.testing
|
||||
def _global_name(package_name):
|
||||
# strip npm scoped package qualifier
|
||||
start = 1 if package_name.startswith("@") else 0
|
||||
parts = package_name[start:].split("/")
|
||||
result_parts = []
|
||||
for p in parts:
|
||||
# Special case for angular's short name
|
||||
if p == "angular":
|
||||
result_parts.append("ng")
|
||||
else:
|
||||
result_parts.append(_convert_dash_case_to_camel_case(p))
|
||||
return ".".join(result_parts)
|
||||
# strip npm scoped package qualifier
|
||||
start = 1 if package_name.startswith("@") else 0
|
||||
parts = package_name[start:].split("/")
|
||||
result_parts = []
|
||||
for p in parts:
|
||||
# Special case for angular's short name
|
||||
if p == "angular":
|
||||
result_parts.append("ng")
|
||||
else:
|
||||
result_parts.append(_convert_dash_case_to_camel_case(p))
|
||||
return ".".join(result_parts)
|
||||
|
||||
WELL_KNOWN_GLOBALS = { p: _global_name(p) for p in [
|
||||
WELL_KNOWN_GLOBALS = {p: _global_name(p) for p in [
|
||||
"@angular/upgrade",
|
||||
"@angular/upgrade/static",
|
||||
"@angular/forms",
|
||||
|
@ -85,242 +90,259 @@ WELL_KNOWN_GLOBALS = { p: _global_name(p) for p in [
|
|||
]}
|
||||
|
||||
def _rollup(ctx, bundle_name, rollup_config, entry_point, inputs, js_output, format = "es", package_name = "", include_tslib = False):
|
||||
map_output = ctx.actions.declare_file(js_output.basename + ".map", sibling = js_output)
|
||||
map_output = ctx.actions.declare_file(js_output.basename + ".map", sibling = js_output)
|
||||
|
||||
args = ctx.actions.args()
|
||||
args.add("--config", rollup_config)
|
||||
args = ctx.actions.args()
|
||||
args.add("--config", rollup_config)
|
||||
|
||||
args.add("--input", entry_point)
|
||||
args.add("--output.file", js_output)
|
||||
args.add("--output.format", format)
|
||||
if package_name:
|
||||
args.add("--output.name", _global_name(package_name))
|
||||
args.add("--amd.id", package_name)
|
||||
args.add("--input", entry_point)
|
||||
args.add("--output.file", js_output)
|
||||
args.add("--output.format", format)
|
||||
if package_name:
|
||||
args.add("--output.name", _global_name(package_name))
|
||||
args.add("--amd.id", package_name)
|
||||
|
||||
# Note: if the input has external source maps then we need to also install and use
|
||||
# `rollup-plugin-sourcemaps`, which will require us to use rollup.config.js file instead
|
||||
# of command line args
|
||||
args.add("--sourcemap")
|
||||
# Note: if the input has external source maps then we need to also install and use
|
||||
# `rollup-plugin-sourcemaps`, which will require us to use rollup.config.js file instead
|
||||
# of command line args
|
||||
args.add("--sourcemap")
|
||||
|
||||
globals = dict(WELL_KNOWN_GLOBALS, **ctx.attr.globals)
|
||||
external = globals.keys()
|
||||
if not include_tslib:
|
||||
external.append("tslib")
|
||||
args.add_joined("--external", external, join_with=",")
|
||||
globals = dict(WELL_KNOWN_GLOBALS, **ctx.attr.globals)
|
||||
external = globals.keys()
|
||||
if not include_tslib:
|
||||
external.append("tslib")
|
||||
args.add_joined("--external", external, join_with = ",")
|
||||
|
||||
args.add_joined(
|
||||
"--globals",
|
||||
["%s:%s" % g for g in globals.items()],
|
||||
join_with=",")
|
||||
args.add_joined(
|
||||
"--globals",
|
||||
["%s:%s" % g for g in globals.items()],
|
||||
join_with = ",",
|
||||
)
|
||||
|
||||
args.add("--silent")
|
||||
args.add("--silent")
|
||||
|
||||
other_inputs = [ctx.executable._rollup, rollup_config]
|
||||
if ctx.file.license_banner:
|
||||
other_inputs.append(ctx.file.license_banner)
|
||||
if ctx.version_file:
|
||||
other_inputs.append(ctx.version_file)
|
||||
ctx.actions.run(
|
||||
progress_message = "ng_package: Rollup %s %s" % (bundle_name, ctx.label),
|
||||
mnemonic = "AngularPackageRollup",
|
||||
inputs = inputs.to_list() + other_inputs,
|
||||
outputs = [js_output, map_output],
|
||||
executable = ctx.executable._rollup,
|
||||
arguments = [args],
|
||||
)
|
||||
return struct(
|
||||
js = js_output,
|
||||
map = map_output,
|
||||
)
|
||||
other_inputs = [ctx.executable._rollup, rollup_config]
|
||||
if ctx.file.license_banner:
|
||||
other_inputs.append(ctx.file.license_banner)
|
||||
if ctx.version_file:
|
||||
other_inputs.append(ctx.version_file)
|
||||
ctx.actions.run(
|
||||
progress_message = "ng_package: Rollup %s %s" % (bundle_name, ctx.label),
|
||||
mnemonic = "AngularPackageRollup",
|
||||
inputs = inputs.to_list() + other_inputs,
|
||||
outputs = [js_output, map_output],
|
||||
executable = ctx.executable._rollup,
|
||||
arguments = [args],
|
||||
)
|
||||
return struct(
|
||||
js = js_output,
|
||||
map = map_output,
|
||||
)
|
||||
|
||||
# convert from [{js: js_file1, map: map_file1}, ...] to
|
||||
# [js_filepath1, map_filepath1, ...]
|
||||
def _flatten_paths(directory):
|
||||
result = []
|
||||
for f in directory:
|
||||
result.append(f.js.path)
|
||||
if f.map:
|
||||
result.append(f.map.path)
|
||||
return result
|
||||
|
||||
result = []
|
||||
for f in directory:
|
||||
result.append(f.js.path)
|
||||
if f.map:
|
||||
result.append(f.map.path)
|
||||
return result
|
||||
|
||||
# takes an depset of files and returns an array that doesn't contain any generated files by ngc
|
||||
def _filter_out_generated_files(files):
|
||||
result = []
|
||||
for file in files:
|
||||
if (not(file.path.endswith(".ngfactory.js") or file.path.endswith(".ngsummary.js") or file.path.endswith(".ngstyle.js"))):
|
||||
result.append(file)
|
||||
return depset(result)
|
||||
|
||||
result = []
|
||||
for file in files:
|
||||
if (not (file.path.endswith(".ngfactory.js") or file.path.endswith(".ngsummary.js") or file.path.endswith(".ngstyle.js"))):
|
||||
result.append(file)
|
||||
return depset(result)
|
||||
|
||||
def _esm2015_root_dir(ctx):
|
||||
return ctx.label.name + ".es6"
|
||||
|
||||
return ctx.label.name + ".es6"
|
||||
|
||||
# ng_package produces package that is npm-ready.
|
||||
def _ng_package_impl(ctx):
|
||||
npm_package_directory = ctx.actions.declare_directory("%s.ng_pkg" % ctx.label.name)
|
||||
npm_package_directory = ctx.actions.declare_directory("%s.ng_pkg" % ctx.label.name)
|
||||
|
||||
esm_2015_files = _filter_out_generated_files(collect_es6_sources(ctx))
|
||||
esm5_sources = _filter_out_generated_files(flatten_esm5(ctx))
|
||||
esm_2015_files = _filter_out_generated_files(collect_es6_sources(ctx))
|
||||
esm5_sources = _filter_out_generated_files(flatten_esm5(ctx))
|
||||
|
||||
# These accumulators match the directory names where the files live in the
|
||||
# Angular package format.
|
||||
fesm2015 = []
|
||||
fesm5 = []
|
||||
esm2015 = []
|
||||
esm5 = []
|
||||
bundles = []
|
||||
# These accumulators match the directory names where the files live in the
|
||||
# Angular package format.
|
||||
fesm2015 = []
|
||||
fesm5 = []
|
||||
esm2015 = []
|
||||
esm5 = []
|
||||
bundles = []
|
||||
|
||||
# For Angular Package Format v6, we put all the individual .js files in the
|
||||
# esm5/ and esm2015/ folders.
|
||||
for f in esm5_sources.to_list():
|
||||
if f.path.endswith(".js"):
|
||||
esm5.append(struct(js = f, map = None))
|
||||
for f in esm_2015_files.to_list():
|
||||
if f.path.endswith(".js"):
|
||||
esm2015.append(struct(js = f, map = None))
|
||||
# For Angular Package Format v6, we put all the individual .js files in the
|
||||
# esm5/ and esm2015/ folders.
|
||||
for f in esm5_sources.to_list():
|
||||
if f.path.endswith(".js"):
|
||||
esm5.append(struct(js = f, map = None))
|
||||
for f in esm_2015_files.to_list():
|
||||
if f.path.endswith(".js"):
|
||||
esm2015.append(struct(js = f, map = None))
|
||||
|
||||
# We infer the entry points to be:
|
||||
# - ng_module rules in the deps (they have an "angular" provider)
|
||||
# - in this package or a subpackage
|
||||
# - those that have a module_name attribute (they produce flat module metadata)
|
||||
flat_module_metadata = []
|
||||
# Name given in the package.json name field, eg. @angular/core/testing
|
||||
package_name = ""
|
||||
deps_in_package = [d for d in ctx.attr.deps if d.label.package.startswith(ctx.label.package)]
|
||||
for dep in deps_in_package:
|
||||
# Intentionally evaluates to empty string for the main entry point
|
||||
entry_point = dep.label.package[len(ctx.label.package) + 1:]
|
||||
if hasattr(dep, "module_name"):
|
||||
package_name = dep.module_name
|
||||
if hasattr(dep, "angular") and hasattr(dep.angular, "flat_module_metadata"):
|
||||
flat_module_metadata.append(dep.angular.flat_module_metadata)
|
||||
flat_module_out_file = dep.angular.flat_module_metadata.flat_module_out_file + ".js"
|
||||
# We infer the entry points to be:
|
||||
# - ng_module rules in the deps (they have an "angular" provider)
|
||||
# - in this package or a subpackage
|
||||
# - those that have a module_name attribute (they produce flat module metadata)
|
||||
flat_module_metadata = []
|
||||
|
||||
# Name given in the package.json name field, eg. @angular/core/testing
|
||||
package_name = ""
|
||||
deps_in_package = [d for d in ctx.attr.deps if d.label.package.startswith(ctx.label.package)]
|
||||
for dep in deps_in_package:
|
||||
# Intentionally evaluates to empty string for the main entry point
|
||||
entry_point = dep.label.package[len(ctx.label.package) + 1:]
|
||||
if hasattr(dep, "module_name"):
|
||||
package_name = dep.module_name
|
||||
if hasattr(dep, "angular") and hasattr(dep.angular, "flat_module_metadata"):
|
||||
flat_module_metadata.append(dep.angular.flat_module_metadata)
|
||||
flat_module_out_file = dep.angular.flat_module_metadata.flat_module_out_file + ".js"
|
||||
else:
|
||||
# fallback to a reasonable default
|
||||
flat_module_out_file = "index.js"
|
||||
|
||||
es2015_entry_point = "/".join([p for p in [
|
||||
ctx.bin_dir.path,
|
||||
ctx.label.package,
|
||||
_esm2015_root_dir(ctx),
|
||||
ctx.label.package,
|
||||
entry_point,
|
||||
flat_module_out_file,
|
||||
] if p])
|
||||
|
||||
es5_entry_point = "/".join([p for p in [
|
||||
ctx.label.package,
|
||||
entry_point,
|
||||
flat_module_out_file,
|
||||
] if p])
|
||||
|
||||
if entry_point:
|
||||
# TODO jasonaden says there is no particular reason these filenames differ
|
||||
prefix = primary_entry_point_name(ctx.attr.name, ctx.attr.entry_point, ctx.attr.entry_point_name)
|
||||
umd_output_filename = "-".join([prefix] + entry_point.split("/"))
|
||||
fesm_output_filename = entry_point.replace("/", "__")
|
||||
fesm2015_output = ctx.actions.declare_file("fesm2015/%s.js" % fesm_output_filename)
|
||||
fesm5_output = ctx.actions.declare_file("%s.js" % fesm_output_filename)
|
||||
umd_output = ctx.actions.declare_file("%s.umd.js" % umd_output_filename)
|
||||
min_output = ctx.actions.declare_file("%s.umd.min.js" % umd_output_filename)
|
||||
else:
|
||||
fesm2015_output = ctx.outputs.fesm2015
|
||||
fesm5_output = ctx.outputs.fesm5
|
||||
umd_output = ctx.outputs.umd
|
||||
min_output = ctx.outputs.umd_min
|
||||
|
||||
esm2015_config = write_rollup_config(ctx, [], "/".join([ctx.bin_dir.path, ctx.label.package, _esm2015_root_dir(ctx)]), filename = "_%s.rollup_esm2015.conf.js")
|
||||
esm5_config = write_rollup_config(ctx, [], "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]), filename = "_%s.rollup_esm5.conf.js")
|
||||
|
||||
fesm2015.append(_rollup(ctx, "fesm2015", esm2015_config, es2015_entry_point, esm_2015_files + ctx.files.node_modules, fesm2015_output))
|
||||
fesm5.append(_rollup(ctx, "fesm5", esm5_config, es5_entry_point, esm5_sources + ctx.files.node_modules, fesm5_output))
|
||||
|
||||
bundles.append(
|
||||
_rollup(
|
||||
ctx,
|
||||
"umd",
|
||||
esm5_config,
|
||||
es5_entry_point,
|
||||
esm5_sources + ctx.files.node_modules,
|
||||
umd_output,
|
||||
format = "umd",
|
||||
package_name = package_name,
|
||||
include_tslib = True,
|
||||
),
|
||||
)
|
||||
uglify_sourcemap = run_uglify(
|
||||
ctx,
|
||||
umd_output,
|
||||
min_output,
|
||||
config_name = entry_point.replace("/", "_"),
|
||||
)
|
||||
bundles.append(struct(js = min_output, map = uglify_sourcemap))
|
||||
|
||||
packager_inputs = (
|
||||
ctx.files.srcs +
|
||||
ctx.files.data +
|
||||
esm5_sources.to_list() +
|
||||
depset(transitive = [
|
||||
d.typescript.transitive_declarations
|
||||
for d in ctx.attr.deps
|
||||
if hasattr(d, "typescript")
|
||||
]).to_list() +
|
||||
[f.js for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles] +
|
||||
[f.map for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles if f.map]
|
||||
)
|
||||
|
||||
packager_args = ctx.actions.args()
|
||||
packager_args.use_param_file("%s", use_always = True)
|
||||
|
||||
# The order of arguments matters here, as they are read in order in packager.ts.
|
||||
packager_args.add(npm_package_directory.path)
|
||||
packager_args.add(ctx.label.package)
|
||||
packager_args.add_joined([ctx.bin_dir.path, ctx.label.package], join_with = "/")
|
||||
packager_args.add_joined([ctx.genfiles_dir.path, ctx.label.package], join_with = "/")
|
||||
|
||||
# Marshal the metadata into a JSON string so we can parse the data structure
|
||||
# in the TypeScript program easily.
|
||||
metadata_arg = {}
|
||||
for m in flat_module_metadata:
|
||||
packager_inputs.extend([m.metadata_file])
|
||||
metadata_arg[m.module_name] = {
|
||||
"index": m.typings_file.path.replace(".d.ts", ".js"),
|
||||
"typings": m.typings_file.path,
|
||||
"metadata": m.metadata_file.path,
|
||||
}
|
||||
packager_args.add(str(metadata_arg))
|
||||
|
||||
if ctx.file.readme_md:
|
||||
packager_inputs.append(ctx.file.readme_md)
|
||||
packager_args.add(ctx.file.readme_md.path)
|
||||
else:
|
||||
# fallback to a reasonable default
|
||||
flat_module_out_file = "index.js"
|
||||
# placeholder
|
||||
packager_args.add("")
|
||||
|
||||
es2015_entry_point = "/".join([p for p in [
|
||||
ctx.bin_dir.path,
|
||||
ctx.label.package,
|
||||
_esm2015_root_dir(ctx),
|
||||
ctx.label.package,
|
||||
entry_point,
|
||||
flat_module_out_file,
|
||||
] if p])
|
||||
packager_args.add_joined(_flatten_paths(fesm2015), join_with = ",")
|
||||
packager_args.add_joined(_flatten_paths(fesm5), join_with = ",")
|
||||
packager_args.add_joined(_flatten_paths(esm2015), join_with = ",")
|
||||
packager_args.add_joined(_flatten_paths(esm5), join_with = ",")
|
||||
packager_args.add_joined(_flatten_paths(bundles), join_with = ",")
|
||||
packager_args.add_joined([s.path for s in ctx.files.srcs], join_with = ",")
|
||||
|
||||
es5_entry_point = "/".join([p for p in [
|
||||
ctx.label.package,
|
||||
entry_point,
|
||||
flat_module_out_file,
|
||||
] if p])
|
||||
# TODO: figure out a better way to gather runfiles providers from the transitive closure.
|
||||
packager_args.add_joined([d.path for d in ctx.files.data], join_with = ",")
|
||||
|
||||
if entry_point:
|
||||
# TODO jasonaden says there is no particular reason these filenames differ
|
||||
prefix = primary_entry_point_name(ctx.attr.name, ctx.attr.entry_point, ctx.attr.entry_point_name)
|
||||
umd_output_filename = "-".join([prefix] + entry_point.split("/"))
|
||||
fesm_output_filename = entry_point.replace("/", "__")
|
||||
fesm2015_output = ctx.actions.declare_file("fesm2015/%s.js" % fesm_output_filename)
|
||||
fesm5_output = ctx.actions.declare_file("%s.js" % fesm_output_filename)
|
||||
umd_output = ctx.actions.declare_file("%s.umd.js" % umd_output_filename)
|
||||
min_output = ctx.actions.declare_file("%s.umd.min.js" % umd_output_filename)
|
||||
if ctx.file.license_banner:
|
||||
packager_inputs.append(ctx.file.license_banner)
|
||||
packager_args.add(ctx.file.license_banner)
|
||||
else:
|
||||
fesm2015_output = ctx.outputs.fesm2015
|
||||
fesm5_output = ctx.outputs.fesm5
|
||||
umd_output = ctx.outputs.umd
|
||||
min_output = ctx.outputs.umd_min
|
||||
# placeholder
|
||||
packager_args.add("")
|
||||
|
||||
esm2015_config = write_rollup_config(ctx, [], "/".join([ctx.bin_dir.path, ctx.label.package, _esm2015_root_dir(ctx)]), filename="_%s.rollup_esm2015.conf.js")
|
||||
esm5_config = write_rollup_config(ctx, [], "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]), filename="_%s.rollup_esm5.conf.js")
|
||||
ctx.actions.run(
|
||||
progress_message = "Angular Packaging: building npm package %s" % str(ctx.label),
|
||||
mnemonic = "AngularPackage",
|
||||
inputs = packager_inputs,
|
||||
outputs = [npm_package_directory],
|
||||
executable = ctx.executable._ng_packager,
|
||||
arguments = [packager_args],
|
||||
)
|
||||
|
||||
fesm2015.append(_rollup(ctx, "fesm2015", esm2015_config, es2015_entry_point, esm_2015_files + ctx.files.node_modules, fesm2015_output))
|
||||
fesm5.append(_rollup(ctx, "fesm5", esm5_config, es5_entry_point, esm5_sources + ctx.files.node_modules, fesm5_output))
|
||||
devfiles = depset()
|
||||
if ctx.attr.include_devmode_srcs:
|
||||
for d in ctx.attr.deps:
|
||||
devfiles = depset(transitive = [devfiles, d.files, d.node_sources])
|
||||
|
||||
bundles.append(
|
||||
_rollup(ctx, "umd", esm5_config, es5_entry_point, esm5_sources + ctx.files.node_modules, umd_output,
|
||||
format = "umd", package_name = package_name, include_tslib = True))
|
||||
uglify_sourcemap = run_uglify(ctx, umd_output, min_output,
|
||||
config_name = entry_point.replace("/", "_"))
|
||||
bundles.append(struct(js = min_output, map = uglify_sourcemap))
|
||||
|
||||
packager_inputs = (
|
||||
ctx.files.srcs +
|
||||
ctx.files.data +
|
||||
esm5_sources.to_list() +
|
||||
depset(transitive = [d.typescript.transitive_declarations
|
||||
for d in ctx.attr.deps
|
||||
if hasattr(d, "typescript")]).to_list() +
|
||||
[f.js for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles] +
|
||||
[f.map for f in fesm2015 + fesm5 + esm2015 + esm5 + bundles if f.map])
|
||||
|
||||
packager_args = ctx.actions.args()
|
||||
packager_args.use_param_file("%s", use_always = True)
|
||||
|
||||
# The order of arguments matters here, as they are read in order in packager.ts.
|
||||
packager_args.add(npm_package_directory.path)
|
||||
packager_args.add(ctx.label.package)
|
||||
packager_args.add_joined([ctx.bin_dir.path, ctx.label.package], join_with="/")
|
||||
packager_args.add_joined([ctx.genfiles_dir.path, ctx.label.package], join_with="/")
|
||||
|
||||
# Marshal the metadata into a JSON string so we can parse the data structure
|
||||
# in the TypeScript program easily.
|
||||
metadata_arg = {}
|
||||
for m in flat_module_metadata:
|
||||
packager_inputs.extend([m.metadata_file])
|
||||
metadata_arg[m.module_name] = {
|
||||
"index": m.typings_file.path.replace(".d.ts", ".js"),
|
||||
"typings": m.typings_file.path,
|
||||
"metadata": m.metadata_file.path,
|
||||
}
|
||||
packager_args.add(str(metadata_arg))
|
||||
|
||||
if ctx.file.readme_md:
|
||||
packager_inputs.append(ctx.file.readme_md)
|
||||
packager_args.add(ctx.file.readme_md.path)
|
||||
else:
|
||||
# placeholder
|
||||
packager_args.add("")
|
||||
|
||||
packager_args.add_joined(_flatten_paths(fesm2015), join_with=",")
|
||||
packager_args.add_joined(_flatten_paths(fesm5), join_with=",")
|
||||
packager_args.add_joined(_flatten_paths(esm2015), join_with=",")
|
||||
packager_args.add_joined(_flatten_paths(esm5), join_with=",")
|
||||
packager_args.add_joined(_flatten_paths(bundles), join_with=",")
|
||||
packager_args.add_joined([s.path for s in ctx.files.srcs], join_with=",")
|
||||
|
||||
# TODO: figure out a better way to gather runfiles providers from the transitive closure.
|
||||
packager_args.add_joined([d.path for d in ctx.files.data], join_with=",")
|
||||
|
||||
if ctx.file.license_banner:
|
||||
packager_inputs.append(ctx.file.license_banner)
|
||||
packager_args.add(ctx.file.license_banner)
|
||||
else:
|
||||
# placeholder
|
||||
packager_args.add("")
|
||||
|
||||
ctx.actions.run(
|
||||
progress_message = "Angular Packaging: building npm package %s" % str(ctx.label),
|
||||
mnemonic = "AngularPackage",
|
||||
inputs = packager_inputs,
|
||||
outputs = [npm_package_directory],
|
||||
executable = ctx.executable._ng_packager,
|
||||
arguments = [packager_args],
|
||||
)
|
||||
|
||||
devfiles = depset()
|
||||
if ctx.attr.include_devmode_srcs:
|
||||
for d in ctx.attr.deps:
|
||||
devfiles = depset(transitive = [devfiles, d.files, d.node_sources])
|
||||
|
||||
# Re-use the create_package function from the nodejs npm_package rule.
|
||||
package_dir = create_package(
|
||||
ctx,
|
||||
devfiles.to_list(),
|
||||
[npm_package_directory] + ctx.files.packages)
|
||||
return [DefaultInfo(
|
||||
files = depset([package_dir])
|
||||
)]
|
||||
# Re-use the create_package function from the nodejs npm_package rule.
|
||||
package_dir = create_package(
|
||||
ctx,
|
||||
devfiles.to_list(),
|
||||
[npm_package_directory] + ctx.files.packages,
|
||||
)
|
||||
return [DefaultInfo(
|
||||
files = depset([package_dir]),
|
||||
)]
|
||||
|
||||
NG_PACKAGE_ATTRS = dict(NPM_PACKAGE_ATTRS, **dict(ROLLUP_ATTRS, **{
|
||||
"srcs": attr.label_list(allow_files = True),
|
||||
|
@ -335,22 +357,29 @@ NG_PACKAGE_ATTRS = dict(NPM_PACKAGE_ATTRS, **dict(ROLLUP_ATTRS, **{
|
|||
),
|
||||
"include_devmode_srcs": attr.bool(default = False),
|
||||
"readme_md": attr.label(allow_single_file = FileType([".md"])),
|
||||
"globals": attr.string_dict(default={}),
|
||||
"globals": attr.string_dict(default = {}),
|
||||
"entry_point_name": attr.string(
|
||||
doc = "Name to use when generating bundle files for the primary entry-point.",
|
||||
doc = "Name to use when generating bundle files for the primary entry-point.",
|
||||
),
|
||||
"_ng_packager": attr.label(
|
||||
default=Label("//packages/bazel/src/ng_package:packager"),
|
||||
executable=True, cfg="host"),
|
||||
default = Label("//packages/bazel/src/ng_package:packager"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
"_rollup": attr.label(
|
||||
default=Label("@build_bazel_rules_nodejs//internal/rollup"),
|
||||
executable=True, cfg="host"),
|
||||
default = Label("@build_bazel_rules_nodejs//internal/rollup"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
"_rollup_config_tmpl": attr.label(
|
||||
default=Label("@build_bazel_rules_nodejs//internal/rollup:rollup.config.js"),
|
||||
allow_single_file=True),
|
||||
default = Label("@build_bazel_rules_nodejs//internal/rollup:rollup.config.js"),
|
||||
allow_single_file = True,
|
||||
),
|
||||
"_uglify": attr.label(
|
||||
default=Label("@build_bazel_rules_nodejs//internal/rollup:uglify"),
|
||||
executable=True, cfg="host"),
|
||||
default = Label("@build_bazel_rules_nodejs//internal/rollup:uglify"),
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
),
|
||||
}))
|
||||
|
||||
# Angular wants these named after the entry_point,
|
||||
|
@ -360,57 +389,57 @@ NG_PACKAGE_ATTRS = dict(NPM_PACKAGE_ATTRS, **dict(ROLLUP_ATTRS, **{
|
|||
# some/path/to/my/package/index.js
|
||||
# we assume the files should be named "package.*.js"
|
||||
def primary_entry_point_name(name, entry_point, entry_point_name):
|
||||
"""This is not a public API.
|
||||
"""This is not a public API.
|
||||
|
||||
Compute the name of the primary entry point in the library.
|
||||
Compute the name of the primary entry point in the library.
|
||||
|
||||
Args:
|
||||
name: the name of the `ng_package` rule, as a fallback.
|
||||
entry_point: The starting point of the application, see rollup_bundle.
|
||||
entry_point_name: if set, this is the returned value.
|
||||
Args:
|
||||
name: the name of the `ng_package` rule, as a fallback.
|
||||
entry_point: The starting point of the application, see rollup_bundle.
|
||||
entry_point_name: if set, this is the returned value.
|
||||
|
||||
Returns:
|
||||
name of the entry point, which will appear in the name of generated bundles
|
||||
"""
|
||||
if entry_point_name:
|
||||
# If an explicit entry_point_name is given, use that.
|
||||
return entry_point_name
|
||||
elif entry_point.find("/") >= 0:
|
||||
# If the entry_point has multiple path segments, use the second one.
|
||||
# E.g., for "@angular/cdk/a11y", use "cdk".
|
||||
return entry_point.split("/")[-2]
|
||||
else:
|
||||
# Fall back to the name of the ng_package rule.
|
||||
return name
|
||||
Returns:
|
||||
name of the entry point, which will appear in the name of generated bundles
|
||||
"""
|
||||
if entry_point_name:
|
||||
# If an explicit entry_point_name is given, use that.
|
||||
return entry_point_name
|
||||
elif entry_point.find("/") >= 0:
|
||||
# If the entry_point has multiple path segments, use the second one.
|
||||
# E.g., for "@angular/cdk/a11y", use "cdk".
|
||||
return entry_point.split("/")[-2]
|
||||
else:
|
||||
# Fall back to the name of the ng_package rule.
|
||||
return name
|
||||
|
||||
def ng_package_outputs(name, entry_point, entry_point_name):
|
||||
"""This is not a public API.
|
||||
"""This is not a public API.
|
||||
|
||||
This function computes the named outputs for an ng_package rule.
|
||||
This function computes the named outputs for an ng_package rule.
|
||||
|
||||
Args:
|
||||
name: value of the name attribute
|
||||
entry_point: value of the entry_point attribute
|
||||
entry_point_name: value of the entry_point_name attribute
|
||||
Args:
|
||||
name: value of the name attribute
|
||||
entry_point: value of the entry_point attribute
|
||||
entry_point_name: value of the entry_point_name attribute
|
||||
|
||||
Returns:
|
||||
dict of named outputs of the rule
|
||||
"""
|
||||
Returns:
|
||||
dict of named outputs of the rule
|
||||
"""
|
||||
|
||||
basename = primary_entry_point_name(name, entry_point, entry_point_name)
|
||||
outputs = {
|
||||
"fesm5": "fesm5/%s.js" % basename,
|
||||
"fesm2015": "fesm2015/%s.js" % basename,
|
||||
"umd": "%s.umd.js" % basename,
|
||||
"umd_min": "%s.umd.min.js" % basename,
|
||||
}
|
||||
for key in NPM_PACKAGE_OUTPUTS:
|
||||
# NPM_PACKAGE_OUTPUTS is a "normal" dict-valued outputs so it looks like
|
||||
# "pack": "%{name}.pack",
|
||||
# But this is a function-valued outputs.
|
||||
# Bazel won't replace the %{name} token so we have to do it.
|
||||
outputs[key] = NPM_PACKAGE_OUTPUTS[key].replace("%{name}", name)
|
||||
return outputs
|
||||
basename = primary_entry_point_name(name, entry_point, entry_point_name)
|
||||
outputs = {
|
||||
"fesm5": "fesm5/%s.js" % basename,
|
||||
"fesm2015": "fesm2015/%s.js" % basename,
|
||||
"umd": "%s.umd.js" % basename,
|
||||
"umd_min": "%s.umd.min.js" % basename,
|
||||
}
|
||||
for key in NPM_PACKAGE_OUTPUTS:
|
||||
# NPM_PACKAGE_OUTPUTS is a "normal" dict-valued outputs so it looks like
|
||||
# "pack": "%{name}.pack",
|
||||
# But this is a function-valued outputs.
|
||||
# Bazel won't replace the %{name} token so we have to do it.
|
||||
outputs[key] = NPM_PACKAGE_OUTPUTS[key].replace("%{name}", name)
|
||||
return outputs
|
||||
|
||||
ng_package = rule(
|
||||
implementation = _ng_package_impl,
|
||||
|
@ -419,4 +448,4 @@ ng_package = rule(
|
|||
)
|
||||
"""
|
||||
ng_package produces an npm-ready package from an Angular library.
|
||||
"""
|
||||
"""
|
||||
|
|
|
@ -14,125 +14,132 @@
|
|||
[rollup_bundle]: https://bazelbuild.github.io/rules_nodejs/rollup/rollup_bundle.html
|
||||
"""
|
||||
|
||||
load("@build_bazel_rules_nodejs//internal/rollup:rollup_bundle.bzl",
|
||||
"rollup_module_mappings_aspect",
|
||||
load(
|
||||
"@build_bazel_rules_nodejs//internal/rollup:rollup_bundle.bzl",
|
||||
"ROLLUP_ATTRS",
|
||||
"ROLLUP_OUTPUTS",
|
||||
"write_rollup_config",
|
||||
"rollup_module_mappings_aspect",
|
||||
"run_rollup",
|
||||
"run_sourcemapexplorer",
|
||||
"run_uglify",
|
||||
"run_sourcemapexplorer")
|
||||
"write_rollup_config",
|
||||
)
|
||||
load("@build_bazel_rules_nodejs//internal:collect_es6_sources.bzl", collect_es2015_sources = "collect_es6_sources")
|
||||
load(":esm5.bzl", "esm5_outputs_aspect", "flatten_esm5", "esm5_root_dir")
|
||||
load(":esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5")
|
||||
|
||||
PACKAGES=["packages/core/src", "packages/common/src", "packages/compiler/src", "external/rxjs"]
|
||||
PLUGIN_CONFIG="{sideEffectFreeModules: [\n%s]}" % ",\n".join(
|
||||
[" '.esm5/{0}'".format(p) for p in PACKAGES])
|
||||
BO_ROLLUP="angular_cli/packages/angular_devkit/build_optimizer/src/build-optimizer/rollup-plugin.js"
|
||||
BO_PLUGIN="require('%s').default(%s)" % (BO_ROLLUP, PLUGIN_CONFIG)
|
||||
PACKAGES = ["packages/core/src", "packages/common/src", "packages/compiler/src", "external/rxjs"]
|
||||
PLUGIN_CONFIG = "{sideEffectFreeModules: [\n%s]}" % ",\n".join(
|
||||
[" '.esm5/{0}'".format(p) for p in PACKAGES],
|
||||
)
|
||||
BO_ROLLUP = "angular_cli/packages/angular_devkit/build_optimizer/src/build-optimizer/rollup-plugin.js"
|
||||
BO_PLUGIN = "require('%s').default(%s)" % (BO_ROLLUP, PLUGIN_CONFIG)
|
||||
|
||||
def _use_plain_rollup(ctx):
|
||||
"""Determine whether to use the Angular or upstream versions of the rollup_bundle rule.
|
||||
"""Determine whether to use the Angular or upstream versions of the rollup_bundle rule.
|
||||
|
||||
In most modes, the Angular version of rollup is used. This runs build optimizer as part of its
|
||||
processing, which affects decorators and annotations.
|
||||
In most modes, the Angular version of rollup is used. This runs build optimizer as part of its
|
||||
processing, which affects decorators and annotations.
|
||||
|
||||
In JIT modes, an emulation of the upstream rollup_bundle rule is used. This avoids running
|
||||
build optimizer on code which isn't designed to be optimized by it.
|
||||
In JIT modes, an emulation of the upstream rollup_bundle rule is used. This avoids running
|
||||
build optimizer on code which isn't designed to be optimized by it.
|
||||
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
Args:
|
||||
ctx: skylark rule execution context
|
||||
|
||||
Returns:
|
||||
true iff the Angular version of rollup with build optimizer should be used, false otherwise
|
||||
"""
|
||||
Returns:
|
||||
true iff the Angular version of rollup with build optimizer should be used, false otherwise
|
||||
"""
|
||||
|
||||
if 'compile' not in ctx.var:
|
||||
return False
|
||||
|
||||
strategy = ctx.var['compile']
|
||||
return strategy == 'jit'
|
||||
if "compile" not in ctx.var:
|
||||
return False
|
||||
|
||||
strategy = ctx.var["compile"]
|
||||
return strategy == "jit"
|
||||
|
||||
def run_brotli(ctx, input, output):
|
||||
"""Execute the Brotli compression utility.
|
||||
"""Execute the Brotli compression utility.
|
||||
|
||||
Args:
|
||||
ctx: Bazel's rule execution context
|
||||
input: any file
|
||||
output: the compressed file
|
||||
"""
|
||||
ctx.actions.run(
|
||||
executable = ctx.executable._brotli,
|
||||
inputs = [input],
|
||||
outputs = [output],
|
||||
arguments = ["--output=%s" % output.path, input.path],
|
||||
)
|
||||
Args:
|
||||
ctx: Bazel's rule execution context
|
||||
input: any file
|
||||
output: the compressed file
|
||||
"""
|
||||
ctx.actions.run(
|
||||
executable = ctx.executable._brotli,
|
||||
inputs = [input],
|
||||
outputs = [output],
|
||||
arguments = ["--output=%s" % output.path, input.path],
|
||||
)
|
||||
|
||||
# Borrowed from bazelbuild/rules_nodejs
|
||||
def _run_tsc(ctx, input, output):
|
||||
args = ctx.actions.args()
|
||||
args.add("--target", "es5")
|
||||
args.add("--allowJS")
|
||||
args.add(input)
|
||||
args.add("--outFile", output)
|
||||
args = ctx.actions.args()
|
||||
args.add("--target", "es5")
|
||||
args.add("--allowJS")
|
||||
args.add(input)
|
||||
args.add("--outFile", output)
|
||||
|
||||
ctx.action(
|
||||
executable = ctx.executable._tsc,
|
||||
inputs = [input],
|
||||
outputs = [output],
|
||||
arguments = [args]
|
||||
)
|
||||
ctx.action(
|
||||
executable = ctx.executable._tsc,
|
||||
inputs = [input],
|
||||
outputs = [output],
|
||||
arguments = [args],
|
||||
)
|
||||
|
||||
# Borrowed from bazelbuild/rules_nodejs, with the addition of brotli compression output
|
||||
def _plain_rollup_bundle(ctx):
|
||||
rollup_config = write_rollup_config(ctx)
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), rollup_config, ctx.outputs.build_es6)
|
||||
_run_tsc(ctx, ctx.outputs.build_es6, ctx.outputs.build_es5)
|
||||
source_map = run_uglify(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min)
|
||||
run_uglify(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True)
|
||||
umd_rollup_config = write_rollup_config(ctx, filename = "_%s_umd.rollup.conf.js", output_format = "umd")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), umd_rollup_config, ctx.outputs.build_umd)
|
||||
run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, source_map, ctx.outputs.explore_html)
|
||||
rollup_config = write_rollup_config(ctx)
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), rollup_config, ctx.outputs.build_es6)
|
||||
_run_tsc(ctx, ctx.outputs.build_es6, ctx.outputs.build_es5)
|
||||
source_map = run_uglify(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min)
|
||||
run_uglify(ctx, ctx.outputs.build_es5, ctx.outputs.build_es5_min_debug, debug = True)
|
||||
umd_rollup_config = write_rollup_config(ctx, filename = "_%s_umd.rollup.conf.js", output_format = "umd")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), umd_rollup_config, ctx.outputs.build_umd)
|
||||
run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, source_map, ctx.outputs.explore_html)
|
||||
|
||||
run_brotli(ctx, ctx.outputs.build_es5_min, ctx.outputs.build_es5_min_compressed)
|
||||
files = [ctx.outputs.build_es5_min, source_map]
|
||||
return DefaultInfo(files = depset(files), runfiles = ctx.runfiles(files))
|
||||
run_brotli(ctx, ctx.outputs.build_es5_min, ctx.outputs.build_es5_min_compressed)
|
||||
files = [ctx.outputs.build_es5_min, source_map]
|
||||
return DefaultInfo(files = depset(files), runfiles = ctx.runfiles(files))
|
||||
|
||||
def _ng_rollup_bundle(ctx):
|
||||
# Escape and use the plain rollup rule if the compilation strategy requires it
|
||||
if _use_plain_rollup(ctx):
|
||||
return _plain_rollup_bundle(ctx)
|
||||
# Escape and use the plain rollup rule if the compilation strategy requires it
|
||||
if _use_plain_rollup(ctx):
|
||||
return _plain_rollup_bundle(ctx)
|
||||
|
||||
# We don't expect anyone to make use of this bundle yet, but it makes this rule
|
||||
# compatible with rollup_bundle which allows them to be easily swapped back and
|
||||
# forth.
|
||||
esm2015_rollup_config = write_rollup_config(ctx, filename = "_%s.rollup_es6.conf.js")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), esm2015_rollup_config, ctx.outputs.build_es6)
|
||||
# We don't expect anyone to make use of this bundle yet, but it makes this rule
|
||||
# compatible with rollup_bundle which allows them to be easily swapped back and
|
||||
# forth.
|
||||
esm2015_rollup_config = write_rollup_config(ctx, filename = "_%s.rollup_es6.conf.js")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), esm2015_rollup_config, ctx.outputs.build_es6)
|
||||
|
||||
esm5_sources = flatten_esm5(ctx)
|
||||
esm5_sources = flatten_esm5(ctx)
|
||||
|
||||
rollup_config = write_rollup_config(ctx, [BO_PLUGIN], "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]))
|
||||
rollup_sourcemap = run_rollup(ctx, esm5_sources, rollup_config, ctx.outputs.build_es5)
|
||||
rollup_config = write_rollup_config(ctx, [BO_PLUGIN], "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]))
|
||||
rollup_sourcemap = run_rollup(ctx, esm5_sources, rollup_config, ctx.outputs.build_es5)
|
||||
|
||||
sourcemap = run_uglify(ctx,
|
||||
ctx.outputs.build_es5,
|
||||
ctx.outputs.build_es5_min,
|
||||
comments = False,
|
||||
in_source_map = rollup_sourcemap)
|
||||
run_uglify(ctx,
|
||||
ctx.outputs.build_es5,
|
||||
ctx.outputs.build_es5_min_debug,
|
||||
debug = True, comments = False)
|
||||
sourcemap = run_uglify(
|
||||
ctx,
|
||||
ctx.outputs.build_es5,
|
||||
ctx.outputs.build_es5_min,
|
||||
comments = False,
|
||||
in_source_map = rollup_sourcemap,
|
||||
)
|
||||
run_uglify(
|
||||
ctx,
|
||||
ctx.outputs.build_es5,
|
||||
ctx.outputs.build_es5_min_debug,
|
||||
debug = True,
|
||||
comments = False,
|
||||
)
|
||||
|
||||
umd_rollup_config = write_rollup_config(ctx, filename = "_%s_umd.rollup.conf.js", output_format = "umd")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), umd_rollup_config, ctx.outputs.build_umd)
|
||||
umd_rollup_config = write_rollup_config(ctx, filename = "_%s_umd.rollup.conf.js", output_format = "umd")
|
||||
run_rollup(ctx, collect_es2015_sources(ctx), umd_rollup_config, ctx.outputs.build_umd)
|
||||
|
||||
run_brotli(ctx, ctx.outputs.build_es5_min, ctx.outputs.build_es5_min_compressed)
|
||||
run_brotli(ctx, ctx.outputs.build_es5_min, ctx.outputs.build_es5_min_compressed)
|
||||
|
||||
run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, sourcemap, ctx.outputs.explore_html)
|
||||
run_sourcemapexplorer(ctx, ctx.outputs.build_es5_min, sourcemap, ctx.outputs.explore_html)
|
||||
|
||||
return DefaultInfo(files=depset([ctx.outputs.build_es5_min, sourcemap]))
|
||||
return DefaultInfo(files = depset([ctx.outputs.build_es5_min, sourcemap]))
|
||||
|
||||
ng_rollup_bundle = rule(
|
||||
implementation = _ng_rollup_bundle,
|
||||
|
@ -143,16 +150,18 @@ ng_rollup_bundle = rule(
|
|||
aspects = [
|
||||
rollup_module_mappings_aspect,
|
||||
esm5_outputs_aspect,
|
||||
]
|
||||
],
|
||||
),
|
||||
"_rollup": attr.label(
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
default = Label("@angular//packages/bazel/src:rollup_with_build_optimizer")),
|
||||
default = Label("@angular//packages/bazel/src:rollup_with_build_optimizer"),
|
||||
),
|
||||
"_brotli": attr.label(
|
||||
executable = True,
|
||||
cfg = "host",
|
||||
default = Label("@org_brotli//:brotli")),
|
||||
default = Label("@org_brotli//:brotli"),
|
||||
),
|
||||
}),
|
||||
outputs = dict(ROLLUP_OUTPUTS, **{
|
||||
"build_es5_min_compressed": "%{name}.min.js.br",
|
||||
|
@ -167,4 +176,4 @@ that rule are used here too.
|
|||
[Rollup]: https://rollupjs.org/
|
||||
[Build Optimizer]: https://www.npmjs.com/package/@angular-devkit/build-optimizer
|
||||
[rollup_bundle]: https://bazelbuild.github.io/rules_nodejs/rollup/rollup_bundle.html
|
||||
"""
|
||||
"""
|
||||
|
|
|
@ -8,13 +8,13 @@
|
|||
load("@build_bazel_rules_nodejs//:defs.bzl", "yarn_install")
|
||||
|
||||
def ng_setup_workspace():
|
||||
"""This repository rule should be called from your WORKSPACE file.
|
||||
"""This repository rule should be called from your WORKSPACE file.
|
||||
|
||||
It creates some additional Bazel external repositories that are used internally
|
||||
by the Angular rules.
|
||||
"""
|
||||
yarn_install(
|
||||
name = "angular_packager_deps",
|
||||
package_json = "@angular//packages/bazel/src/ng_package:package.json",
|
||||
yarn_lock = "@angular//packages/bazel/src/ng_package:yarn.lock",
|
||||
)
|
||||
It creates some additional Bazel external repositories that are used internally
|
||||
by the Angular rules.
|
||||
"""
|
||||
yarn_install(
|
||||
name = "angular_packager_deps",
|
||||
package_json = "@angular//packages/bazel/src/ng_package:package.json",
|
||||
yarn_lock = "@angular//packages/bazel/src/ng_package:yarn.lock",
|
||||
)
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
# found in the LICENSE file at https://angular.io/license
|
||||
"Run end-to-end tests with Protractor"
|
||||
|
||||
load("@build_bazel_rules_nodejs//internal:node.bzl",
|
||||
"sources_aspect",
|
||||
load(
|
||||
"@build_bazel_rules_nodejs//internal:node.bzl",
|
||||
"expand_path_into_runfiles",
|
||||
"sources_aspect",
|
||||
)
|
||||
load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite")
|
||||
load("@io_bazel_rules_webtesting//web/internal:constants.bzl", "DEFAULT_WRAPPED_TEST_TAGS")
|
||||
|
@ -15,69 +16,71 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
|||
_CONF_TMPL = "//packages/bazel/src/protractor:protractor.conf.js"
|
||||
|
||||
def _protractor_web_test_impl(ctx):
|
||||
configuration = ctx.actions.declare_file(
|
||||
"%s.conf.js" % ctx.label.name,
|
||||
sibling=ctx.outputs.executable)
|
||||
configuration = ctx.actions.declare_file(
|
||||
"%s.conf.js" % ctx.label.name,
|
||||
sibling = ctx.outputs.executable,
|
||||
)
|
||||
|
||||
files = depset(ctx.files.srcs)
|
||||
for d in ctx.attr.deps:
|
||||
if hasattr(d, "node_sources"):
|
||||
files = depset(transitive = [files, d.node_sources])
|
||||
elif hasattr(d, "files"):
|
||||
files = depset(transitive = [files, d.files])
|
||||
files = depset(ctx.files.srcs)
|
||||
for d in ctx.attr.deps:
|
||||
if hasattr(d, "node_sources"):
|
||||
files = depset(transitive = [files, d.node_sources])
|
||||
elif hasattr(d, "files"):
|
||||
files = depset(transitive = [files, d.files])
|
||||
|
||||
specs = [
|
||||
expand_path_into_runfiles(ctx, f.short_path)
|
||||
for f in files
|
||||
]
|
||||
specs = [
|
||||
expand_path_into_runfiles(ctx, f.short_path)
|
||||
for f in files
|
||||
]
|
||||
|
||||
configuration_sources = []
|
||||
if ctx.file.configuration:
|
||||
configuration_sources = [ctx.file.configuration]
|
||||
if hasattr(ctx.attr.configuration, "node_sources"):
|
||||
configuration_sources = ctx.attr.configuration.node_sources.to_list()
|
||||
configuration_sources = []
|
||||
if ctx.file.configuration:
|
||||
configuration_sources = [ctx.file.configuration]
|
||||
if hasattr(ctx.attr.configuration, "node_sources"):
|
||||
configuration_sources = ctx.attr.configuration.node_sources.to_list()
|
||||
|
||||
configuration_file = ctx.file.configuration
|
||||
if hasattr(ctx.attr.configuration, "typescript"):
|
||||
configuration_file = ctx.attr.configuration.typescript.es5_sources.to_list()[0]
|
||||
configuration_file = ctx.file.configuration
|
||||
if hasattr(ctx.attr.configuration, "typescript"):
|
||||
configuration_file = ctx.attr.configuration.typescript.es5_sources.to_list()[0]
|
||||
|
||||
on_prepare_sources = []
|
||||
if ctx.file.on_prepare:
|
||||
on_prepare_sources = [ctx.file.on_prepare]
|
||||
if hasattr(ctx.attr.on_prepare, "node_sources"):
|
||||
on_prepare_sources = ctx.attr.on_prepare.node_sources.to_list()
|
||||
on_prepare_sources = []
|
||||
if ctx.file.on_prepare:
|
||||
on_prepare_sources = [ctx.file.on_prepare]
|
||||
if hasattr(ctx.attr.on_prepare, "node_sources"):
|
||||
on_prepare_sources = ctx.attr.on_prepare.node_sources.to_list()
|
||||
|
||||
on_prepare_file = ctx.file.on_prepare
|
||||
if hasattr(ctx.attr.on_prepare, "typescript"):
|
||||
on_prepare_file = ctx.attr.on_prepare.typescript.es5_sources.to_list()[0]
|
||||
on_prepare_file = ctx.file.on_prepare
|
||||
if hasattr(ctx.attr.on_prepare, "typescript"):
|
||||
on_prepare_file = ctx.attr.on_prepare.typescript.es5_sources.to_list()[0]
|
||||
|
||||
protractor_executable_path = ctx.executable.protractor.short_path
|
||||
if protractor_executable_path.startswith('..'):
|
||||
protractor_executable_path = "external" + protractor_executable_path[2:]
|
||||
protractor_executable_path = ctx.executable.protractor.short_path
|
||||
if protractor_executable_path.startswith(".."):
|
||||
protractor_executable_path = "external" + protractor_executable_path[2:]
|
||||
|
||||
server_executable_path = ''
|
||||
if ctx.executable.server:
|
||||
server_executable_path = ctx.executable.server.short_path
|
||||
if server_executable_path.startswith('..'):
|
||||
server_executable_path = "external" + protractor_executable_path[2:]
|
||||
server_executable_path = ""
|
||||
if ctx.executable.server:
|
||||
server_executable_path = ctx.executable.server.short_path
|
||||
if server_executable_path.startswith(".."):
|
||||
server_executable_path = "external" + protractor_executable_path[2:]
|
||||
|
||||
ctx.actions.expand_template(
|
||||
output = configuration,
|
||||
template = ctx.file._conf_tmpl,
|
||||
substitutions = {
|
||||
"TMPL_config": expand_path_into_runfiles(ctx, configuration_file.short_path) if configuration_file else "",
|
||||
"TMPL_on_prepare": expand_path_into_runfiles(ctx, on_prepare_file.short_path) if on_prepare_file else "",
|
||||
"TMPL_workspace": ctx.workspace_name,
|
||||
"TMPL_server": server_executable_path,
|
||||
"TMPL_specs": "\n".join([" '%s'," % e for e in specs]),
|
||||
})
|
||||
ctx.actions.expand_template(
|
||||
output = configuration,
|
||||
template = ctx.file._conf_tmpl,
|
||||
substitutions = {
|
||||
"TMPL_config": expand_path_into_runfiles(ctx, configuration_file.short_path) if configuration_file else "",
|
||||
"TMPL_on_prepare": expand_path_into_runfiles(ctx, on_prepare_file.short_path) if on_prepare_file else "",
|
||||
"TMPL_workspace": ctx.workspace_name,
|
||||
"TMPL_server": server_executable_path,
|
||||
"TMPL_specs": "\n".join([" '%s'," % e for e in specs]),
|
||||
},
|
||||
)
|
||||
|
||||
runfiles = [configuration] + configuration_sources + on_prepare_sources
|
||||
runfiles = [configuration] + configuration_sources + on_prepare_sources
|
||||
|
||||
ctx.actions.write(
|
||||
output = ctx.outputs.executable,
|
||||
is_executable = True,
|
||||
content = """#!/usr/bin/env bash
|
||||
ctx.actions.write(
|
||||
output = ctx.outputs.executable,
|
||||
is_executable = True,
|
||||
content = """#!/usr/bin/env bash
|
||||
if [ -e "$RUNFILE_MANIFEST_FILE" ]; then
|
||||
while read line; do
|
||||
declare -a PARTS=($line)
|
||||
|
@ -100,19 +103,22 @@ echo "Protractor $PROTRACTOR_VERSION"
|
|||
|
||||
# Run the protractor binary
|
||||
$PROTRACTOR $CONF
|
||||
""".format(TMPL_protractor = protractor_executable_path,
|
||||
TMPL_conf = configuration.short_path))
|
||||
return [DefaultInfo(
|
||||
files = depset([ctx.outputs.executable]),
|
||||
runfiles = ctx.runfiles(
|
||||
files = runfiles,
|
||||
transitive_files = files,
|
||||
# Propagate protractor_bin and its runfiles
|
||||
collect_data = True,
|
||||
collect_default = True,
|
||||
),
|
||||
executable = ctx.outputs.executable,
|
||||
)]
|
||||
""".format(
|
||||
TMPL_protractor = protractor_executable_path,
|
||||
TMPL_conf = configuration.short_path,
|
||||
),
|
||||
)
|
||||
return [DefaultInfo(
|
||||
files = depset([ctx.outputs.executable]),
|
||||
runfiles = ctx.runfiles(
|
||||
files = runfiles,
|
||||
transitive_files = files,
|
||||
# Propagate protractor_bin and its runfiles
|
||||
collect_data = True,
|
||||
collect_default = True,
|
||||
),
|
||||
executable = ctx.outputs.executable,
|
||||
)]
|
||||
|
||||
_protractor_web_test = rule(
|
||||
implementation = _protractor_web_test_impl,
|
||||
|
@ -123,36 +129,43 @@ _protractor_web_test = rule(
|
|||
doc = "Protractor configuration file",
|
||||
allow_single_file = True,
|
||||
cfg = "data",
|
||||
aspects = [sources_aspect]),
|
||||
aspects = [sources_aspect],
|
||||
),
|
||||
"srcs": attr.label_list(
|
||||
doc = "A list of JavaScript test files",
|
||||
allow_files = [".js"]),
|
||||
allow_files = [".js"],
|
||||
),
|
||||
"on_prepare": attr.label(
|
||||
doc = """A file with a node.js script to run once before all tests run.
|
||||
If the script exports a function which returns a promise, protractor
|
||||
will wait for the promise to resolve before beginning tests.""",
|
||||
allow_single_file = True,
|
||||
cfg = "data",
|
||||
aspects = [sources_aspect]),
|
||||
aspects = [sources_aspect],
|
||||
),
|
||||
"deps": attr.label_list(
|
||||
doc = "Other targets which produce JavaScript such as `ts_library`",
|
||||
allow_files = True,
|
||||
aspects = [sources_aspect]),
|
||||
aspects = [sources_aspect],
|
||||
),
|
||||
"data": attr.label_list(
|
||||
doc = "Runtime dependencies",
|
||||
cfg = "data"),
|
||||
cfg = "data",
|
||||
),
|
||||
"server": attr.label(
|
||||
doc = "Optional server executable target",
|
||||
executable = True,
|
||||
cfg = "data",
|
||||
single_file = False,
|
||||
allow_files = True),
|
||||
allow_files = True,
|
||||
),
|
||||
"protractor": attr.label(
|
||||
doc = "Protractor executable target (set by protractor_web_test macro)",
|
||||
executable = True,
|
||||
cfg = "data",
|
||||
single_file = False,
|
||||
allow_files = True),
|
||||
allow_files = True,
|
||||
),
|
||||
"_conf_tmpl": attr.label(
|
||||
default = Label(_CONF_TMPL),
|
||||
allow_single_file = True,
|
||||
|
@ -161,180 +174,184 @@ _protractor_web_test = rule(
|
|||
)
|
||||
|
||||
def protractor_web_test(
|
||||
name,
|
||||
configuration = None,
|
||||
on_prepare = None,
|
||||
srcs = [],
|
||||
deps = [],
|
||||
data = [],
|
||||
server = None,
|
||||
tags = [],
|
||||
**kwargs):
|
||||
"""Runs a protractor test in a browser.
|
||||
name,
|
||||
configuration = None,
|
||||
on_prepare = None,
|
||||
srcs = [],
|
||||
deps = [],
|
||||
data = [],
|
||||
server = None,
|
||||
tags = [],
|
||||
**kwargs):
|
||||
"""Runs a protractor test in a browser.
|
||||
|
||||
Args:
|
||||
name: The name of the test
|
||||
configuration: Protractor configuration file.
|
||||
on_prepare: A file with a node.js script to run once before all tests run.
|
||||
If the script exports a function which returns a promise, protractor
|
||||
will wait for the promise to resolve before beginning tests.
|
||||
srcs: JavaScript source files
|
||||
deps: Other targets which produce JavaScript such as `ts_library`
|
||||
data: Runtime dependencies
|
||||
server: Optional server executable target
|
||||
tags: Standard Bazel tags, this macro adds one for ibazel
|
||||
**kwargs: passed through to `_protractor_web_test`
|
||||
"""
|
||||
Args:
|
||||
name: The name of the test
|
||||
configuration: Protractor configuration file.
|
||||
on_prepare: A file with a node.js script to run once before all tests run.
|
||||
If the script exports a function which returns a promise, protractor
|
||||
will wait for the promise to resolve before beginning tests.
|
||||
srcs: JavaScript source files
|
||||
deps: Other targets which produce JavaScript such as `ts_library`
|
||||
data: Runtime dependencies
|
||||
server: Optional server executable target
|
||||
tags: Standard Bazel tags, this macro adds one for ibazel
|
||||
**kwargs: passed through to `_protractor_web_test`
|
||||
"""
|
||||
|
||||
protractor_bin_name = name + "_protractor_bin"
|
||||
protractor_bin_name = name + "_protractor_bin"
|
||||
|
||||
nodejs_binary(
|
||||
name = protractor_bin_name,
|
||||
entry_point = "protractor/bin/protractor",
|
||||
data = srcs + deps + data,
|
||||
node_modules = "@//:node_modules",
|
||||
testonly = 1,
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
nodejs_binary(
|
||||
name = protractor_bin_name,
|
||||
entry_point = "protractor/bin/protractor",
|
||||
data = srcs + deps + data,
|
||||
node_modules = "@//:node_modules",
|
||||
testonly = 1,
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
# Our binary dependency must be in data[] for collect_data to pick it up
|
||||
# FIXME: maybe we can just ask :protractor_bin_name for its runfiles attr
|
||||
web_test_data = data + [":" + protractor_bin_name]
|
||||
if server:
|
||||
web_test_data += [server]
|
||||
# Our binary dependency must be in data[] for collect_data to pick it up
|
||||
# FIXME: maybe we can just ask :protractor_bin_name for its runfiles attr
|
||||
web_test_data = data + [":" + protractor_bin_name]
|
||||
if server:
|
||||
web_test_data += [server]
|
||||
|
||||
_protractor_web_test(
|
||||
name = name,
|
||||
configuration = configuration,
|
||||
on_prepare=on_prepare,
|
||||
srcs = srcs,
|
||||
deps = deps,
|
||||
data = web_test_data,
|
||||
server = server,
|
||||
protractor = protractor_bin_name,
|
||||
tags = tags + [
|
||||
# Users don't need to know that this tag is required to run under ibazel
|
||||
"ibazel_notify_changes",
|
||||
],
|
||||
**kwargs)
|
||||
_protractor_web_test(
|
||||
name = name,
|
||||
configuration = configuration,
|
||||
on_prepare = on_prepare,
|
||||
srcs = srcs,
|
||||
deps = deps,
|
||||
data = web_test_data,
|
||||
server = server,
|
||||
protractor = protractor_bin_name,
|
||||
tags = tags + [
|
||||
# Users don't need to know that this tag is required to run under ibazel
|
||||
"ibazel_notify_changes",
|
||||
],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def protractor_web_test_suite(
|
||||
name,
|
||||
configuration = None,
|
||||
on_prepare = None,
|
||||
srcs = [],
|
||||
deps = [],
|
||||
data = [],
|
||||
server = None,
|
||||
browsers=["@io_bazel_rules_webtesting//browsers:chromium-local"],
|
||||
args=None,
|
||||
browser_overrides=None,
|
||||
config=None,
|
||||
flaky=None,
|
||||
local=None,
|
||||
shard_count=None,
|
||||
size=None,
|
||||
tags = [],
|
||||
test_suite_tags=None,
|
||||
timeout=None,
|
||||
visibility=None,
|
||||
web_test_data=[],
|
||||
wrapped_test_tags=None,
|
||||
**remaining_keyword_args):
|
||||
"""Defines a test_suite of web_test targets that wrap a protractor_web_test target.
|
||||
name,
|
||||
configuration = None,
|
||||
on_prepare = None,
|
||||
srcs = [],
|
||||
deps = [],
|
||||
data = [],
|
||||
server = None,
|
||||
browsers = ["@io_bazel_rules_webtesting//browsers:chromium-local"],
|
||||
args = None,
|
||||
browser_overrides = None,
|
||||
config = None,
|
||||
flaky = None,
|
||||
local = None,
|
||||
shard_count = None,
|
||||
size = None,
|
||||
tags = [],
|
||||
test_suite_tags = None,
|
||||
timeout = None,
|
||||
visibility = None,
|
||||
web_test_data = [],
|
||||
wrapped_test_tags = None,
|
||||
**remaining_keyword_args):
|
||||
"""Defines a test_suite of web_test targets that wrap a protractor_web_test target.
|
||||
|
||||
Args:
|
||||
name: The base name of the test.
|
||||
configuration: Protractor configuration file.
|
||||
on_prepare: A file with a node.js script to run once before all tests run.
|
||||
If the script exports a function which returns a promise, protractor
|
||||
will wait for the promise to resolve before beginning tests.
|
||||
srcs: JavaScript source files
|
||||
deps: Other targets which produce JavaScript such as `ts_library`
|
||||
data: Runtime dependencies
|
||||
server: Optional server executable target
|
||||
browsers: A sequence of labels specifying the browsers to use.
|
||||
args: Args for web_test targets generated by this extension.
|
||||
browser_overrides: Dictionary; optional; default is an empty dictionary. A
|
||||
dictionary mapping from browser names to browser-specific web_test
|
||||
attributes, such as shard_count, flakiness, timeout, etc. For example:
|
||||
{'//browsers:chrome-native': {'shard_count': 3, 'flaky': 1}
|
||||
'//browsers:firefox-native': {'shard_count': 1, 'timeout': 100}}.
|
||||
config: Label; optional; Configuration of web test features.
|
||||
flaky: A boolean specifying that the test is flaky. If set, the test will
|
||||
be retried up to 3 times (default: 0)
|
||||
local: boolean; optional.
|
||||
shard_count: The number of test shards to use per browser. (default: 1)
|
||||
size: A string specifying the test size. (default: 'large')
|
||||
tags: A list of test tag strings to apply to each generated web_test target.
|
||||
This macro adds a couple for ibazel.
|
||||
test_suite_tags: A list of tag strings for the generated test_suite.
|
||||
timeout: A string specifying the test timeout (default: computed from size)
|
||||
visibility: List of labels; optional.
|
||||
web_test_data: Data dependencies for the web_test.
|
||||
wrapped_test_tags: A list of test tag strings to use for the wrapped test
|
||||
**remaining_keyword_args: Arguments for the wrapped test target.
|
||||
"""
|
||||
# Check explicitly for None so that users can set this to the empty list
|
||||
if wrapped_test_tags == None:
|
||||
wrapped_test_tags = DEFAULT_WRAPPED_TEST_TAGS
|
||||
Args:
|
||||
name: The base name of the test.
|
||||
configuration: Protractor configuration file.
|
||||
on_prepare: A file with a node.js script to run once before all tests run.
|
||||
If the script exports a function which returns a promise, protractor
|
||||
will wait for the promise to resolve before beginning tests.
|
||||
srcs: JavaScript source files
|
||||
deps: Other targets which produce JavaScript such as `ts_library`
|
||||
data: Runtime dependencies
|
||||
server: Optional server executable target
|
||||
browsers: A sequence of labels specifying the browsers to use.
|
||||
args: Args for web_test targets generated by this extension.
|
||||
browser_overrides: Dictionary; optional; default is an empty dictionary. A
|
||||
dictionary mapping from browser names to browser-specific web_test
|
||||
attributes, such as shard_count, flakiness, timeout, etc. For example:
|
||||
{'//browsers:chrome-native': {'shard_count': 3, 'flaky': 1}
|
||||
'//browsers:firefox-native': {'shard_count': 1, 'timeout': 100}}.
|
||||
config: Label; optional; Configuration of web test features.
|
||||
flaky: A boolean specifying that the test is flaky. If set, the test will
|
||||
be retried up to 3 times (default: 0)
|
||||
local: boolean; optional.
|
||||
shard_count: The number of test shards to use per browser. (default: 1)
|
||||
size: A string specifying the test size. (default: 'large')
|
||||
tags: A list of test tag strings to apply to each generated web_test target.
|
||||
This macro adds a couple for ibazel.
|
||||
test_suite_tags: A list of tag strings for the generated test_suite.
|
||||
timeout: A string specifying the test timeout (default: computed from size)
|
||||
visibility: List of labels; optional.
|
||||
web_test_data: Data dependencies for the web_test.
|
||||
wrapped_test_tags: A list of test tag strings to use for the wrapped test
|
||||
**remaining_keyword_args: Arguments for the wrapped test target.
|
||||
"""
|
||||
|
||||
size = size or "large"
|
||||
# Check explicitly for None so that users can set this to the empty list
|
||||
if wrapped_test_tags == None:
|
||||
wrapped_test_tags = DEFAULT_WRAPPED_TEST_TAGS
|
||||
|
||||
wrapped_test_name = name + "_wrapped_test"
|
||||
protractor_bin_name = name + "_protractor_bin"
|
||||
size = size or "large"
|
||||
|
||||
# Users don't need to know that this tag is required to run under ibazel
|
||||
tags = tags + ["ibazel_notify_changes"]
|
||||
wrapped_test_name = name + "_wrapped_test"
|
||||
protractor_bin_name = name + "_protractor_bin"
|
||||
|
||||
nodejs_binary(
|
||||
name = protractor_bin_name,
|
||||
entry_point = "protractor/bin/protractor",
|
||||
data = srcs + deps + data,
|
||||
node_modules = "@//:node_modules",
|
||||
testonly = 1,
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
# Users don't need to know that this tag is required to run under ibazel
|
||||
tags = tags + ["ibazel_notify_changes"]
|
||||
|
||||
# Our binary dependency must be in data[] for collect_data to pick it up
|
||||
# FIXME: maybe we can just ask the :protractor_bin_name for its runfiles attr
|
||||
web_test_data = web_test_data + [":" + protractor_bin_name]
|
||||
if server:
|
||||
web_test_data += [server]
|
||||
nodejs_binary(
|
||||
name = protractor_bin_name,
|
||||
entry_point = "protractor/bin/protractor",
|
||||
data = srcs + deps + data,
|
||||
node_modules = "@//:node_modules",
|
||||
testonly = 1,
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
_protractor_web_test(
|
||||
name=wrapped_test_name,
|
||||
configuration=configuration,
|
||||
on_prepare=on_prepare,
|
||||
srcs=srcs,
|
||||
deps=deps,
|
||||
data=web_test_data,
|
||||
server=server,
|
||||
protractor=protractor_bin_name,
|
||||
args=args,
|
||||
flaky=flaky,
|
||||
local=local,
|
||||
shard_count=shard_count,
|
||||
size=size,
|
||||
tags=wrapped_test_tags,
|
||||
timeout=timeout,
|
||||
visibility=["//visibility:private"],
|
||||
**remaining_keyword_args)
|
||||
# Our binary dependency must be in data[] for collect_data to pick it up
|
||||
# FIXME: maybe we can just ask the :protractor_bin_name for its runfiles attr
|
||||
web_test_data = web_test_data + [":" + protractor_bin_name]
|
||||
if server:
|
||||
web_test_data += [server]
|
||||
|
||||
web_test_suite(
|
||||
name=name,
|
||||
launcher=":"+wrapped_test_name,
|
||||
args=args,
|
||||
browsers=browsers,
|
||||
browser_overrides=browser_overrides,
|
||||
config=config,
|
||||
data=web_test_data,
|
||||
flaky=flaky,
|
||||
local=local,
|
||||
shard_count=shard_count,
|
||||
size=size,
|
||||
tags=tags,
|
||||
test=wrapped_test_name,
|
||||
test_suite_tags=test_suite_tags,
|
||||
timeout=timeout,
|
||||
visibility=visibility)
|
||||
_protractor_web_test(
|
||||
name = wrapped_test_name,
|
||||
configuration = configuration,
|
||||
on_prepare = on_prepare,
|
||||
srcs = srcs,
|
||||
deps = deps,
|
||||
data = web_test_data,
|
||||
server = server,
|
||||
protractor = protractor_bin_name,
|
||||
args = args,
|
||||
flaky = flaky,
|
||||
local = local,
|
||||
shard_count = shard_count,
|
||||
size = size,
|
||||
tags = wrapped_test_tags,
|
||||
timeout = timeout,
|
||||
visibility = ["//visibility:private"],
|
||||
**remaining_keyword_args
|
||||
)
|
||||
|
||||
web_test_suite(
|
||||
name = name,
|
||||
launcher = ":" + wrapped_test_name,
|
||||
args = args,
|
||||
browsers = browsers,
|
||||
browser_overrides = browser_overrides,
|
||||
config = config,
|
||||
data = web_test_data,
|
||||
flaky = flaky,
|
||||
local = local,
|
||||
shard_count = shard_count,
|
||||
size = size,
|
||||
tags = tags,
|
||||
test = wrapped_test_name,
|
||||
test_suite_tags = test_suite_tags,
|
||||
timeout = timeout,
|
||||
visibility = visibility,
|
||||
)
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
"""Allows different paths for these imports in google3.
|
||||
"""
|
||||
|
||||
load("@build_bazel_rules_typescript//internal:build_defs.bzl",
|
||||
load(
|
||||
"@build_bazel_rules_typescript//internal:build_defs.bzl",
|
||||
_tsc_wrapped_tsconfig = "tsc_wrapped_tsconfig",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//internal:common/compilation.bzl",
|
||||
load(
|
||||
"@build_bazel_rules_typescript//internal:common/compilation.bzl",
|
||||
_COMMON_ATTRIBUTES = "COMMON_ATTRIBUTES",
|
||||
_COMMON_OUTPUTS = "COMMON_OUTPUTS",
|
||||
_compile_ts = "compile_ts",
|
||||
_DEPS_ASPECTS = "DEPS_ASPECTS",
|
||||
_compile_ts = "compile_ts",
|
||||
_ts_providers_dict_to_struct = "ts_providers_dict_to_struct",
|
||||
)
|
||||
|
||||
load("@build_bazel_rules_typescript//internal:common/json_marshal.bzl",
|
||||
load(
|
||||
"@build_bazel_rules_typescript//internal:common/json_marshal.bzl",
|
||||
_json_marshal = "json_marshal",
|
||||
)
|
||||
|
||||
|
|
|
@ -6,16 +6,16 @@
|
|||
"""
|
||||
|
||||
def _extract_flat_module_index(ctx):
|
||||
files = []
|
||||
for dep in ctx.attr.deps:
|
||||
if hasattr(dep, "angular"):
|
||||
metadata = dep.angular.flat_module_metadata
|
||||
files.extend([metadata.metadata_file, metadata.typings_file])
|
||||
return [DefaultInfo(files = depset(files))]
|
||||
files = []
|
||||
for dep in ctx.attr.deps:
|
||||
if hasattr(dep, "angular"):
|
||||
metadata = dep.angular.flat_module_metadata
|
||||
files.extend([metadata.metadata_file, metadata.typings_file])
|
||||
return [DefaultInfo(files = depset(files))]
|
||||
|
||||
extract_flat_module_index = rule(
|
||||
implementation = _extract_flat_module_index,
|
||||
attrs = {
|
||||
"deps": attr.label_list(),
|
||||
"deps": attr.label_list(),
|
||||
},
|
||||
)
|
||||
|
|
|
@ -9,14 +9,15 @@ This allows editors and other tools to easily use the language service bundle
|
|||
without having to provide all of the angular specific peer dependencies.
|
||||
"""
|
||||
|
||||
load("@build_bazel_rules_nodejs//internal/rollup:rollup_bundle.bzl",
|
||||
load(
|
||||
"@build_bazel_rules_nodejs//internal/rollup:rollup_bundle.bzl",
|
||||
"ROLLUP_ATTRS",
|
||||
"rollup_module_mappings_aspect",
|
||||
"write_rollup_config",
|
||||
"run_rollup",
|
||||
"run_uglify"
|
||||
"run_uglify",
|
||||
"write_rollup_config",
|
||||
)
|
||||
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "flatten_esm5", "esm5_root_dir")
|
||||
load("//packages/bazel/src:esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5")
|
||||
|
||||
# Note: the file is called "umd.js" and "umd.min.js" because of historical
|
||||
# reasons. The format is actually amd and not umd, but we are afraid to rename
|
||||
|
@ -28,13 +29,15 @@ _ROLLUP_OUTPUTS = {
|
|||
}
|
||||
|
||||
def _ls_rollup_bundle(ctx):
|
||||
esm5_sources = flatten_esm5(ctx)
|
||||
rollup_config = write_rollup_config(ctx,
|
||||
root_dir = "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]),
|
||||
output_format = "amd")
|
||||
run_rollup(ctx, esm5_sources, rollup_config, ctx.outputs.build_umd)
|
||||
source_map = run_uglify(ctx, ctx.outputs.build_umd, ctx.outputs.build_umd_min)
|
||||
return DefaultInfo(files=depset([ctx.outputs.build_umd, ctx.outputs.build_umd_min, source_map]))
|
||||
esm5_sources = flatten_esm5(ctx)
|
||||
rollup_config = write_rollup_config(
|
||||
ctx,
|
||||
root_dir = "/".join([ctx.bin_dir.path, ctx.label.package, esm5_root_dir(ctx)]),
|
||||
output_format = "amd",
|
||||
)
|
||||
run_rollup(ctx, esm5_sources, rollup_config, ctx.outputs.build_umd)
|
||||
source_map = run_uglify(ctx, ctx.outputs.build_umd, ctx.outputs.build_umd_min)
|
||||
return DefaultInfo(files = depset([ctx.outputs.build_umd, ctx.outputs.build_umd_min, source_map]))
|
||||
|
||||
ls_rollup_bundle = rule(
|
||||
implementation = _ls_rollup_bundle,
|
||||
|
@ -45,4 +48,4 @@ ls_rollup_bundle = rule(
|
|||
]),
|
||||
}),
|
||||
outputs = _ROLLUP_OUTPUTS,
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Re-export of some bazel rules with repository-wide defaults."""
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", _npm_package = "npm_package")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", _ts_library = "ts_library", _ts_web_test_suite = "ts_web_test_suite")
|
||||
load("//packages/bazel:index.bzl", _ng_module = "ng_module", _ng_package = "ng_package")
|
||||
|
@ -9,96 +10,99 @@ DEFAULT_NODE_MODULES = "@angular_deps//:node_modules"
|
|||
|
||||
# Packages which are versioned together on npm
|
||||
ANGULAR_SCOPED_PACKAGES = ["@angular/%s" % p for p in [
|
||||
# core should be the first package because it's the main package in the group
|
||||
# this is significant for Angular CLI and "ng update" specifically, @angular/core
|
||||
# is considered the identifier of the group by these tools.
|
||||
"core",
|
||||
"bazel",
|
||||
"common",
|
||||
"compiler",
|
||||
"compiler-cli",
|
||||
"animations",
|
||||
"elements",
|
||||
"platform-browser",
|
||||
"platform-browser-dynamic",
|
||||
"forms",
|
||||
"http",
|
||||
"platform-server",
|
||||
"platform-webworker",
|
||||
"platform-webworker-dynamic",
|
||||
"upgrade",
|
||||
"router",
|
||||
"language-service",
|
||||
"service-worker",
|
||||
# core should be the first package because it's the main package in the group
|
||||
# this is significant for Angular CLI and "ng update" specifically, @angular/core
|
||||
# is considered the identifier of the group by these tools.
|
||||
"core",
|
||||
"bazel",
|
||||
"common",
|
||||
"compiler",
|
||||
"compiler-cli",
|
||||
"animations",
|
||||
"elements",
|
||||
"platform-browser",
|
||||
"platform-browser-dynamic",
|
||||
"forms",
|
||||
"http",
|
||||
"platform-server",
|
||||
"platform-webworker",
|
||||
"platform-webworker-dynamic",
|
||||
"upgrade",
|
||||
"router",
|
||||
"language-service",
|
||||
"service-worker",
|
||||
]]
|
||||
|
||||
PKG_GROUP_REPLACEMENTS = {
|
||||
"\"NG_UPDATE_PACKAGE_GROUP\"": """[
|
||||
%s
|
||||
]""" % ",\n ".join(["\"%s\"" % s for s in ANGULAR_SCOPED_PACKAGES])
|
||||
]""" % ",\n ".join(["\"%s\"" % s for s in ANGULAR_SCOPED_PACKAGES]),
|
||||
}
|
||||
|
||||
def ts_library(tsconfig = None, node_modules = DEFAULT_NODE_MODULES, **kwargs):
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
_ts_library(tsconfig = tsconfig, node_modules = node_modules, **kwargs)
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
_ts_library(tsconfig = tsconfig, node_modules = node_modules, **kwargs)
|
||||
|
||||
def ng_module(name, tsconfig = None, entry_point = None, node_modules = DEFAULT_NODE_MODULES, **kwargs):
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
if not entry_point:
|
||||
entry_point = "public_api.ts"
|
||||
_ng_module(name = name, flat_module_out_file = name, tsconfig = tsconfig, entry_point = entry_point, node_modules = node_modules, **kwargs)
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
if not entry_point:
|
||||
entry_point = "public_api.ts"
|
||||
_ng_module(name = name, flat_module_out_file = name, tsconfig = tsconfig, entry_point = entry_point, node_modules = node_modules, **kwargs)
|
||||
|
||||
# ivy_ng_module behaves like ng_module, and under --define=compile=legacy it runs ngc with global
|
||||
# analysis but produces Ivy outputs. Under other compile modes, it behaves as ng_module.
|
||||
# TODO(alxhub): remove when ngtsc supports the same use cases.
|
||||
def ivy_ng_module(name, tsconfig = None, entry_point = None, **kwargs):
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
if not entry_point:
|
||||
entry_point = "public_api.ts"
|
||||
_internal_global_ng_module(name = name, flat_module_out_file = name, tsconfig = tsconfig, entry_point = entry_point, **kwargs)
|
||||
if not tsconfig:
|
||||
tsconfig = DEFAULT_TSCONFIG
|
||||
if not entry_point:
|
||||
entry_point = "public_api.ts"
|
||||
_internal_global_ng_module(name = name, flat_module_out_file = name, tsconfig = tsconfig, entry_point = entry_point, **kwargs)
|
||||
|
||||
def ng_package(name, readme_md = None, license_banner = None, **kwargs):
|
||||
if not readme_md:
|
||||
readme_md = "//packages:README.md"
|
||||
if not license_banner:
|
||||
license_banner = "//packages:license-banner.txt"
|
||||
if not readme_md:
|
||||
readme_md = "//packages:README.md"
|
||||
if not license_banner:
|
||||
license_banner = "//packages:license-banner.txt"
|
||||
|
||||
_ng_package(
|
||||
name = name,
|
||||
readme_md = readme_md,
|
||||
license_banner = license_banner,
|
||||
replacements = PKG_GROUP_REPLACEMENTS,
|
||||
**kwargs)
|
||||
_ng_package(
|
||||
name = name,
|
||||
readme_md = readme_md,
|
||||
license_banner = license_banner,
|
||||
replacements = PKG_GROUP_REPLACEMENTS,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def npm_package(name, replacements = {}, **kwargs):
|
||||
_npm_package(
|
||||
name = name,
|
||||
replacements = dict(replacements, **PKG_GROUP_REPLACEMENTS),
|
||||
**kwargs)
|
||||
_npm_package(
|
||||
name = name,
|
||||
replacements = dict(replacements, **PKG_GROUP_REPLACEMENTS),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def ts_web_test_suite(bootstrap = [], deps = [], **kwargs):
|
||||
if not bootstrap:
|
||||
bootstrap = ["//:web_test_bootstrap_scripts"]
|
||||
local_deps = [
|
||||
"@angular_deps//:node_modules/tslib/tslib.js",
|
||||
"//tools/testing:browser",
|
||||
] + deps
|
||||
if not bootstrap:
|
||||
bootstrap = ["//:web_test_bootstrap_scripts"]
|
||||
local_deps = [
|
||||
"@angular_deps//:node_modules/tslib/tslib.js",
|
||||
"//tools/testing:browser",
|
||||
] + deps
|
||||
|
||||
_ts_web_test_suite(
|
||||
bootstrap = bootstrap,
|
||||
deps = local_deps,
|
||||
# Run unit tests on local Chromium by default.
|
||||
# You can exclude tests based on tags, e.g. to skip Firefox testing,
|
||||
# `bazel test --test_tag_filters=-browser:firefox-local [targets]`
|
||||
browsers = [
|
||||
"@io_bazel_rules_webtesting//browsers:chromium-local",
|
||||
# Don't test on local Firefox by default, for faster builds.
|
||||
# We think that bugs in Angular tend to be caught the same in any
|
||||
# evergreen browser.
|
||||
# "@io_bazel_rules_webtesting//browsers:firefox-local",
|
||||
# TODO(alexeagle): add remote browsers on SauceLabs
|
||||
],
|
||||
**kwargs)
|
||||
_ts_web_test_suite(
|
||||
bootstrap = bootstrap,
|
||||
deps = local_deps,
|
||||
# Run unit tests on local Chromium by default.
|
||||
# You can exclude tests based on tags, e.g. to skip Firefox testing,
|
||||
# `bazel test --test_tag_filters=-browser:firefox-local [targets]`
|
||||
browsers = [
|
||||
"@io_bazel_rules_webtesting//browsers:chromium-local",
|
||||
# Don't test on local Firefox by default, for faster builds.
|
||||
# We think that bugs in Angular tend to be caught the same in any
|
||||
# evergreen browser.
|
||||
# "@io_bazel_rules_webtesting//browsers:firefox-local",
|
||||
# TODO(alexeagle): add remote browsers on SauceLabs
|
||||
],
|
||||
**kwargs
|
||||
)
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
|
||||
See https://www.npmjs.com/package/http-server
|
||||
"""
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary")
|
||||
|
||||
def http_server(templated_args = [], **kwargs):
|
||||
# By default, we pass an argument pointing the http server to the
|
||||
# package of the caller.
|
||||
# This assumes there is an index.html in the package directory.
|
||||
if not templated_args:
|
||||
templated_args = [native.package_name()]
|
||||
# By default, we pass an argument pointing the http server to the
|
||||
# package of the caller.
|
||||
# This assumes there is an index.html in the package directory.
|
||||
if not templated_args:
|
||||
templated_args = [native.package_name()]
|
||||
|
||||
nodejs_binary(
|
||||
node_modules = "@http-server_runtime_deps//:node_modules",
|
||||
entry_point = "http-server/bin/http-server",
|
||||
templated_args = templated_args,
|
||||
**kwargs)
|
||||
nodejs_binary(
|
||||
node_modules = "@http-server_runtime_deps//:node_modules",
|
||||
entry_point = "http-server/bin/http-server",
|
||||
templated_args = templated_args,
|
||||
**kwargs
|
||||
)
|
||||
|
|
|
@ -9,17 +9,17 @@ load("@build_bazel_rules_nodejs//:defs.bzl", "yarn_install")
|
|||
load("@angular//packages/bazel/src:ng_setup_workspace.bzl", _ng_setup_workspace = "ng_setup_workspace")
|
||||
|
||||
def ng_setup_workspace():
|
||||
"""This repository rule should be called from your WORKSPACE file.
|
||||
"""This repository rule should be called from your WORKSPACE file.
|
||||
|
||||
It creates some additional Bazel external repositories that are used internally
|
||||
to build angular
|
||||
"""
|
||||
yarn_install(
|
||||
name = "angular_deps",
|
||||
package_json = "@angular//:package.json",
|
||||
yarn_lock = "@angular//:yarn.lock",
|
||||
data = ["@angular//:tools/yarn/check-yarn.js", "@angular//:tools/postinstall-patches.js"],
|
||||
node_modules_filegroup = """
|
||||
It creates some additional Bazel external repositories that are used internally
|
||||
to build angular
|
||||
"""
|
||||
yarn_install(
|
||||
name = "angular_deps",
|
||||
package_json = "@angular//:package.json",
|
||||
yarn_lock = "@angular//:yarn.lock",
|
||||
data = ["@angular//:tools/yarn/check-yarn.js", "@angular//:tools/postinstall-patches.js"],
|
||||
node_modules_filegroup = """
|
||||
filegroup(
|
||||
name = "node_modules",
|
||||
srcs = glob(["/".join([
|
||||
|
@ -239,6 +239,7 @@ filegroup(
|
|||
"node_modules/protractor/**",
|
||||
"node_modules/@schematics/angular/**",
|
||||
]))
|
||||
""")
|
||||
""",
|
||||
)
|
||||
|
||||
_ng_setup_workspace()
|
||||
_ng_setup_workspace()
|
||||
|
|
|
@ -6,30 +6,30 @@
|
|||
"""This test verifies that a set of top level symbols from a javascript file match a gold file.
|
||||
"""
|
||||
|
||||
# This does a deep import under //internal because of not wanting the wrapper macro
|
||||
# This does a deep import under //internal because of not wanting the wrapper macro
|
||||
# because it introduces an extra target_bin target.
|
||||
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_test", "nodejs_binary")
|
||||
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_binary", "nodejs_test")
|
||||
|
||||
def js_expected_symbol_test(name, src, golden, **kwargs):
|
||||
"""This test verifies that a set of top level symbols from a javascript file match a gold file.
|
||||
"""
|
||||
all_data = [src, golden]
|
||||
all_data += [Label("//tools/symbol-extractor:lib")]
|
||||
all_data += [Label("@bazel_tools//tools/bash/runfiles")]
|
||||
entry_point = "angular/tools/symbol-extractor/cli.js"
|
||||
"""This test verifies that a set of top level symbols from a javascript file match a gold file.
|
||||
"""
|
||||
all_data = [src, golden]
|
||||
all_data += [Label("//tools/symbol-extractor:lib")]
|
||||
all_data += [Label("@bazel_tools//tools/bash/runfiles")]
|
||||
entry_point = "angular/tools/symbol-extractor/cli.js"
|
||||
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = all_data,
|
||||
entry_point = entry_point,
|
||||
templated_args = ["$(location %s)" % src, "$(location %s)" % golden],
|
||||
**kwargs
|
||||
)
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = all_data,
|
||||
entry_point = entry_point,
|
||||
templated_args = ["$(location %s)" % src, "$(location %s)" % golden],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = name + '.accept',
|
||||
data = all_data,
|
||||
entry_point = entry_point,
|
||||
templated_args = ["$(location %s)" % src, "$(location %s)" % golden, '--accept'],
|
||||
**kwargs
|
||||
)
|
||||
nodejs_binary(
|
||||
name = name + ".accept",
|
||||
data = all_data,
|
||||
entry_point = entry_point,
|
||||
templated_args = ["$(location %s)" % src, "$(location %s)" % golden, "--accept"],
|
||||
**kwargs
|
||||
)
|
||||
|
|
|
@ -14,43 +14,45 @@
|
|||
|
||||
"""Runs ts_api_guardian
|
||||
"""
|
||||
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_test", "nodejs_binary")
|
||||
|
||||
load("@build_bazel_rules_nodejs//internal/node:node.bzl", "nodejs_binary", "nodejs_test")
|
||||
|
||||
COMMON_MODULE_IDENTIFIERS = ["angular", "jasmine", "protractor"]
|
||||
|
||||
def ts_api_guardian_test(name, golden, actual, data = [], **kwargs):
|
||||
"""Runs ts_api_guardian
|
||||
"""
|
||||
data += [
|
||||
"//tools/ts-api-guardian:lib",
|
||||
"//tools/ts-api-guardian:bin/ts-api-guardian",
|
||||
"@bazel_tools//tools/bash/runfiles",
|
||||
]
|
||||
"""Runs ts_api_guardian
|
||||
"""
|
||||
data += [
|
||||
"//tools/ts-api-guardian:lib",
|
||||
"//tools/ts-api-guardian:bin/ts-api-guardian",
|
||||
"@bazel_tools//tools/bash/runfiles",
|
||||
]
|
||||
|
||||
args = [
|
||||
# Needed so that node doesn't walk back to the source directory.
|
||||
# From there, the relative imports would point to .ts files.
|
||||
"--node_options=--preserve-symlinks",
|
||||
"--stripExportPattern", "^\(__\|ɵ\)",
|
||||
]
|
||||
for i in COMMON_MODULE_IDENTIFIERS:
|
||||
args += ["--allowModuleIdentifiers", i]
|
||||
args = [
|
||||
# Needed so that node doesn't walk back to the source directory.
|
||||
# From there, the relative imports would point to .ts files.
|
||||
"--node_options=--preserve-symlinks",
|
||||
"--stripExportPattern",
|
||||
"^\(__\|ɵ\)",
|
||||
]
|
||||
for i in COMMON_MODULE_IDENTIFIERS:
|
||||
args += ["--allowModuleIdentifiers", i]
|
||||
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = data,
|
||||
node_modules = "@ts-api-guardian_runtime_deps//:node_modules",
|
||||
entry_point = "angular/tools/ts-api-guardian/bin/ts-api-guardian",
|
||||
templated_args = args + ["--verify", golden, actual],
|
||||
testonly = 1,
|
||||
**kwargs
|
||||
)
|
||||
nodejs_test(
|
||||
name = name,
|
||||
data = data,
|
||||
node_modules = "@ts-api-guardian_runtime_deps//:node_modules",
|
||||
entry_point = "angular/tools/ts-api-guardian/bin/ts-api-guardian",
|
||||
templated_args = args + ["--verify", golden, actual],
|
||||
testonly = 1,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
nodejs_binary(
|
||||
name = name + ".accept",
|
||||
data = data,
|
||||
node_modules = "@ts-api-guardian_runtime_deps//:node_modules",
|
||||
entry_point = "angular/tools/ts-api-guardian/bin/ts-api-guardian",
|
||||
templated_args = args + ["--out", golden, actual],
|
||||
**kwargs
|
||||
)
|
||||
nodejs_binary(
|
||||
name = name + ".accept",
|
||||
data = data,
|
||||
node_modules = "@ts-api-guardian_runtime_deps//:node_modules",
|
||||
entry_point = "angular/tools/ts-api-guardian/bin/ts-api-guardian",
|
||||
templated_args = args + ["--out", golden, actual],
|
||||
**kwargs
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue