blob: 9df387e9eda7a5c5819ad1cfcbe45541fd9ec7cc [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
13def _srcs_module_impl(ctx):
14 srcs = ["@rules_rust{}".format(src.owner) for src in ctx.files.srcs]
15 if not srcs:
16 fail("`srcs` cannot be empty")
17 output = ctx.actions.declare_file(ctx.label.name)
18
19 ctx.actions.write(
20 output = output,
21 content = _SRCS_TEMPLATE.format(
22 srcs = "\n ".join(["\"{}\",".format(src) for src in srcs]),
23 ),
24 )
25
26 return DefaultInfo(
27 files = depset([output]),
28 )
29
30_srcs_module = rule(
31 doc = "A rule for writing a list of sources to a templated file",
32 implementation = _srcs_module_impl,
33 attrs = {
34 "srcs": attr.label(
35 doc = "A filegroup of source files",
36 allow_files = True,
37 ),
38 },
39)
40
41_INSTALLER_TEMPLATE = """\
42#!/bin/bash
43set -euo pipefail
44cp -f "{path}" "${{BUILD_WORKSPACE_DIRECTORY}}/{dest}"
45"""
46
47def _srcs_installer_impl(ctx):
48 output = ctx.actions.declare_file(ctx.label.name + ".sh")
49 target_file = ctx.file.input
50 dest = ctx.file.dest.short_path
51
52 ctx.actions.write(
53 output = output,
54 content = _INSTALLER_TEMPLATE.format(
55 path = target_file.short_path,
56 dest = dest,
57 ),
58 is_executable = True,
59 )
60
61 return DefaultInfo(
62 files = depset([output]),
63 runfiles = ctx.runfiles(files = [target_file]),
64 executable = output,
65 )
66
67_srcs_installer = rule(
68 doc = "A rule for writing a file back to the repository",
69 implementation = _srcs_installer_impl,
70 attrs = {
71 "dest": attr.label(
72 doc = "the file name to use for installation",
73 allow_single_file = True,
74 mandatory = True,
75 ),
76 "input": attr.label(
77 doc = "The file to write back to the repository",
78 allow_single_file = True,
79 mandatory = True,
80 ),
81 },
82 executable = True,
83)
84
85def srcs_module(name, dest, **kwargs):
86 """A helper rule to ensure the bootstrapping functionality of `cargo-bazel` is always up to date
87
88 Args:
89 name (str): The name of the sources module
90 dest (str): The filename the module should be written as in the current package.
91 **kwargs (dict): Additional keyword arguments
92 """
93 tags = kwargs.pop("tags", [])
94
95 _srcs_module(
96 name = name,
97 tags = tags,
98 **kwargs
99 )
100
101 _srcs_installer(
102 name = name + ".install",
103 input = name,
104 dest = dest,
105 tags = tags,
106 )