xref: /aosp_15_r20/external/bazelbuild-kotlin-rules/kotlin/jvm/util/file_factory.bzl (revision 3a22c0a33dd99bcca39a024d43e6fbcc55c2806e)
1# Copyright 2022 Google LLC. 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#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
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
15"""FileFactory"""
16
17load("//:visibility.bzl", "RULES_KOTLIN")
18
19visibility(RULES_KOTLIN)
20
21def FileFactory(ctx, base):
22    """Creates files with names derived from some base file or prefix
23
24    Including the name of a rule is not always enough to guarantee unique filenames. For example,
25    helper functions that declare their own output files may be called multiple times in the same
26    rule impl.
27
28    Args:
29        ctx: ctx
30        base: [File|string] The file to derive other filenames from, or an exact base prefix
31
32    Returns:
33        FileFactory
34    """
35
36    if type(base) != "string":
37        base = _scrub_base_file(ctx, base)
38
39    def declare_directory(suffix):
40        return ctx.actions.declare_directory(base + suffix)
41
42    def declare_file(suffix):
43        return ctx.actions.declare_file(base + suffix)
44
45    def derive(suffix):
46        return FileFactory(ctx, base + suffix)
47
48    return struct(
49        base_as_path = ctx.bin_dir.path + "/" + ctx.label.package + "/" + base,
50        declare_directory = declare_directory,
51        declare_file = declare_file,
52        derive = derive,
53    )
54
55def _scrub_base_file(ctx, file):
56    if not file.extension:
57        fail("Base file must have an extension: was %s" % (file.path))
58    if file.owner.package != ctx.label.package:
59        fail("Base file must be from ctx package: was %s expected %s" % (file.owner.package, ctx.label.package))
60
61    return file.short_path.removeprefix(ctx.label.package + "/").rsplit(".", 1)[0]
62