@@ -198,7 +198,28 @@ def _go_sdk_impl(ctx):
198198 host_detected_goos , host_detected_goarch = detect_host_platform (ctx )
199199 toolchains = []
200200
201- sdks_by_version = getattr (ctx , "facts" , None ) or {}
201+ all_sdks_by_version = {}
202+ used_sdks_by_version = {}
203+ facts = getattr (ctx , "facts" , {})
204+
205+ def get_sdks_by_version_cached (version ):
206+ # Avoid a download without a known digest in the SDK repo rule by fetching the SDKs filename
207+ # and digest here. When using a version of Bazel that supports module extension facts, this
208+ # info will be persisted in the lockfile, allowing for truly airgapped builds with an
209+ # up-to-date lockfile and download (formerly repository) cache.
210+ sdks = facts .get (version )
211+ if sdks == None :
212+ # Lazily fetch the information about all SDKs so that we avoid the download if the facts
213+ # already contain all the versions we care about.
214+ if not all_sdks_by_version :
215+ all_sdks_by_version .clear ()
216+ all_sdks_by_version .update (fetch_sdks_by_version (ctx , allow_fail = True ))
217+ sdks = all_sdks_by_version .get (version )
218+ if sdks == None :
219+ return None
220+ used_sdks_by_version [version ] = sdks
221+ return sdks
222+
202223 used_versions = {}
203224
204225 for module in ctx .modules :
@@ -267,7 +288,7 @@ def _go_sdk_impl(ctx):
267288
268289 _download_sdk (
269290 module_ctx = ctx ,
270- sdks_by_version = sdks_by_version ,
291+ get_sdks_by_version = get_sdks_by_version_cached ,
271292 used_versions = used_versions ,
272293 name = name ,
273294 goos = download_tag .goos ,
@@ -308,7 +329,7 @@ def _go_sdk_impl(ctx):
308329
309330 _download_sdk (
310331 module_ctx = ctx ,
311- sdks_by_version = sdks_by_version ,
332+ get_sdks_by_version = get_sdks_by_version_cached ,
312333 used_versions = used_versions ,
313334 name = default_name ,
314335 goos = goos ,
@@ -381,11 +402,7 @@ def _go_sdk_impl(ctx):
381402
382403 # See _download_sdk below for details on these facts.
383404 if hasattr (ctx , "facts" ):
384- kwargs ["facts" ] = {
385- version : sdk_info
386- for version , sdk_info in sdks_by_version .items ()
387- if version in used_versions
388- }
405+ kwargs ["facts" ] = used_sdks_by_version
389406 return ctx .extension_metadata (** kwargs )
390407 else :
391408 return None
@@ -416,23 +433,11 @@ def _left_pad_zero(index, length):
416433 fail ("index must be non-negative" )
417434 return ("0" * length + str (index ))[- length :]
418435
419- def _download_sdk (* , module_ctx , sdks_by_version , used_versions , name , goos , goarch , download_tag ):
436+ def _download_sdk (* , module_ctx , get_sdks_by_version , used_versions , name , goos , goarch , download_tag ):
420437 version = download_tag .version
421438 sdks = download_tag .sdks
422439 if version and not sdks :
423- # Avoid a download without a known digest in the SDK repo rule by fetching the SDKs filename
424- # and digest here. When using a version of Bazel that supports module extension facts, this
425- # info will be persisted in the lockfile, allowing for truly airgapped builds with an
426- # up-to-date lockfile and download (formerly repository) cache.
427- if version not in sdks_by_version :
428- # Lazily fetch the information about all SDKs so that we avoid the download if the facts
429- # already contain all the versions we care about.
430- sdks_by_version .clear ()
431- sdks_by_version .update (fetch_sdks_by_version (module_ctx ))
432- if version not in sdks_by_version :
433- fail ("go_sdk: no SDKs found for version {} requested by" .format (version ), download_tag )
434- used_versions [version ] = True
435- sdks = sdks_by_version [version ]
440+ sdks = get_sdks_by_version (version )
436441
437442 go_download_sdk_rule (
438443 name = name ,
0 commit comments