blob: 84551c734112f35cd9f7471e35a1a7a378530ec7 [file] [log] [blame]
Mike Kruskal898d8fa2023-10-18 12:21:32 -07001# Protocol Buffers - Google's data interchange format
2# Copyright 2023 Google Inc. All rights reserved.
3#
4# Use of this source code is governed by a BSD-style
5# license that can be found in the LICENSE file or at
6# https://developers.google.com/open-source/licenses/bsd
7
8"""
9Provide a rule for generating the intermediate feature set defaults used for feature resolution.
10
11See go/life-of-a-featureset for more information.
12"""
13
14def _compile_edition_defaults_impl(ctx):
15 out_file = ctx.actions.declare_file(ctx.outputs.output.basename)
16 sources = []
17 paths = []
18 for src in ctx.attr.srcs:
19 sources.extend(src[ProtoInfo].transitive_sources.to_list())
20 paths.extend(src[ProtoInfo].transitive_proto_path.to_list())
21
22 args = ctx.actions.args()
Mike Kruskal7a0e10e2024-03-11 10:36:19 -070023 args.add("--edition_defaults_out", out_file)
Mike Kruskal898d8fa2023-10-18 12:21:32 -070024
Mike Kruskal7a0e10e2024-03-11 10:36:19 -070025 args.add("--edition_defaults_minimum", ctx.attr.minimum_edition)
26 args.add("--edition_defaults_maximum", ctx.attr.maximum_edition)
Mike Kruskal898d8fa2023-10-18 12:21:32 -070027 for p in paths:
28 args.add("--proto_path", p)
29 for source in sources:
30 args.add(source)
31 ctx.actions.run(
32 outputs = [out_file],
33 inputs = sources,
Mike Kruskal7d87a172024-04-11 14:14:43 -070034 executable = ctx.executable.protoc or ctx.executable._protoc_minimal,
Mike Kruskal898d8fa2023-10-18 12:21:32 -070035 arguments = [args],
36 progress_message = "Generating edition defaults",
37 )
38
39compile_edition_defaults = rule(
40 attrs = {
41 "srcs": attr.label_list(
42 mandatory = True,
43 allow_rules = ["proto_library"],
44 providers = [ProtoInfo],
45 ),
46 "minimum_edition": attr.string(mandatory = True),
47 "maximum_edition": attr.string(mandatory = True),
Mike Kruskal7d87a172024-04-11 14:14:43 -070048 "protoc": attr.label(
49 mandatory = False,
50 executable = True,
51 cfg = "exec",
52 ),
53 "_protoc_minimal": attr.label(
Mike Kruskal898d8fa2023-10-18 12:21:32 -070054 default = "//src/google/protobuf/compiler:protoc_minimal",
55 executable = True,
56 cfg = "exec",
57 ),
58 },
59 implementation = _compile_edition_defaults_impl,
60 outputs = {
61 "output": "%{name}.binpb",
62 },
63)
64
65def _embed_edition_defaults_impl(ctx):
Mike Kruskalf66d8762024-02-26 16:58:16 -080066 if ctx.attr.encoding == "base64":
67 args = "--encoding=base64"
68 elif ctx.attr.encoding == "octal":
69 args = "--encoding=octal"
70 else:
71 fail("Unknown encoding %s" % ctx.attr.encoding)
Mike Kruskal898d8fa2023-10-18 12:21:32 -070072 ctx.actions.run_shell(
73 outputs = [ctx.outputs.output],
74 inputs = [ctx.file.defaults, ctx.file.template],
75 tools = [ctx.executable._escape],
76 command = """
Mike Kruskalf66d8762024-02-26 16:58:16 -080077 DEFAULTS_RAW=$({escape} {args} < {defaults})
Mike Kruskal898d8fa2023-10-18 12:21:32 -070078 # Windows requires extra escaping.
79 DEFAULTS_ESCAPED=$(echo $DEFAULTS_RAW | sed 's/\\\\/\\\\\\\\/g' ||
80 echo $DEFAULTS_RAW | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g')
81 cp -f {template} {output}
82 # MacOS requires a backup file.
83 sed -i.bak \"s|{placeholder}|$DEFAULTS_ESCAPED|g\" {output}
84 """.format(
85 escape = ctx.executable._escape.path,
Mike Kruskalf66d8762024-02-26 16:58:16 -080086 args = args,
Mike Kruskal898d8fa2023-10-18 12:21:32 -070087 defaults = ctx.file.defaults.path,
88 template = ctx.file.template.path,
89 output = ctx.outputs.output.path,
90 placeholder = ctx.attr.placeholder,
91 ),
92 )
93
94embed_edition_defaults = rule(
Mike Kruskalf66d8762024-02-26 16:58:16 -080095 doc = "genrule to embed edition defaults binary data into a template file.",
Mike Kruskal898d8fa2023-10-18 12:21:32 -070096 attrs = {
97 "defaults": attr.label(
98 mandatory = True,
99 allow_single_file = True,
100 allow_rules = ["compile_edition_defaults"],
101 providers = [ProtoInfo],
102 doc = "The compile_edition_defaults rule to embed",
103 ),
104 "output": attr.output(
105 mandatory = True,
106 doc = "The name of the output file",
107 ),
108 "template": attr.label(
109 mandatory = True,
110 allow_single_file = True,
111 doc = "The template to use for generating the output file",
112 ),
113 "placeholder": attr.string(
114 mandatory = True,
115 doc = "The placeholder to replace with a serialized string in the template",
116 ),
Mike Kruskalf66d8762024-02-26 16:58:16 -0800117 "encoding": attr.string(
118 default = "octal",
119 values = ["octal", "base64"],
120 doc = "The encoding format to use for the binary data (octal or base64)",
121 ),
Mike Kruskal898d8fa2023-10-18 12:21:32 -0700122 "_escape": attr.label(
Mike Kruskalea810242024-04-16 11:11:03 -0700123 default = "//editions:internal_defaults_escape",
Mike Kruskal898d8fa2023-10-18 12:21:32 -0700124 executable = True,
125 cfg = "exec",
126 ),
127 },
128 implementation = _embed_edition_defaults_impl,
129)