From bcf98f82739ee99dfbbb0b353a4f3f1323cdb1d4 Mon Sep 17 00:00:00 2001 From: James Woglom Date: Thu, 26 Dec 2024 15:54:48 -0500 Subject: [PATCH] augment javadoc with messageprops --- .github/workflows/javadoc.yml | 7 ++ .../messages/bluetooth/Characteristic.java | 15 +++ scripts/javadoc_messageprops.py | 101 ++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 scripts/javadoc_messageprops.py diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 967855f1..938825ef 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -16,6 +16,13 @@ jobs: - name: Checkout the repo uses: actions/checkout@v3 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: run javadoc_messageprops.py + run: python3 scripts/javadoc_messageprops.py messages/src/main/java/com/jwoglom/pumpx2/pump/messages/ + - name: set up JDK 11 uses: actions/setup-java@v3 with: diff --git a/messages/src/main/java/com/jwoglom/pumpx2/pump/messages/bluetooth/Characteristic.java b/messages/src/main/java/com/jwoglom/pumpx2/pump/messages/bluetooth/Characteristic.java index dd5bab5b..1b5eb416 100644 --- a/messages/src/main/java/com/jwoglom/pumpx2/pump/messages/bluetooth/Characteristic.java +++ b/messages/src/main/java/com/jwoglom/pumpx2/pump/messages/bluetooth/Characteristic.java @@ -15,10 +15,25 @@ * TODO: refactor all uses to this class */ public enum Characteristic { + /** + * 7B83FFF6-9F77-4E5C-8064-AAE2C24838B9 + */ CURRENT_STATUS(CURRENT_STATUS_CHARACTERISTICS), + /** + * 7B83FFF8-9F77-4E5C-8064-AAE2C24838B9 + */ HISTORY_LOG(HISTORY_LOG_CHARACTERISTICS), + /** + * 7B83FFF9-9F77-4E5C-8064-AAE2C24838B9 + */ AUTHORIZATION(AUTHORIZATION_CHARACTERISTICS), + /** + * 7B83FFFC-9F77-4E5C-8064-AAE2C24838B9 + */ CONTROL(CONTROL_CHARACTERISTICS), + /** + * 7B83FFFD-9F77-4E5C-8064-AAE2C24838B9 + */ CONTROL_STREAM(CONTROL_STREAM_CHARACTERISTICS), ; diff --git a/scripts/javadoc_messageprops.py b/scripts/javadoc_messageprops.py new file mode 100644 index 00000000..34ab5b51 --- /dev/null +++ b/scripts/javadoc_messageprops.py @@ -0,0 +1,101 @@ +import re +import os +import sys +import tempfile +import shutil + +DIR = sys.argv[1] + +def convert_message_props(java_file): + """Converts @MessageProps annotations to Javadoc comments.""" + + with open(java_file, 'r+') as f: + content = f.read() + + pattern = r"^(\s*)@MessageProps\(\s*([^\)]+)\s*\)\s*$" + javadoc_pattern = r"/\*\*[\s\S]*?\*/\n" + + def convert_value(value): + if value.endswith(".class"): + clsname = value[:-6] + fp = find_file_path(clsname) + if fp: + return "{@link %s}" % fp + elif "." in value: + fp = find_file_path(value[:value.rindex(".")]) + if fp: + return "{@link %s#%s}" % (fp, value[1+value.rindex("."):]) + return value + + def replacement(match): + indentation = match.group(1) + props_string = match.group(2) + props = {} + + if "\n" not in indentation: + indentation = "\n" + indentation + + param_pattern = r"(\w+)\s*=\s*([^,]+)(?:,|$)" + param_matches = re.findall(param_pattern, props_string) + + for param_name, param_value in param_matches: + props[param_name] = convert_value(param_value.strip()) + + javadoc_match = re.search(javadoc_pattern, content, re.MULTILINE) + if javadoc_match and javadoc_match.span(0) < match.span(0): + javadoc = javadoc_match.group(0).replace('*/', '*') + javadoc += f"{indentation} *" + javadoc += f"{indentation} *
" + javadoc += f"{indentation} *" + else: + javadoc = f"{indentation}/**" + + if 'MessageType#REQUEST' in props.get('type'): + javadoc += f"{indentation} * Request message for {props.get('response')}, opCode {props.get('opCode')}, size {props.get('size')}" + javadoc += f"{indentation} *" + javadoc += f"{indentation} *
" + javadoc += f"{indentation} *" + elif 'MessageType#RESPONSE' in props.get('type'): + javadoc += f"{indentation} * Response message for {props.get('request')}, opCode {props.get('opCode')}, size {props.get('size')}" + javadoc += f"{indentation} *" + javadoc += f"{indentation} *
" + javadoc += f"{indentation} *" + javadoc += f"{indentation} * " + javadoc += f"{indentation} * " + javadoc += f"{indentation} * " + for name, value in props.items(): + javadoc += f"{indentation} * " + javadoc += f"{indentation} *
Message properties:
 {name}  {value} 
" + javadoc += f"{indentation} */" + return javadoc + match.group(0) + + new_content = re.sub(pattern, replacement, content, flags=re.MULTILINE) + + with tempfile.NamedTemporaryFile(mode='w', delete=False) as tmp_file: + tmp_file.write(new_content) + shutil.move(tmp_file.name, java_file) + return new_content != content + +def process_directory(directory): + """Recursively processes Java files in a directory.""" + for root, _, files in os.walk(directory): + for file in files: + if file.endswith(".java"): + file_path = os.path.join(root, file) + if convert_message_props(file_path): + print("Processed", file_path) + +def find_file_path(clsname): + clsname = clsname.replace(".", "/") + clsname += ".java" + for root, _, files in os.walk(DIR): + for file in files: + file_path = os.path.join(root, file) + if file_path.endswith(clsname) and "com/jwoglom/" in file_path: + f = file_path.split("com/jwoglom/") + return "com.jwoglom." + (f[1].replace("/", ".")[:-5]) + return None + + +if __name__ == '__main__': + process_directory(DIR) \ No newline at end of file