diff --git a/examples/fragment_to_shorthand/README.md b/examples/fragment_to_shorthand/README.md new file mode 100644 index 0000000..d124439 --- /dev/null +++ b/examples/fragment_to_shorthand/README.md @@ -0,0 +1,67 @@ +# Transform React Fragment to Shorthand Syntax + +This example demonstrates how to use Codegen to automatically convert React Fragment components to the shorthand syntax (<>). The script makes this process simple by handling all the tedious manual updates automatically. + +> [!NOTE] +> This codemod helps modernize React codebases by using the more concise fragment syntax while maintaining functionality. + +## How the Migration Script Works + +The script automates the entire conversion process in a few key steps: + +1. **Fragment Detection** + ```jsx + // From: + +
Hello
+
World
+
+ + // To: + <> +
Hello
+
World
+ + ``` + +2. **Import Cleanup** + ```typescript + // From: + import React, { Fragment } from 'react'; + + // To: + import React from 'react'; + ``` + +## Why This Makes Migration Easy + +1. **Zero Manual Updates** + - Codegen SDK handles all Fragment replacements + - Automatically cleans up imports + +2. **Consistent Changes** + - Ensures all Fragments are converted + - Maintains code functionality + +3. **Safe Transformations** + - Preserves JSX structure + - Handles nested Fragments correctly + +## Running the Migration + + +The script will: +1. Find all Fragment components +2. Convert them to shorthand syntax +3. Clean up Fragment imports +4. Preserve other React imports + +## Learn More + +- [React Fragments](https://react.dev/reference/react/Fragment) +- [JSX Fragments](https://react.dev/reference/jsx#jsx-fragments) +- [Codegen Documentation](https://docs.codegen.com) +- [More on Codegen SDK jsx elements API](https://docs.codegen.com/api-reference/typescript/JSXElement#jsxelement) +## Contributing + +Feel free to submit issues and enhancement requests! \ No newline at end of file diff --git a/examples/fragment_to_shorthand/run.py b/examples/fragment_to_shorthand/run.py new file mode 100644 index 0000000..c140cb1 --- /dev/null +++ b/examples/fragment_to_shorthand/run.py @@ -0,0 +1,39 @@ +import codegen +from codegen import Codebase +from codegen.sdk.enums import ProgrammingLanguage + + +@codegen.function("fragment_to_shorthand") +def run(codebase: Codebase): + print("๐Ÿ” Starting Fragment syntax conversion...") + + for file in codebase.files: + print(f"๐Ÿ“ Processing: {file.filepath}") + + fragments_found = False + + # Convert Fragment components to shorthand + for element in file.jsx_elements: + if element.name == "Fragment": + print(f"๐Ÿ”„ Converting Fragment in {file.filepath}") + element.set_name("") # Convert to <> syntax + fragments_found = True + + # Clean up Fragment imports if we found and converted any + if fragments_found: + for import_stmt in file.import_statements: + for imp in import_stmt.imports: + if imp.name == "Fragment": + print(f"๐Ÿงน Removing Fragment import from {file.filepath}") + imp.remove() + + if fragments_found: + print(f"โœจ Completed conversion in {file.filepath}") + codebase.commit() + + +if __name__ == "__main__": + print("๐ŸŽฏ Starting Fragment to shorthand conversion...") + codebase = Codebase.from_repo("RocketChat/Rocket.Chat", commit="a4f2102af1c2e875c60cafebd0163105bdaca678", programming_language=ProgrammingLanguage.TYPESCRIPT) + run(codebase) + print("โœ… Done! All Fragments converted to shorthand syntax!") diff --git a/examples/reexport_management/run.py b/examples/reexport_management/run.py index 2d80234..b4b0aaf 100644 --- a/examples/reexport_management/run.py +++ b/examples/reexport_management/run.py @@ -1,19 +1,23 @@ import codegen from codegen import Codebase + from codegen.sdk.typescript.file import TSImport + from codegen.sdk.enums import ProgrammingLanguage processed_imports = set() + + @codegen.function("reexport_management") def run(codebase: Codebase): print("๐Ÿš€ Starting reexport analysis...") for file in codebase.files: # Only process files under /src/shared - if "examples/analize_reexports" not in file.filepath or '/src/shared' not in file.filepath: + if "examples/analize_reexports" not in file.filepath or "/src/shared" not in file.filepath: continue - + print(f"๐Ÿ“ Analyzing: {file.filepath}") - + # Gather all reexports that are not external exports all_reexports = [] for export_stmt in file.export_statements: @@ -34,10 +38,7 @@ def run(codebase: Codebase): print(f"๐Ÿ”„ Processing: {export.name} -> {resolved_public_file}") # Get relative path from the "public" file back to the original file - relative_path = codebase.get_relative_path( - from_file=resolved_public_file, - to_file=export.resolved_symbol.filepath - ) + relative_path = codebase.get_relative_path(from_file=resolved_public_file, to_file=export.resolved_symbol.filepath) # Ensure the "public" file exists if not codebase.has_file(resolved_public_file): @@ -69,14 +70,9 @@ def run(codebase: Codebase): print(f"๐Ÿ“ Updated existing type export for {export.name}") else: if export.is_aliased(): - target_file.insert_before( - f'export type {{ {export.resolved_symbol.name} as {export.name} }} ' - f'from "{relative_path}"' - ) + target_file.insert_before(f'export type {{ {export.resolved_symbol.name} as {export.name} }} from "{relative_path}"') else: - target_file.insert_before( - f'export type {{ {export.name} }} from "{relative_path}"' - ) + target_file.insert_before(f'export type {{ {export.name} }} from "{relative_path}"') print(f"โœจ Added new type export for {export.name}") # C) Normal export @@ -90,14 +86,9 @@ def run(codebase: Codebase): print(f"๐Ÿ“ Updated existing export for {export.name}") else: if export.is_aliased(): - target_file.insert_before( - f'export {{ {export.resolved_symbol.name} as {export.name} }} ' - f'from "{relative_path}"' - ) + target_file.insert_before(f'export {{ {export.resolved_symbol.name} as {export.name} }} from "{relative_path}"') else: - target_file.insert_before( - f'export {{ {export.name} }} from "{relative_path}"' - ) + target_file.insert_before(f'export {{ {export.name} }} from "{relative_path}"') print(f"โœจ Added new export for {export.name}") # Update import usages @@ -131,6 +122,7 @@ def run(codebase: Codebase): print(f"๐Ÿงน Removed empty file: {file.filepath}") codebase.commit() + if __name__ == "__main__": print("๐ŸŽฏ Starting reexport organization...") codebase = Codebase("./", programming_language=ProgrammingLanguage.TYPESCRIPT)