Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 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 | # |
Googler | bd7a6b9 | 2022-02-24 07:38:58 -0800 | [diff] [blame] | 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 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 | """Defines a repository rule that generates an archive consisting of the specified files to fetch""" |
| 15 | |
Fabian Meumertzheim | b9a0578 | 2024-05-13 09:18:57 -0700 | [diff] [blame] | 16 | load("//src/tools/bzlmod:utils.bzl", "parse_http_artifacts", "parse_registry_files") |
Tony Aiuto | 3b2d310 | 2021-01-07 03:40:14 -0800 | [diff] [blame] | 17 | |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 18 | _BUILD = """ |
Googler | 8c41763f7 | 2022-07-08 06:09:05 -0700 | [diff] [blame] | 19 | load("@rules_pkg//pkg:tar.bzl", "pkg_tar") |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 20 | |
Yun Peng | 50c8375 | 2023-10-10 18:30:26 -0700 | [diff] [blame] | 21 | filegroup( |
| 22 | name="files", |
| 23 | srcs = {srcs}, |
| 24 | visibility = ["//visibility:public"], |
| 25 | ) |
| 26 | |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 27 | pkg_tar( |
| 28 | name="archives", |
Yun Peng | 50c8375 | 2023-10-10 18:30:26 -0700 | [diff] [blame] | 29 | srcs = [":files"], |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 30 | strip_prefix = "{strip_prefix}", |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 31 | package_dir = "{dirname}", |
| 32 | visibility = ["//visibility:public"], |
| 33 | ) |
| 34 | |
| 35 | """ |
| 36 | |
| 37 | def _distdir_tar_impl(ctx): |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 38 | for name in ctx.attr.archives: |
| 39 | ctx.download(ctx.attr.urls[name], name, ctx.attr.sha256[name], False) |
| 40 | ctx.file("WORKSPACE", "") |
| 41 | ctx.file( |
| 42 | "BUILD", |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 43 | _BUILD.format(srcs = ctx.attr.archives, strip_prefix = "", dirname = ctx.attr.dirname), |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 44 | ) |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 45 | |
| 46 | _distdir_tar_attrs = { |
vladmos | 20a042f | 2018-06-01 04:51:21 -0700 | [diff] [blame] | 47 | "archives": attr.string_list(), |
| 48 | "sha256": attr.string_dict(), |
| 49 | "urls": attr.string_list_dict(), |
| 50 | "dirname": attr.string(default = "distdir"), |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 51 | } |
| 52 | |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 53 | _distdir_tar = repository_rule( |
Klaus Aehlig | 3c9cd82 | 2018-05-24 03:35:42 -0700 | [diff] [blame] | 54 | implementation = _distdir_tar_impl, |
| 55 | attrs = _distdir_tar_attrs, |
| 56 | ) |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 57 | |
Yun Peng | c1f2aff | 2023-11-07 09:51:02 -0800 | [diff] [blame] | 58 | def distdir_tar(name, dist_deps): |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 59 | """Creates a repository whose content is a set of tar files. |
| 60 | |
| 61 | Args: |
| 62 | name: repo name. |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 63 | dist_deps: map of repo names to dict of archive, sha256, and urls. |
| 64 | """ |
Yun Peng | c1f2aff | 2023-11-07 09:51:02 -0800 | [diff] [blame] | 65 | archives = [] |
| 66 | sha256 = {} |
| 67 | urls = {} |
| 68 | for _, info in dist_deps.items(): |
| 69 | archive_file = info["archive"] |
| 70 | archives.append(archive_file) |
| 71 | sha256[archive_file] = info["sha256"] |
| 72 | urls[archive_file] = info["urls"] |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 73 | _distdir_tar( |
| 74 | name = name, |
| 75 | archives = archives, |
| 76 | sha256 = sha256, |
| 77 | urls = urls, |
Tony Aiuto | 337e717 | 2020-12-09 10:20:14 -0800 | [diff] [blame] | 78 | ) |
Tony Aiuto | 3b2d310 | 2021-01-07 03:40:14 -0800 | [diff] [blame] | 79 | |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 80 | def _repo_cache_tar_impl(ctx): |
| 81 | """Generate a repository cache as a tar file. |
| 82 | |
| 83 | This repository rule does the following: |
| 84 | 1. parse all http artifacts required for generating the given list of repositories from the lock file. |
| 85 | 2. downloads all http artifacts to create a repository cache directory structure. |
| 86 | 3. creates a pkg_tar target which packages the repository cache directory structure. |
| 87 | """ |
| 88 | lockfile_path = ctx.path(ctx.attr.lockfile) |
| 89 | http_artifacts = parse_http_artifacts(ctx, lockfile_path, ctx.attr.repos) |
Fabian Meumertzheim | b9a0578 | 2024-05-13 09:18:57 -0700 | [diff] [blame] | 90 | registry_files = parse_registry_files(ctx, lockfile_path, ctx.attr.module_files) |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 91 | |
Xdng Yng | c46b9ce | 2024-10-01 14:21:54 -0700 | [diff] [blame] | 92 | if "protobuf+" not in ctx.attr.repos: |
| 93 | # HACK: protobuf is currently an archive_override, so it doesn't show up in the lockfile. |
| 94 | # we manually add it to the tar entry here. |
| 95 | http_artifacts.append({ |
Googler | c92c103 | 2024-10-06 11:51:46 -0700 | [diff] [blame] | 96 | "url": "https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc1/protobuf-29.0-rc1.zip", |
| 97 | "integrity": "sha256-tSay4N4FspF+VnsNCTGtMH3xV4ZrtHioxNeB/bjQhsI=", |
Xdng Yng | c46b9ce | 2024-10-01 14:21:54 -0700 | [diff] [blame] | 98 | }) |
| 99 | |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 100 | archive_files = [] |
| 101 | readme_content = "This directory contains repository cache artifacts for the following URLs:\n\n" |
Fabian Meumertzheim | b9a0578 | 2024-05-13 09:18:57 -0700 | [diff] [blame] | 102 | for artifact in http_artifacts + registry_files: |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 103 | url = artifact["url"] |
| 104 | if "integrity" in artifact: |
| 105 | # ./tempfile could be a hard link if --experimental_repository_cache_hardlinks is used, |
| 106 | # therefore we must delete it before creating or writing it again. |
| 107 | ctx.delete("./tempfile") |
| 108 | checksum = ctx.download(url, "./tempfile", executable = False, integrity = artifact["integrity"]) |
| 109 | artifact["sha256"] = checksum.sha256 |
| 110 | |
| 111 | if "sha256" in artifact: |
| 112 | sha256 = artifact["sha256"] |
| 113 | output_file = "content_addressable/sha256/%s/file" % sha256 |
| 114 | ctx.download(url, output_file, sha256, executable = False) |
| 115 | archive_files.append(output_file) |
| 116 | readme_content += "- %s (SHA256: %s)\n" % (url, sha256) |
| 117 | else: |
| 118 | fail("Could not find integrity or sha256 hash for artifact %s" % url) |
| 119 | |
| 120 | ctx.file("README.md", readme_content) |
| 121 | ctx.file( |
| 122 | "BUILD", |
| 123 | _BUILD.format( |
| 124 | srcs = archive_files + ["README.md"], |
| 125 | strip_prefix = "external/" + ctx.attr.name, |
| 126 | dirname = ctx.attr.dirname, |
| 127 | ), |
| 128 | ) |
| 129 | |
| 130 | _repo_cache_tar_attrs = { |
| 131 | "lockfile": attr.label(default = Label("//:MODULE.bazel.lock")), |
| 132 | "dirname": attr.string(default = "repository_cache"), |
| 133 | "repos": attr.string_list(), |
Fabian Meumertzheim | b9a0578 | 2024-05-13 09:18:57 -0700 | [diff] [blame] | 134 | "module_files": attr.label_list(), |
Yun Peng | b27ca73 | 2023-09-06 02:57:04 -0700 | [diff] [blame] | 135 | } |
| 136 | |
| 137 | repo_cache_tar = repository_rule( |
| 138 | implementation = _repo_cache_tar_impl, |
| 139 | attrs = _repo_cache_tar_attrs, |
| 140 | ) |