blob: a8a82b6ef83a3e409ff64cdab74a1d1a05ed5350 [file] [log] [blame]
Jan Schär954c4b32025-07-18 09:46:25 +02001def _multi_platform_transition_impl(_settings, attr):
2 return {
3 str(platform): {"//command_line_option:platforms": str(platform)}
4 for platform in attr.platforms
5 }
6
7_multi_platform_transition = transition(
8 implementation = _multi_platform_transition_impl,
9 inputs = [],
10 outputs = ["//command_line_option:platforms"],
11)
12
13def _platform_independent_transition_impl(_settings, _attr):
14 return {"//command_line_option:platforms": "//build/platforms:all"}
15
16_platform_independent_transition = transition(
17 implementation = _platform_independent_transition_impl,
18 inputs = [],
19 outputs = ["//command_line_option:platforms"],
20)
21
22def _oci_index_impl(ctx):
23 inputs = []
24 transitive_runfiles = []
25 args = ctx.actions.args()
26
27 for platform in ctx.attr.platforms:
28 # Use ctx.split_attr because for ctx.attr, the order is unspecified.
29 image = ctx.split_attr.src[str(platform.label)]
30 files = image[DefaultInfo].files.to_list()
31 if len(files) != 1:
32 fail("image does not have exactly one directory: {}", files)
33 file = files[0]
34 if not file.is_directory:
35 fail("image is not a directory: {}", file)
36 inputs.append(file)
37 args.add("-image", file.path)
38 transitive_runfiles.append(image[DefaultInfo].default_runfiles)
39
40 output = ctx.actions.declare_directory(ctx.label.name)
41 args.add("-out", output.path)
42
43 ctx.actions.run(
44 mnemonic = "MkOCIIndex",
45 executable = ctx.executable._mkoci_index,
46 arguments = [args],
47 inputs = inputs,
48 outputs = [output],
49 )
50
51 # The inputs are referenced by symlinks.
52 runfiles = ctx.runfiles(files = inputs)
53
54 # Also merge the runfiles of the input images, in case they already use symlinks.
55 runfiles = runfiles.merge_all(transitive_runfiles)
56 return [DefaultInfo(
57 files = depset([output]),
58 runfiles = runfiles,
59 )]
60
61oci_index = rule(
62 cfg = _platform_independent_transition,
63 implementation = _oci_index_impl,
64 doc = """
65 Build a multi-platform OCI index. This rule works with arbitrary image
66 types, as it does not attempt to parse the image config.
67
68 Since the index is not for a specific platform, it is transitioned to
69 the platform-independent platform.
70 """,
71 attrs = {
72 "src": attr.label(
73 doc = """
74 OCI image, stored in an OCI layout directory. The descriptor in
75 the index.json should include platform information, as the
76 descriptor is copied as is into the generated index.
77 """,
78 mandatory = True,
79 allow_files = True,
80 cfg = _multi_platform_transition,
81 ),
82 "platforms": attr.label_list(
83 doc = """
84 A list of platforms for which the OCI image is built and added to the index.
85 """,
86 mandatory = True,
87 providers = [platform_common.PlatformInfo],
88 ),
89
90 # Tool
91 "_mkoci_index": attr.label(
92 default = Label("//osbase/build/mkoci/index:mkoci_index"),
93 executable = True,
94 cfg = "exec",
95 ),
96 },
97)