github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/internal/go_repository_tools.bzl (about)

     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  
    15  load("//internal:common.bzl", "env_execute", "executable_extension")
    16  load("//internal:go_repository_cache.bzl", "read_cache_env")
    17  load("//internal:go_repository_tools_srcs.bzl", "GO_REPOSITORY_TOOLS_SRCS")
    18  
    19  _GO_REPOSITORY_TOOLS_BUILD_FILE = """
    20  package(default_visibility = ["//visibility:public"])
    21  
    22  filegroup(
    23      name = "fetch_repo",
    24      srcs = ["bin/fetch_repo{extension}"],
    25  )
    26  
    27  filegroup(
    28      name = "gazelle",
    29      srcs = ["bin/gazelle{extension}"],
    30  )
    31  
    32  filegroup(
    33      name = "generate_repo_config",
    34      srcs = ["bin/generate_repo_config{extension}"],
    35  )
    36  
    37  exports_files(["ROOT"])
    38  """
    39  
    40  def _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  
   117  go_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  
   140  go_repository depends on two Go binaries: fetch_repo and gazelle. We can't
   141  build these with Bazel inside a repository rule, and we don't want to manage
   142  prebuilt binaries, so we build them in here with go build, using whichever
   143  SDK rules_go is using.
   144  """