blob: 3f4c2cf2c0123a0d53e3d39da23081a69b491c8a [file] [log] [blame]
Klaus Aehlig3c9cd822018-05-24 03:35:42 -07001# 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#
Googlerbd7a6b92022-02-24 07:38:58 -08007# http://www.apache.org/licenses/LICENSE-2.0
Klaus Aehlig3c9cd822018-05-24 03:35:42 -07008#
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 Meumertzheimb9a05782024-05-13 09:18:57 -070016load("//src/tools/bzlmod:utils.bzl", "parse_http_artifacts", "parse_registry_files")
Tony Aiuto3b2d3102021-01-07 03:40:14 -080017
vladmos20a042f2018-06-01 04:51:21 -070018_BUILD = """
Googler8c41763f72022-07-08 06:09:05 -070019load("@rules_pkg//pkg:tar.bzl", "pkg_tar")
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070020
Yun Peng50c83752023-10-10 18:30:26 -070021filegroup(
22 name="files",
23 srcs = {srcs},
24 visibility = ["//visibility:public"],
25)
26
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070027pkg_tar(
28 name="archives",
Yun Peng50c83752023-10-10 18:30:26 -070029 srcs = [":files"],
Yun Pengb27ca732023-09-06 02:57:04 -070030 strip_prefix = "{strip_prefix}",
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070031 package_dir = "{dirname}",
32 visibility = ["//visibility:public"],
33)
34
35"""
36
37def _distdir_tar_impl(ctx):
vladmos20a042f2018-06-01 04:51:21 -070038 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 Pengb27ca732023-09-06 02:57:04 -070043 _BUILD.format(srcs = ctx.attr.archives, strip_prefix = "", dirname = ctx.attr.dirname),
vladmos20a042f2018-06-01 04:51:21 -070044 )
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070045
46_distdir_tar_attrs = {
vladmos20a042f2018-06-01 04:51:21 -070047 "archives": attr.string_list(),
48 "sha256": attr.string_dict(),
49 "urls": attr.string_list_dict(),
50 "dirname": attr.string(default = "distdir"),
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070051}
52
Tony Aiuto337e7172020-12-09 10:20:14 -080053_distdir_tar = repository_rule(
Klaus Aehlig3c9cd822018-05-24 03:35:42 -070054 implementation = _distdir_tar_impl,
55 attrs = _distdir_tar_attrs,
56)
Tony Aiuto337e7172020-12-09 10:20:14 -080057
Yun Pengc1f2aff2023-11-07 09:51:02 -080058def distdir_tar(name, dist_deps):
Tony Aiuto337e7172020-12-09 10:20:14 -080059 """Creates a repository whose content is a set of tar files.
60
61 Args:
62 name: repo name.
Tony Aiuto337e7172020-12-09 10:20:14 -080063 dist_deps: map of repo names to dict of archive, sha256, and urls.
64 """
Yun Pengc1f2aff2023-11-07 09:51:02 -080065 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 Aiuto337e7172020-12-09 10:20:14 -080073 _distdir_tar(
74 name = name,
75 archives = archives,
76 sha256 = sha256,
77 urls = urls,
Tony Aiuto337e7172020-12-09 10:20:14 -080078 )
Tony Aiuto3b2d3102021-01-07 03:40:14 -080079
Yun Pengb27ca732023-09-06 02:57:04 -070080def _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 Meumertzheimb9a05782024-05-13 09:18:57 -070090 registry_files = parse_registry_files(ctx, lockfile_path, ctx.attr.module_files)
Yun Pengb27ca732023-09-06 02:57:04 -070091
Xdng Yngc46b9ce2024-10-01 14:21:54 -070092 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({
Googlerc92c1032024-10-06 11:51:46 -070096 "url": "https://github.com/protocolbuffers/protobuf/releases/download/v29.0-rc1/protobuf-29.0-rc1.zip",
97 "integrity": "sha256-tSay4N4FspF+VnsNCTGtMH3xV4ZrtHioxNeB/bjQhsI=",
Xdng Yngc46b9ce2024-10-01 14:21:54 -070098 })
99
Yun Pengb27ca732023-09-06 02:57:04 -0700100 archive_files = []
101 readme_content = "This directory contains repository cache artifacts for the following URLs:\n\n"
Fabian Meumertzheimb9a05782024-05-13 09:18:57 -0700102 for artifact in http_artifacts + registry_files:
Yun Pengb27ca732023-09-06 02:57:04 -0700103 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 Meumertzheimb9a05782024-05-13 09:18:57 -0700134 "module_files": attr.label_list(),
Yun Pengb27ca732023-09-06 02:57:04 -0700135}
136
137repo_cache_tar = repository_rule(
138 implementation = _repo_cache_tar_impl,
139 attrs = _repo_cache_tar_attrs,
140)