From 375a8e7179dce109fbae6f5f2740b78b76ebf573 Mon Sep 17 00:00:00 2001 From: Jay Conrod Date: Wed, 17 May 2023 13:47:08 -0700 Subject: [PATCH] go_download_sdk: apply extraction workaround to zips on non-windows OSs The Go distribution contains at least one test file with an invalid unicode name. Bazel cannot extract the distribution archive on some operating systems and file systems; Darwin with AFS at least is affected. For .tar.gz files, we workaround the failure in ctx.download_and_extract by using the native system tar. This PR applies a similar workaround for .zip files on non-Windows OSs. Windows itself is not affected (ctx.download_and_extract works), so the workaround is not applied there. This is only really needed when you have a Darwin host and a Windows executor (don't ask). For #2771 --- go/private/sdk.bzl | 28 +++++++++++++++---- .../go_download_sdk/go_download_sdk_test.go | 26 ++++++++++++++++- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/go/private/sdk.bzl b/go/private/sdk.bzl index 5a3ef4228c..d83e8e5f23 100644 --- a/go/private/sdk.bzl +++ b/go/private/sdk.bzl @@ -405,14 +405,17 @@ def _register_toolchains(repo): def _remote_sdk(ctx, urls, strip_prefix, sha256): if len(urls) == 0: fail("no urls specified") + host_goos, _ = _detect_host_platform(ctx) + ctx.report_progress("Downloading and extracting Go toolchain") + + # BUG(#2771): Use a system tool to extract the archive instead of + # Bazel's implementation. With some configurations (macOS + Docker + + # some particular file system binding), Bazel's implementation rejects + # files with invalid unicode names. Go has at least one test case with a + # file like this, but we haven't been able to reproduce the failure, so + # instead, we use this workaround. if urls[0].endswith(".tar.gz"): - # BUG(#2771): Use a system tool to extract the archive instead of - # Bazel's implementation. With some configurations (macOS + Docker + - # some particular file system binding), Bazel's implementation rejects - # files with invalid unicode names. Go has at least one test case with a - # file like this, but we haven't been able to reproduce the failure, so - # instead, we use this workaround. if strip_prefix != "go": fail("strip_prefix not supported") ctx.download( @@ -424,6 +427,19 @@ def _remote_sdk(ctx, urls, strip_prefix, sha256): if res.return_code: fail("error extracting Go SDK:\n" + res.stdout + res.stderr) ctx.delete("go_sdk.tar.gz") + elif urls[0].endswith(".zip") and host_goos != "windows": + # Bazel on Windows does not have this bug, but we still need this + # workaround to extract a Windows .zip file from a Darwin or Linux host. + if strip_prefix != "go": + fail("strip_prefix not supported") + ctx.download( + url = urls, + sha256 = sha256, + output = "go_sdk.zip", + ) + res = ctx.execute(["bash", "-c", "unzip go_sdk.zip && mv go/* . && rmdir go"]) + if res.return_code: + fail("error extracting Go SDK:\n" + res.stdout + res.stderr) else: ctx.download_and_extract( url = urls, diff --git a/tests/core/go_download_sdk/go_download_sdk_test.go b/tests/core/go_download_sdk/go_download_sdk_test.go index 4a5999ee10..61bd05b89f 100644 --- a/tests/core/go_download_sdk/go_download_sdk_test.go +++ b/tests/core/go_download_sdk/go_download_sdk_test.go @@ -57,6 +57,7 @@ func Test(t *testing.T) { for _, test := range []struct { desc, rule string optToWantVersion map[string]string + fetchOnly string }{ { desc: "version", @@ -70,7 +71,8 @@ go_download_sdk( `, optToWantVersion: map[string]string{"": "go1.16"}, - }, { + }, + { desc: "custom_archives", rule: ` load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk") @@ -114,6 +116,21 @@ go_download_sdk( "--@io_bazel_rules_go//go/toolchain:sdk_version=1.17.1": "go1.17.1", }, }, + { + // Cover workaround for #2771. + desc: "windows_zip", + rule: ` +load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk") + +go_download_sdk( + name = "go_sdk", + goarch = "amd64", + goos = "windows", + version = "1.20.4", +) +`, + fetchOnly: "@go_sdk//:BUILD.bazel", + }, } { t.Run(test.desc, func(t *testing.T) { origWorkspaceData, err := ioutil.ReadFile("WORKSPACE") @@ -143,6 +160,13 @@ go_register_toolchains() } }() + if test.fetchOnly != "" { + if err := bazel_testing.RunBazel("fetch", test.fetchOnly); err != nil { + t.Fatal(err) + } + return + } + for opt, wantVersion := range test.optToWantVersion { t.Run(wantVersion, func(t *testing.T) { args := []string{