blob: d836331b7b2e5b060665f84f4d243d8233c2febd [file] [log] [blame]
Brian Silvermancc09f182022-03-09 15:40:20 -08001"""Utilities directly related to bootstrapping `cargo-bazel`"""
2
3_SRCS_TEMPLATE = """\
4\"\"\"A generate file containing all source files used to produce `cargo-bazel`\"\"\"
5
6# Each source file is tracked as a target so the `cargo_bootstrap_repository`
7# rule will know to automatically rebuild if any of the sources changed.
8CARGO_BAZEL_SRCS = [
9 {srcs}
10]
11"""
12
Adam Snaider1c095c92023-07-08 02:09:58 -040013def _format_src_label(label):
14 if label.workspace_name != "":
15 fail("`srcs` must be from the rules_rust repository")
16 return "Label(\"{}\"),".format(str(label).lstrip("@"))
17
Brian Silvermancc09f182022-03-09 15:40:20 -080018def _srcs_module_impl(ctx):
Adam Snaider1c095c92023-07-08 02:09:58 -040019 srcs = [_format_src_label(src.owner) for src in ctx.files.srcs]
Brian Silvermancc09f182022-03-09 15:40:20 -080020 if not srcs:
21 fail("`srcs` cannot be empty")
22 output = ctx.actions.declare_file(ctx.label.name)
23
24 ctx.actions.write(
25 output = output,
26 content = _SRCS_TEMPLATE.format(
Adam Snaider1c095c92023-07-08 02:09:58 -040027 srcs = "\n ".join(srcs),
Brian Silvermancc09f182022-03-09 15:40:20 -080028 ),
29 )
30
31 return DefaultInfo(
32 files = depset([output]),
33 )
34
35_srcs_module = rule(
36 doc = "A rule for writing a list of sources to a templated file",
37 implementation = _srcs_module_impl,
38 attrs = {
39 "srcs": attr.label(
40 doc = "A filegroup of source files",
41 allow_files = True,
42 ),
43 },
44)
45
46_INSTALLER_TEMPLATE = """\
47#!/bin/bash
48set -euo pipefail
49cp -f "{path}" "${{BUILD_WORKSPACE_DIRECTORY}}/{dest}"
50"""
51
52def _srcs_installer_impl(ctx):
53 output = ctx.actions.declare_file(ctx.label.name + ".sh")
54 target_file = ctx.file.input
55 dest = ctx.file.dest.short_path
56
57 ctx.actions.write(
58 output = output,
59 content = _INSTALLER_TEMPLATE.format(
60 path = target_file.short_path,
61 dest = dest,
62 ),
63 is_executable = True,
64 )
65
66 return DefaultInfo(
67 files = depset([output]),
68 runfiles = ctx.runfiles(files = [target_file]),
69 executable = output,
70 )
71
72_srcs_installer = rule(
73 doc = "A rule for writing a file back to the repository",
74 implementation = _srcs_installer_impl,
75 attrs = {
76 "dest": attr.label(
77 doc = "the file name to use for installation",
78 allow_single_file = True,
79 mandatory = True,
80 ),
81 "input": attr.label(
82 doc = "The file to write back to the repository",
83 allow_single_file = True,
84 mandatory = True,
85 ),
86 },
87 executable = True,
88)
89
90def srcs_module(name, dest, **kwargs):
91 """A helper rule to ensure the bootstrapping functionality of `cargo-bazel` is always up to date
92
93 Args:
94 name (str): The name of the sources module
95 dest (str): The filename the module should be written as in the current package.
96 **kwargs (dict): Additional keyword arguments
97 """
98 tags = kwargs.pop("tags", [])
99
100 _srcs_module(
101 name = name,
102 tags = tags,
103 **kwargs
104 )
105
106 _srcs_installer(
107 name = name + ".install",
108 input = name,
109 dest = dest,
110 tags = tags,
111 )