blob: cbc02a7b9f3a72ead280c7ddb8f79d7a4541e4fb [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
92 archive_files = []
93 readme_content = "This directory contains repository cache artifacts for the following URLs:\n\n"
Fabian Meumertzheimb9a05782024-05-13 09:18:57 -070094 for artifact in http_artifacts + registry_files:
Yun Pengb27ca732023-09-06 02:57:04 -070095 url = artifact["url"]
96 if "integrity" in artifact:
97 # ./tempfile could be a hard link if --experimental_repository_cache_hardlinks is used,
98 # therefore we must delete it before creating or writing it again.
99 ctx.delete("./tempfile")
100 checksum = ctx.download(url, "./tempfile", executable = False, integrity = artifact["integrity"])
101 artifact["sha256"] = checksum.sha256
102
103 if "sha256" in artifact:
104 sha256 = artifact["sha256"]
105 output_file = "content_addressable/sha256/%s/file" % sha256
106 ctx.download(url, output_file, sha256, executable = False)
107 archive_files.append(output_file)
108 readme_content += "- %s (SHA256: %s)\n" % (url, sha256)
109 else:
110 fail("Could not find integrity or sha256 hash for artifact %s" % url)
111
112 ctx.file("README.md", readme_content)
113 ctx.file(
114 "BUILD",
115 _BUILD.format(
116 srcs = archive_files + ["README.md"],
117 strip_prefix = "external/" + ctx.attr.name,
118 dirname = ctx.attr.dirname,
119 ),
120 )
121
122_repo_cache_tar_attrs = {
123 "lockfile": attr.label(default = Label("//:MODULE.bazel.lock")),
124 "dirname": attr.string(default = "repository_cache"),
125 "repos": attr.string_list(),
Fabian Meumertzheimb9a05782024-05-13 09:18:57 -0700126 "module_files": attr.label_list(),
Yun Pengb27ca732023-09-06 02:57:04 -0700127}
128
129repo_cache_tar = repository_rule(
130 implementation = _repo_cache_tar_impl,
131 attrs = _repo_cache_tar_attrs,
132)