From 484a30cc87931d8695a2c393333a1120ecb512a6 Mon Sep 17 00:00:00 2001 From: Marc Redemske Date: Thu, 2 May 2024 23:48:04 +0200 Subject: [PATCH] refactor(toolchain): auto generate toolchains file --- MODULE.bazel.lock | 2 +- e2e/MODULE.bazel.lock | 2 +- lib/extensions.bzl | 12 +-- lib/toolchains.bzl | 12 +++ toolchains/BUILD.bazel | 107 ++++++++++++--------- toolchains/private/BUILD.bazel | 1 + toolchains/private/all_toolchains.awk | 15 +++ toolchains/private/generate_toolchains.bzl | 47 +++++++++ toolchains/private/header.awk | 12 +++ toolchains/private/resolved_toolchains.awk | 10 ++ toolchains/private/tools.awk | 12 +++ toolchains/toolchains.bzl | 75 +++++++++++---- 12 files changed, 233 insertions(+), 74 deletions(-) create mode 100644 toolchains/private/BUILD.bazel create mode 100644 toolchains/private/all_toolchains.awk create mode 100644 toolchains/private/generate_toolchains.bzl create mode 100644 toolchains/private/header.awk create mode 100644 toolchains/private/resolved_toolchains.awk create mode 100644 toolchains/private/tools.awk diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index e1a6925..b636629 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -926,7 +926,7 @@ "moduleExtensions": { "//lib:extensions.bzl%tools": { "general": { - "bzlTransitiveDigest": "WBDWr+9IjHNE+VYGgmC2zIUIZbDm/vgC15l6CproYuo=", + "bzlTransitiveDigest": "hEVFh0YQrpxBu/QKqEP2wSQEHwYgBOCNXakmthqX7o4=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { diff --git a/e2e/MODULE.bazel.lock b/e2e/MODULE.bazel.lock index 97b1052..06103cd 100644 --- a/e2e/MODULE.bazel.lock +++ b/e2e/MODULE.bazel.lock @@ -1523,7 +1523,7 @@ }, "@@bzlparty_tools~override//lib:extensions.bzl%tools": { "general": { - "bzlTransitiveDigest": "WBDWr+9IjHNE+VYGgmC2zIUIZbDm/vgC15l6CproYuo=", + "bzlTransitiveDigest": "hEVFh0YQrpxBu/QKqEP2wSQEHwYgBOCNXakmthqX7o4=", "accumulatedFileDigests": {}, "envVariables": {}, "generatedRepoSpecs": { diff --git a/lib/extensions.bzl b/lib/extensions.bzl index 03981ac..4dd3e2f 100644 --- a/lib/extensions.bzl +++ b/lib/extensions.bzl @@ -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)}) diff --git a/lib/toolchains.bzl b/lib/toolchains.bzl index a0af098..c66d9c9 100644 --- a/lib/toolchains.bzl +++ b/lib/toolchains.bzl @@ -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 diff --git a/toolchains/BUILD.bazel b/toolchains/BUILD.bazel index 87eca8d..657872f 100644 --- a/toolchains/BUILD.bazel +++ b/toolchains/BUILD.bazel @@ -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 +# ], +# ) diff --git a/toolchains/private/BUILD.bazel b/toolchains/private/BUILD.bazel new file mode 100644 index 0000000..219bbd7 --- /dev/null +++ b/toolchains/private/BUILD.bazel @@ -0,0 +1 @@ +exports_files(glob(["*awk"])) diff --git a/toolchains/private/all_toolchains.awk b/toolchains/private/all_toolchains.awk new file mode 100644 index 0000000..cb342ed --- /dev/null +++ b/toolchains/private/all_toolchains.awk @@ -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 " )" +} diff --git a/toolchains/private/generate_toolchains.bzl b/toolchains/private/generate_toolchains.bzl new file mode 100644 index 0000000..37a57cb --- /dev/null +++ b/toolchains/private/generate_toolchains.bzl @@ -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"], +) diff --git a/toolchains/private/header.awk b/toolchains/private/header.awk new file mode 100644 index 0000000..2e4d71a --- /dev/null +++ b/toolchains/private/header.awk @@ -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 "" +} diff --git a/toolchains/private/resolved_toolchains.awk b/toolchains/private/resolved_toolchains.awk new file mode 100644 index 0000000..c8304d2 --- /dev/null +++ b/toolchains/private/resolved_toolchains.awk @@ -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 "" +} diff --git a/toolchains/private/tools.awk b/toolchains/private/tools.awk new file mode 100644 index 0000000..0f17068 --- /dev/null +++ b/toolchains/private/tools.awk @@ -0,0 +1,12 @@ +BEGIN { + print "TOOLS = {" +} + +{ + print " \"" $0 "\": " toupper($0) "_ASSETS," +} + +END { + print "}" + print "" +} diff --git a/toolchains/toolchains.bzl b/toolchains/toolchains.bzl index b955b80..83706ff 100644 --- a/toolchains/toolchains.bzl +++ b/toolchains/toolchains.bzl @@ -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"], + )