Skip to content

Commit

Permalink
[go_sdk download] allow patches to standard library (#3684)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyler-french committed Sep 15, 2023
1 parent f03a723 commit 9ebc93c
Show file tree
Hide file tree
Showing 10 changed files with 207 additions and 13 deletions.
14 changes: 14 additions & 0 deletions docs/doc_helpers.bzl
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("@io_bazel_stardoc//stardoc:stardoc.bzl", "stardoc")
load("@bazel_skylib//rules:write_file.bzl", "write_file")
load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
Expand Down
14 changes: 14 additions & 0 deletions go/extensions.bzl
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("//go/private:extensions.bzl", _go_sdk = "go_sdk")

go_sdk = _go_sdk
1 change: 1 addition & 0 deletions go/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ bzl_library(
"//go/private:nogo",
"//go/private:platforms",
"//go/private/skylib/lib:versions",
"@bazel_tools//tools/build_defs/repo:utils.bzl",
],
)

Expand Down
23 changes: 23 additions & 0 deletions go/private/extensions.bzl
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("//go/private:sdk.bzl", "detect_host_platform", "go_download_sdk_rule", "go_host_sdk_rule", "go_multiple_toolchains")
load("//go/private:repositories.bzl", "go_rules_dependencies")

Expand Down Expand Up @@ -31,6 +45,13 @@ _download_tag = tag_class(
),
"urls": attr.string_list(default = ["https://dl.google.com/go/{}"]),
"version": attr.string(),
"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.",
),
"strip_prefix": attr.string(default = "go"),
},
)
Expand Down Expand Up @@ -93,6 +114,8 @@ def _go_sdk_impl(ctx):
goarch = download_tag.goarch,
sdks = download_tag.sdks,
experiments = download_tag.experiments,
patches = download_tag.patches,
patch_strip = download_tag.patch_strip,
urls = download_tag.urls,
version = download_tag.version,
strip_prefix = download_tag.strip_prefix,
Expand Down
34 changes: 22 additions & 12 deletions go/private/sdk.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load(
"//go/private:common.bzl",
"executable_path",
)
load(
"//go/private:nogo.bzl",
"go_register_nogo",
)
load(
"//go/private/skylib/lib:versions.bzl",
"versions",
)
load("//go/private:common.bzl", "executable_path")
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")

MIN_SUPPORTED_VERSION = (1, 14, 0)

Expand Down Expand Up @@ -75,6 +67,10 @@ def _go_download_sdk_impl(ctx):
version = ctx.attr.version
sdks = ctx.attr.sdks

if not version:
if ctx.attr.patches:
fail("a single version must be specified to apply patches")

if not sdks:
# If sdks was unspecified, download a full list of files.
# If version was unspecified, pick the latest version.
Expand Down Expand Up @@ -115,7 +111,9 @@ def _go_download_sdk_impl(ctx):
if platform not in sdks:
fail("unsupported platform {}".format(platform))
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, ".")
_sdk_build_file(ctx, platform, detected_version, experiments = ctx.attr.experiments)
Expand Down Expand Up @@ -146,6 +144,13 @@ 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"),
),
Expand Down Expand Up @@ -175,6 +180,11 @@ def _to_constant_name(s):
# Prefix with _ as identifiers are not allowed to start with numbers.
return "_" + "".join([c if c.isalnum() else "_" for c in s.elems()]).upper()

def _get_patch_args(patch_strip):
if patch_strip:
return ["-p{}".format(patch_strip)]
return []

def go_toolchains_single_definition(ctx, *, prefix, goos, goarch, sdk_repo, sdk_type, sdk_version):
if not goos and not goarch:
goos, goarch = detect_host_platform(ctx)
Expand Down
5 changes: 5 additions & 0 deletions tests/bcr/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ go_test(
embed = [":lib"],
)

go_test(
name = "sdk_patch_test",
srcs = ["sdk_patch_test.go"],
)

go_library(
name = "mockable",
srcs = [
Expand Down
8 changes: 7 additions & 1 deletion tests/bcr/MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ bazel_dep(name = "gazelle", version = "0.32.0")
bazel_dep(name = "protobuf", version = "3.19.6")

go_sdk = use_extension("@my_rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.19.5")
go_sdk.download(
version = "1.21.1",
patch_strip = 1,
patches = [
"//:test_go_sdk.patch",
],
)

# Request an invalid SDK to verify that it isn't fetched since the first tag takes precedence.
go_sdk.host(version = "3.0.0")
Expand Down
27 changes: 27 additions & 0 deletions tests/bcr/sdk_patch_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2019 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package lib

import (
"os"

"testing"
)

func TestName(t *testing.T) {
if os.SayHello != "Hello" {
t.Fail()
}
}
13 changes: 13 additions & 0 deletions tests/bcr/test_go_sdk.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/src/os/dir.go b/src/os/dir.go
index 5306bcb..d110a19 100644
--- a/src/os/dir.go
+++ b/src/os/dir.go
@@ -17,6 +17,8 @@ const (
readdirFileInfo
)

+const SayHello = "Hello"
+
// Readdir reads the contents of the directory associated with file and
// returns a slice of up to n FileInfo values, as would be returned
// by Lstat, in directory order. Subsequent calls on the same file will yield
81 changes: 81 additions & 0 deletions tests/core/go_download_sdk/go_download_sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ go_test(
srcs = ["version_test.go"],
)
go_test(
name = "patch_test",
srcs = ["patch_test.go"],
)
-- version_test.go --
package version_test
Expand All @@ -49,6 +54,19 @@ func Test(t *testing.T) {
t.Errorf("got version %q; want %q", v, *want)
}
}
-- patch_test.go --
package version_test
import (
"os"
"testing"
)
func Test(t *testing.T) {
if v := os.SayHello; v != "Hello"{
t.Errorf("got version %q; want \"Hello\"", v)
}
}
`,
})
}
Expand Down Expand Up @@ -185,3 +203,66 @@ go_register_toolchains()
})
}
}

func TestPatch(t *testing.T) {
origWorkspaceData, err := ioutil.ReadFile("WORKSPACE")
if err != nil {
t.Fatal(err)
}

i := bytes.Index(origWorkspaceData, []byte("go_rules_dependencies()"))
if i < 0 {
t.Fatal("could not find call to go_rules_dependencies()")
}

buf := &bytes.Buffer{}
buf.Write(origWorkspaceData[:i])
buf.WriteString(`
load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk")
go_download_sdk(
name = "go_sdk_patched",
version = "1.21.1",
patch_strip = 1,
patches = ["//:test.patch"],
)
go_rules_dependencies()
go_register_toolchains()
`)
if err := ioutil.WriteFile("WORKSPACE", buf.Bytes(), 0666); err != nil {
t.Fatal(err)
}

patchContent := []byte(`diff --git a/src/os/dir.go b/src/os/dir.go
index 5306bcb..d110a19 100644
--- a/src/os/dir.go
+++ b/src/os/dir.go
@@ -17,6 +17,8 @@ const (
readdirFileInfo
)
+const SayHello = "Hello"
+
// Readdir reads the contents of the directory associated with file and
// returns a slice of up to n FileInfo values, as would be returned
// by Lstat, in directory order. Subsequent calls on the same file will yield
`)

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

if err := bazel_testing.RunBazel(
"test",
"//:patch_test",
); err != nil {
t.Fatal(err)
}
}

0 comments on commit 9ebc93c

Please sign in to comment.