> ## Documentation Index
> Fetch the complete documentation index at: https://codegeninc-codegen-bot-sdk-docs-2-0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizing Your Codebase

Codegen SDK provides a powerful set of tools for deterministically moving code safely and efficiently. This guide will walk you through the basics of moving code with Codegen SDK.

Common use cases include:

<AccordionGroup>
  <Accordion title="Splitting up large files">
    ```python
    print(f"🔍 Processing file: {filepath}")
    file = codebase.get_file(filepath)

    # Get the directory path for creating new files
    dir_path = file.directory.path if file.directory else ""

    # Iterate through all functions in the file
    for function in file.functions:
        # Create new filename based on function name
        new_filepath = f"{dir_path}/{function.name}.py"
        print(f"📝 Creating new file: {new_filepath}")

        # Create the new file
        new_file = codebase.create_file(new_filepath)

        # Move the function to the new file, including dependencies
        print(f"➡️ Moving function: {function.name}")
        function.move_to_file(new_file, include_dependencies=True)
    ```
  </Accordion>

  <Accordion title="Organize code into modules">
    ```python
    # Dictionary to track modules and their functions
    module_map = {
        "utils": lambda f: f.name.startswith("util_") or f.name.startswith("helper_"),
        "api": lambda f: f.name.startswith("api_") or f.name.startswith("endpoint_"),
        "data": lambda f: f.name.startswith("data_") or f.name.startswith("db_"),
        "core": lambda f: True  # Default module for other functions
    }

    print("🔍 Starting code organization...")

    # Create module directories if they don't exist
    for module in module_map.keys():
        if not codebase.has_directory(module):
            print(f"📁 Creating module directory: {module}")
            codebase.create_directory(module, exist_ok=True)

    # Process each file in the codebase
    for file in codebase.files:
        print(f"\n📄 Processing file: {file.filepath}")

        # Skip if file is already in a module directory
        if any(file.filepath.startswith(module) for module in module_map.keys()):
            continue

        # Process each function in the file
        for function in file.functions:
            # Determine which module this function belongs to
            target_module = next(
                (module for module, condition in module_map.items()
                 if condition(function)),
                "core"
            )

            # Create the new file path
            new_filepath = f"{target_module}/{function.name}.py"

            print(f"  ➡️ Moving {function.name} to {target_module} module")

            # Create new file and move function
            if not codebase.has_file(new_filepath):
                new_file = codebase.create_file(new_filepath)
                function.move_to_file(new_file, include_dependencies=True)

    print("\n✅ Code organization complete!")
    ```
  </Accordion>

  <Accordion title="Break up import cycles">
    ```python
    # Create a graph to detect cycles
    import networkx as nx

    # Build dependency graph
    G = nx.DiGraph()

    # Add edges for imports between files
    for file in codebase.files:
        for imp in file.imports:
            if imp.from_file:
                G.add_edge(file.filepath, imp.from_file.filepath)

    # Find cycles in the graph
    cycles = list(nx.simple_cycles(G))

    if not cycles:
        print("✅ No import cycles found!")
        exit()

    print(f"🔍 Found {len(cycles)} import cycles")

    # Process each cycle
    for cycle in cycles:
        print(f"\n⭕ Processing cycle: {' -> '.join(cycle)}")

        # Get the first two files in the cycle
        file1 = codebase.get_file(cycle[0])
        file2 = codebase.get_file(cycle[1])

        # Find functions in file1 that are used by file2
        for function in file1.functions:
            if any(usage.file == file2 for usage in function.usages):
                # Create new file for the shared function
                new_filepath = f"shared/{function.name}.py"
                print(f"  ➡️ Moving {function.name} to {new_filepath}")

                if not codebase.has_directory("shared"):
                    codebase.create_directory("shared")

                new_file = codebase.create_file(new_filepath)
                function.move_to_file(new_file, include_dependencies=True)

    print("\n✅ Import cycles resolved!")
    ```
  </Accordion>
</AccordionGroup>

<Tip>
  Most operations in Codegen will automatically handle updaging
  [dependencies](/building-with-codegen/dependencies-and-usages) and
  [imports](/building-with-codegen/imports). See [Moving
  Symbols](/building-with-codegen/moving-symbols) to learn more.
</Tip>

## Basic Symbol Movement

To move a symbol from one file to another, you can use the [move\_to\_file](/api-reference/core/Function#move-to-file) method.

<CodeGroup>
  ```python python
  # Get the symbol
  symbol_to_move = source_file.get_symbol("my_function")
  # Pick a destination file
  dst_file = codebase.get_file("path/to/dst/location.py")
  # Move the symbol, move all of its dependencies with it (remove from old file), and add an import of symbol into old file
  symbol_to_move.move_to_file(dst_file, include_dependencies=True, strategy="add_back_edge")
  ```

  ```python typescript
  # Get the symbol
  symbol_to_move = source_file.get_symbol("myFunction")
  # Pick a destination file
  dst_file = codebase.get_file("path/to/dst/location.ts")
  # Move the symbol, move all of its dependencies with it (remove from old file), and add an import of symbol into old file
  symbol_to_move.move_to_file(dst_file, include_dependencies=True, strategy="add_back_edge")
  ```
</CodeGroup>

This will move `my_function` to `path/to/dst/location.py`, safely updating all references to it in the process.

## Updating Imports

After moving a symbol, you may need to update imports throughout your codebase. GraphSitter offers two strategies for this:

1. **Update All Imports**: This strategy updates all imports across the codebase to reflect the new location of the symbol.

<CodeGroup>
  ```python python
  symbol_to_move = codebase.get_symbol("symbol_to_move")
  dst_file = codebase.create_file("new_file.py")
  symbol_to_move.move_to_file(dst_file, strategy="update_all_imports")
  ```

  ```python typescript
  symbol_to_move = codebase.get_symbol("symbolToMove")
  dst_file = codebase.create_file("new_file.ts")
  symbol_to_move.move_to_file(dst_file, strategy="update_all_imports")
  ```
</CodeGroup>

<Warning>Updating all imports can result in very large PRs</Warning>

2. **Add Back Edge**: This strategy adds an import in the original file that re-imports (and exports) the moved symbol, maintaining backwards compatibility. This will result in fewer total modifications, as existing imports will not need to be updated.

<CodeGroup>
  ```python python
  symbol_to_move = codebase.get_symbol("symbol_to_move")
  dst_file = codebase.create_file("new_file.py")
  symbol_to_move.move_to_file(dst_file, strategy="add_back_edge")
  ```

  ```python typescript
  symbol_to_move = codebase.get_symbol("symbolToMove")
  dst_file = codebase.create_file("new_file.ts")
  symbol_to_move.move_to_file(dst_file, strategy="add_back_edge")
  ```
</CodeGroup>

## Handling Dependencies

By default, Codegen will move all of a symbols dependencies along with it. This ensures that your codebase remains consistent and functional.

<CodeGroup>
  ```python python
  my_symbol = codebase.get_symbol("my_symbol")
  dst_file = codebase.create_file("new_file.py")
  my_symbol.move_to_file(dst_file, include_dependencies=True)
  ```

  ```python typescript
  my_symbol = codebase.get_symbol("mySymbol")
  dst_file = codebase.create_file("new_file.ts")
  my_symbol.move_to_file(dst_file, include_dependencies=True)
  ```
</CodeGroup>

If you set `include_dependencies=False`, only the symbol itself will be moved, and any dependencies will remain in the original file.

## Moving Multiple Symbols

If you need to move multiple symbols, you can do so in a loop:

```python
source_file = codebase.get_file("path/to/source_file.py")
dest_file = codebase.get_file("path/to/destination_file.py")
# Create a list of symbols to move
symbols_to_move = [source_file.get_function("my_function"), source_file.get_class("MyClass")]
# Move each symbol to the destination file
for symbol in symbols_to_move:
    symbol.move_to_file(dest_file, include_dependencies=True, strategy="update_all_imports")
```

## Best Practices

1. **Commit After Major Changes**: If you're making multiple significant changes, use `codebase.commit()` between them to ensure the codebase graph is up-to-date.

2. **Re-fetch References**: After a commit, re-fetch any file or symbol references you're working with, as they may have become stale.

3. **Handle Errors**: Be prepared to handle cases where symbols or files might not exist, or where moves might fail due to naming conflicts.

By following these guidelines, you can effectively move symbols around your codebase while maintaining its integrity and functionality.
