From 29f9036f0e70fba322e797dce25792011c65742d Mon Sep 17 00:00:00 2001 From: Dave Wilding Date: Wed, 4 Dec 2024 13:45:06 +0800 Subject: [PATCH] Updated CLI reference generator script --- docs/generate_command_docs.py | 123 +++++++++------------------------- 1 file changed, 30 insertions(+), 93 deletions(-) diff --git a/docs/generate_command_docs.py b/docs/generate_command_docs.py index f2a007e3e..2136c9212 100644 --- a/docs/generate_command_docs.py +++ b/docs/generate_command_docs.py @@ -1,8 +1,6 @@ """This module generates reference docs for pebble CLI commands.""" import logging -import os -import re import subprocess import typing @@ -10,26 +8,8 @@ logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) -AUTOMATED_START_MARKER = "" -AUTOMATED_STOP_MARKER = "" -TEMPLATE = """\ -(reference_pebble_{command}_command)= -# {command} command - -{description} - -## Usage - - -```{{terminal}} - :input: command -``` - -""" - - -def get_all_commands() -> typing.List[typing.Tuple[str, str]]: +def get_all_commands() -> typing.List[str]: process = subprocess.run( ["go", "run", "../cmd/pebble", "help", "--all"], text=True, @@ -37,7 +17,7 @@ def get_all_commands() -> typing.List[typing.Tuple[str, str]]: check=True, ) return sorted( - line.split(maxsplit=1) + line.split(maxsplit=1)[0] for line in process.stdout.splitlines() if line.startswith(" ") ) @@ -56,90 +36,50 @@ def get_command_help_output(cmd: str) -> str: ).stdout -def render_code_block_cmd(text: str, cmd: str) -> str: - return re.sub(r"(:input: ).*$", rf"\1{cmd}", text, count=1, flags=re.MULTILINE) - - -def render_code_block_output(text: str, output: str) -> str: - start_pos = text.find(AUTOMATED_START_MARKER) - end_pos = text.find(AUTOMATED_STOP_MARKER) + len(AUTOMATED_STOP_MARKER) - return text[:start_pos] + output + text[end_pos:] - - -def update_toc(cmds: typing.List[typing.Tuple[str, str]]): - index_page = "reference/cli-commands/cli-commands.md" - with open(index_page, "r") as file: - text = file.read() - - start_index = text.find("```{toctree}") - end_index = text.find("```", start_index + 1) + 3 - cmd_list = "\n".join(f"{cmd[0]} <{cmd[0]}>" for cmd in cmds) - - toc_tree = f"""\ -```{{toctree}} -:titlesonly: -:maxdepth: 1 - -{cmd_list} -```""" - - text = text[:start_index] + toc_tree + text[end_index:] - with open(index_page, "w") as file: - file.write(text) +class Markers: + def __init__(self, cmd: str): + self.start = f"" + self.end = f"" -def create_file_if_not_exist(filepath: str, cmd: str) -> bool: - file_existed = os.path.exists(filepath) - if not file_existed: - logger.info( - "The doc for command %s doesn't exist, creating from the template.", cmd - ) - with open(filepath, "w") as file: - file.write(TEMPLATE) - return file_existed - - -def generate_help_command_and_output(cmd: str) -> typing.Tuple[str, str]: +def generate_example(cmd: str, markers: Markers) -> str: args = ["help"] if cmd == "help" else [cmd, "--help"] help_cmd_str = " ".join(["pebble"] + args) go_run_cmd = " ".join(["go", "run", "../cmd/pebble"] + args) - help_cmd_output = get_command_help_output(go_run_cmd).strip() + help_output = get_command_help_output(go_run_cmd).strip() - output = f"""\ - + return f"""\ +{markers.start} ```{{terminal}} :input: {help_cmd_str} -{help_cmd_output} +{help_output} ``` -""" - - return help_cmd_str, output +{markers.end}""" -def process_command(cmd: str, description: str): - logger.info("Processing doc for command %s.", cmd) +def insert_example(text: str, markers: Markers, example: str) -> str: + start_pos = text.find(markers.start) + end_pos = text.find(markers.end) + len(markers.end) + return text[:start_pos] + example + text[end_pos:] - file_path = f"reference/cli-commands/{cmd}.md" - file_existed = create_file_if_not_exist(file_path, cmd) +def process_commands(cmds: typing.List[str]): + file_path = "reference/cli-commands.md" with open(file_path, "r") as file: text = file.read() - if AUTOMATED_START_MARKER not in text: - logger.info( - 'The marker for automated doc generation is not found in the "%s" doc, ignore.', - cmd, - ) - return - - help_cmd, help_cmd_output = generate_help_command_and_output(cmd) - description = f"The `{cmd}` command is used to {description.lower()}." - - if not file_existed: - text = text.format(command=cmd, description=description) + for cmd in cmds: + logger.info("Processing doc for command %s.", cmd) + markers = Markers(cmd) + if markers.start not in text: + logger.info( + 'The marker for automated doc generation is not found for command "%s", ignore.', + cmd, + ) + continue - text = render_code_block_cmd(text, help_cmd) - text = render_code_block_output(text, help_cmd_output) + example = generate_example(cmd, markers) + text = insert_example(text, markers, example) with open(file_path, "w") as file: file.write(text) @@ -147,11 +87,8 @@ def process_command(cmd: str, description: str): def main(): cmds = get_all_commands() - for cmd, description in cmds: - process_command(cmd, description) + process_commands(cmds) - logger.info("Update toc tree.") - update_toc(cmds) logger.info("Done!")