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)