Skip to content

Commit ea9e983

Browse files
authored
Added a hub repository for helm toolchains (#220)
This cleans up MODULE.bazel files.
1 parent c2ea40d commit ea9e983

File tree

4 files changed

+314
-105
lines changed

4 files changed

+314
-105
lines changed

MODULE.bazel

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,16 @@ use_repo(
3232
)
3333

3434
helm = use_extension("@rules_helm//helm:extensions.bzl", "helm")
35+
helm.toolchain()
36+
helm.host_tools()
3537
use_repo(
3638
helm,
3739
"helm",
38-
"helm_darwin_amd64_toolchain",
39-
"helm_darwin_arm64_toolchain",
40-
"helm_linux_amd64_toolchain",
41-
"helm_linux_arm64_toolchain",
42-
"helm_windows_amd64_toolchain",
40+
"helm_toolchains",
4341
)
4442

4543
register_toolchains(
46-
"@helm_darwin_amd64_toolchain//:toolchain",
47-
"@helm_darwin_arm64_toolchain//:toolchain",
48-
"@helm_linux_amd64_toolchain//:toolchain",
49-
"@helm_linux_arm64_toolchain//:toolchain",
50-
"@helm_windows_amd64_toolchain//:toolchain",
44+
"@helm_toolchains//:all",
5145
)
5246

5347
helm_test = use_extension("@rules_helm//tests:test_extensions.bzl", "helm_test", dev_dependency = True)

helm/extensions.bzl

Lines changed: 141 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""Bzlmod extensions"""
22

3-
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
43
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
54
load(
65
"//helm/private:repositories.bzl",
76
"helm_host_alias_repository",
87
"helm_toolchain_repository",
8+
"helm_toolchain_repository_hub",
99
)
1010
load(
1111
"//helm/private:versions.bzl",
@@ -15,87 +15,127 @@ load(
1515
"HELM_VERSIONS",
1616
)
1717

18-
_HELM_TAR_BUILD_CONTENT = """\
19-
package(default_visibility = ["//visibility:public"])
20-
exports_files(glob(["**"]))
21-
"""
22-
23-
def _helm_impl(ctx):
24-
toolchain_config = {
25-
"helm_url_templates": DEFAULT_HELM_URL_TEMPLATES,
26-
"plugins": [],
27-
"version": DEFAULT_HELM_VERSION,
28-
}
29-
for module in ctx.modules:
30-
if not module.is_root:
31-
# TODO support toolchain generation from non-root modules. This requires encoding all options into the repo name and adding deduplication.
32-
print("Ignoring call to helm module extension in non-root module.") # buildifier: disable=print
33-
continue
34-
if len(module.tags.toolchain) > 1:
35-
# TODO support generating multiple toolchains. This requires encoding all options into the repo name and adding deduplication.
36-
fail("Only a single call to helm.toolchain() is taken into account. Please remove the other ones.")
37-
for toolchain_option in module.tags.toolchain:
38-
toolchain_config["version"] = toolchain_option.version
39-
toolchain_config["helm_url_templates"] = toolchain_option.helm_url_templates
40-
toolchain_config["plugins"] = toolchain_option.plugins
41-
42-
_register_toolchains(**toolchain_config)
43-
44-
def _register_toolchains(version, helm_url_templates, plugins):
45-
if not version in HELM_VERSIONS:
46-
fail("{} is not a supported version ({})".format(version, HELM_VERSIONS.keys()))
47-
48-
helm_version_info = HELM_VERSIONS[version]
49-
50-
for platform, integrity in helm_version_info.items():
51-
if platform.startswith("windows"):
52-
compression = "zip"
53-
else:
54-
compression = "tar.gz"
55-
56-
# The URLs for linux-i386 artifacts are actually published under
57-
# a different name. The check below accounts for this.
58-
# https://github.com/abrisco/rules_helm/issues/76
59-
url_platform = platform
60-
if url_platform == "linux-i386":
61-
url_platform = "linux-386"
62-
63-
name = "helm_{}".format(platform.replace("-", "_"))
18+
def _find_modules(module_ctx):
19+
root = None
20+
rules_module = None
21+
for mod in module_ctx.modules:
22+
if mod.is_root:
23+
root = mod
24+
if mod.name == "rules_helm":
25+
rules_module = mod
26+
if root == None:
27+
root = rules_module
28+
if rules_module == None:
29+
fail("Unable to find rules_helm module")
30+
31+
return root, rules_module
32+
33+
def _helm_impl(module_ctx):
34+
root_mod, rules_mod = _find_modules(module_ctx)
35+
36+
toolchains = root_mod.tags.toolchain
37+
if not toolchains:
38+
toolchains = rules_mod.tags.toolchain
39+
40+
host_tools = root_mod.tags.host_tools
41+
if not host_tools:
42+
host_tools = rules_mod.tags.host_tools
43+
44+
for attrs in toolchains:
45+
if attrs.version not in HELM_VERSIONS:
46+
fail("Helm toolchain hub `{}` was given unsupported version `{}`. Try: {}".format(
47+
attrs.name,
48+
attrs.version,
49+
HELM_VERSIONS.keys(),
50+
))
51+
available = HELM_VERSIONS[attrs.version]
52+
toolchain_names = []
53+
toolchain_labels = {}
54+
target_compatible_with = {}
55+
exec_compatible_with = {}
56+
57+
for platform, integrity in available.items():
58+
if platform.startswith("windows"):
59+
compression = "zip"
60+
else:
61+
compression = "tar.gz"
62+
63+
# The URLs for linux-i386 artifacts are actually published under
64+
# a different name. The check below accounts for this.
65+
# https://github.com/abrisco/rules_helm/issues/76
66+
url_platform = platform
67+
if url_platform == "linux-i386":
68+
url_platform = "linux-386"
69+
70+
toolchain_repo_name = "{}__{}_{}_bin".format(attrs.name, attrs.version, platform.replace("-", "_"))
71+
72+
# Create the hub-specific binary repository
73+
maybe(
74+
helm_toolchain_repository,
75+
name = toolchain_repo_name,
76+
urls = [
77+
template.replace(
78+
"{version}",
79+
attrs.version,
80+
).replace(
81+
"{platform}",
82+
url_platform,
83+
).replace(
84+
"{compression}",
85+
compression,
86+
)
87+
for template in attrs.helm_url_templates
88+
],
89+
integrity = integrity,
90+
strip_prefix = url_platform,
91+
plugins = attrs.plugins,
92+
platform = platform,
93+
)
94+
95+
toolchain_names.append(toolchain_repo_name)
96+
toolchain_labels[toolchain_repo_name] = "@{}".format(toolchain_repo_name)
97+
target_compatible_with[toolchain_repo_name] = []
98+
exec_compatible_with[toolchain_repo_name] = CONSTRAINTS[platform]
99+
64100
maybe(
65-
http_archive,
66-
name = name,
67-
urls = [
68-
template.replace(
69-
"{version}",
70-
version,
71-
).replace(
72-
"{platform}",
73-
url_platform,
74-
).replace(
75-
"{compression}",
76-
compression,
77-
)
78-
for template in helm_url_templates
79-
],
80-
build_file_content = _HELM_TAR_BUILD_CONTENT,
81-
integrity = integrity,
82-
strip_prefix = url_platform,
101+
helm_toolchain_repository_hub,
102+
name = attrs.name,
103+
toolchain_labels = toolchain_labels,
104+
toolchain_names = toolchain_names,
105+
exec_compatible_with = exec_compatible_with,
106+
target_compatible_with = target_compatible_with,
83107
)
108+
109+
# Process host_tools tags
110+
for host_tools_attrs in host_tools:
84111
maybe(
85-
helm_toolchain_repository,
86-
name = name + "_toolchain",
87-
platform = platform,
88-
plugins = plugins,
89-
exec_compatible_with = CONSTRAINTS[platform],
112+
helm_host_alias_repository,
113+
name = host_tools_attrs.name,
90114
)
91115

92-
maybe(
93-
helm_host_alias_repository,
94-
name = "helm",
116+
return module_ctx.extension_metadata(
117+
reproducible = True,
95118
)
96119

97120
_toolchain = tag_class(
98-
doc = "Configure a helm toolchain.",
121+
doc = """\
122+
An extension for defining a `helm_toolchain` from a download archive.
123+
124+
An example of defining and registering toolchains:
125+
126+
```python
127+
helm = use_extension("@rules_helm//helm:extensions.bzl", "helm")
128+
helm.toolchain(
129+
name = "helm_toolchains",
130+
version = "3.14.4",
131+
)
132+
use_repo(helm, "helm_toolchains")
133+
134+
register_toolchains(
135+
"@helm_toolchains//:all",
136+
)
137+
```
138+
""",
99139
attrs = {
100140
"helm_url_templates": attr.string_list(
101141
doc = (
@@ -105,6 +145,10 @@ _toolchain = tag_class(
105145
),
106146
default = DEFAULT_HELM_URL_TEMPLATES,
107147
),
148+
"name": attr.string(
149+
doc = "The name of the toolchain hub repository.",
150+
default = "helm_toolchains",
151+
),
108152
"plugins": attr.string_list(
109153
doc = "A list of plugins to add to the generated toolchain.",
110154
default = [],
@@ -116,9 +160,32 @@ _toolchain = tag_class(
116160
},
117161
)
118162

163+
_host_tools = tag_class(
164+
doc = """\
165+
An extension for creating a host alias repository that provides a shorter name for the host platform's helm binary.
166+
167+
An example of defining and using host tools:
168+
169+
```python
170+
helm = use_extension("@rules_helm//helm:extensions.bzl", "helm")
171+
helm.host_tools(name = "helm")
172+
use_repo(helm, "helm")
173+
174+
# Then you can use @helm//:helm in your BUILD files
175+
```
176+
""",
177+
attrs = {
178+
"name": attr.string(
179+
doc = "The name of the host alias repository.",
180+
default = "helm",
181+
),
182+
},
183+
)
184+
119185
helm = module_extension(
120186
implementation = _helm_impl,
121187
tag_classes = {
188+
"host_tools": _host_tools,
122189
"toolchain": _toolchain,
123190
},
124191
)

0 commit comments

Comments
 (0)