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

     1  # Copyright 2018 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  def _http_archive_impl(ctx):
    16      print("http_archive is deprecated. Use http_archive from @bazel_tools//tools/build_defs/repo:http.bzl instead.")
    17      overlay = _resolve_overlay(ctx, ctx.attr.overlay)
    18      ctx.download_and_extract(
    19          url = ctx.attr.urls,
    20          sha256 = ctx.attr.sha256,
    21          type = ctx.attr.type,
    22          stripPrefix = ctx.attr.strip_prefix,
    23      )
    24      _apply_overlay(ctx, overlay)
    25  
    26  http_archive = repository_rule(
    27      implementation = _http_archive_impl,
    28      doc = """
    29  **NOTE:** `http_archive` is deprecated in favor of the rule of the same name
    30  in [@bazel_tools//tools/build_defs/repo:http.bzl].
    31  
    32  `http_archive` downloads a project over HTTP(S). It has the same features as
    33  the [native http_archive rule], but it also allows you to copy a set of files
    34  into the repository after download. This is particularly useful for placing
    35  pre-generated build files.
    36  
    37  **Example**
    38  
    39  ```starlark
    40  load("@bazel_gazelle//:deps.bzl", "http_archive")
    41  
    42  http_archive(
    43      name = "com_github_pkg_errors",
    44      urls = ["https://codeload.github.com/pkg/errors/zip/816c9085562cd7ee03e7f8188a1cfd942858cded"],
    45      strip_prefix = "errors-816c9085562cd7ee03e7f8188a1cfd942858cded",
    46      type = "zip",
    47      overlay = {
    48          "@my_repo//third_party:com_github_pkg_errors/BUILD.bazel.in" : "BUILD.bazel",
    49      },
    50  )
    51  ```
    52  """,
    53      attrs = {
    54          "urls": attr.string_list(
    55              doc = """A list of HTTP(S) URLs where the project can be downloaded. Bazel will
    56              attempt to download the first URL; the others are mirrors.""",
    57          ),
    58          "sha256": attr.string(
    59              doc = """The SHA-256 sum of the downloaded archive. When set, Bazel will verify the
    60              archive against this sum before extracting it.
    61  
    62              **CAUTION:** Do not use this with services that prepare source archives on
    63              demand, such as codeload.github.com. Any minor change in the server software
    64              can cause differences in file order, alignment, and compression that break
    65              SHA-256 sums.""",
    66          ),
    67          "strip_prefix": attr.string(
    68              doc = "A directory prefix to strip. See [http_archive.strip_prefix].",
    69          ),
    70          "type": attr.string(
    71              doc = """One of `"zip"`, `"tar.gz"`, `"tgz"`, `"tar.bz2"`, `"tar.xz"`.
    72  
    73              The file format of the repository archive. This is normally inferred from
    74              the downloaded file name.""",
    75          ),
    76          "overlay": attr.label_keyed_string_dict(
    77              allow_files = True,
    78              doc = """A set of files to copy into the downloaded repository. The keys in this
    79              dictionary are Bazel labels that point to the files to copy. These must be
    80              fully qualified labels (i.e., `@repo//pkg:name`) because relative labels
    81              are interpreted in the checked out repository, not the repository containing
    82              the WORKSPACE file. The values in this dictionary are root-relative paths
    83              where the overlay files should be written.
    84  
    85              It's convenient to store the overlay dictionaries for all repositories in
    86              a separate .bzl file. See Gazelle's `manifest.bzl`_ for an example.""",
    87          ),
    88      },
    89  )
    90  # TODO(jayconrod): add strip_count to remove a number of unnamed
    91  # parent directories.
    92  # TODO(jayconrod): add sha256_contents to check sha256sum on files extracted
    93  # from the archive instead of on the archive itself.
    94  
    95  def _git_repository_impl(ctx):
    96      print("git_repository is deprecated. Use git_repository from @bazel_tools//tools/build_defs/repo:git.bzl instead.")
    97      if not ctx.attr.commit and not ctx.attr.tag:
    98          fail("either 'commit' or 'tag' must be specified")
    99      if ctx.attr.commit and ctx.attr.tag:
   100          fail("'commit' and 'tag' may not both be specified")
   101  
   102      overlay = _resolve_overlay(ctx, ctx.attr.overlay)
   103  
   104      # TODO(jayconrod): sanitize inputs passed to git.
   105      revision = ctx.attr.commit if ctx.attr.commit else ctx.attr.tag
   106      _check_execute(ctx, ["git", "clone", "-n", ctx.attr.remote, "."], "failed to clone %s" % ctx.attr.remote)
   107      _check_execute(ctx, ["git", "checkout", revision], "failed to checkout revision %s in remote %s" % (revision, ctx.attr.remote))
   108  
   109      _apply_overlay(ctx, overlay)
   110  
   111  git_repository = repository_rule(
   112      implementation = _git_repository_impl,
   113      doc = """
   114  **NOTE:** `git_repository` is deprecated in favor of the rule of the same name
   115  in [@bazel_tools//tools/build_defs/repo:git.bzl].
   116  
   117  `git_repository` downloads a project with git. It has the same features as the
   118  [native git_repository rule], but it also allows you to copy a set of files
   119  into the repository after download. This is particularly useful for placing
   120  pre-generated build files.
   121  
   122  **Example**
   123  
   124  ```starlark
   125  load("@bazel_gazelle//:deps.bzl", "git_repository")
   126  
   127  git_repository(
   128      name = "com_github_pkg_errors",
   129      remote = "https://github.com/pkg/errors",
   130      commit = "816c9085562cd7ee03e7f8188a1cfd942858cded",
   131      overlay = {
   132          "@my_repo//third_party:com_github_pkg_errors/BUILD.bazel.in" : "BUILD.bazel",
   133      },
   134  )
   135  ```
   136  """,
   137      attrs = {
   138          "commit": attr.string(
   139              doc = "The git commit to check out. Either `commit` or `tag` may be specified.",
   140          ),
   141          "remote": attr.string(
   142              doc = "The remote repository to download.",
   143              mandatory = True,
   144          ),
   145          "tag": attr.string(
   146              doc = "The git tag to check out. Either `commit` or `tag` may be specified.",
   147          ),
   148          "overlay": attr.label_keyed_string_dict(
   149              allow_files = True,
   150              doc = """A set of files to copy into the downloaded repository. The keys in this
   151  dictionary are Bazel labels that point to the files to copy. These must be
   152  fully qualified labels (i.e., `@repo//pkg:name`) because relative labels
   153  are interpreted in the checked out repository, not the repository containing
   154  the WORKSPACE file. The values in this dictionary are root-relative paths
   155  where the overlay files should be written.
   156  
   157  It's convenient to store the overlay dictionaries for all repositories in
   158  a separate .bzl file. See Gazelle's `manifest.bzl`_ for an example.""",
   159          ),
   160      },
   161  )
   162  
   163  def _resolve_overlay(ctx, overlay):
   164      """Resolve overlay labels to paths.
   165  
   166      This should be done before downloading the repository, since it may
   167      trigger restarts.
   168      """
   169      return [(ctx.path(src_label), dst_rel) for src_label, dst_rel in overlay.items()]
   170  
   171  def _apply_overlay(ctx, overlay):
   172      """Copies overlay files into the repository.
   173  
   174      This should be done after downloading the repository, since it may replace
   175      downloaded files.
   176      """
   177  
   178      # TODO(jayconrod): sanitize destination paths.
   179      for src_path, dst_rel in overlay:
   180          ctx.template(dst_rel, src_path)
   181  
   182  def _check_execute(ctx, arguments, message):
   183      res = ctx.execute(arguments)
   184      if res.return_code != 0:
   185          fail(message + "\n" + res.stdout + res.stderr)