David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 1 | # Copyright 2016 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 | """Rules for downloading files and archives over HTTP. |
| 15 | |
| 16 | ### Setup |
| 17 | |
| 18 | To use these rules, load them in your `WORKSPACE` file as follows: |
| 19 | |
| 20 | ```python |
| 21 | load( |
| 22 | "@bazel_tools//tools/build_defs/repo:http.bzl", |
| 23 | "http_archive", |
| 24 | "http_file", |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 25 | "http_jar", |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 26 | ) |
| 27 | ``` |
| 28 | |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 29 | These rules are improved versions of the native http rules and will eventually |
| 30 | replace the native rules. |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 31 | """ |
| 32 | |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 33 | load( |
| 34 | ":utils.bzl", |
| 35 | "patch", |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 36 | "read_netrc", |
Zhongpeng Lin | f421474 | 2022-01-21 04:31:27 -0800 | [diff] [blame] | 37 | "read_user_netrc", |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 38 | "update_attrs", |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 39 | "use_netrc", |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 40 | "workspace_and_buildfile", |
| 41 | ) |
| 42 | |
Jingwen Chen | c5ec3c0 | 2020-03-25 16:53:15 -0700 | [diff] [blame] | 43 | # Shared between http_jar, http_file and http_archive. |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 44 | |
| 45 | _URL_DOC = """A URL to a file that will be made available to Bazel. |
| 46 | |
| 47 | This must be a file, http or https URL. Redirections are followed. |
| 48 | Authentication is not supported. |
| 49 | |
| 50 | More flexibility can be achieved by the urls parameter that allows |
| 51 | to specify alternative URLs to fetch from.""" |
| 52 | |
| 53 | _URLS_DOC = """A list of URLs to a file that will be made available to Bazel. |
| 54 | |
| 55 | Each entry must be a file, http or https URL. Redirections are followed. |
| 56 | Authentication is not supported. |
| 57 | |
| 58 | URLs are tried in order until one succeeds, so you should list local mirrors first. |
| 59 | If all downloads fail, the rule will fail.""" |
| 60 | |
| 61 | def _get_all_urls(ctx): |
| 62 | """Returns all urls provided via the url or urls attributes. |
| 63 | |
| 64 | Also checks that at least one url is provided.""" |
| 65 | if not ctx.attr.url and not ctx.attr.urls: |
| 66 | fail("At least one of url and urls must be provided") |
| 67 | |
| 68 | all_urls = [] |
| 69 | if ctx.attr.urls: |
| 70 | all_urls = ctx.attr.urls |
| 71 | if ctx.attr.url: |
| 72 | all_urls = [ctx.attr.url] + all_urls |
| 73 | |
| 74 | return all_urls |
| 75 | |
Jingwen Chen | c5ec3c0 | 2020-03-25 16:53:15 -0700 | [diff] [blame] | 76 | _AUTH_PATTERN_DOC = """An optional dict mapping host names to custom authorization patterns. |
| 77 | |
| 78 | If a URL's host name is present in this dict the value will be used as a pattern when |
| 79 | generating the authorization header for the http request. This enables the use of custom |
| 80 | authorization schemes used in a lot of common cloud storage providers. |
| 81 | |
| 82 | The pattern currently supports 2 tokens: <code><login></code> and |
| 83 | <code><password></code>, which are replaced with their equivalent value |
| 84 | in the netrc file for the same host name. After formatting, the result is set |
| 85 | as the value for the <code>Authorization</code> field of the HTTP request. |
| 86 | |
| 87 | Example attribute and netrc for a http download to an oauth2 enabled API using a bearer token: |
| 88 | |
| 89 | <pre> |
| 90 | auth_patterns = { |
| 91 | "storage.cloudprovider.com": "Bearer <password>" |
| 92 | } |
| 93 | </pre> |
| 94 | |
| 95 | netrc: |
| 96 | |
| 97 | <pre> |
| 98 | machine storage.cloudprovider.com |
| 99 | password RANDOM-TOKEN |
| 100 | </pre> |
| 101 | |
| 102 | The final HTTP request would have the following header: |
| 103 | |
| 104 | <pre> |
| 105 | Authorization: Bearer RANDOM-TOKEN |
| 106 | </pre> |
| 107 | """ |
| 108 | |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 109 | def _get_auth(ctx, urls): |
| 110 | """Given the list of URLs obtain the correct auth dict.""" |
| 111 | if ctx.attr.netrc: |
| 112 | netrc = read_netrc(ctx, ctx.attr.netrc) |
Zhongpeng Lin | f421474 | 2022-01-21 04:31:27 -0800 | [diff] [blame] | 113 | else: |
| 114 | netrc = read_user_netrc(ctx) |
| 115 | return use_netrc(netrc, urls, ctx.attr.auth_patterns) |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 116 | |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 117 | def _http_archive_impl(ctx): |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 118 | """Implementation of the http_archive rule.""" |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 119 | if ctx.attr.build_file and ctx.attr.build_file_content: |
Nicolas Lopez | 2c9c05b | 2018-08-07 06:43:52 -0700 | [diff] [blame] | 120 | fail("Only one of build_file and build_file_content can be provided.") |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 121 | |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 122 | all_urls = _get_all_urls(ctx) |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 123 | auth = _get_auth(ctx, all_urls) |
| 124 | |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 125 | download_info = ctx.download_and_extract( |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 126 | all_urls, |
| 127 | "", |
| 128 | ctx.attr.sha256, |
| 129 | ctx.attr.type, |
| 130 | ctx.attr.strip_prefix, |
Klaus Aehlig | c917ab2 | 2019-05-20 07:08:30 -0700 | [diff] [blame] | 131 | canonical_id = ctx.attr.canonical_id, |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 132 | auth = auth, |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 133 | integrity = ctx.attr.integrity, |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 134 | ) |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 135 | workspace_and_buildfile(ctx) |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 136 | patch(ctx, auth = auth) |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 137 | |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 138 | # We don't need to override the sha256 attribute if integrity is already specified. |
| 139 | sha256_override = {} if ctx.attr.integrity else {"sha256": download_info.sha256} |
| 140 | return update_attrs(ctx.attr, _http_archive_attrs.keys(), sha256_override) |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 141 | |
Jay Bazuzi | d6089e6 | 2022-03-15 10:38:47 -0700 | [diff] [blame] | 142 | _HTTP_FILE_BUILD = """\ |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 143 | package(default_visibility = ["//visibility:public"]) |
| 144 | |
| 145 | filegroup( |
| 146 | name = "file", |
Nicolas Lopez | 2c9c05b | 2018-08-07 06:43:52 -0700 | [diff] [blame] | 147 | srcs = ["{}"], |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 148 | ) |
| 149 | """ |
| 150 | |
| 151 | def _http_file_impl(ctx): |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 152 | """Implementation of the http_file rule.""" |
Nicolas Lopez | 2c9c05b | 2018-08-07 06:43:52 -0700 | [diff] [blame] | 153 | repo_root = ctx.path(".") |
| 154 | forbidden_files = [ |
| 155 | repo_root, |
| 156 | ctx.path("WORKSPACE"), |
| 157 | ctx.path("BUILD"), |
| 158 | ctx.path("BUILD.bazel"), |
| 159 | ctx.path("file/BUILD"), |
| 160 | ctx.path("file/BUILD.bazel"), |
| 161 | ] |
| 162 | downloaded_file_path = ctx.attr.downloaded_file_path |
| 163 | download_path = ctx.path("file/" + downloaded_file_path) |
| 164 | if download_path in forbidden_files or not str(download_path).startswith(str(repo_root)): |
| 165 | fail("'%s' cannot be used as downloaded_file_path in http_file" % ctx.attr.downloaded_file_path) |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 166 | all_urls = _get_all_urls(ctx) |
| 167 | auth = _get_auth(ctx, all_urls) |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 168 | download_info = ctx.download( |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 169 | all_urls, |
Nicolas Lopez | 2c9c05b | 2018-08-07 06:43:52 -0700 | [diff] [blame] | 170 | "file/" + downloaded_file_path, |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 171 | ctx.attr.sha256, |
| 172 | ctx.attr.executable, |
David Ostrovsky | 3e5ece3 | 2020-01-20 02:29:56 -0800 | [diff] [blame] | 173 | canonical_id = ctx.attr.canonical_id, |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 174 | auth = auth, |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 175 | ) |
| 176 | ctx.file("WORKSPACE", "workspace(name = \"{name}\")".format(name = ctx.name)) |
Nicolas Lopez | 2c9c05b | 2018-08-07 06:43:52 -0700 | [diff] [blame] | 177 | ctx.file("file/BUILD", _HTTP_FILE_BUILD.format(downloaded_file_path)) |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 178 | |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 179 | return update_attrs(ctx.attr, _http_file_attrs.keys(), {"sha256": download_info.sha256}) |
| 180 | |
Jay Bazuzi | d6089e6 | 2022-03-15 10:38:47 -0700 | [diff] [blame] | 181 | _HTTP_JAR_BUILD = """\ |
George Gensure | cfda041 | 2020-01-10 11:09:42 -0800 | [diff] [blame] | 182 | load("@rules_java//java:defs.bzl", "java_import") |
| 183 | |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 184 | package(default_visibility = ["//visibility:public"]) |
| 185 | |
| 186 | java_import( |
| 187 | name = 'jar', |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 188 | jars = ["{file_name}"], |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 189 | visibility = ['//visibility:public'], |
| 190 | ) |
| 191 | |
| 192 | filegroup( |
| 193 | name = 'file', |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 194 | srcs = ["{file_name}"], |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 195 | visibility = ['//visibility:public'], |
| 196 | ) |
| 197 | |
| 198 | """ |
| 199 | |
| 200 | def _http_jar_impl(ctx): |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 201 | """Implementation of the http_jar rule.""" |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 202 | all_urls = _get_all_urls(ctx) |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 203 | auth = _get_auth(ctx, all_urls) |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 204 | downloaded_file_name = ctx.attr.downloaded_file_name |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 205 | download_info = ctx.download( |
| 206 | all_urls, |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 207 | "jar/" + downloaded_file_name, |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 208 | ctx.attr.sha256, |
David Ostrovsky | 3e5ece3 | 2020-01-20 02:29:56 -0800 | [diff] [blame] | 209 | canonical_id = ctx.attr.canonical_id, |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 210 | auth = auth, |
Klaus Aehlig | e1e074c | 2019-07-04 04:20:09 -0700 | [diff] [blame] | 211 | ) |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 212 | ctx.file("WORKSPACE", "workspace(name = \"{name}\")".format(name = ctx.name)) |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 213 | ctx.file("jar/BUILD", _HTTP_JAR_BUILD.format(file_name = downloaded_file_name)) |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 214 | return update_attrs(ctx.attr, _http_jar_attrs.keys(), {"sha256": download_info.sha256}) |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 215 | |
| 216 | _http_archive_attrs = { |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 217 | "url": attr.string(doc = _URL_DOC), |
| 218 | "urls": attr.string_list(doc = _URLS_DOC), |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 219 | "sha256": attr.string( |
| 220 | doc = """The expected SHA-256 of the file downloaded. |
| 221 | |
| 222 | This must match the SHA-256 of the file downloaded. _It is a security risk |
| 223 | to omit the SHA-256 as remote files can change._ At best omitting this |
| 224 | field will make your build non-hermetic. It is optional to make development |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 225 | easier but either this attribute or `integrity` should be set before shipping.""", |
| 226 | ), |
| 227 | "integrity": attr.string( |
| 228 | doc = """Expected checksum in Subresource Integrity format of the file downloaded. |
| 229 | |
| 230 | This must match the checksum of the file downloaded. _It is a security risk |
| 231 | to omit the checksum as remote files can change._ At best omitting this |
| 232 | field will make your build non-hermetic. It is optional to make development |
| 233 | easier but either this attribute or `sha256` should be set before shipping.""", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 234 | ), |
pcloudy | 7aa5237 | 2022-01-11 05:03:54 -0800 | [diff] [blame] | 235 | "netrc": attr.string( |
| 236 | doc = "Location of the .netrc file to use for authentication", |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 237 | ), |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 238 | "auth_patterns": attr.string_dict( |
Jingwen Chen | c5ec3c0 | 2020-03-25 16:53:15 -0700 | [diff] [blame] | 239 | doc = _AUTH_PATTERN_DOC, |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 240 | ), |
Klaus Aehlig | c917ab2 | 2019-05-20 07:08:30 -0700 | [diff] [blame] | 241 | "canonical_id": attr.string( |
Googler | e9bef0c | 2019-11-21 08:32:07 -0800 | [diff] [blame] | 242 | doc = """A canonical id of the archive downloaded. |
Klaus Aehlig | c917ab2 | 2019-05-20 07:08:30 -0700 | [diff] [blame] | 243 | |
David Ostrovsky | 3e5ece3 | 2020-01-20 02:29:56 -0800 | [diff] [blame] | 244 | If specified and non-empty, bazel will not take the archive from cache, |
| 245 | unless it was added to the cache by a request with the same canonical id. |
Klaus Aehlig | c917ab2 | 2019-05-20 07:08:30 -0700 | [diff] [blame] | 246 | """, |
| 247 | ), |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 248 | "strip_prefix": attr.string( |
| 249 | doc = """A directory prefix to strip from the extracted files. |
| 250 | |
| 251 | Many archives contain a top-level directory that contains all of the useful |
| 252 | files in archive. Instead of needing to specify this prefix over and over |
| 253 | in the `build_file`, this field can be used to strip it from all of the |
| 254 | extracted files. |
| 255 | |
| 256 | For example, suppose you are using `foo-lib-latest.zip`, which contains the |
| 257 | directory `foo-lib-1.2.3/` under which there is a `WORKSPACE` file and are |
| 258 | `src/`, `lib/`, and `test/` directories that contain the actual code you |
| 259 | wish to build. Specify `strip_prefix = "foo-lib-1.2.3"` to use the |
| 260 | `foo-lib-1.2.3` directory as your top-level directory. |
| 261 | |
| 262 | Note that if there are files outside of this directory, they will be |
| 263 | discarded and inaccessible (e.g., a top-level license file). This includes |
| 264 | files/directories that start with the prefix but are not in the directory |
| 265 | (e.g., `foo-lib-1.2.3.release-notes`). If the specified prefix does not |
| 266 | match a directory in the archive, Bazel will return an error.""", |
| 267 | ), |
| 268 | "type": attr.string( |
| 269 | doc = """The archive type of the downloaded file. |
| 270 | |
| 271 | By default, the archive type is determined from the file extension of the |
| 272 | URL. If the file has no extension, you can explicitly specify one of the |
Christopher Peterson Sauer | 9055c67 | 2021-07-28 10:43:20 -0700 | [diff] [blame] | 273 | following: `"zip"`, `"jar"`, `"war"`, `"aar"`, `"tar"`, `"tar.gz"`, `"tgz"`, |
Kevin Lubick | 9c98120 | 2022-04-05 06:56:26 -0700 | [diff] [blame] | 274 | `"tar.xz"`, `"txz"`, `"tar.zst"`, `"tzst"`, `tar.bz2`, `"ar"`, or `"deb"`.""", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 275 | ), |
| 276 | "patches": attr.label_list( |
| 277 | default = [], |
| 278 | doc = |
Yun Peng | 80a63d7 | 2019-07-11 06:52:25 -0700 | [diff] [blame] | 279 | "A list of files that are to be applied as patches after " + |
| 280 | "extracting the archive. By default, it uses the Bazel-native patch implementation " + |
| 281 | "which doesn't support fuzz match and binary patch, but Bazel will fall back to use " + |
| 282 | "patch command line tool if `patch_tool` attribute is specified or there are " + |
| 283 | "arguments other than `-p` in `patch_args` attribute.", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 284 | ), |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 285 | "remote_patches": attr.string_dict( |
| 286 | default = {}, |
| 287 | doc = |
| 288 | "A map of patch file URL to its integrity value, they are applied after extracting " + |
| 289 | "the archive and before applying patch files from the `patches` attribute. " + |
| 290 | "It uses the Bazel-native patch implementation, you can specify the patch strip " + |
| 291 | "number with `remote_patch_strip`", |
| 292 | ), |
| 293 | "remote_patch_strip": attr.int( |
| 294 | default = 0, |
| 295 | doc = |
| 296 | "The number of leading slashes to be stripped from the file name in the remote patches.", |
| 297 | ), |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 298 | "patch_tool": attr.string( |
Yun Peng | 80a63d7 | 2019-07-11 06:52:25 -0700 | [diff] [blame] | 299 | default = "", |
| 300 | doc = "The patch(1) utility to use. If this is specified, Bazel will use the specifed " + |
| 301 | "patch tool instead of the Bazel-native patch implementation.", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 302 | ), |
| 303 | "patch_args": attr.string_list( |
| 304 | default = ["-p0"], |
Yun Peng | 80a63d7 | 2019-07-11 06:52:25 -0700 | [diff] [blame] | 305 | doc = |
| 306 | "The arguments given to the patch tool. Defaults to -p0, " + |
| 307 | "however -p1 will usually be needed for patches generated by " + |
| 308 | "git. If multiple -p arguments are specified, the last one will take effect." + |
| 309 | "If arguments other than -p are specified, Bazel will fall back to use patch " + |
| 310 | "command line tool instead of the Bazel-native patch implementation. When falling " + |
| 311 | "back to patch command line tool and patch_tool attribute is not specified, " + |
pcloudy | e9a4e93 | 2021-07-07 04:55:00 -0700 | [diff] [blame] | 312 | "`patch` will be used. This only affects patch files in the `patches` attribute.", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 313 | ), |
| 314 | "patch_cmds": attr.string_list( |
| 315 | default = [], |
Yun Peng | 80a63d7 | 2019-07-11 06:52:25 -0700 | [diff] [blame] | 316 | doc = "Sequence of Bash commands to be applied on Linux/Macos after patches are applied.", |
| 317 | ), |
| 318 | "patch_cmds_win": attr.string_list( |
| 319 | default = [], |
| 320 | doc = "Sequence of Powershell commands to be applied on Windows after patches are " + |
| 321 | "applied. If this attribute is not set, patch_cmds will be executed on Windows, " + |
| 322 | "which requires Bash binary to exist.", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 323 | ), |
| 324 | "build_file": attr.label( |
| 325 | allow_single_file = True, |
| 326 | doc = |
| 327 | "The file to use as the BUILD file for this repository." + |
| 328 | "This attribute is an absolute label (use '@//' for the main " + |
| 329 | "repo). The file does not need to be named BUILD, but can " + |
| 330 | "be (something like BUILD.new-repo-name may work well for " + |
| 331 | "distinguishing it from the repository's actual BUILD files. " + |
| 332 | "Either build_file or build_file_content can be specified, but " + |
| 333 | "not both.", |
| 334 | ), |
| 335 | "build_file_content": attr.string( |
| 336 | doc = |
| 337 | "The content for the BUILD file for this repository. " + |
| 338 | "Either build_file or build_file_content can be specified, but " + |
| 339 | "not both.", |
| 340 | ), |
| 341 | "workspace_file": attr.label( |
| 342 | doc = |
| 343 | "The file to use as the `WORKSPACE` file for this repository. " + |
| 344 | "Either `workspace_file` or `workspace_file_content` can be " + |
| 345 | "specified, or neither, but not both.", |
| 346 | ), |
| 347 | "workspace_file_content": attr.string( |
| 348 | doc = |
| 349 | "The content for the WORKSPACE file for this repository. " + |
| 350 | "Either `workspace_file` or `workspace_file_content` can be " + |
| 351 | "specified, or neither, but not both.", |
| 352 | ), |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 353 | } |
| 354 | |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 355 | http_archive = repository_rule( |
| 356 | implementation = _http_archive_impl, |
| 357 | attrs = _http_archive_attrs, |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 358 | doc = |
| 359 | """Downloads a Bazel repository as a compressed archive file, decompresses it, |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 360 | and makes its targets available for binding. |
| 361 | |
Kevin Lubick | 9c98120 | 2022-04-05 06:56:26 -0700 | [diff] [blame] | 362 | It supports the following file extensions: `"zip"`, `"jar"`, `"war"`, `"aar"`, `"tar"`, |
| 363 | `"tar.gz"`, `"tgz"`, `"tar.xz"`, `"txz"`, `"tar.zst"`, `"tzst"`, `tar.bz2`, `"ar"`, |
| 364 | or `"deb"`. |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 365 | |
| 366 | Examples: |
| 367 | Suppose the current repository contains the source code for a chat program, |
| 368 | rooted at the directory `~/chat-app`. It needs to depend on an SSL library |
| 369 | which is available from http://example.com/openssl.zip. This `.zip` file |
| 370 | contains the following directory structure: |
| 371 | |
| 372 | ``` |
| 373 | WORKSPACE |
| 374 | src/ |
| 375 | openssl.cc |
| 376 | openssl.h |
| 377 | ``` |
| 378 | |
| 379 | In the local repository, the user creates a `openssl.BUILD` file which |
| 380 | contains the following target definition: |
| 381 | |
| 382 | ```python |
| 383 | cc_library( |
| 384 | name = "openssl-lib", |
| 385 | srcs = ["src/openssl.cc"], |
| 386 | hdrs = ["src/openssl.h"], |
| 387 | ) |
| 388 | ``` |
| 389 | |
| 390 | Targets in the `~/chat-app` repository can depend on this target if the |
| 391 | following lines are added to `~/chat-app/WORKSPACE`: |
| 392 | |
| 393 | ```python |
Klaus Aehlig | 8808f95 | 2019-03-22 02:59:01 -0700 | [diff] [blame] | 394 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") |
| 395 | |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 396 | http_archive( |
| 397 | name = "my_ssl", |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 398 | url = "http://example.com/openssl.zip", |
Klaus Aehlig | cbe6aed | 2019-04-26 06:30:46 -0700 | [diff] [blame] | 399 | sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 400 | build_file = "@//:openssl.BUILD", |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 401 | ) |
| 402 | ``` |
| 403 | |
| 404 | Then targets would specify `@my_ssl//:openssl-lib` as a dependency. |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 405 | """, |
| 406 | ) |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 407 | |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 408 | _http_file_attrs = { |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 409 | "executable": attr.bool( |
| 410 | doc = "If the downloaded file should be made executable.", |
| 411 | ), |
| 412 | "downloaded_file_path": attr.string( |
| 413 | default = "downloaded", |
| 414 | doc = "Path assigned to the file downloaded", |
| 415 | ), |
| 416 | "sha256": attr.string( |
| 417 | doc = """The expected SHA-256 of the file downloaded. |
| 418 | |
| 419 | This must match the SHA-256 of the file downloaded. _It is a security risk |
| 420 | to omit the SHA-256 as remote files can change._ At best omitting this |
| 421 | field will make your build non-hermetic. It is optional to make development |
| 422 | easier but should be set before shipping.""", |
| 423 | ), |
David Ostrovsky | 3e5ece3 | 2020-01-20 02:29:56 -0800 | [diff] [blame] | 424 | "canonical_id": attr.string( |
| 425 | doc = """A canonical id of the archive downloaded. |
| 426 | |
| 427 | If specified and non-empty, bazel will not take the archive from cache, |
| 428 | unless it was added to the cache by a request with the same canonical id. |
| 429 | """, |
| 430 | ), |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 431 | "url": attr.string(doc = _URL_DOC), |
| 432 | "urls": attr.string_list(doc = _URLS_DOC), |
pcloudy | 7aa5237 | 2022-01-11 05:03:54 -0800 | [diff] [blame] | 433 | "netrc": attr.string( |
| 434 | doc = "Location of the .netrc file to use for authentication", |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 435 | ), |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 436 | "auth_patterns": attr.string_dict( |
Jingwen Chen | c5ec3c0 | 2020-03-25 16:53:15 -0700 | [diff] [blame] | 437 | doc = _AUTH_PATTERN_DOC, |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 438 | ), |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 439 | } |
| 440 | |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 441 | http_file = repository_rule( |
| 442 | implementation = _http_file_impl, |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 443 | attrs = _http_file_attrs, |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 444 | doc = |
| 445 | """Downloads a file from a URL and makes it available to be used as a file |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 446 | group. |
| 447 | |
| 448 | Examples: |
| 449 | Suppose you need to have a debian package for your custom rules. This package |
| 450 | is available from http://example.com/package.deb. Then you can add to your |
| 451 | WORKSPACE file: |
| 452 | |
| 453 | ```python |
Klaus Aehlig | 8808f95 | 2019-03-22 02:59:01 -0700 | [diff] [blame] | 454 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") |
| 455 | |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 456 | http_file( |
| 457 | name = "my_deb", |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 458 | url = "http://example.com/package.deb", |
Klaus Aehlig | cbe6aed | 2019-04-26 06:30:46 -0700 | [diff] [blame] | 459 | sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", |
David Chen | 451599a | 2016-11-18 23:58:35 +0000 | [diff] [blame] | 460 | ) |
| 461 | ``` |
| 462 | |
| 463 | Targets would specify `@my_deb//file` as a dependency to depend on this file. |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 464 | """, |
| 465 | ) |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 466 | |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 467 | _http_jar_attrs = { |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 468 | "sha256": attr.string( |
| 469 | doc = "The expected SHA-256 of the file downloaded.", |
| 470 | ), |
David Ostrovsky | 3e5ece3 | 2020-01-20 02:29:56 -0800 | [diff] [blame] | 471 | "canonical_id": attr.string( |
| 472 | doc = """A canonical id of the archive downloaded. |
| 473 | |
| 474 | If specified and non-empty, bazel will not take the archive from cache, |
| 475 | unless it was added to the cache by a request with the same canonical id. |
| 476 | """, |
| 477 | ), |
Christopher Peterson Sauer | d273cb6 | 2022-05-17 08:20:57 -0700 | [diff] [blame^] | 478 | "url": attr.string(doc = _URL_DOC + "\n\nThe URL must end in `.jar`."), |
| 479 | "urls": attr.string_list(doc = _URLS_DOC + "\n\nAll URLs must end in `.jar`."), |
pcloudy | 7aa5237 | 2022-01-11 05:03:54 -0800 | [diff] [blame] | 480 | "netrc": attr.string( |
| 481 | doc = "Location of the .netrc file to use for authentication", |
Klaus Aehlig | c3d73f7 | 2019-09-20 07:17:33 -0700 | [diff] [blame] | 482 | ), |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 483 | "auth_patterns": attr.string_dict( |
Jingwen Chen | c5ec3c0 | 2020-03-25 16:53:15 -0700 | [diff] [blame] | 484 | doc = _AUTH_PATTERN_DOC, |
Cristian Hancila | db64550 | 2020-03-09 11:12:52 -0700 | [diff] [blame] | 485 | ), |
Rabi Shanker Guha | 15b1840 | 2021-09-21 10:42:39 -0700 | [diff] [blame] | 486 | "downloaded_file_name": attr.string( |
| 487 | default = "downloaded.jar", |
| 488 | doc = "Filename assigned to the jar downloaded", |
| 489 | ), |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 490 | } |
| 491 | |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 492 | http_jar = repository_rule( |
| 493 | implementation = _http_jar_impl, |
dannark | 94e1dcc | 2018-12-20 16:35:32 -0800 | [diff] [blame] | 494 | attrs = _http_jar_attrs, |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 495 | doc = |
| 496 | """Downloads a jar from a URL and makes it available as java_import |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 497 | |
| 498 | Downloaded files must have a .jar extension. |
| 499 | |
| 500 | Examples: |
| 501 | Suppose the current repository contains the source code for a chat program, rooted at the |
| 502 | directory `~/chat-app`. It needs to depend on an SSL library which is available from |
| 503 | `http://example.com/openssl-0.2.jar`. |
| 504 | |
| 505 | Targets in the `~/chat-app` repository can depend on this target if the following lines are |
| 506 | added to `~/chat-app/WORKSPACE`: |
| 507 | |
| 508 | ```python |
Klaus Aehlig | 8808f95 | 2019-03-22 02:59:01 -0700 | [diff] [blame] | 509 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") |
| 510 | |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 511 | http_jar( |
| 512 | name = "my_ssl", |
| 513 | url = "http://example.com/openssl-0.2.jar", |
Klaus Aehlig | cbe6aed | 2019-04-26 06:30:46 -0700 | [diff] [blame] | 514 | sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", |
Klaus Aehlig | 17735dd | 2018-05-23 07:13:49 -0700 | [diff] [blame] | 515 | ) |
| 516 | ``` |
| 517 | |
| 518 | Targets would specify <code>@my_ssl//jar</code> as a dependency to depend on this jar. |
| 519 | |
Laszlo Csomor | e926cfc | 2018-06-21 06:02:16 -0700 | [diff] [blame] | 520 | You may also reference files on the current system (localhost) by using "file:///path/to/file" |
| 521 | if you are on Unix-based systems. If you're on Windows, use "file:///c:/path/to/file". In both |
| 522 | examples, note the three slashes (`/`) -- the first two slashes belong to `file://` and the third |
| 523 | one belongs to the absolute path to the file. |
Klaus Aehlig | 852c11f | 2019-03-19 06:42:17 -0700 | [diff] [blame] | 524 | """, |
| 525 | ) |