Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow patching to stdlib #3670

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion go/private/extensions.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,15 @@ def _go_sdk_impl(ctx):
tag_type = "download",
index = index,
)
patch_args = ["-p{}".format(download_tag.patch_strip)] if download_tag.patch_strip else []
go_download_sdk_rule(
name = name,
goos = download_tag.goos,
goarch = download_tag.goarch,
sdks = download_tag.sdks,
experiments = download_tag.experiments,
patches = download_tag.patches,
patch_strip = download_tag.patch_strip,
patch_args = patch_args,
urls = download_tag.urls,
version = download_tag.version,
strip_prefix = download_tag.strip_prefix,
Expand Down
82 changes: 60 additions & 22 deletions go/private/sdk.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,56 @@ 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_tool": attr.string(
default = "",
doc = "The patch(1) utility to use. If this is specified, Bazel will use the specified " +
"patch tool instead of the Bazel-native patch implementation.",
),
"patch_args": attr.string_list(
default = ["-p0"],
doc =
"The arguments given to the patch tool. Defaults to -p0, " +
"however -p1 will usually be needed for patches generated by " +
"git. If multiple -p arguments are specified, the last one will take effect." +
"If arguments other than -p are specified, Bazel will fall back to use patch " +
"command line tool instead of the Bazel-native patch implementation. When falling " +
"back to patch command line tool and patch_tool attribute is not specified, " +
"`patch` will be used. This only affects patch files in the `patches` attribute.",
),
"patch_cmds": attr.string_list(
default = [],
doc = "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.",
),
"patch_cmds_win": attr.string_list(
default = [],
doc = "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.",
),
}

MIN_SUPPORTED_VERSION = (1, 14, 0)

def _go_host_sdk_impl(ctx):
Expand All @@ -29,15 +79,15 @@ def _go_host_sdk_impl(ctx):
go_host_sdk_rule = repository_rule(
implementation = _go_host_sdk_impl,
environ = ["GOROOT"],
attrs = {
attrs = dict({
"version": attr.string(),
"experiments": attr.string_list(
doc = "Go experiments to enable via GOEXPERIMENT",
),
"_sdk_build_file": attr.label(
default = Label("//go/private:BUILD.sdk.bazel"),
),
},
}, **patch_attrs),
)

def go_host_sdk(name, register_toolchains = True, **kwargs):
Expand Down Expand Up @@ -111,9 +161,7 @@ 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 All @@ -134,7 +182,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 +192,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 All @@ -180,11 +221,6 @@ 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 Expand Up @@ -335,7 +371,7 @@ def _go_local_sdk_impl(ctx):

_go_local_sdk = repository_rule(
implementation = _go_local_sdk_impl,
attrs = {
attrs = dict({
"path": attr.string(),
"version": attr.string(),
"experiments": attr.string_list(
Expand All @@ -344,7 +380,7 @@ _go_local_sdk = repository_rule(
"_sdk_build_file": attr.label(
default = Label("//go/private:BUILD.sdk.bazel"),
),
},
}, **patch_attrs),
)

def go_local_sdk(name, register_toolchains = True, **kwargs):
Expand Down Expand Up @@ -381,7 +417,7 @@ def _go_wrap_sdk_impl(ctx):

_go_wrap_sdk = repository_rule(
implementation = _go_wrap_sdk_impl,
attrs = {
attrs = dict({
"root_file": attr.label(
mandatory = False,
doc = "A file in the SDK root direcotry. Used to determine GOROOT.",
Expand All @@ -397,7 +433,7 @@ _go_wrap_sdk = repository_rule(
"_sdk_build_file": attr.label(
default = Label("//go/private:BUILD.sdk.bazel"),
),
},
}, **patch_attrs),
)

def go_wrap_sdk(name, register_toolchains = True, **kwargs):
Expand Down Expand Up @@ -490,6 +526,8 @@ def _sdk_build_file(ctx, platform, version, experiments):
if not "nocoverageredesign" in experiments and not "coverageredesign" in experiments:
experiments = experiments + ["nocoverageredesign"]

patch(ctx)

ctx.template(
"BUILD.bazel",
ctx.path(ctx.attr._sdk_build_file),
Expand Down
Loading