Skip to content

Commit

Permalink
Expose Toolchains and add ripgrep/sd toolchains.
Browse files Browse the repository at this point in the history
  • Loading branch information
rickvanprim committed Jun 22, 2024
1 parent 31b4bb6 commit aaf0250
Show file tree
Hide file tree
Showing 11 changed files with 682 additions and 1 deletion.
4 changes: 3 additions & 1 deletion internal_deps.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Users should *not* need to install these. If users see a load()
statement from these, that's a bug in our distribution.
"""

load("//lib:repositories.bzl", "register_bats_toolchains", "register_coreutils_toolchains", "register_jq_toolchains", "register_tar_toolchains", "register_yq_toolchains")
load("//lib:repositories.bzl", "register_bats_toolchains", "register_coreutils_toolchains", "register_jq_toolchains", "register_ripgrep_toolchains", "register_sd_toolchains", "register_tar_toolchains", "register_yq_toolchains")
load("//lib:utils.bzl", http_archive = "maybe_http_archive")

# buildifier: disable=unnamed-macro
Expand Down Expand Up @@ -66,6 +66,8 @@ def bazel_lib_internal_deps():

# Register toolchains for tests
register_jq_toolchains()
register_ripgrep_toolchains()
register_sd_toolchains()
register_yq_toolchains()
register_coreutils_toolchains()
register_tar_toolchains()
Expand Down
8 changes: 8 additions & 0 deletions lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ toolchain_type(
name = "jq_toolchain_type",
)

toolchain_type(
name = "ripgrep_toolchain_type",
)

toolchain_type(
name = "sd_toolchain_type",
)

toolchain_type(
name = "yq_toolchain_type",
)
Expand Down
22 changes: 22 additions & 0 deletions lib/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ load(
"DEFAULT_EXPAND_TEMPLATE_REPOSITORY",
"DEFAULT_JQ_REPOSITORY",
"DEFAULT_JQ_VERSION",
"DEFAULT_RIPGREP_REPOSITORY",
"DEFAULT_RIPGREP_VERSION",
"DEFAULT_SD_REPOSITORY",
"DEFAULT_SD_VERSION",
"DEFAULT_TAR_REPOSITORY",
"DEFAULT_YQ_REPOSITORY",
"DEFAULT_YQ_VERSION",
Expand All @@ -21,6 +25,8 @@ load(
"register_coreutils_toolchains",
"register_expand_template_toolchains",
"register_jq_toolchains",
"register_ripgrep_toolchains",
"register_sd_toolchains",
"register_tar_toolchains",
"register_yq_toolchains",
"register_zstd_toolchains",
Expand Down Expand Up @@ -68,6 +74,20 @@ def _toolchains_extension_impl(mctx):
toolchain_repos_fn = lambda name, version: register_jq_toolchains(name = name, version = version, register = False),
)

extension_utils.toolchain_repos_bfs(
mctx = mctx,
get_tag_fn = lambda tags: tags.ripgrep,
toolchain_name = "ripgrep",
toolchain_repos_fn = lambda name, version: register_ripgrep_toolchains(name = name, version = version, register = False),
)

extension_utils.toolchain_repos_bfs(
mctx = mctx,
get_tag_fn = lambda tags: tags.sd,
toolchain_name = "sd",
toolchain_repos_fn = lambda name, version: register_sd_toolchains(name = name, version = version, register = False),
)

extension_utils.toolchain_repos_bfs(
mctx = mctx,
get_tag_fn = lambda tags: tags.yq,
Expand Down Expand Up @@ -123,6 +143,8 @@ toolchains = module_extension(
"copy_directory": tag_class(attrs = {"name": attr.string(default = DEFAULT_COPY_DIRECTORY_REPOSITORY)}),
"copy_to_directory": tag_class(attrs = {"name": attr.string(default = DEFAULT_COPY_TO_DIRECTORY_REPOSITORY)}),
"jq": tag_class(attrs = {"name": attr.string(default = DEFAULT_JQ_REPOSITORY), "version": attr.string(default = DEFAULT_JQ_VERSION)}),
"ripgrep": tag_class(attrs = {"name": attr.string(default = DEFAULT_RIPGREP_REPOSITORY), "version": attr.string(default = DEFAULT_RIPGREP_VERSION)}),
"sd": tag_class(attrs = {"name": attr.string(default = DEFAULT_SD_REPOSITORY), "version": attr.string(default = DEFAULT_SD_VERSION)}),
"yq": tag_class(attrs = {"name": attr.string(default = DEFAULT_YQ_REPOSITORY), "version": attr.string(default = DEFAULT_YQ_VERSION)}),
"coreutils": tag_class(attrs = {"name": attr.string(default = DEFAULT_COREUTILS_REPOSITORY), "version": attr.string(default = DEFAULT_COREUTILS_VERSION)}),
"tar": tag_class(attrs = {"name": attr.string(default = DEFAULT_TAR_REPOSITORY)}),
Expand Down
220 changes: 220 additions & 0 deletions lib/private/ripgrep_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
"Setup ripgrep (rg) toolchain repositories and rules"

# Platform names follow the platform naming convention in @aspect_bazel_lib//:lib/private/repo_utils.bzl
RIPGREP_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",
],
),
}

DEFAULT_RIPGREP_VERSION = "14.1.0"

# https://github.com/BurntSushi/ripgrep
#
# The integrity hashes can be automatically fetched for the ripgrep releases by running
# `tools/ripgrep_mirror_release.sh`.
RIPGREP_VERSIONS = {
"14.1.0": {
"darwin_arm64": {
"filename": "ripgrep-14.1.0-aarch64-apple-darwin.tar.gz",
"sha256": "sha256-/FnKPqpbW8+hSI7rgCkbrQ6OKELgXUQA/Hsp1e5L0ms="
},
"linux_arm64": {
"filename": "ripgrep-14.1.0-aarch64-unknown-linux-gnu.tar.gz",
"sha256": "sha256-yMIQuZhE+/FrejbRyWPoNRvKX/LdfHiPX7pKwYuoxg0="
},
"musleabi_linux_armv7": {
"filename": "ripgrep-14.1.0-armv7-unknown-linux-musleabi.tar.gz",
"sha256": "sha256-FgQVP5gg+ExAiSWJQSncCyF3DHINj8vzmsSDknqawpg="
},
"musleabihf_linux_armv7": {
"filename": "ripgrep-14.1.0-armv7-unknown-linux-musleabihf.tar.gz",
"sha256": "sha256-BWXgjITywVS+y/LK8JYBHY4ul7kqcbodERP0PTWbHqA="
},
"linux_powerpc64": {
"filename": "ripgrep-14.1.0-powerpc64-unknown-linux-gnu.tar.gz",
"sha256": "sha256-uCG3Mg2bekSYaNT/3ltc/ENp/bE9zzJUNb9PC1rkb+g="
},
"linux_s390x": {
"filename": "ripgrep-14.1.0-s390x-unknown-linux-gnu.tar.gz",
"sha256": "sha256-4Wb0qM1nAJkq+LqI62p8WrKDjkQG3x6PBW6cRVQxRpE="
},
"darwin_amd64": {
"filename": "ripgrep-14.1.0-x86_64-apple-darwin.tar.gz",
"sha256": "sha256-TYgvyUXlqbYIClwFBvf+Sq6hkcGGU1VCjdS/oJb5dLU="
},
"windows_amd64": {
"filename": "ripgrep-14.1.0-x86_64-pc-windows-msvc.zip",
"sha256": "sha256-/k917fqlDw1P7L9HaWt2KfNEnJwsWk2oKHUxOeWi4gM="
},
"linux_amd64": {
"filename": "ripgrep-14.1.0-x86_64-unknown-linux-musl.tar.gz",
"sha256": "sha256-+EdXsH9CX+XPEdh99mRGkcZEpc0jSKLGcIlCcpmdO6c="
}
}
}

RipgrepInfo = provider(
doc = "Provide info for executing ripgrep",
fields = {
"bin": "Executable ripgrep binary",
},
)

def _ripgrep_toolchain_impl(ctx):
binary = ctx.file.binary

# Make the $(RIPGREP_BIN) variable available in places like genrules.
# See https://docs.bazel.build/versions/main/be/make-variables.html#custom_variables
template_variables = platform_common.TemplateVariableInfo({
"RIPGREP_BIN": binary.path,
})
default_info = DefaultInfo(
files = depset([binary]),
runfiles = ctx.runfiles(files = [binary]),
)
ripgrep_info = RipgrepInfo(
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(
ripgrep_info = ripgrep_info,
template_variables = template_variables,
default = default_info,
)

return [default_info, toolchain_info, template_variables]

ripgrep_toolchain = rule(
implementation = _ripgrep_toolchain_impl,
attrs = {
"binary": attr.label(
mandatory = True,
allow_single_file = True,
),
},
)

def _ripgrep_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:ripgrep_toolchain.bzl
# Forward all the providers
def _resolved_toolchain_impl(ctx):
toolchain_info = ctx.toolchains["@aspect_bazel_lib//lib:ripgrep_toolchain_type"]
return [
toolchain_info,
toolchain_info.default,
toolchain_info.ripgrep_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:ripgrep_toolchain_type"],
incompatible_use_toolchain_transition = True,
)
"""
rctx.file("defs.bzl", starlark_content)

build_content = """# @generated by @aspect_bazel_lib//lib/private:ripgrep_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 ripgrep_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 RIPGREP_PLATFORMS.items():
build_content += """
toolchain(
name = "{platform}_toolchain",
exec_compatible_with = {compatible_with},
toolchain = "@{user_repository_name}_{platform}//:ripgrep_toolchain",
toolchain_type = "@aspect_bazel_lib//lib:ripgrep_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)

ripgrep_toolchains_repo = repository_rule(
_ripgrep_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 _ripgrep_platform_repo_impl(rctx):
is_windows = rctx.attr.platform.startswith("windows_")
platform = rctx.attr.platform
filename = RIPGREP_VERSIONS[rctx.attr.version][platform]["filename"]
url = "https://github.com/BurntSushi/ripgrep/releases/download/{}/{}".format(
rctx.attr.version,
filename,
)
rctx.download_and_extract(
url = url,
stripPrefix = filename.replace(".zip", "").replace(".tar.gz", ""),
integrity = RIPGREP_VERSIONS[rctx.attr.version][platform]["sha256"],
)
build_content = """# @generated by @aspect_bazel_lib//lib/private:ripgrep_toolchain.bzl
load("@aspect_bazel_lib//lib/private:ripgrep_toolchain.bzl", "ripgrep_toolchain")
exports_files(["{0}"])
ripgrep_toolchain(name = "ripgrep_toolchain", binary = "{0}", visibility = ["//visibility:public"])
""".format("rg.exe" if is_windows else "rg")

# Base BUILD file for this repository
rctx.file("BUILD.bazel", build_content)

ripgrep_platform_repo = repository_rule(
implementation = _ripgrep_platform_repo_impl,
doc = "Fetch external tools needed for ripgrep toolchain",
attrs = {
"version": attr.string(mandatory = True, values = RIPGREP_VERSIONS.keys()),
"platform": attr.string(mandatory = True, values = RIPGREP_PLATFORMS.keys()),
},
)
Loading

0 comments on commit aaf0250

Please sign in to comment.