Skip to content

Commit f8aba64

Browse files
committed
Fix up
1 parent 04bb04b commit f8aba64

File tree

4 files changed

+3209
-30
lines changed

4 files changed

+3209
-30
lines changed

go/private/extensions.bzl

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,34 @@ 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 {}
202-
used_versions = {}
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. We take care to only do this once and
214+
# also accept failures to support airgapped builds: the user may have set sdk hashes on
215+
# all SDK repos they actually intend to use, but others (e.g., the default SDK added by
216+
# rules_go) trigger this path even if they would never be selected by toolchain
217+
# resolution. We must not break those builds.
218+
if not all_sdks_by_version:
219+
all_sdks_by_version.clear()
220+
all_sdks_by_version.update(fetch_sdks_by_version(ctx, allow_fail = True))
221+
sdks = all_sdks_by_version.get(version)
222+
if sdks == None:
223+
# This is either caused by an invalid version or because we are in an airgapped build
224+
# and the version wasn't present in facts. Since we don't want to fail in the latter
225+
# case, we leave it to the repository rule to report a useful error message.
226+
return None
227+
used_sdks_by_version[version] = sdks
228+
return sdks
203229

204230
for module in ctx.modules:
205231
# Apply wrapped toolchains first to override specific platforms from the
@@ -266,9 +292,7 @@ def _go_sdk_impl(ctx):
266292
)
267293

268294
_download_sdk(
269-
module_ctx = ctx,
270-
sdks_by_version = sdks_by_version,
271-
used_versions = used_versions,
295+
get_sdks_by_version = get_sdks_by_version_cached,
272296
name = name,
273297
goos = download_tag.goos,
274298
goarch = download_tag.goarch,
@@ -307,9 +331,7 @@ def _go_sdk_impl(ctx):
307331
)
308332

309333
_download_sdk(
310-
module_ctx = ctx,
311-
sdks_by_version = sdks_by_version,
312-
used_versions = used_versions,
334+
get_sdks_by_version = get_sdks_by_version_cached,
313335
name = default_name,
314336
goos = goos,
315337
goarch = goarch,
@@ -381,11 +403,7 @@ def _go_sdk_impl(ctx):
381403

382404
# See _download_sdk below for details on these facts.
383405
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-
}
406+
kwargs["facts"] = used_sdks_by_version
389407
return ctx.extension_metadata(**kwargs)
390408
else:
391409
return None
@@ -416,23 +434,11 @@ def _left_pad_zero(index, length):
416434
fail("index must be non-negative")
417435
return ("0" * length + str(index))[-length:]
418436

419-
def _download_sdk(*, module_ctx, sdks_by_version, used_versions, name, goos, goarch, download_tag):
437+
def _download_sdk(*, get_sdks_by_version, name, goos, goarch, download_tag):
420438
version = download_tag.version
421439
sdks = download_tag.sdks
422440
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]
441+
sdks = get_sdks_by_version(version)
436442

437443
go_download_sdk_rule(
438444
name = name,

go/private/sdk.bzl

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,16 +570,26 @@ def _parse_versions_json(data):
570570
for sdk in sdks
571571
}
572572

573-
def fetch_sdks_by_version(ctx):
574-
ctx.download(
573+
def fetch_sdks_by_version(ctx, allow_fail = False):
574+
result = ctx.download(
575575
url = [
576576
"https://go.dev/dl/?mode=json&include=all",
577577
"https://golang.google.cn/dl/?mode=json&include=all",
578578
],
579579
output = "versions.json",
580+
allow_fail = allow_fail,
580581
)
582+
if not result.success:
583+
return {}
581584
data = ctx.read("versions.json")
582585

586+
# If the download is redirected through a proxy such as Artifactory, it may
587+
# drop the query parameters and return an HTML page instead. In that case,
588+
# just return an empty map if allow_fail is set. It is unfortunately not
589+
# possible to attempt parsing as JSON and catch the error.
590+
if (not data or data[0] != "[") and allow_fail:
591+
return {}
592+
583593
# module_ctx doesn't have delete, but its files are temporary anyway.
584594
if hasattr(ctx, "delete"):
585595
ctx.delete("versions.json")

tests/bcr/.bazelversion

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
7.4.1
1+
1079973bd513b69fb56becc7fe678c03449b30c3
2+
# A commit on the 8.5.0 release branch with support for facts.
3+
# TODO: Update to 8.5.0 when released.

0 commit comments

Comments
 (0)