Skip to content

Commit

Permalink
go_download_sdk: allow patching to stdlib
Browse files Browse the repository at this point in the history
  • Loading branch information
hunshcn authored and tyler-french committed Sep 18, 2023
1 parent 09a206c commit abb369a
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 18 deletions.
41 changes: 31 additions & 10 deletions go/private/sdk.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ load("//go/private:nogo.bzl", "go_register_nogo")
load("//go/private/skylib/lib:versions.bzl", "versions")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "patch")

patch_attrs = {
"patches": attr.label_list(
default = [],
doc =
"A list of files that are to be applied as patches to go sdk. " +
"By default, it uses the Bazel-native patch implementation " +
"which doesn't support fuzz match and binary patch, but Bazel will fall back to use " +
"patch command line tool if `patch_tool` attribute is specified or there are " +
"arguments other than `-p` in `patch_args` attribute.",
),
"remote_patches": attr.string_dict(
default = {},
doc =
"A map of patch file URL to its integrity value, they are applied before applying patch" +
"files from the `patches` attribute. It uses the Bazel-native patch implementation, " +
"you can specify the patch strip number with `remote_patch_strip`",
),
"remote_patch_strip": attr.int(
default = 0,
doc =
"The number of leading slashes to be stripped from the file name in the remote patches.",
),
"patch_strip": attr.int(
default = 0,
doc = "The number of leading path segments to be stripped from the file name in the patches.",
),
}

MIN_SUPPORTED_VERSION = (1, 14, 0)

def _go_host_sdk_impl(ctx):
Expand Down Expand Up @@ -113,9 +141,9 @@ def _go_download_sdk_impl(ctx):
filename, sha256 = sdks[platform]

_remote_sdk(ctx, [url.format(filename) for url in ctx.attr.urls], ctx.attr.strip_prefix, sha256)
patch(ctx, patch_args = _get_patch_args(ctx.attr.patch_strip))

detected_version = _detect_sdk_version(ctx, ".")
patch(ctx, patch_args = _get_patch_args(ctx.attr.patch_strip))
_sdk_build_file(ctx, platform, detected_version, experiments = ctx.attr.experiments)

if not ctx.attr.sdks and not ctx.attr.version:
Expand All @@ -134,7 +162,7 @@ def _go_download_sdk_impl(ctx):

go_download_sdk_rule = repository_rule(
implementation = _go_download_sdk_impl,
attrs = {
attrs = dict({
"goos": attr.string(),
"goarch": attr.string(),
"sdks": attr.string_list_dict(),
Expand All @@ -144,17 +172,10 @@ go_download_sdk_rule = repository_rule(
"urls": attr.string_list(default = ["https://dl.google.com/go/{}"]),
"version": attr.string(),
"strip_prefix": attr.string(default = "go"),
"patches": attr.label_list(
doc = "A list of patches to apply to the SDK after downloading it",
),
"patch_strip": attr.int(
default = 0,
doc = "The number of leading path segments to be stripped from the file name in the patches.",
),
"_sdk_build_file": attr.label(
default = Label("//go/private:BUILD.sdk.bazel"),
),
},
}, **patch_attrs),
)

def _define_version_constants(version, prefix = ""):
Expand Down
59 changes: 59 additions & 0 deletions go/toolchains.rst
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,41 @@ This downloads a Go SDK for use in toolchains.
| Go distribution (with a different SHA-256 sum) or a version of Go |
| not supported by rules_go (for example, a beta or release candidate). |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`patches` | :type:`label_list` | :value:`[]` |
+--------------------------------+-----------------------------+---------------------------------------------+
| A list of files that are to be applied to go sdk. By default, it uses the Bazel-native patch |
| implementation which doesn't support fuzz match and binary patch, but Bazel will fall back to use |
| patch command line tool if `patch_tool` attribute is specified. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`remote_patches` | :type:`string_dict` | :value:`{}` |
+--------------------------------+-----------------------------+---------------------------------------------+
| A map of patch file URL to its integrity value, they are applied before applying patch files |
| from the `patches` attribute. It uses the Bazel-native patch implementation, you can specify |
| the patch strip number with `remote_patch_strip`. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`remote_patch_strip` | :type:`int` | :value:`0` |
+--------------------------------+-----------------------------+---------------------------------------------+
| The number of leading slashes to be stripped from the file name in the remote patches. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`patch_tool` | :type:`string` | :value:`""` |
+--------------------------------+-----------------------------+---------------------------------------------+
| The patch(1) utility to use. If this is specified, Bazel will use the specified |
| patch tool instead of the Bazel-native patch implementation. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`patch_strip` | :type:`int` | :value:`0` |
+--------------------------------+-----------------------------+---------------------------------------------+
| The number of leading slashes to be stripped from the file name in thepatches. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`patch_cmds` | :type:`string_list` | :value:`[]` |
+--------------------------------+-----------------------------+---------------------------------------------+
| Sequence of Bash commands to be applied on Linux/Macos after patches are applied. |
+--------------------------------+-----------------------------+---------------------------------------------+
| :param:`patch_cmds_win` | :type:`string_list` | :value:`[]` |
+--------------------------------+-----------------------------+---------------------------------------------+
| Sequence of Powershell commands to be applied on Windows after patches are applied. |
| If this attribute is not set, patch_cmds will be executed on Windows, which requires Bash binary to exist. |
+--------------------------------+-----------------------------+---------------------------------------------+


**Example**:

Expand Down Expand Up @@ -343,6 +378,10 @@ This downloads a Go SDK for use in toolchains.
"linux_amd64": ("go1.18.1.linux-amd64.tar.gz", "b3b815f47ababac13810fc6021eb73d65478e0b2db4b09d348eefad9581a2334"),
"darwin_amd64": ("go1.18.1.darwin-amd64.tar.gz", "3703e9a0db1000f18c0c7b524f3d378aac71219b4715a6a4c5683eb639f41a4d"),
},
patch_strip = 1,
patches = [
"//patches:cgo_issue_fix.patch",
]
)
go_rules_dependencies()
Expand Down Expand Up @@ -375,6 +414,26 @@ used. Otherwise, ``go env GOROOT`` is used.
+--------------------------------+-----------------------------+-----------------------------------+
| Go experiments to enable via `GOEXPERIMENT`. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`patches` | :type:`label_list` | :value:`[]` |
+--------------------------------+-----------------------------+-----------------------------------+
| A list of files that are to be applied to go sdk. By default, it uses the Bazel-native patch |
| implementation which doesn't support fuzz match and binary patch, but Bazel will fall back to |
| use patch command line tool if `patch_tool` attribute is specified |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`remote_patches` | :type:`string_dict` | :value:`{}` |
+--------------------------------+-----------------------------+-----------------------------------+
| A map of patch file URL to its integrity value, they are applied before applying patch files |
| from the `patches` attribute. It uses the Bazel-native patch implementation, you can specify |
| the patch strip number with `remote_patch_strip`. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`remote_patch_strip` | :type:`int` | :value:`0` |
+--------------------------------+-----------------------------+-----------------------------------+
| The number of leading slashes to be stripped from the file name in the remote patches. |
+--------------------------------+-----------------------------+-----------------------------------+
| :param:`patch_strip` | :type:`int` | :value:`0` |
+--------------------------------+-----------------------------+-----------------------------------+
| The number of leading slashes to be stripped from the file name in the patches. |
+--------------------------------+-----------------------------+-----------------------------------+

go_local_sdk
~~~~~~~~~~~~
Expand Down
44 changes: 36 additions & 8 deletions tests/core/go_download_sdk/go_download_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package go_download_sdk_test

import (
"bytes"
"io/ioutil"
"os"
"testing"

"github.com/bazelbuild/rules_go/go/tools/bazel_testing"
Expand All @@ -25,12 +25,26 @@ import (
func TestMain(m *testing.M) {
bazel_testing.TestMain(m, bazel_testing.Args{
Main: `
-- go.patch --
--- src/runtime/extern.go 1969-12-31 16:00:00
+++ src/runtime/extern.go 2000-01-01 00:00:00.000000000 -0000
@@ -244,7 +244,7 @@
// It is either the commit hash and date at the time of the build or,
// when possible, a release tag like "go1.3".
func Version() string {
- return sys.TheVersion
+ return "go100.0"
}
// GOOS is the running program's operating system target:
-- BUILD.bazel --
load("@io_bazel_rules_go//go:def.bzl", "go_test")
go_test(
name = "version_test",
srcs = ["version_test.go"],
pure = "on",
)
go_test(
Expand Down Expand Up @@ -77,6 +91,20 @@ func Test(t *testing.T) {
optToWantVersion map[string]string
fetchOnly string
}{
{
desc: "patch",
rule: `
load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk")
go_download_sdk(
name = "go_sdk_patch",
version = "1.16",
patches = ["//:go.patch"],
)
`,
optToWantVersion: map[string]string{"": "go100.0"},
},
{
desc: "version",
rule: `
Expand Down Expand Up @@ -151,7 +179,7 @@ go_download_sdk(
},
} {
t.Run(test.desc, func(t *testing.T) {
origWorkspaceData, err := ioutil.ReadFile("WORKSPACE")
origWorkspaceData, err := os.ReadFile("WORKSPACE")
if err != nil {
t.Fatal(err)
}
Expand All @@ -169,11 +197,11 @@ go_rules_dependencies()
go_register_toolchains()
`)
if err := ioutil.WriteFile("WORKSPACE", buf.Bytes(), 0666); err != nil {
if err := os.WriteFile("WORKSPACE", buf.Bytes(), 0666); err != nil {
t.Fatal(err)
}
defer func() {
if err := ioutil.WriteFile("WORKSPACE", origWorkspaceData, 0666); err != nil {
if err := os.WriteFile("WORKSPACE", origWorkspaceData, 0666); err != nil {
t.Errorf("error restoring WORKSPACE: %v", err)
}
}()
Expand Down Expand Up @@ -205,7 +233,7 @@ go_register_toolchains()
}

func TestPatch(t *testing.T) {
origWorkspaceData, err := ioutil.ReadFile("WORKSPACE")
origWorkspaceData, err := os.ReadFile("WORKSPACE")
if err != nil {
t.Fatal(err)
}
Expand All @@ -231,7 +259,7 @@ go_rules_dependencies()
go_register_toolchains()
`)
if err := ioutil.WriteFile("WORKSPACE", buf.Bytes(), 0666); err != nil {
if err := os.WriteFile("WORKSPACE", buf.Bytes(), 0666); err != nil {
t.Fatal(err)
}

Expand All @@ -250,11 +278,11 @@ index 5306bcb..d110a19 100644
// by Lstat, in directory order. Subsequent calls on the same file will yield
`)

if err := ioutil.WriteFile("test.patch", patchContent, 0666); err != nil {
if err := os.WriteFile("test.patch", patchContent, 0666); err != nil {
t.Fatal(err)
}
defer func() {
if err := ioutil.WriteFile("WORKSPACE", origWorkspaceData, 0666); err != nil {
if err := os.WriteFile("WORKSPACE", origWorkspaceData, 0666); err != nil {
t.Errorf("error restoring WORKSPACE: %v", err)
}
}()
Expand Down

0 comments on commit abb369a

Please sign in to comment.