xref: /aosp_15_r20/external/bazel-skylib/rules/private/write_file_private.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1*bcb5dc79SHONG Yifan# Copyright 2019 The Bazel Authors. All rights reserved.
2*bcb5dc79SHONG Yifan#
3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License");
4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License.
5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at
6*bcb5dc79SHONG Yifan#
7*bcb5dc79SHONG Yifan#    http://www.apache.org/licenses/LICENSE-2.0
8*bcb5dc79SHONG Yifan#
9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software
10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS,
11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and
13*bcb5dc79SHONG Yifan# limitations under the License.
14*bcb5dc79SHONG Yifan
15*bcb5dc79SHONG Yifan"""Implementation of write_file macro and underlying rules.
16*bcb5dc79SHONG Yifan
17*bcb5dc79SHONG YifanThese rules write a UTF-8 encoded text file, using Bazel's FileWriteAction.
18*bcb5dc79SHONG Yifan'_write_xfile' marks the resulting file executable, '_write_file' does not.
19*bcb5dc79SHONG Yifan"""
20*bcb5dc79SHONG Yifan
21*bcb5dc79SHONG Yifandef _common_impl(ctx, is_windows, is_executable):
22*bcb5dc79SHONG Yifan    if ctx.attr.newline == "auto":
23*bcb5dc79SHONG Yifan        newline = "\r\n" if is_windows else "\n"
24*bcb5dc79SHONG Yifan    elif ctx.attr.newline == "windows":
25*bcb5dc79SHONG Yifan        newline = "\r\n"
26*bcb5dc79SHONG Yifan    else:
27*bcb5dc79SHONG Yifan        newline = "\n"
28*bcb5dc79SHONG Yifan
29*bcb5dc79SHONG Yifan    # ctx.actions.write creates a FileWriteAction which uses UTF-8 encoding.
30*bcb5dc79SHONG Yifan    ctx.actions.write(
31*bcb5dc79SHONG Yifan        output = ctx.outputs.out,
32*bcb5dc79SHONG Yifan        content = newline.join(ctx.attr.content) if ctx.attr.content else "",
33*bcb5dc79SHONG Yifan        is_executable = is_executable,
34*bcb5dc79SHONG Yifan    )
35*bcb5dc79SHONG Yifan    files = depset(direct = [ctx.outputs.out])
36*bcb5dc79SHONG Yifan    runfiles = ctx.runfiles(files = [ctx.outputs.out])
37*bcb5dc79SHONG Yifan    if is_executable:
38*bcb5dc79SHONG Yifan        return [DefaultInfo(files = files, runfiles = runfiles, executable = ctx.outputs.out)]
39*bcb5dc79SHONG Yifan    else:
40*bcb5dc79SHONG Yifan        # Do not include the copied file into the default runfiles of the
41*bcb5dc79SHONG Yifan        # target, but ensure that it is picked up by native rule's data
42*bcb5dc79SHONG Yifan        # attribute despite https://github.com/bazelbuild/bazel/issues/15043.
43*bcb5dc79SHONG Yifan        return [DefaultInfo(files = files, data_runfiles = runfiles)]
44*bcb5dc79SHONG Yifan
45*bcb5dc79SHONG Yifandef _impl(ctx):
46*bcb5dc79SHONG Yifan    return _common_impl(ctx, ctx.attr.is_windows, False)
47*bcb5dc79SHONG Yifan
48*bcb5dc79SHONG Yifandef _ximpl(ctx):
49*bcb5dc79SHONG Yifan    return _common_impl(ctx, ctx.attr.is_windows, True)
50*bcb5dc79SHONG Yifan
51*bcb5dc79SHONG Yifan_ATTRS = {
52*bcb5dc79SHONG Yifan    "out": attr.output(mandatory = True),
53*bcb5dc79SHONG Yifan    "content": attr.string_list(mandatory = False, allow_empty = True),
54*bcb5dc79SHONG Yifan    "newline": attr.string(values = ["unix", "windows", "auto"], default = "auto"),
55*bcb5dc79SHONG Yifan    "is_windows": attr.bool(mandatory = True),
56*bcb5dc79SHONG Yifan}
57*bcb5dc79SHONG Yifan
58*bcb5dc79SHONG Yifan_write_file = rule(
59*bcb5dc79SHONG Yifan    implementation = _impl,
60*bcb5dc79SHONG Yifan    provides = [DefaultInfo],
61*bcb5dc79SHONG Yifan    attrs = _ATTRS,
62*bcb5dc79SHONG Yifan)
63*bcb5dc79SHONG Yifan
64*bcb5dc79SHONG Yifan_write_xfile = rule(
65*bcb5dc79SHONG Yifan    implementation = _ximpl,
66*bcb5dc79SHONG Yifan    executable = True,
67*bcb5dc79SHONG Yifan    provides = [DefaultInfo],
68*bcb5dc79SHONG Yifan    attrs = _ATTRS,
69*bcb5dc79SHONG Yifan)
70*bcb5dc79SHONG Yifan
71*bcb5dc79SHONG Yifandef write_file(
72*bcb5dc79SHONG Yifan        name,
73*bcb5dc79SHONG Yifan        out,
74*bcb5dc79SHONG Yifan        content = [],
75*bcb5dc79SHONG Yifan        is_executable = False,
76*bcb5dc79SHONG Yifan        newline = "auto",
77*bcb5dc79SHONG Yifan        **kwargs):
78*bcb5dc79SHONG Yifan    """Creates a UTF-8 encoded text file.
79*bcb5dc79SHONG Yifan
80*bcb5dc79SHONG Yifan    Args:
81*bcb5dc79SHONG Yifan      name: Name of the rule.
82*bcb5dc79SHONG Yifan      out: Path of the output file, relative to this package.
83*bcb5dc79SHONG Yifan      content: A list of strings. Lines of text, the contents of the file.
84*bcb5dc79SHONG Yifan          Newlines are added automatically after every line except the last one.
85*bcb5dc79SHONG Yifan      is_executable: A boolean. Whether to make the output file executable.
86*bcb5dc79SHONG Yifan          When True, the rule's output can be executed using `bazel run` and can
87*bcb5dc79SHONG Yifan          be in the srcs of binary and test rules that require executable
88*bcb5dc79SHONG Yifan          sources.
89*bcb5dc79SHONG Yifan      newline: one of ["auto", "unix", "windows"]: line endings to use. "auto"
90*bcb5dc79SHONG Yifan          for platform-determined, "unix" for LF, and "windows" for CRLF.
91*bcb5dc79SHONG Yifan      **kwargs: further keyword arguments, e.g. `visibility`
92*bcb5dc79SHONG Yifan    """
93*bcb5dc79SHONG Yifan    if is_executable:
94*bcb5dc79SHONG Yifan        _write_xfile(
95*bcb5dc79SHONG Yifan            name = name,
96*bcb5dc79SHONG Yifan            content = content,
97*bcb5dc79SHONG Yifan            out = out,
98*bcb5dc79SHONG Yifan            newline = newline or "auto",
99*bcb5dc79SHONG Yifan            is_windows = select({
100*bcb5dc79SHONG Yifan                "@bazel_tools//src/conditions:host_windows": True,
101*bcb5dc79SHONG Yifan                "//conditions:default": False,
102*bcb5dc79SHONG Yifan            }),
103*bcb5dc79SHONG Yifan            **kwargs
104*bcb5dc79SHONG Yifan        )
105*bcb5dc79SHONG Yifan    else:
106*bcb5dc79SHONG Yifan        _write_file(
107*bcb5dc79SHONG Yifan            name = name,
108*bcb5dc79SHONG Yifan            content = content,
109*bcb5dc79SHONG Yifan            out = out,
110*bcb5dc79SHONG Yifan            newline = newline or "auto",
111*bcb5dc79SHONG Yifan            is_windows = select({
112*bcb5dc79SHONG Yifan                "@bazel_tools//src/conditions:host_windows": True,
113*bcb5dc79SHONG Yifan                "//conditions:default": False,
114*bcb5dc79SHONG Yifan            }),
115*bcb5dc79SHONG Yifan            **kwargs
116*bcb5dc79SHONG Yifan        )
117