From 153fc5cbbba809978fdedb31ec98da25d60daa3a Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 23:12:18 +0000 Subject: [PATCH 1/2] Add standalone script to remove empty object parameters from usePresenter calls --- scripts/codemods/README.md | 50 ++++++ .../codemods/remove_empty_presenter_params.py | 142 ++++++++++++++++++ scripts/standalone/README.md | 54 +++++++ .../remove_empty_presenter_params.py | 142 ++++++++++++++++++ 4 files changed, 388 insertions(+) create mode 100644 scripts/codemods/README.md create mode 100755 scripts/codemods/remove_empty_presenter_params.py create mode 100644 scripts/standalone/README.md create mode 100755 scripts/standalone/remove_empty_presenter_params.py diff --git a/scripts/codemods/README.md b/scripts/codemods/README.md new file mode 100644 index 000000000..3a9d61181 --- /dev/null +++ b/scripts/codemods/README.md @@ -0,0 +1,50 @@ +# Codemods + +This directory contains scripts for automated code modifications (codemods). + +## Available Codemods + +### Remove Empty Presenter Parameters + +The `remove_empty_presenter_params.py` script finds all usages of the `usePresenter` function and removes the second parameter when it's an empty object (`{}`). + +#### Usage + +```bash +# Run in dry-run mode (doesn't modify files, just shows what would change) +python scripts/codemods/remove_empty_presenter_params.py --dry-run + +# Run and apply changes +python scripts/codemods/remove_empty_presenter_params.py +``` + +#### What it does + +This script: + +1. Searches for all JavaScript and TypeScript files in your codebase +2. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) +3. Removes the empty object parameter while preserving the rest of the function call +4. Reports all changes made + +#### Examples + +Before: +```javascript +const presenter = usePresenter(data, {}); +``` + +After: +```javascript +const presenter = usePresenter(data); +``` + +Before: +```javascript +const presenter = usePresenter(data, {}, options); +``` + +After: +```javascript +const presenter = usePresenter(data, options); +``` diff --git a/scripts/codemods/remove_empty_presenter_params.py b/scripts/codemods/remove_empty_presenter_params.py new file mode 100755 index 000000000..0263d6a6a --- /dev/null +++ b/scripts/codemods/remove_empty_presenter_params.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +""" +Script to find and remove empty object parameters from usePresenter calls. + +This script searches for all usages of the usePresenter function in a codebase +and removes the second parameter when it's an empty object ({}). + +Usage: + python scripts/codemods/remove_empty_presenter_params.py [--dry-run] + +Options: + --dry-run Only print the changes without modifying files +""" + +import argparse +import os +import re +import sys +from pathlib import Path +from typing import List, Tuple + +# Regular expressions to match different forms of empty objects +EMPTY_OBJECT_PATTERNS = [ + r'\{\s*\}', # {} + r'\{\s*\/\*.*?\*\/\s*\}', # { /* comment */ } + r'\{\s*\/\/.*?\n\s*\}', # { // comment \n } +] + +# Combined pattern for any empty object +EMPTY_OBJECT_REGEX = '|'.join(f'({pattern})' for pattern in EMPTY_OBJECT_PATTERNS) + +# Pattern to match usePresenter calls with a second parameter +# This handles various forms of the function call +USE_PRESENTER_REGEX = re.compile( + r'(usePresenter\s*\(\s*[^,)]+\s*,\s*)(' + EMPTY_OBJECT_REGEX + r')(\s*[,)])', + re.MULTILINE | re.DOTALL +) + +def find_js_ts_files(root_dir: str) -> List[Path]: + """Find all JavaScript and TypeScript files in the given directory.""" + extensions = ['.js', '.jsx', '.ts', '.tsx'] + files = [] + + for ext in extensions: + for path in Path(root_dir).rglob(f'*{ext}'): + # Skip node_modules and other common directories to ignore + if 'node_modules' not in str(path) and '.git' not in str(path): + files.append(path) + + return files + +def process_file(file_path: Path, dry_run: bool = False) -> Tuple[int, List[str]]: + """ + Process a single file to find and modify usePresenter calls. + + Args: + file_path: Path to the file to process + dry_run: If True, don't modify the file, just report changes + + Returns: + Tuple of (number of changes, list of changes) + """ + with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Find all matches + matches = list(USE_PRESENTER_REGEX.finditer(content)) + if not matches: + return 0, [] + + # Track changes + changes = [] + new_content = content + offset = 0 + + for match in matches: + # Extract the parts of the match + before_obj = match.group(1) # usePresenter(arg1, + empty_obj = match.group(2) # {} + after_obj = match.group(3) # ) or , arg3) + + # Determine the replacement + if after_obj.strip() == ')': + # If this is the last parameter, remove the comma and the empty object + replacement = before_obj.rstrip(',') + after_obj + else: + # If there are more parameters, just remove the empty object + replacement = before_obj + after_obj.lstrip(',') + + # Calculate positions with offset adjustment + start = match.start() + offset + end = match.end() + offset + + # Apply the replacement + new_content = new_content[:start] + replacement + new_content[end:] + + # Update offset for future replacements + offset += len(replacement) - (end - start) + + # Record the change + line_num = content.count('\n', 0, match.start()) + 1 + changes.append(f"Line {line_num}: Removed empty object parameter") + + # Write changes if not in dry run mode + if not dry_run and changes: + with open(file_path, 'w', encoding='utf-8') as f: + f.write(new_content) + + return len(changes), changes + +def main(): + parser = argparse.ArgumentParser(description='Remove empty object parameters from usePresenter calls') + parser.add_argument('--dry-run', action='store_true', help='Only print changes without modifying files') + args = parser.parse_args() + + # Get the current directory as the root + root_dir = os.getcwd() + + print(f"Searching for JavaScript and TypeScript files in {root_dir}...") + files = find_js_ts_files(root_dir) + print(f"Found {len(files)} files to process") + + total_changes = 0 + modified_files = 0 + + for file_path in files: + num_changes, changes = process_file(file_path, args.dry_run) + if num_changes > 0: + modified_files += 1 + rel_path = file_path.relative_to(root_dir) + print(f"\nModified {rel_path} ({num_changes} changes):") + for change in changes: + print(f" - {change}") + + total_changes += num_changes + + print(f"\nSummary: Modified {modified_files} files with {total_changes} changes") + if args.dry_run: + print("Note: This was a dry run. No files were actually modified.") + +if __name__ == "__main__": + main() diff --git a/scripts/standalone/README.md b/scripts/standalone/README.md new file mode 100644 index 000000000..d1920932b --- /dev/null +++ b/scripts/standalone/README.md @@ -0,0 +1,54 @@ +# Standalone Scripts + +This directory contains standalone scripts that don't rely on the Codegen SDK. These scripts can be used in any codebase without additional dependencies. + +## Available Scripts + +### Remove Empty Presenter Parameters + +The `remove_empty_presenter_params.py` script finds all usages of the `usePresenter` function and removes the second parameter when it's an empty object (`{}`). + +#### Usage + +```bash +# Run in dry-run mode (doesn't modify files, just shows what would change) +python scripts/standalone/remove_empty_presenter_params.py --dry-run + +# Run and apply changes +python scripts/standalone/remove_empty_presenter_params.py +``` + +#### What it does + +This script: + +1. Searches for all JavaScript and TypeScript files in your codebase +2. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) +3. Removes the empty object parameter while preserving the rest of the function call +4. Reports all changes made + +#### Examples + +Before: +```javascript +const presenter = usePresenter(data, {}); +``` + +After: +```javascript +const presenter = usePresenter(data); +``` + +Before: +```javascript +const presenter = usePresenter(data, {}, options); +``` + +After: +```javascript +const presenter = usePresenter(data, options); +``` + +#### How it works + +The script uses regular expressions to find and modify `usePresenter` calls. It handles various forms of empty objects, including those with whitespace and comments. The script is designed to be lightweight and doesn't require any external dependencies beyond the Python standard library. diff --git a/scripts/standalone/remove_empty_presenter_params.py b/scripts/standalone/remove_empty_presenter_params.py new file mode 100755 index 000000000..706efb181 --- /dev/null +++ b/scripts/standalone/remove_empty_presenter_params.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +""" +Standalone script to find and remove empty object parameters from usePresenter calls. + +This script searches for all usages of the usePresenter function in a codebase +and removes the second parameter when it's an empty object ({}). + +Usage: + python scripts/standalone/remove_empty_presenter_params.py [--dry-run] + +Options: + --dry-run Only print the changes without modifying files +""" + +import argparse +import os +import re +import sys +from pathlib import Path +from typing import List, Tuple + +# Regular expressions to match different forms of empty objects +EMPTY_OBJECT_PATTERNS = [ + r'\{\s*\}', # {} + r'\{\s*\/\*.*?\*\/\s*\}', # { /* comment */ } + r'\{\s*\/\/.*?\n\s*\}', # { // comment \n } +] + +# Combined pattern for any empty object +EMPTY_OBJECT_REGEX = '|'.join(f'({pattern})' for pattern in EMPTY_OBJECT_PATTERNS) + +# Pattern to match usePresenter calls with a second parameter +# This handles various forms of the function call +USE_PRESENTER_REGEX = re.compile( + r'(usePresenter\s*\(\s*[^,)]+\s*,\s*)(' + EMPTY_OBJECT_REGEX + r')(\s*[,)])', + re.MULTILINE | re.DOTALL +) + +def find_js_ts_files(root_dir: str) -> List[Path]: + """Find all JavaScript and TypeScript files in the given directory.""" + extensions = ['.js', '.jsx', '.ts', '.tsx'] + files = [] + + for ext in extensions: + for path in Path(root_dir).rglob(f'*{ext}'): + # Skip node_modules and other common directories to ignore + if 'node_modules' not in str(path) and '.git' not in str(path): + files.append(path) + + return files + +def process_file(file_path: Path, dry_run: bool = False) -> Tuple[int, List[str]]: + """ + Process a single file to find and modify usePresenter calls. + + Args: + file_path: Path to the file to process + dry_run: If True, don't modify the file, just report changes + + Returns: + Tuple of (number of changes, list of changes) + """ + with open(file_path, 'r', encoding='utf-8') as f: + content = f.read() + + # Find all matches + matches = list(USE_PRESENTER_REGEX.finditer(content)) + if not matches: + return 0, [] + + # Track changes + changes = [] + new_content = content + offset = 0 + + for match in matches: + # Extract the parts of the match + before_obj = match.group(1) # usePresenter(arg1, + empty_obj = match.group(2) # {} + after_obj = match.group(3) # ) or , arg3) + + # Determine the replacement + if after_obj.strip() == ')': + # If this is the last parameter, remove the comma and the empty object + replacement = before_obj.rstrip(',') + after_obj + else: + # If there are more parameters, just remove the empty object + replacement = before_obj + after_obj.lstrip(',') + + # Calculate positions with offset adjustment + start = match.start() + offset + end = match.end() + offset + + # Apply the replacement + new_content = new_content[:start] + replacement + new_content[end:] + + # Update offset for future replacements + offset += len(replacement) - (end - start) + + # Record the change + line_num = content.count('\n', 0, match.start()) + 1 + changes.append(f"Line {line_num}: Removed empty object parameter") + + # Write changes if not in dry run mode + if not dry_run and changes: + with open(file_path, 'w', encoding='utf-8') as f: + f.write(new_content) + + return len(changes), changes + +def main(): + parser = argparse.ArgumentParser(description='Remove empty object parameters from usePresenter calls') + parser.add_argument('--dry-run', action='store_true', help='Only print changes without modifying files') + args = parser.parse_args() + + # Get the current directory as the root + root_dir = os.getcwd() + + print(f"Searching for JavaScript and TypeScript files in {root_dir}...") + files = find_js_ts_files(root_dir) + print(f"Found {len(files)} files to process") + + total_changes = 0 + modified_files = 0 + + for file_path in files: + num_changes, changes = process_file(file_path, args.dry_run) + if num_changes > 0: + modified_files += 1 + rel_path = file_path.relative_to(root_dir) + print(f"\nModified {rel_path} ({num_changes} changes):") + for change in changes: + print(f" - {change}") + + total_changes += num_changes + + print(f"\nSummary: Modified {modified_files} files with {total_changes} changes") + if args.dry_run: + print("Note: This was a dry run. No files were actually modified.") + +if __name__ == "__main__": + main() From bb92e003a73e413d2b2f8e0bdfe9be7421bc366b Mon Sep 17 00:00:00 2001 From: "codegen-sh[bot]" <131295404+codegen-sh[bot]@users.noreply.github.com> Date: Wed, 2 Apr 2025 23:13:05 +0000 Subject: [PATCH 2/2] Automated pre-commit update --- scripts/codemods/README.md | 10 +- .../codemods/remove_empty_presenter_params.py | 95 +++++++++---------- scripts/standalone/README.md | 10 +- .../remove_empty_presenter_params.py | 95 +++++++++---------- 4 files changed, 106 insertions(+), 104 deletions(-) diff --git a/scripts/codemods/README.md b/scripts/codemods/README.md index 3a9d61181..42e893815 100644 --- a/scripts/codemods/README.md +++ b/scripts/codemods/README.md @@ -23,28 +23,32 @@ python scripts/codemods/remove_empty_presenter_params.py This script: 1. Searches for all JavaScript and TypeScript files in your codebase -2. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) -3. Removes the empty object parameter while preserving the rest of the function call -4. Reports all changes made +1. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) +1. Removes the empty object parameter while preserving the rest of the function call +1. Reports all changes made #### Examples Before: + ```javascript const presenter = usePresenter(data, {}); ``` After: + ```javascript const presenter = usePresenter(data); ``` Before: + ```javascript const presenter = usePresenter(data, {}, options); ``` After: + ```javascript const presenter = usePresenter(data, options); ``` diff --git a/scripts/codemods/remove_empty_presenter_params.py b/scripts/codemods/remove_empty_presenter_params.py index 0263d6a6a..af8111823 100755 --- a/scripts/codemods/remove_empty_presenter_params.py +++ b/scripts/codemods/remove_empty_presenter_params.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -""" -Script to find and remove empty object parameters from usePresenter calls. +"""Script to find and remove empty object parameters from usePresenter calls. This script searches for all usages of the usePresenter function in a codebase and removes the second parameter when it's an empty object ({}). @@ -15,114 +14,111 @@ import argparse import os import re -import sys from pathlib import Path -from typing import List, Tuple # Regular expressions to match different forms of empty objects EMPTY_OBJECT_PATTERNS = [ - r'\{\s*\}', # {} - r'\{\s*\/\*.*?\*\/\s*\}', # { /* comment */ } - r'\{\s*\/\/.*?\n\s*\}', # { // comment \n } + r"\{\s*\}", # {} + r"\{\s*\/\*.*?\*\/\s*\}", # { /* comment */ } + r"\{\s*\/\/.*?\n\s*\}", # { // comment \n } ] # Combined pattern for any empty object -EMPTY_OBJECT_REGEX = '|'.join(f'({pattern})' for pattern in EMPTY_OBJECT_PATTERNS) +EMPTY_OBJECT_REGEX = "|".join(f"({pattern})" for pattern in EMPTY_OBJECT_PATTERNS) # Pattern to match usePresenter calls with a second parameter # This handles various forms of the function call -USE_PRESENTER_REGEX = re.compile( - r'(usePresenter\s*\(\s*[^,)]+\s*,\s*)(' + EMPTY_OBJECT_REGEX + r')(\s*[,)])', - re.MULTILINE | re.DOTALL -) +USE_PRESENTER_REGEX = re.compile(r"(usePresenter\s*\(\s*[^,)]+\s*,\s*)(" + EMPTY_OBJECT_REGEX + r")(\s*[,)])", re.MULTILINE | re.DOTALL) + -def find_js_ts_files(root_dir: str) -> List[Path]: +def find_js_ts_files(root_dir: str) -> list[Path]: """Find all JavaScript and TypeScript files in the given directory.""" - extensions = ['.js', '.jsx', '.ts', '.tsx'] + extensions = [".js", ".jsx", ".ts", ".tsx"] files = [] - + for ext in extensions: - for path in Path(root_dir).rglob(f'*{ext}'): + for path in Path(root_dir).rglob(f"*{ext}"): # Skip node_modules and other common directories to ignore - if 'node_modules' not in str(path) and '.git' not in str(path): + if "node_modules" not in str(path) and ".git" not in str(path): files.append(path) - + return files -def process_file(file_path: Path, dry_run: bool = False) -> Tuple[int, List[str]]: - """ - Process a single file to find and modify usePresenter calls. - + +def process_file(file_path: Path, dry_run: bool = False) -> tuple[int, list[str]]: + """Process a single file to find and modify usePresenter calls. + Args: file_path: Path to the file to process dry_run: If True, don't modify the file, just report changes - + Returns: Tuple of (number of changes, list of changes) """ - with open(file_path, 'r', encoding='utf-8') as f: + with open(file_path, encoding="utf-8") as f: content = f.read() - + # Find all matches matches = list(USE_PRESENTER_REGEX.finditer(content)) if not matches: return 0, [] - + # Track changes changes = [] new_content = content offset = 0 - + for match in matches: # Extract the parts of the match before_obj = match.group(1) # usePresenter(arg1, - empty_obj = match.group(2) # {} - after_obj = match.group(3) # ) or , arg3) - + empty_obj = match.group(2) # {} + after_obj = match.group(3) # ) or , arg3) + # Determine the replacement - if after_obj.strip() == ')': + if after_obj.strip() == ")": # If this is the last parameter, remove the comma and the empty object - replacement = before_obj.rstrip(',') + after_obj + replacement = before_obj.rstrip(",") + after_obj else: # If there are more parameters, just remove the empty object - replacement = before_obj + after_obj.lstrip(',') - + replacement = before_obj + after_obj.lstrip(",") + # Calculate positions with offset adjustment start = match.start() + offset end = match.end() + offset - + # Apply the replacement new_content = new_content[:start] + replacement + new_content[end:] - + # Update offset for future replacements offset += len(replacement) - (end - start) - + # Record the change - line_num = content.count('\n', 0, match.start()) + 1 + line_num = content.count("\n", 0, match.start()) + 1 changes.append(f"Line {line_num}: Removed empty object parameter") - + # Write changes if not in dry run mode if not dry_run and changes: - with open(file_path, 'w', encoding='utf-8') as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(new_content) - + return len(changes), changes + def main(): - parser = argparse.ArgumentParser(description='Remove empty object parameters from usePresenter calls') - parser.add_argument('--dry-run', action='store_true', help='Only print changes without modifying files') + parser = argparse.ArgumentParser(description="Remove empty object parameters from usePresenter calls") + parser.add_argument("--dry-run", action="store_true", help="Only print changes without modifying files") args = parser.parse_args() - + # Get the current directory as the root root_dir = os.getcwd() - + print(f"Searching for JavaScript and TypeScript files in {root_dir}...") files = find_js_ts_files(root_dir) print(f"Found {len(files)} files to process") - + total_changes = 0 modified_files = 0 - + for file_path in files: num_changes, changes = process_file(file_path, args.dry_run) if num_changes > 0: @@ -131,12 +127,13 @@ def main(): print(f"\nModified {rel_path} ({num_changes} changes):") for change in changes: print(f" - {change}") - + total_changes += num_changes - + print(f"\nSummary: Modified {modified_files} files with {total_changes} changes") if args.dry_run: print("Note: This was a dry run. No files were actually modified.") + if __name__ == "__main__": main() diff --git a/scripts/standalone/README.md b/scripts/standalone/README.md index d1920932b..87cea8a95 100644 --- a/scripts/standalone/README.md +++ b/scripts/standalone/README.md @@ -23,28 +23,32 @@ python scripts/standalone/remove_empty_presenter_params.py This script: 1. Searches for all JavaScript and TypeScript files in your codebase -2. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) -3. Removes the empty object parameter while preserving the rest of the function call -4. Reports all changes made +1. Finds all calls to `usePresenter` where the second parameter is an empty object (`{}`) +1. Removes the empty object parameter while preserving the rest of the function call +1. Reports all changes made #### Examples Before: + ```javascript const presenter = usePresenter(data, {}); ``` After: + ```javascript const presenter = usePresenter(data); ``` Before: + ```javascript const presenter = usePresenter(data, {}, options); ``` After: + ```javascript const presenter = usePresenter(data, options); ``` diff --git a/scripts/standalone/remove_empty_presenter_params.py b/scripts/standalone/remove_empty_presenter_params.py index 706efb181..b8d00df30 100755 --- a/scripts/standalone/remove_empty_presenter_params.py +++ b/scripts/standalone/remove_empty_presenter_params.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -""" -Standalone script to find and remove empty object parameters from usePresenter calls. +"""Standalone script to find and remove empty object parameters from usePresenter calls. This script searches for all usages of the usePresenter function in a codebase and removes the second parameter when it's an empty object ({}). @@ -15,114 +14,111 @@ import argparse import os import re -import sys from pathlib import Path -from typing import List, Tuple # Regular expressions to match different forms of empty objects EMPTY_OBJECT_PATTERNS = [ - r'\{\s*\}', # {} - r'\{\s*\/\*.*?\*\/\s*\}', # { /* comment */ } - r'\{\s*\/\/.*?\n\s*\}', # { // comment \n } + r"\{\s*\}", # {} + r"\{\s*\/\*.*?\*\/\s*\}", # { /* comment */ } + r"\{\s*\/\/.*?\n\s*\}", # { // comment \n } ] # Combined pattern for any empty object -EMPTY_OBJECT_REGEX = '|'.join(f'({pattern})' for pattern in EMPTY_OBJECT_PATTERNS) +EMPTY_OBJECT_REGEX = "|".join(f"({pattern})" for pattern in EMPTY_OBJECT_PATTERNS) # Pattern to match usePresenter calls with a second parameter # This handles various forms of the function call -USE_PRESENTER_REGEX = re.compile( - r'(usePresenter\s*\(\s*[^,)]+\s*,\s*)(' + EMPTY_OBJECT_REGEX + r')(\s*[,)])', - re.MULTILINE | re.DOTALL -) +USE_PRESENTER_REGEX = re.compile(r"(usePresenter\s*\(\s*[^,)]+\s*,\s*)(" + EMPTY_OBJECT_REGEX + r")(\s*[,)])", re.MULTILINE | re.DOTALL) + -def find_js_ts_files(root_dir: str) -> List[Path]: +def find_js_ts_files(root_dir: str) -> list[Path]: """Find all JavaScript and TypeScript files in the given directory.""" - extensions = ['.js', '.jsx', '.ts', '.tsx'] + extensions = [".js", ".jsx", ".ts", ".tsx"] files = [] - + for ext in extensions: - for path in Path(root_dir).rglob(f'*{ext}'): + for path in Path(root_dir).rglob(f"*{ext}"): # Skip node_modules and other common directories to ignore - if 'node_modules' not in str(path) and '.git' not in str(path): + if "node_modules" not in str(path) and ".git" not in str(path): files.append(path) - + return files -def process_file(file_path: Path, dry_run: bool = False) -> Tuple[int, List[str]]: - """ - Process a single file to find and modify usePresenter calls. - + +def process_file(file_path: Path, dry_run: bool = False) -> tuple[int, list[str]]: + """Process a single file to find and modify usePresenter calls. + Args: file_path: Path to the file to process dry_run: If True, don't modify the file, just report changes - + Returns: Tuple of (number of changes, list of changes) """ - with open(file_path, 'r', encoding='utf-8') as f: + with open(file_path, encoding="utf-8") as f: content = f.read() - + # Find all matches matches = list(USE_PRESENTER_REGEX.finditer(content)) if not matches: return 0, [] - + # Track changes changes = [] new_content = content offset = 0 - + for match in matches: # Extract the parts of the match before_obj = match.group(1) # usePresenter(arg1, - empty_obj = match.group(2) # {} - after_obj = match.group(3) # ) or , arg3) - + empty_obj = match.group(2) # {} + after_obj = match.group(3) # ) or , arg3) + # Determine the replacement - if after_obj.strip() == ')': + if after_obj.strip() == ")": # If this is the last parameter, remove the comma and the empty object - replacement = before_obj.rstrip(',') + after_obj + replacement = before_obj.rstrip(",") + after_obj else: # If there are more parameters, just remove the empty object - replacement = before_obj + after_obj.lstrip(',') - + replacement = before_obj + after_obj.lstrip(",") + # Calculate positions with offset adjustment start = match.start() + offset end = match.end() + offset - + # Apply the replacement new_content = new_content[:start] + replacement + new_content[end:] - + # Update offset for future replacements offset += len(replacement) - (end - start) - + # Record the change - line_num = content.count('\n', 0, match.start()) + 1 + line_num = content.count("\n", 0, match.start()) + 1 changes.append(f"Line {line_num}: Removed empty object parameter") - + # Write changes if not in dry run mode if not dry_run and changes: - with open(file_path, 'w', encoding='utf-8') as f: + with open(file_path, "w", encoding="utf-8") as f: f.write(new_content) - + return len(changes), changes + def main(): - parser = argparse.ArgumentParser(description='Remove empty object parameters from usePresenter calls') - parser.add_argument('--dry-run', action='store_true', help='Only print changes without modifying files') + parser = argparse.ArgumentParser(description="Remove empty object parameters from usePresenter calls") + parser.add_argument("--dry-run", action="store_true", help="Only print changes without modifying files") args = parser.parse_args() - + # Get the current directory as the root root_dir = os.getcwd() - + print(f"Searching for JavaScript and TypeScript files in {root_dir}...") files = find_js_ts_files(root_dir) print(f"Found {len(files)} files to process") - + total_changes = 0 modified_files = 0 - + for file_path in files: num_changes, changes = process_file(file_path, args.dry_run) if num_changes > 0: @@ -131,12 +127,13 @@ def main(): print(f"\nModified {rel_path} ({num_changes} changes):") for change in changes: print(f" - {change}") - + total_changes += num_changes - + print(f"\nSummary: Modified {modified_files} files with {total_changes} changes") if args.dry_run: print("Note: This was a dry run. No files were actually modified.") + if __name__ == "__main__": main()