blob: 9f2d98c783451f2213f6a327fae3a6e7fca0953a [file] [log] [blame]
# 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.
load("//internal:common.bzl", "env_execute", "executable_extension")
load("//internal:go_repository_cache.bzl", "read_cache_env")
load("//internal:go_repository_tools_srcs.bzl", "GO_REPOSITORY_TOOLS_SRCS")
_GO_REPOSITORY_TOOLS_BUILD_FILE = """
package(default_visibility = ["//visibility:public"])
filegroup(
name = "fetch_repo",
srcs = ["bin/fetch_repo{extension}"],
)
filegroup(
name = "gazelle",
srcs = ["bin/gazelle{extension}"],
)
filegroup(
name = "generate_repo_config",
srcs = ["bin/generate_repo_config{extension}"],
)
exports_files(["ROOT"])
"""
def _go_repository_tools_impl(ctx):
# Create a link to the gazelle repo. This will be our GOPATH.
env = read_cache_env(ctx, str(ctx.path(ctx.attr.go_cache)))
extension = executable_extension(ctx)
go_tool = env["GOROOT"] + "/bin/go" + extension
ctx.symlink(
ctx.path(Label("//:WORKSPACE")).dirname,
"src/github.com/bazelbuild/bazel-gazelle",
)
env.update({
"GOPATH": str(ctx.path(".")),
"GOBIN": "",
"GO111MODULE": "off",
# workaround: avoid the Go SDK paths from leaking into the binary
"GOROOT_FINAL": "GOROOT",
# workaround: avoid cgo paths in /tmp leaking into binary
"CGO_ENABLED": "0",
})
if "PATH" in ctx.os.environ:
# workaround: to find gcc for go link tool on Arm platform
env["PATH"] = ctx.os.environ["PATH"]
if "GOPROXY" in ctx.os.environ:
env["GOPROXY"] = ctx.os.environ["GOPROXY"]
# Make sure the list of source is up to date.
# We don't want to run the script, then resolve each source file it returns.
# If many of the sources changed even slightly, Bazel would restart this
# rule each time. Compiling the script is relatively slow.
# Don't try this on Windows: bazel does not set up symbolic links.
if "windows" not in ctx.os.name:
result = env_execute(
ctx,
[
go_tool,
"run",
ctx.path(ctx.attr._list_repository_tools_srcs),
"-dir=src/github.com/bazelbuild/bazel-gazelle",
"-check=internal/go_repository_tools_srcs.bzl",
],
environment = env,
)
if result.return_code:
fail("list_repository_tools_srcs: " + result.stderr)
# Build the tools.
args = [
go_tool,
"install",
"-ldflags",
"-w -s",
"-gcflags",
"all=-trimpath=" + env["GOPATH"],
"-asmflags",
"all=-trimpath=" + env["GOPATH"],
"github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
"github.com/bazelbuild/bazel-gazelle/cmd/fetch_repo",
"github.com/bazelbuild/bazel-gazelle/cmd/generate_repo_config",
]
result = env_execute(ctx, args, environment = env)
if result.return_code:
fail("failed to build tools: " + result.stderr)
# add a build file to export the tools
ctx.file(
"BUILD.bazel",
_GO_REPOSITORY_TOOLS_BUILD_FILE.format(extension = executable_extension(ctx)),
False,
)
ctx.file(
"ROOT",
"",
False,
)
go_repository_tools = repository_rule(
_go_repository_tools_impl,
attrs = {
"go_cache": attr.label(
mandatory = True,
allow_single_file = True,
),
"_go_repository_tools_srcs": attr.label_list(
default = GO_REPOSITORY_TOOLS_SRCS,
),
"_list_repository_tools_srcs": attr.label(
default = "//internal:list_repository_tools_srcs.go",
),
},
environ = [
"GOCACHE",
"GOPATH",
"GO_REPOSITORY_USE_HOST_CACHE",
],
)
"""go_repository_tools is a synthetic repository used by go_repository.
go_repository depends on two Go binaries: fetch_repo and gazelle. We can't
build these with Bazel inside a repository rule, and we don't want to manage
prebuilt binaries, so we build them in here with go build, using whichever
SDK rules_go is using.
"""