1# Copyright 2019 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15load("//internal:common.bzl", "env_execute", "executable_extension")
16load("//internal:go_repository_cache.bzl", "read_cache_env")
17load("//internal:go_repository_tools_srcs.bzl", "GO_REPOSITORY_TOOLS_SRCS")
18
19_GO_REPOSITORY_TOOLS_BUILD_FILE = """
20package(default_visibility = ["//visibility:public"])
21
22filegroup(
23 name = "fetch_repo",
24 srcs = ["bin/fetch_repo{extension}"],
25)
26
27filegroup(
28 name = "gazelle",
29 srcs = ["bin/gazelle{extension}"],
30)
31
32filegroup(
33 name = "generate_repo_config",
34 srcs = ["bin/generate_repo_config{extension}"],
35)
36
37exports_files(["ROOT"])
38"""
39
40def _go_repository_tools_impl(ctx):
41 # Create a link to the gazelle repo. This will be our GOPATH.
42 env = read_cache_env(ctx, str(ctx.path(ctx.attr.go_cache)))
43 extension = executable_extension(ctx)
44 go_tool = env["GOROOT"] + "/bin/go" + extension
45
46 ctx.symlink(
47 ctx.path(Label("//:WORKSPACE")).dirname,
48 "src/github.com/bazelbuild/bazel-gazelle",
49 )
50
51 env.update({
52 "GOPATH": str(ctx.path(".")),
53 "GOBIN": "",
54 "GO111MODULE": "off",
55 # workaround: avoid the Go SDK paths from leaking into the binary
56 "GOROOT_FINAL": "GOROOT",
57 # workaround: avoid cgo paths in /tmp leaking into binary
58 "CGO_ENABLED": "0",
59 })
60
61 if "PATH" in ctx.os.environ:
62 # workaround: to find gcc for go link tool on Arm platform
63 env["PATH"] = ctx.os.environ["PATH"]
64 if "GOPROXY" in ctx.os.environ:
65 env["GOPROXY"] = ctx.os.environ["GOPROXY"]
66
67 # Make sure the list of source is up to date.
68 # We don't want to run the script, then resolve each source file it returns.
69 # If many of the sources changed even slightly, Bazel would restart this
70 # rule each time. Compiling the script is relatively slow.
71 # Don't try this on Windows: bazel does not set up symbolic links.
72 if "windows" not in ctx.os.name:
73 result = env_execute(
74 ctx,
75 [
76 go_tool,
77 "run",
78 ctx.path(ctx.attr._list_repository_tools_srcs),
79 "-dir=src/github.com/bazelbuild/bazel-gazelle",
80 "-check=internal/go_repository_tools_srcs.bzl",
81 ],
82 environment = env,
83 )
84 if result.return_code:
85 fail("list_repository_tools_srcs: " + result.stderr)
86
87 # Build the tools.
88 args = [
89 go_tool,
90 "install",
91 "-ldflags",
92 "-w -s",
93 "-gcflags",
94 "all=-trimpath=" + env["GOPATH"],
95 "-asmflags",
96 "all=-trimpath=" + env["GOPATH"],
97 "github.com/bazelbuild/bazel-gazelle/cmd/gazelle",
98 "github.com/bazelbuild/bazel-gazelle/cmd/fetch_repo",
99 "github.com/bazelbuild/bazel-gazelle/cmd/generate_repo_config",
100 ]
101 result = env_execute(ctx, args, environment = env)
102 if result.return_code:
103 fail("failed to build tools: " + result.stderr)
104
105 # add a build file to export the tools
106 ctx.file(
107 "BUILD.bazel",
108 _GO_REPOSITORY_TOOLS_BUILD_FILE.format(extension = executable_extension(ctx)),
109 False,
110 )
111 ctx.file(
112 "ROOT",
113 "",
114 False,
115 )
116
117go_repository_tools = repository_rule(
118 _go_repository_tools_impl,
119 attrs = {
120 "go_cache": attr.label(
121 mandatory = True,
122 allow_single_file = True,
123 ),
124 "_go_repository_tools_srcs": attr.label_list(
125 default = GO_REPOSITORY_TOOLS_SRCS,
126 ),
127 "_list_repository_tools_srcs": attr.label(
128 default = "//internal:list_repository_tools_srcs.go",
129 ),
130 },
131 environ = [
132 "GOCACHE",
133 "GOPATH",
134 "GO_REPOSITORY_USE_HOST_CACHE",
135 ],
136)
137"""go_repository_tools is a synthetic repository used by go_repository.
138
139
140go_repository depends on two Go binaries: fetch_repo and gazelle. We can't
141build these with Bazel inside a repository rule, and we don't want to manage
142prebuilt binaries, so we build them in here with go build, using whichever
143SDK rules_go is using.
144"""
View as plain text