blob: e81af5efd80614788c8e5ae7b2d1c65fc32178b4 [file] [log] [blame]
#!/usr/bin/env python
import contextlib
import glob
import io
import os
import pathlib
import re
import libcxx.test.header_information
def find_script(file):
"""Finds the script used to generate a file inside the file itself. The script is delimited by
BEGIN-SCRIPT and END-SCRIPT markers.
"""
with open(file, "r") as f:
content = f.read()
match = re.search(
r"^BEGIN-SCRIPT$(.+)^END-SCRIPT$", content, flags=re.MULTILINE | re.DOTALL
)
if not match:
raise RuntimeError(
"Was unable to find a script delimited with BEGIN-SCRIPT/END-SCRIPT markers in {}".format(
test_file
)
)
return match.group(1)
def execute_script(script, variables):
"""Executes the provided Mako template with the given variables available during the
evaluation of the script, and returns the result.
"""
code = compile(script, "fake-filename", "exec")
output = io.StringIO()
with contextlib.redirect_stdout(output):
exec(code, variables)
output = output.getvalue()
return output
def generate_new_file(file, new_content):
"""Generates the new content of the file by inserting the new content in-between
two '// GENERATED-MARKER' markers located in the file.
"""
with open(file, "r") as f:
old_content = f.read()
try:
before, begin_marker, _, end_marker, after = re.split(
r"(// GENERATED-MARKER\n)", old_content, flags=re.MULTILINE | re.DOTALL
)
except ValueError:
raise RuntimeError(
"Failed to split {} based on markers, please make sure the file has exactly two '// GENERATED-MARKER' occurrences".format(
file
)
)
return before + begin_marker + new_content + end_marker + after
def produce(test_file, variables):
script = find_script(test_file)
result = execute_script(script, variables)
new_content = generate_new_file(test_file, result)
with open(test_file, "w", newline="\n") as f:
f.write(new_content)
def main():
monorepo_root = pathlib.Path(
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
)
test = pathlib.Path(os.path.join(monorepo_root, "libcxx", "test"))
assert monorepo_root.exists()
produce(test.joinpath("libcxx/transitive_includes.sh.cpp"), libcxx.test.header_information.variables)
if __name__ == "__main__":
main()