Skip to content

Commit

Permalink
refactor(toolchain): auto generate toolchains file
Browse files Browse the repository at this point in the history
  • Loading branch information
mgred committed May 2, 2024
1 parent b1926fb commit 484a30c
Show file tree
Hide file tree
Showing 12 changed files with 233 additions and 74 deletions.
2 changes: 1 addition & 1 deletion MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion e2e/MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 1 addition & 11 deletions lib/extensions.bzl
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
# buildifier: disable=module-docstring
load("//lib:toolchains.bzl", "platform_toolchains")
load("//toolchains/goawk:assets.bzl", GOAWK_ASSETS = "ASSETS")
load("//toolchains/ripgrep:assets.bzl", RIPGREP_ASSETS = "ASSETS")
load("//toolchains/typos:assets.bzl", TYPOS_ASSETS = "ASSETS")
load("//toolchains/xsv:assets.bzl", XSV_ASSETS = "ASSETS")

TOOLS = {
"goawk": GOAWK_ASSETS,
"ripgrep": RIPGREP_ASSETS,
"typos": TYPOS_ASSETS,
"xsv": XSV_ASSETS,
}
load("//toolchains:toolchains.bzl", "TOOLS")

TAG_CLASSES = {
t: tag_class(attrs = {"name": attr.string(default = t)})
Expand Down
12 changes: 12 additions & 0 deletions lib/toolchains.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,15 @@ _binary_toolchains = repository_rule(
"build_file": attr.string(mandatory = True),
},
)

def resolved_toolchain_impl(toolchain):
def _impl(ctx):
toolchain_info = ctx.toolchains[toolchain]
return [
toolchain_info,
toolchain_info.default,
toolchain_info.binary_info,
toolchain_info.template_variables,
]

return _impl
107 changes: 64 additions & 43 deletions toolchains/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -1,49 +1,70 @@
load(
":toolchains.bzl",
"goawk_resolved_toolchain",
"ripgrep_resolved_toolchain",
"typos_resolved_toolchain",
"xsv_resolved_toolchain",
)

package(default_visibility = ["//visibility:public"])

toolchain_type(
name = "goawk_toolchain_type",
visibility = ["//visibility:public"],
)

goawk_resolved_toolchain(
name = "goawk",
visibility = ["//visibility:public"],
)
load("//toolchains/private:generate_toolchains.bzl", "generate_toolchains")

toolchain_type(
name = "ripgrep_toolchain_type",
visibility = ["//visibility:public"],
)

ripgrep_resolved_toolchain(
name = "ripgrep",
visibility = ["//visibility:public"],
)
# load("@bazel_skylib//rules:write_file.bzl", "write_file")
load(":toolchains.bzl", "all_toolchains")

toolchain_type(
name = "typos_toolchain_type",
visibility = ["//visibility:public"],
)
package(default_visibility = ["//visibility:public"])

typos_resolved_toolchain(
name = "typos",
visibility = ["//visibility:public"],
)
TOOLS = [
"goawk",
"ripgrep",
"typos",
"xsv",
]

toolchain_type(
name = "xsv_toolchain_type",
visibility = ["//visibility:public"],
)
all_toolchains()

xsv_resolved_toolchain(
name = "xsv",
visibility = ["//visibility:public"],
generate_toolchains(
name = "toolchains",
tools = TOOLS,
)
# write_file(
# name = "tools",
# out = "tools_bzl",
# content = [
# """\
# # buildifier: disable=module-docstring
# load("//toolchains/{name}:assets.bzl", {var}_ASSETS = "ASSETS")
# """.format(
# name = tool,
# var = tool.upper(),
# )
# for tool in TOOLS
# ] + ["TOOLS = {"] +
# [
# """\
# "{name}": {var}_ASSETS,
# """.format(
# name = tool,
# var = tool.upper(),
# )
# for tool in TOOLS
# ] + [
# "}",
# ],
# )
#
# write_file(
# name = "toolchains",
# out = "toolchains_bzl",
# content = [
# """\
# # buildifier: disable=module-docstring
# load("//lib:toolchains.bzl", "resolved_toolchain_impl")
# """,
# ] + [
# """\
# {var}_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:{name}_toolchain_type"
#
# {name}_resolved_toolchain = rule(
# implementation = _resolved_toolchain_impl({var}_TOOLCHAIN_TYPE),
# toolchains = [{var}_TOOLCHAIN_TYPE],
# incompatible_use_toolchain_transition = True,
# )
# """.format(
# name = tool,
# var = tool.upper(),
# )
# for tool in TOOLS
# ],
# )
1 change: 1 addition & 0 deletions toolchains/private/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exports_files(glob(["*awk"]))
15 changes: 15 additions & 0 deletions toolchains/private/all_toolchains.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
BEGIN {
print "# buildifier: disable=function-docstring"
print "def all_toolchains(name = \"all_toolchains\"):"
}

{
print " native.toolchain_type("
print " name = \"" $0 "_toolchain_type\","
print " visibility = [\"//visibility:public\"],"
print " )"
print " " $0 "_resolved_toolchain("
print " name = \"" $0 "\","
print " visibility = [\"//visibility:public\"],"
print " )"
}
47 changes: 47 additions & 0 deletions toolchains/private/generate_toolchains.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# buildifier: disable=module-docstring
def _generate_toolchains(ctx):
output = ctx.actions.declare_file("generated_toolchains.bzl")
tools_list = ctx.actions.declare_file("_tools_list")
goawk = ctx.toolchains["@bzlparty_tools//toolchains:goawk_toolchain_type"].binary_info.binary
ctx.actions.write(
output = tools_list,
content = "\n".join(ctx.attr.tools),
)
ctx.actions.run_shell(
outputs = [output],
inputs = ctx.files.partials + [tools_list],
command = "(" + "; ".join(
[
"""\
{goawk} -f {file} {input}\
""".format(goawk = goawk.path, file = p.path, input = tools_list.path)
for p in ctx.files.partials
],
) + ") > {out}".format(out = output.path),
tools = [goawk],
toolchain = "@bzlparty_tools//toolchains:goawk_toolchain_type",
)

return [
DefaultInfo(
files = depset([output]),
runfiles = ctx.runfiles(files = [goawk, tools_list] + ctx.files.partials),
),
]

generate_toolchains = rule(
_generate_toolchains,
attrs = {
"partials": attr.label_list(
allow_files = True,
default = [
Label("//toolchains/private:header.awk"),
Label("//toolchains/private:tools.awk"),
Label("//toolchains/private:resolved_toolchains.awk"),
Label("//toolchains/private:all_toolchains.awk"),
],
),
"tools": attr.string_list(),
},
toolchains = ["@bzlparty_tools//toolchains:goawk_toolchain_type"],
)
12 changes: 12 additions & 0 deletions toolchains/private/header.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
BEGIN {
print "# buildifier: disable=module-docstring"
print "load(\"//lib:toolchains.bzl\", \"resolved_toolchain_impl\")"
}

{
print "load(\"//toolchains/" $0 ":assets.bzl\", " toupper($0) "_ASSETS = \"ASSETS\")"
}

END {
print ""
}
10 changes: 10 additions & 0 deletions toolchains/private/resolved_toolchains.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
print toupper($0) "_TOOLCHAIN_TYPE = \"@bzlparty_tools//toolchains:" $0 "_toolchain_type\""
print ""
print $0 "_resolved_toolchain = rule("
print " implementation = resolved_toolchain_impl(" toupper($0) "_TOOLCHAIN_TYPE),"
print " toolchains = [" toupper($0) "_TOOLCHAIN_TYPE],"
print " incompatible_use_toolchain_transition = True,"
print ")"
print ""
}
12 changes: 12 additions & 0 deletions toolchains/private/tools.awk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
BEGIN {
print "TOOLS = {"
}

{
print " \"" $0 "\": " toupper($0) "_ASSETS,"
}

END {
print "}"
print ""
}
75 changes: 57 additions & 18 deletions toolchains/toolchains.bzl
Original file line number Diff line number Diff line change
@@ -1,41 +1,80 @@
# buildifier: disable=module-docstring
def _resolved_toolchain_impl(toolchain):
def _impl(ctx):
toolchain_info = ctx.toolchains[toolchain]
return [
toolchain_info,
toolchain_info.default,
toolchain_info.binary_info,
toolchain_info.template_variables,
]

return _impl
load("//lib:toolchains.bzl", "resolved_toolchain_impl")
load("//toolchains/goawk:assets.bzl", GOAWK_ASSETS = "ASSETS")
load("//toolchains/ripgrep:assets.bzl", RIPGREP_ASSETS = "ASSETS")
load("//toolchains/typos:assets.bzl", TYPOS_ASSETS = "ASSETS")
load("//toolchains/xsv:assets.bzl", XSV_ASSETS = "ASSETS")

TOOLS = {
"goawk": GOAWK_ASSETS,
"ripgrep": RIPGREP_ASSETS,
"typos": TYPOS_ASSETS,
"xsv": XSV_ASSETS,
}

GOAWK_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:goawk_toolchain_type"
RIPGREP_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:ripgrep_toolchain_type"
TYPOS_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:typos_toolchain_type"
XSV_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:xsv_toolchain_type"

goawk_resolved_toolchain = rule(
implementation = _resolved_toolchain_impl(GOAWK_TOOLCHAIN_TYPE),
implementation = resolved_toolchain_impl(GOAWK_TOOLCHAIN_TYPE),
toolchains = [GOAWK_TOOLCHAIN_TYPE],
incompatible_use_toolchain_transition = True,
)

RIPGREP_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:ripgrep_toolchain_type"

ripgrep_resolved_toolchain = rule(
implementation = _resolved_toolchain_impl(RIPGREP_TOOLCHAIN_TYPE),
implementation = resolved_toolchain_impl(RIPGREP_TOOLCHAIN_TYPE),
toolchains = [RIPGREP_TOOLCHAIN_TYPE],
incompatible_use_toolchain_transition = True,
)

TYPOS_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:typos_toolchain_type"

typos_resolved_toolchain = rule(
implementation = _resolved_toolchain_impl(TYPOS_TOOLCHAIN_TYPE),
implementation = resolved_toolchain_impl(TYPOS_TOOLCHAIN_TYPE),
toolchains = [TYPOS_TOOLCHAIN_TYPE],
incompatible_use_toolchain_transition = True,
)

XSV_TOOLCHAIN_TYPE = "@bzlparty_tools//toolchains:xsv_toolchain_type"

xsv_resolved_toolchain = rule(
implementation = _resolved_toolchain_impl(XSV_TOOLCHAIN_TYPE),
implementation = resolved_toolchain_impl(XSV_TOOLCHAIN_TYPE),
toolchains = [XSV_TOOLCHAIN_TYPE],
incompatible_use_toolchain_transition = True,
)

# buildifier: disable=function-docstring
def all_toolchains(name = "all_toolchains"):
native.toolchain_type(
name = "goawk_toolchain_type",
visibility = ["//visibility:public"],
)
goawk_resolved_toolchain(
name = "goawk",
visibility = ["//visibility:public"],
)
native.toolchain_type(
name = "ripgrep_toolchain_type",
visibility = ["//visibility:public"],
)
ripgrep_resolved_toolchain(
name = "ripgrep",
visibility = ["//visibility:public"],
)
native.toolchain_type(
name = "typos_toolchain_type",
visibility = ["//visibility:public"],
)
typos_resolved_toolchain(
name = "typos",
visibility = ["//visibility:public"],
)
native.toolchain_type(
name = "xsv_toolchain_type",
visibility = ["//visibility:public"],
)
xsv_resolved_toolchain(
name = "xsv",
visibility = ["//visibility:public"],
)

0 comments on commit 484a30c

Please sign in to comment.