11"""Bzlmod extensions"""
22
3- load ("@bazel_tools//tools/build_defs/repo:http.bzl" , "http_archive" )
43load ("@bazel_tools//tools/build_defs/repo:utils.bzl" , "maybe" )
54load (
65 "//helm/private:repositories.bzl" ,
76 "helm_host_alias_repository" ,
87 "helm_toolchain_repository" ,
8+ "helm_toolchain_repository_hub" ,
99)
1010load (
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+
119185helm = module_extension (
120186 implementation = _helm_impl ,
121187 tag_classes = {
188+ "host_tools" : _host_tools ,
122189 "toolchain" : _toolchain ,
123190 },
124191)
0 commit comments