blob: e68bf30f6d7f175c04be4493ef895fe8494a4c6b [file] [log] [blame]
#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
"""Go through all markdown files and autogenerate content based on commands
recorded in the file.
"""
import sys
from pathlib import Path
import re
import subprocess
import argparse
import os
from typing import Callable
START_MARKER_PATTERN = re.compile(r"\n<!--\s*BEGIN\s*AUTOGEN\s*(?P<cmd>.+)\s*-->\n")
END_MARKER_PATTERN = re.compile(r"\n<!--\s*END\s*AUTOGEN\s*-->\n")
def apply_to_all_files(path: Path, fn: Callable[[Path], None]):
for child in path.iterdir():
if child.is_file():
fn(child)
if child.is_dir():
apply_to_all_files(child, fn)
def autogen_rewrite_md(filepath: Path, dry_run: bool):
# only consider .md files
if not filepath.name.endswith(".md"):
return
content = filepath.read_text()
modified = False
pos = 0
while True:
# search next start marker
match_start = START_MARKER_PATTERN.search(content, pos)
if match_start is None:
# no more replacements to do
break
cmd = match_start.group('cmd').strip()
# search end marker after the start marker
match_end = END_MARKER_PATTERN.search(content, pos)
if match_end is None:
sys.exit(f"Error in {filepath}: start marker with command '{cmd}' without end marker")
print(f"In {filepath}: running '{cmd}'")
if dry_run:
# don't run
pos = match_end.end(0)
continue
res = subprocess.run(cmd, shell=True, capture_output=True)
if res.stderr:
print(
f"The command '{cmd}' output "
f"the following error messages:\n{res.stderr.decode()}"
)
if res.returncode != 0:
sys.exit(f"The command '{cmd}' had a non-zero return code.")
new_content = res.stdout.decode()
# replace content
content = content[0:match_start.end(0)] + new_content + content[match_end.start(0):]
modified = True
# resume after end line, adjust for new content size
pos = match_end.end(0) + len(new_content) - (match_end.start(0) - match_start.end(0))
# write back
if modified:
filepath.write_text(content)
def main(args: argparse.Namespace):
this_file_path = Path(__file__)
repo_root = this_file_path.parent.parent.resolve()
os.chdir(repo_root)
apply_to_all_files(repo_root, lambda x: autogen_rewrite_md(x, args.dry_run))
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument("--dry-run",
help = "print commands to execute but do not execute them",
action="store_true")
args = parser.parse_args()
main(args)