feat: support stamp substituions (#435)

This commit is contained in:
Sahin Yort 2023-05-16 16:14:50 -07:00 committed by GitHub
parent e0ae19940c
commit 6af964f261
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 538 additions and 38 deletions

View File

@ -16,6 +16,8 @@ try-import %workspace%/.aspect/bazelrc/bazel6.bazelrc
# For testing our --stamp behavior.
# Normally users would use a --workspace_status_command with a script that calls `git describe`.
build --embed_label=v1.2.3
# Mock versioning command to test the --stamp behavior
build --workspace_status_command="echo BUILD_SCM_VERSION 1.2.3"
# For releasing, use --workspace_status_command and stamp
build:release --workspace_status_command "${PWD}/workspace_status.sh"

View File

@ -13,12 +13,14 @@ bazel_dep(name = "stardoc", repo_name = "io_bazel_stardoc", version = "0.5.0")
ext = use_extension("@aspect_bazel_lib//lib:extensions.bzl", "ext")
use_repo(ext, "copy_directory_toolchains", "copy_to_directory_toolchains", "jq_toolchains", "yq_toolchains", "coreutils_toolchains")
use_repo(ext, "copy_directory_toolchains", "copy_to_directory_toolchains", "jq_toolchains", "yq_toolchains", "coreutils_toolchains", "expand_template_toolchains")
register_toolchains(
"@copy_directory_toolchains//:all",
"@copy_to_directory_toolchains//:all",
"@jq_toolchains//:all",
"@yq_toolchains//:all",
"@coreutils_toolchains//:all"
"@coreutils_toolchains//:all",
"@expand_template_toolchains//:all"
)

View File

@ -37,6 +37,11 @@ stardoc_with_diff_test(
bzl_library_target = "//lib:expand_make_vars",
)
stardoc_with_diff_test(
name = "expand_template",
bzl_library_target = "//lib:expand_template",
)
stardoc_with_diff_test(
name = "params_file",
bzl_library_target = "//lib:params_file",

View File

@ -7,7 +7,7 @@ Public API for expanding variables
## expand_template
<pre>
expand_template(<a href="#expand_template-name">name</a>, <a href="#expand_template-data">data</a>, <a href="#expand_template-is_executable">is_executable</a>, <a href="#expand_template-out">out</a>, <a href="#expand_template-substitutions">substitutions</a>, <a href="#expand_template-template">template</a>)
expand_template(<a href="#expand_template-name">name</a>, <a href="#expand_template-data">data</a>, <a href="#expand_template-is_executable">is_executable</a>, <a href="#expand_template-out">out</a>, <a href="#expand_template-stamp">stamp</a>, <a href="#expand_template-stamp_substitutions">stamp_substitutions</a>, <a href="#expand_template-substitutions">substitutions</a>, <a href="#expand_template-template">template</a>)
</pre>
Template expansion
@ -31,7 +31,9 @@ such as `$(BINDIR)`, `$(TARGET_CPU)`, and `$(COMPILATION_MODE)` as documented in
| <a id="expand_template-data"></a>data | List of targets for additional lookup information. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="expand_template-is_executable"></a>is_executable | Whether to mark the output file as executable. | Boolean | optional | False |
| <a id="expand_template-out"></a>out | Where to write the expanded file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="expand_template-substitutions"></a>substitutions | Mapping of strings to substitutions. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | required | |
| <a id="expand_template-stamp"></a>stamp | Whether to encode build information into the output. Possible values:<br><br> - <code>stamp = 1</code>: Always stamp the build information into the output, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result. - <code>stamp = 0</code>: Never stamp, instead replace build information by constant values. This gives good build result caching. - <code>stamp = -1</code>: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag. Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | -1 |
| <a id="expand_template-stamp_substitutions"></a>stamp_substitutions | Mapping of strings to substitutions.<br><br> There are overlayed on top of substitutions when stamping is enabled for the target.<br><br> Substitutions can contain $(execpath :target) and $(rootpath :target) expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when stamping is enabled for the target. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="expand_template-substitutions"></a>substitutions | Mapping of strings to substitutions.<br><br> Substitutions can contain $(execpath :target) and $(rootpath :target) expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when stamping is enabled for the target. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="expand_template-template"></a>template | The template file to expand. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |

39
docs/expand_template.md generated Normal file
View File

@ -0,0 +1,39 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->
Public API for expand template
<a id="expand_template"></a>
## expand_template
<pre>
expand_template(<a href="#expand_template-name">name</a>, <a href="#expand_template-data">data</a>, <a href="#expand_template-is_executable">is_executable</a>, <a href="#expand_template-out">out</a>, <a href="#expand_template-stamp">stamp</a>, <a href="#expand_template-stamp_substitutions">stamp_substitutions</a>, <a href="#expand_template-substitutions">substitutions</a>, <a href="#expand_template-template">template</a>)
</pre>
Template expansion
This performs a simple search over the template file for the keys in substitutions,
and replaces them with the corresponding values.
Values may also use location templates as documented in
[expand_locations](https://github.com/aspect-build/bazel-lib/blob/main/docs/expand_make_vars.md#expand_locations)
as well as [configuration variables](https://docs.bazel.build/versions/main/skylark/lib/ctx.html#var)
such as `$(BINDIR)`, `$(TARGET_CPU)`, and `$(COMPILATION_MODE)` as documented in
[expand_variables](https://github.com/aspect-build/bazel-lib/blob/main/docs/expand_make_vars.md#expand_variables).
**ATTRIBUTES**
| Name | Description | Type | Mandatory | Default |
| :------------- | :------------- | :------------- | :------------- | :------------- |
| <a id="expand_template-name"></a>name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required | |
| <a id="expand_template-data"></a>data | List of targets for additional lookup information. | <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a> | optional | [] |
| <a id="expand_template-is_executable"></a>is_executable | Whether to mark the output file as executable. | Boolean | optional | False |
| <a id="expand_template-out"></a>out | Where to write the expanded file. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |
| <a id="expand_template-stamp"></a>stamp | Whether to encode build information into the output. Possible values:<br><br> - <code>stamp = 1</code>: Always stamp the build information into the output, even in [--nostamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) builds. This setting should be avoided, since it is non-deterministic. It potentially causes remote cache misses for the target and any downstream actions that depend on the result. - <code>stamp = 0</code>: Never stamp, instead replace build information by constant values. This gives good build result caching. - <code>stamp = -1</code>: Embedding of build information is controlled by the [--[no]stamp](https://docs.bazel.build/versions/main/user-manual.html#flag--stamp) flag. Stamped targets are not rebuilt unless their dependencies change. | Integer | optional | -1 |
| <a id="expand_template-stamp_substitutions"></a>stamp_substitutions | Mapping of strings to substitutions.<br><br> There are overlayed on top of substitutions when stamping is enabled for the target.<br><br> Substitutions can contain $(execpath :target) and $(rootpath :target) expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when stamping is enabled for the target. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="expand_template-substitutions"></a>substitutions | Mapping of strings to substitutions.<br><br> Substitutions can contain $(execpath :target) and $(rootpath :target) expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when stamping is enabled for the target. | <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a> | optional | {} |
| <a id="expand_template-template"></a>template | The template file to expand. | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required | |

19
docs/repositories.md generated
View File

@ -78,6 +78,25 @@ Registers coreutils toolchain and repositories
| <a id="register_coreutils_toolchains-register"></a>register | whether to call through to native.register_toolchains. Should be True for WORKSPACE users, but false when used under bzlmod extension | <code>True</code> |
<a id="register_expand_template_toolchains"></a>
## register_expand_template_toolchains
<pre>
register_expand_template_toolchains(<a href="#register_expand_template_toolchains-name">name</a>, <a href="#register_expand_template_toolchains-register">register</a>)
</pre>
Registers expand_template toolchain and repositories
**PARAMETERS**
| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="register_expand_template_toolchains-name"></a>name | override the prefix for the generated toolchain repositories | <code>"expand_template"</code> |
| <a id="register_expand_template_toolchains-register"></a>register | whether to call through to native.register_toolchains. Should be True for WORKSPACE users, but false when used under bzlmod extension | <code>True</code> |
<a id="register_jq_toolchains"></a>
## register_jq_toolchains

View File

@ -9,9 +9,11 @@ import %workspace%/.aspect/bazelrc/debug.bazelrc
import %workspace%/.aspect/bazelrc/javascript.bazelrc
### PROJECT SPECIFIC OPTIONS ###
# for testing expand_template
build --workspace_status_command="echo BUILD_SCM_VERSION 1.2.3"
# Load any settings & overrides specific to the current user from `.aspect/bazelrc/user.bazelrc`.
# This file should appear in `.gitignore` so that settings are not shared with team members. This
# should be last statement in this config so the user configuration is able to overwrite flags from
# this file. See https://bazel.build/configure/best-practices#bazelrc-file.
try-import %workspace%/.aspect/bazelrc/user.bazelrc
try-import %workspace%/.aspect/bazelrc/user.bazelrc

View File

@ -1,6 +1,7 @@
load("@aspect_bazel_lib//lib:copy_directory.bzl", "copy_directory")
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
load("@aspect_bazel_lib//lib:expand_make_vars.bzl", "expand_template")
load("@aspect_bazel_lib//lib:jq.bzl", "jq")
load("@aspect_bazel_lib//lib:yq.bzl", "yq")
@ -61,3 +62,28 @@ diff_test(
# Source directories are not support on remote execution.
tags = ["no-remote-exec"],
)
# Validate that expand_template works and resolves its toolchain
expand_template(
name = "a_tmpl_stamp",
out = "a_stamp",
data = ["a.tmpl"],
stamp = 1,
stamp_substitutions = {
"{{VERSION}}": "v{{BUILD_SCM_VERSION}}",
},
substitutions = {
"{{VERSION}}": "v0.0.0",
"{{WORKSPACE}}": "$(WORKSPACE)",
},
template = "a.tmpl",
)
diff_test(
name = "a_stamp_test",
file1 = ":a_stamp",
file2 = select({
"@aspect_bazel_lib//lib:bzlmod": "a_stamp_expected_bzlmod",
"//conditions:default": "a_stamp_expected",
}),
)

4
e2e/smoke/a.tmpl Normal file
View File

@ -0,0 +1,4 @@
WORKSPACE: {{WORKSPACE}}
VERSION: {{VERSION}}
WORKSPACE: {{WORKSPACE}}
VERSION: {{VERSION}}

View File

@ -0,0 +1,4 @@
WORKSPACE: __main__
VERSION: v1.2.3
WORKSPACE: __main__
VERSION: v1.2.3

View File

@ -0,0 +1,4 @@
WORKSPACE: _main
VERSION: v1.2.3
WORKSPACE: _main
VERSION: v1.2.3

View File

@ -51,6 +51,10 @@ toolchain_type(
name = "coreutils_toolchain_type",
)
toolchain_type(
name = "expand_template_toolchain_type",
)
bzl_library(
name = "docs",
srcs = ["docs.bzl"],
@ -62,8 +66,19 @@ bzl_library(
srcs = ["expand_make_vars.bzl"],
deps = [
"//lib/private/docs:expand_locations",
"//lib/private/docs:expand_template",
"//lib/private/docs:expand_variables",
":expand_template",
],
)
bzl_library(
name = "expand_template",
srcs = ["expand_template.bzl"],
deps = [
"//lib/private/docs:expand_locations",
"//lib/private/docs:expand_variables",
"//lib/private/docs:expand_template",
],
)
@ -216,6 +231,7 @@ bzl_library(
"//lib/private/docs:copy_directory_toolchain",
"//lib/private/docs:copy_to_directory_toolchain",
"//lib/private/docs:coreutils_toolchain",
"//lib/private/docs:expand_template_toolchain",
"//lib/private/docs:jq_toolchain",
"//lib/private/docs:local_config_platform",
"//lib/private/docs:yq_toolchain",

View File

@ -2,8 +2,9 @@
load("//lib/private:expand_locations.bzl", _expand_locations = "expand_locations")
load("//lib/private:expand_variables.bzl", _expand_variables = "expand_variables")
load("//lib/private:expand_template.bzl", _expand_template = "expand_template")
load(":expand_template.bzl", _expand_template = "expand_template")
expand_locations = _expand_locations
expand_variables = _expand_variables
# TODO: 2.0 remove re-export from this file.
expand_template = _expand_template

5
lib/expand_template.bzl Normal file
View File

@ -0,0 +1,5 @@
"Public API for expand template"
load("//lib/private:expand_template.bzl", _expand_template = "expand_template")
expand_template = _expand_template

View File

@ -6,7 +6,8 @@ load(
"register_copy_to_directory_toolchains",
"register_jq_toolchains",
"register_yq_toolchains",
"register_coreutils_toolchains"
"register_coreutils_toolchains",
"register_expand_template_toolchains",
)
load("//lib/private:host_repo.bzl", "host_repo")
@ -16,7 +17,8 @@ def _toolchain_extension(mctx):
register_jq_toolchains(register = False)
register_yq_toolchains(register = False)
register_coreutils_toolchains(register = False)
register_expand_template_toolchains(register = False)
create_host_repo = False
for module in mctx.modules:
if len(module.tags.host) > 0:

View File

@ -102,6 +102,7 @@ bzl_library(
deps = [
":expand_locations",
"@bazel_skylib//lib:dicts",
"//lib:stamping"
],
)
@ -247,6 +248,11 @@ bzl_library(
srcs = ["//lib/private:coreutils_toolchain.bzl"],
)
bzl_library(
name = "expand_template_toolchain",
srcs = ["//lib/private:expand_template_toolchain.bzl"],
deps = ["//lib:stamping"]
)
bzl_library(
name = "strings",

View File

@ -1,21 +1,63 @@
"expand_template rule"
load("@bazel_skylib//lib:dicts.bzl", "dicts")
load(":expand_locations.bzl", _expand_locations = "expand_locations")
load(":expand_variables.bzl", _expand_variables = "expand_variables")
load("//lib:stamping.bzl", "STAMP_ATTRS", "maybe_stamp")
def _expand_substitutions(ctx, substitutions):
result = {}
for k, v in substitutions.items():
result[k] = " ".join([
_expand_variables(ctx, e, outs = [ctx.outputs.out], attribute_name = "substitutions")
for e in _expand_locations(ctx, v, ctx.attr.data).split(" ")
])
return result
def _expand_template_impl(ctx):
template = ctx.file.template
substitutions = _expand_substitutions(ctx, ctx.attr.substitutions)
expand_template_info = ctx.toolchains["@aspect_bazel_lib//lib:expand_template_toolchain_type"].expand_template_info
stamp = maybe_stamp(ctx)
if stamp:
substitutions = dicts.add(substitutions, _expand_substitutions(ctx, ctx.attr.stamp_substitutions))
substitutions_out = ctx.actions.declare_file("{}_substitutions.json".format(ctx.label.name))
ctx.actions.write(
output = substitutions_out,
content = json.encode(substitutions)
)
substitutions = {}
for k, v in ctx.attr.substitutions.items():
substitutions[k] = " ".join([_expand_variables(ctx, e, outs = [ctx.outputs.out], attribute_name = "substitutions") for e in _expand_locations(ctx, v, ctx.attr.data).split(" ")])
inputs = [
ctx.file.template,
stamp.volatile_status_file,
stamp.stable_status_file,
substitutions_out,
]
ctx.actions.expand_template(
template = template,
output = ctx.outputs.out,
substitutions = substitutions,
is_executable = ctx.attr.is_executable,
)
args = ctx.actions.args()
args.add(ctx.file.template)
args.add(ctx.outputs.out)
args.add(substitutions_out)
args.add(stamp.volatile_status_file)
args.add(stamp.stable_status_file)
args.add(ctx.attr.is_executable)
ctx.actions.run(
arguments = [args],
outputs = [ctx.outputs.out],
inputs = inputs,
executable = expand_template_info.bin,
)
else:
ctx.actions.expand_template(
template = ctx.file.template,
output = ctx.outputs.out,
substitutions = substitutions,
is_executable = ctx.attr.is_executable,
)
all_outs = [ctx.outputs.out]
runfiles = ctx.runfiles(files = all_outs)
return [DefaultInfo(files = depset(all_outs), runfiles = runfiles)]
expand_template_lib = struct(
doc = """Template expansion
@ -30,34 +72,49 @@ such as `$(BINDIR)`, `$(TARGET_CPU)`, and `$(COMPILATION_MODE)` as documented in
[expand_variables](https://github.com/aspect-build/bazel-lib/blob/main/docs/expand_make_vars.md#expand_variables).
""",
implementation = _expand_template_impl,
attrs = {
"template": attr.label(
doc = "The template file to expand.",
mandatory = True,
allow_single_file = True,
toolchains = ["@aspect_bazel_lib//lib:expand_template_toolchain_type"],
attrs = dicts.add({
"data": attr.label_list(
doc = "List of targets for additional lookup information.",
allow_files = True,
),
"substitutions": attr.string_dict(
doc = "Mapping of strings to substitutions.",
mandatory = True,
"is_executable": attr.bool(
doc = "Whether to mark the output file as executable.",
),
"out": attr.output(
doc = "Where to write the expanded file.",
mandatory = True,
),
"is_executable": attr.bool(
doc = "Whether to mark the output file as executable.",
default = False,
mandatory = False,
"stamp_substitutions": attr.string_dict(
doc = """Mapping of strings to substitutions.
There are overlayed on top of substitutions when stamping is enabled
for the target.
Substitutions can contain $(execpath :target) and $(rootpath :target)
expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when
stamping is enabled for the target.
""",
),
"data": attr.label_list(
doc = "List of targets for additional lookup information.",
allow_files = True,
"substitutions": attr.string_dict(
doc = """Mapping of strings to substitutions.
Substitutions can contain $(execpath :target) and $(rootpath :target)
expansions, $(MAKEVAR) expansions and {{STAMP_VAR}} expansions when
stamping is enabled for the target.
""",
),
},
"template": attr.label(
doc = "The template file to expand.",
mandatory = True,
allow_single_file = True,
),
}, **STAMP_ATTRS),
)
expand_template = rule(
doc = expand_template_lib.doc,
implementation = expand_template_lib.implementation,
toolchains = expand_template_lib.toolchains,
attrs = expand_template_lib.attrs,
)

View File

@ -0,0 +1,188 @@
"Setup expand_template toolchain repositories and rules"
# https://github.com/aspect-build/bazel-lib/releases
#
# The integrity hashes can be automatically fetched for the latest expand_template release by running
# `tools/expand_template/mirror_release.sh`. To calculate for a specific release run
# `tools/expand_template/mirror_release.sh <release_version>`
EXPAND_TEMPLATE_VERSION = "1.31.3"
EXPAND_TEMPLATE_INTEGRITY = {
"darwin_amd64": "sha256-2QaptqytZw9YQeV8cDA8MagRp998VTGs65btCdbVA0w=",
"darwin_arm64": "sha256-5W65OozVW+qSDRKqcXLjalh/hN/50EX8Z63V6MX/Wwc=",
"linux_amd64": "sha256-hc4+R/U1nq/3VXFerYimWyHFcxocVmt3gwGNvDL94sY=",
"linux_arm64": "sha256-DCm5ns8geCWGg1kpCMAE7RsoZt0OWp4vml7rpT0dYBs=",
"windows_amd64": "sha256-GDHRDOIptZAXHFmC1OOWDQl+3blwhi47RJBciLym4U8=",
}
# Platform names follow the platform naming convention in @aspect_bazel_lib//:lib/private/repo_utils.bzl
EXPAND_TEMPLATE_PLATFORMS = {
"darwin_amd64": struct(
compatible_with = [
"@platforms//os:macos",
"@platforms//cpu:x86_64",
],
),
"darwin_arm64": struct(
compatible_with = [
"@platforms//os:macos",
"@platforms//cpu:aarch64",
],
),
"linux_amd64": struct(
compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
),
"linux_arm64": struct(
compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:aarch64",
],
),
"windows_amd64": struct(
compatible_with = [
"@platforms//os:windows",
"@platforms//cpu:x86_64",
],
),
}
ExpandTemplateInfo = provider(
doc = "Provide info for executing expand_template",
fields = {
"bin": "Executable expand_template binary",
},
)
def _expand_template_toolchain_impl(ctx):
binary = ctx.executable.bin
default_info = DefaultInfo(
files = depset([binary]),
runfiles = ctx.runfiles(files = [binary]),
)
expand_template_info = ExpandTemplateInfo(
bin = binary,
)
# Export all the providers inside our ToolchainInfo
# so the resolved_toolchain rule can grab and re-export them.
toolchain_info = platform_common.ToolchainInfo(
expand_template_info = expand_template_info,
default = default_info,
)
return [default_info, toolchain_info]
expand_template_toolchain = rule(
implementation = _expand_template_toolchain_impl,
attrs = {
"bin": attr.label(
mandatory = True,
allow_single_file = True,
executable = True,
cfg = "exec",
),
},
)
def _expand_template_toolchains_repo_impl(rctx):
# Expose a concrete toolchain which is the result of Bazel resolving the toolchain
# for the execution or target platform.
# Workaround for https://github.com/bazelbuild/bazel/issues/14009
starlark_content = """# @generated by @aspect_bazel_lib//lib/private:expand_template_toolchain.bzl
# Forward all the providers
def _resolved_toolchain_impl(ctx):
toolchain_info = ctx.toolchains["@aspect_bazel_lib//lib:expand_template_toolchain_type"]
return [
toolchain_info,
toolchain_info.default,
toolchain_info.expand_template_info,
toolchain_info.template_variables,
]
# Copied from java_toolchain_alias
# https://cs.opensource.google/bazel/bazel/+/master:tools/jdk/java_toolchain_alias.bzl
resolved_toolchain = rule(
implementation = _resolved_toolchain_impl,
toolchains = ["@aspect_bazel_lib//lib:expand_template_toolchain_type"],
incompatible_use_toolchain_transition = True,
)
"""
rctx.file("defs.bzl", starlark_content)
build_content = """# @generated by @aspect_bazel_lib//lib/private:expand_template_toolchain.bzl
#
# These can be registered in the workspace file or passed to --extra_toolchains flag.
# By default all these toolchains are registered by the expand_template_register_toolchains macro
# so you don't normally need to interact with these targets.
load(":defs.bzl", "resolved_toolchain")
resolved_toolchain(name = "resolved_toolchain", visibility = ["//visibility:public"])
"""
for [platform, meta] in EXPAND_TEMPLATE_PLATFORMS.items():
build_content += """
toolchain(
name = "{platform}_toolchain",
exec_compatible_with = {compatible_with},
toolchain = "@{user_repository_name}_{platform}//:expand_template_toolchain",
toolchain_type = "@aspect_bazel_lib//lib:expand_template_toolchain_type",
)
""".format(
platform = platform,
user_repository_name = rctx.attr.user_repository_name,
compatible_with = meta.compatible_with,
)
# Base BUILD file for this repository
rctx.file("BUILD.bazel", build_content)
expand_template_toolchains_repo = repository_rule(
_expand_template_toolchains_repo_impl,
doc = """Creates a repository with toolchain definitions for all known platforms
which can be registered or selected.""",
attrs = {
"user_repository_name": attr.string(doc = "Base name for toolchains repository"),
},
)
def _expand_template_platform_repo_impl(rctx):
is_windows = rctx.attr.platform.startswith("windows_")
meta = EXPAND_TEMPLATE_PLATFORMS[rctx.attr.platform]
release_platform = meta.release_platform if hasattr(meta, "release_platform") else rctx.attr.platform
# https://github.com/aspect-build/bazel-lib/releases/download/v1.19.0/expand_template-linux_amd64
url = "https://github.com/aspect-build/bazel-lib/releases/download/v{0}/expand_template-{1}{2}".format(
EXPAND_TEMPLATE_VERSION,
release_platform,
".exe" if is_windows else "",
)
rctx.download(
url = url,
output = "expand_template.exe" if is_windows else "expand_template",
executable = True,
integrity = EXPAND_TEMPLATE_INTEGRITY[release_platform],
)
build_content = """# @generated by @aspect_bazel_lib//lib/private:expand_template_toolchain.bzl
load("@aspect_bazel_lib//lib/private:expand_template_toolchain.bzl", "expand_template_toolchain")
exports_files(["{0}"])
expand_template_toolchain(name = "expand_template_toolchain", bin = "{0}", visibility = ["//visibility:public"])
""".format("expand_template.exe" if is_windows else "expand_template")
# Base BUILD file for this repository
rctx.file("BUILD.bazel", build_content)
expand_template_platform_repo = repository_rule(
implementation = _expand_template_platform_repo_impl,
doc = "Fetch external tools needed for expand_template toolchain",
attrs = {
"platform": attr.string(mandatory = True, values = EXPAND_TEMPLATE_PLATFORMS.keys()),
},
)

View File

@ -5,6 +5,7 @@ load("//lib/private:yq_toolchain.bzl", "YQ_PLATFORMS", "yq_host_alias_repo", "yq
load("//lib/private:copy_to_directory_toolchain.bzl", "COPY_TO_DIRECTORY_PLATFORMS", "copy_to_directory_platform_repo", "copy_to_directory_toolchains_repo")
load("//lib/private:coreutils_toolchain.bzl", "COREUTILS_PLATFORMS", "coreutils_platform_repo", "coreutils_toolchains_repo", _DEFAULT_COREUTILS_VERSION = "DEFAULT_COREUTILS_VERSION")
load("//lib/private:copy_directory_toolchain.bzl", "COPY_DIRECTORY_PLATFORMS", "copy_directory_platform_repo", "copy_directory_toolchains_repo")
load("//lib/private:expand_template_toolchain.bzl", "EXPAND_TEMPLATE_PLATFORMS", "expand_template_platform_repo", "expand_template_toolchains_repo")
load("//lib/private:local_config_platform.bzl", "local_config_platform")
load("//lib:utils.bzl", "is_bazel_6_or_greater", http_archive = "maybe_http_archive")
@ -39,6 +40,9 @@ def aspect_bazel_lib_dependencies(override_local_config_platform = False):
register_copy_directory_toolchains()
register_copy_to_directory_toolchains()
# Always register the expand_template toolchain
register_expand_template_toolchains()
# Always register the coreutils toolchain
register_coreutils_toolchains()
@ -161,3 +165,25 @@ def register_copy_to_directory_toolchains(name = "copy_to_directory", register =
name = "%s_toolchains" % name,
user_repository_name = name,
)
def register_expand_template_toolchains(name = "expand_template", register = True):
"""Registers expand_template toolchain and repositories
Args:
name: override the prefix for the generated toolchain repositories
register: whether to call through to native.register_toolchains.
Should be True for WORKSPACE users, but false when used under bzlmod extension
"""
for [platform, meta] in EXPAND_TEMPLATE_PLATFORMS.items():
expand_template_platform_repo(
name = "%s_%s" % (name, platform),
platform = platform,
)
if register:
native.register_toolchains("@%s_toolchains//:%s_toolchain" % (name, platform))
expand_template_toolchains_repo(
name = "%s_toolchains" % name,
user_repository_name = name,
)

View File

@ -0,0 +1,60 @@
load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
load("@aspect_bazel_lib//lib:testing.bzl", "assert_contains")
load("@aspect_bazel_lib//lib:expand_make_vars.bzl", "expand_template")
expand_template(
name = "a_tmpl_stamp",
out = "a_stamp",
data = ["a.tmpl"],
stamp = 1,
stamp_substitutions = {
"{{VERSION}}": "v{{BUILD_SCM_VERSION}}",
},
substitutions = {
"{{TMPL_PATH}}": "$(rootpath a.tmpl)",
"{{VERSION}}": "v0.0.0",
"{{WORKSPACE}}": "$(WORKSPACE)",
},
template = "a.tmpl",
)
diff_test(
name = "a_stamp_test",
file1 = ":a_stamp",
file2 = select({
"@aspect_bazel_lib//lib:bzlmod": "a_stamp_expected_bzlmod",
"//conditions:default": "a_stamp_expected",
}),
)
expand_template(
name = "a_tmpl",
out = "a",
data = ["a.tmpl"],
stamp = 0,
stamp_substitutions = {
"{{VERSION}}": "v{{BUILD_SCM_VERSION}}",
},
substitutions = {
"{{TMPL_PATH}}": "$(rootpath a.tmpl)",
"{{VERSION}}": "v0.0.0",
"{{WORKSPACE}}": "$(WORKSPACE)",
},
template = "a.tmpl",
)
diff_test(
name = "a_test",
file1 = ":a",
file2 = select({
"@aspect_bazel_lib//lib:bzlmod": "a_expected_bzlmod",
"//conditions:default": "a_expected",
}),
)
# This test requires that DefaultInfo be returned with the proper outputs.
assert_contains(
name = "default_info_test",
actual = ":a_tmpl_stamp",
expected = "WORKSPACE:",
)

View File

@ -0,0 +1,6 @@
WORKSPACE: {{WORKSPACE}}
VERSION: {{VERSION}}
TMPL_PATH: {{TMPL_PATH}}
WORKSPACE: {{WORKSPACE}}
VERSION: {{VERSION}}
TMPL_PATH: {{TMPL_PATH}}

View File

@ -0,0 +1,6 @@
WORKSPACE: aspect_bazel_lib
VERSION: v0.0.0
TMPL_PATH: lib/tests/expand_template/a.tmpl
WORKSPACE: aspect_bazel_lib
VERSION: v0.0.0
TMPL_PATH: lib/tests/expand_template/a.tmpl

View File

@ -0,0 +1,6 @@
WORKSPACE: _main
VERSION: v0.0.0
TMPL_PATH: lib/tests/expand_template/a.tmpl
WORKSPACE: _main
VERSION: v0.0.0
TMPL_PATH: lib/tests/expand_template/a.tmpl

View File

@ -0,0 +1,6 @@
WORKSPACE: aspect_bazel_lib
VERSION: v1.2.3
TMPL_PATH: lib/tests/expand_template/a.tmpl
WORKSPACE: aspect_bazel_lib
VERSION: v1.2.3
TMPL_PATH: lib/tests/expand_template/a.tmpl

View File

@ -0,0 +1,6 @@
WORKSPACE: _main
VERSION: v1.2.3
TMPL_PATH: lib/tests/expand_template/a.tmpl
WORKSPACE: _main
VERSION: v1.2.3
TMPL_PATH: lib/tests/expand_template/a.tmpl

View File

@ -12,8 +12,8 @@ else
fi
# Extract the checksums and output a starlark map entry
echo "expand_template_VERSION = \"$version\""
echo "expand_template_INTEGRITY = {"
echo "EXPAND_TEMPLATE_VERSION = \"$version\""
echo "EXPAND_TEMPLATE_INTEGRITY = {"
platforms=(darwin_{amd64,arm64} linux_{amd64,arm64} windows_amd64)
for release in ${platforms[@]}; do
integrity="https://github.com/aspect-build/bazel-lib/releases/download/v$version/expand_template-$release"