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