diff --git a/.github/pr_validation.py b/.github/pr_validation.py index c38508dee..fc493414b 100644 --- a/.github/pr_validation.py +++ b/.github/pr_validation.py @@ -230,6 +230,33 @@ def get_existing_windows_file_names(): return json.loads(response) +def is_existing_windows_file_name(name: str): + return name.lower() in get_existing_windows_file_names() + + +def get_target_module_from_symbol_block_name(symbol_block_name: str): + p = r'(.*?)_?(exe|dll)_?hooks?' + match = re.fullmatch(p, symbol_block_name, flags=re.IGNORECASE) + if not match: + return None + + base_name = match.group(1) + suffix = match.group(2) + return f'{base_name}.{suffix}' + + +def get_target_modules_from_previous_line(previous_line: str): + previous_line = previous_line.lstrip() + if not previous_line.startswith('//'): + return [] + + comment = previous_line.removeprefix('//').strip() + if comment == '': + return [] + + return [x.strip() for x in comment.split(',')] + + def validate_symbol_hooks(path: Path): warnings = 0 @@ -242,35 +269,32 @@ def validate_symbol_hooks(path: Path): line_num = 1 + mod_source[: match.start()].count('\n') - p = r'(.*?)_?(exe|dll)_?hooks?' - if match := re.fullmatch(p, symbol_block_name, flags=re.IGNORECASE): - base_name = match.group(1) - suffix = match.group(2) - full_name = f'{base_name}.{suffix}'.lower() - if full_name not in get_existing_windows_file_names(): - warning_msg = f'"{full_name}" is not recognized as a Windows file name' - warnings += add_warning(path, line_num, warning_msg) - continue + target_from_name = get_target_module_from_symbol_block_name(symbol_block_name) + target_from_name_valid = target_from_name and is_existing_windows_file_name( + target_from_name + ) previous_line = mod_source_lines[line_num - 2] + targets_from_comment = get_target_modules_from_previous_line(previous_line) + targets_from_comment_valid = all( + is_existing_windows_file_name(x) for x in targets_from_comment + ) - if previous_line.lstrip().startswith('//'): - comment = previous_line.lstrip().removeprefix('//').strip() - if comment == '': + if target_from_name_valid and targets_from_comment_valid: + warning_msg = 'Use either a comment or a variable name, not both.' + warnings += add_warning(path, line_num - 1, warning_msg) + elif target_from_name_valid or targets_from_comment_valid: + continue + elif target_from_name or targets_from_comment: + if target_from_name and not is_existing_windows_file_name(target_from_name): warning_msg = ( - 'Empty comment. Specify all target modules in a comment above the' - ' symbol hooks variable, separated with commas.' + f'"{target_from_name}" is not recognized as a Windows file name' ) warnings += add_warning(path, line_num, warning_msg) - continue - names = comment.split(',') - for name in names: - name = name.strip().lower() - if name not in get_existing_windows_file_names(): - warning_msg = ( - f'"{full_name}" is not recognized as a Windows file name' - ) + for target in targets_from_comment: + if not is_existing_windows_file_name(target): + warning_msg = f'"{target}" is not recognized as a Windows file name' warnings += add_warning(path, line_num - 1, warning_msg) continue