Compare commits
1 Commits
main
...
elijah/ref
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ce1886d413 |
@ -551,6 +551,22 @@ def deploy(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
def rename(
|
||||||
|
new_name: str = typer.Argument(
|
||||||
|
help="The new name of the app.",
|
||||||
|
),
|
||||||
|
loglevel: constants.LogLevel = typer.Option(
|
||||||
|
config.loglevel, help="The log level to use."
|
||||||
|
),
|
||||||
|
):
|
||||||
|
"""Rename the app."""
|
||||||
|
from reflex.utils import prerequisites
|
||||||
|
|
||||||
|
new_name = prerequisites.validate_app_name(new_name)
|
||||||
|
prerequisites.rename_app(new_name)
|
||||||
|
|
||||||
|
|
||||||
cli.add_typer(db_cli, name="db", help="Subcommands for managing the database schema.")
|
cli.add_typer(db_cli, name="db", help="Subcommands for managing the database schema.")
|
||||||
cli.add_typer(script_cli, name="script", help="Subcommands running helper scripts.")
|
cli.add_typer(script_cli, name="script", help="Subcommands running helper scripts.")
|
||||||
cli.add_typer(
|
cli.add_typer(
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import ast
|
||||||
import contextlib
|
import contextlib
|
||||||
import dataclasses
|
import dataclasses
|
||||||
import functools
|
import functools
|
||||||
import importlib
|
import importlib
|
||||||
import importlib.metadata
|
import importlib.metadata
|
||||||
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
@ -23,6 +25,7 @@ from pathlib import Path
|
|||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Callable, List, Optional
|
from typing import Callable, List, Optional
|
||||||
|
|
||||||
|
import astor
|
||||||
import httpx
|
import httpx
|
||||||
import typer
|
import typer
|
||||||
from alembic.util.exc import CommandError
|
from alembic.util.exc import CommandError
|
||||||
@ -427,6 +430,111 @@ def validate_app_name(app_name: str | None = None) -> str:
|
|||||||
return app_name
|
return app_name
|
||||||
|
|
||||||
|
|
||||||
|
class ImportRenamer(ast.NodeTransformer):
|
||||||
|
"""Rename imports in a tree."""
|
||||||
|
|
||||||
|
def __init__(self, old_name, new_name):
|
||||||
|
"""Initialize the ImportRenamer."""
|
||||||
|
self.old_name = old_name
|
||||||
|
self.new_name = new_name
|
||||||
|
|
||||||
|
def visit_Import(self, node):
|
||||||
|
"""Rename imports of the form `import foo`."""
|
||||||
|
for alias in node.names:
|
||||||
|
if alias.name == self.old_name:
|
||||||
|
alias.name = self.new_name
|
||||||
|
return node
|
||||||
|
|
||||||
|
def visit_ImportFrom(self, node):
|
||||||
|
"""Rename imports of the form `from foo import bar`."""
|
||||||
|
if node.module == self.old_name:
|
||||||
|
node.module = self.new_name
|
||||||
|
return node
|
||||||
|
|
||||||
|
def visit_Assign(self, node):
|
||||||
|
"""Handle assignments like `config = rx.Config(app_name='foo')`."""
|
||||||
|
if (
|
||||||
|
isinstance(node.targets[0], ast.Name)
|
||||||
|
and node.targets[0].id == "config"
|
||||||
|
and isinstance(node.value, ast.Call)
|
||||||
|
and isinstance(node.value.func, ast.Attribute)
|
||||||
|
and node.value.func.attr == "Config"
|
||||||
|
):
|
||||||
|
for kw in node.value.keywords:
|
||||||
|
if kw.arg == "app_name" and isinstance(kw.value, ast.Constant):
|
||||||
|
if kw.value.value == self.old_name:
|
||||||
|
kw.value = ast.Constant(value=self.new_name)
|
||||||
|
|
||||||
|
# Handle positional arguments
|
||||||
|
if node.value.args and isinstance(node.value.args[0], ast.Constant):
|
||||||
|
if node.value.args[0].value == self.old_name:
|
||||||
|
node.value.args[0] = ast.Constant(value=self.new_name)
|
||||||
|
return node
|
||||||
|
|
||||||
|
|
||||||
|
def rename_imports_and_app_name_in_file(file_path, old_name, new_name):
|
||||||
|
"""Rename imports and update the app_name in rxconfig.py."""
|
||||||
|
file_path = Path(file_path)
|
||||||
|
content = file_path.read_text()
|
||||||
|
|
||||||
|
tree = ast.parse(content)
|
||||||
|
|
||||||
|
transformer = ImportRenamer(old_name, new_name)
|
||||||
|
new_tree = transformer.visit(tree)
|
||||||
|
ast.fix_missing_locations(new_tree)
|
||||||
|
|
||||||
|
modified_content = astor.to_source(new_tree)
|
||||||
|
|
||||||
|
file_path.write_text(modified_content)
|
||||||
|
|
||||||
|
|
||||||
|
def process_directory(directory, old_name, new_name, exclude_dirs=None):
|
||||||
|
"""Process all Python files in a directory, excluding specified directories."""
|
||||||
|
exclude_dirs = exclude_dirs or []
|
||||||
|
directory = Path(directory)
|
||||||
|
|
||||||
|
for root in directory.rglob("*.py"):
|
||||||
|
if not any(root.parts[i] in exclude_dirs for i in range(len(root.parts))):
|
||||||
|
rename_imports_and_app_name_in_file(root, old_name, new_name)
|
||||||
|
|
||||||
|
|
||||||
|
def rename_path_up_tree(full_path, old_name, new_name):
|
||||||
|
"""Rename all instances of `old_name` in the path (file and directories) to `new_name`."""
|
||||||
|
current_path = Path(full_path)
|
||||||
|
new_path = None
|
||||||
|
|
||||||
|
while True:
|
||||||
|
directory, base = current_path.parent, current_path.name
|
||||||
|
|
||||||
|
if old_name in base:
|
||||||
|
new_base = base.replace(old_name, new_name)
|
||||||
|
new_path = directory / new_base
|
||||||
|
current_path.rename(new_path)
|
||||||
|
current_path = new_path
|
||||||
|
else:
|
||||||
|
new_path = current_path
|
||||||
|
|
||||||
|
# Stop if we've reached the root package
|
||||||
|
if old_name not in directory.name:
|
||||||
|
break
|
||||||
|
|
||||||
|
# Move up the directory tree
|
||||||
|
current_path = directory
|
||||||
|
|
||||||
|
return new_path
|
||||||
|
|
||||||
|
|
||||||
|
def rename_app(app_name: str):
|
||||||
|
"""Rename the app directory."""
|
||||||
|
config = get_config()
|
||||||
|
process_directory(
|
||||||
|
Path.cwd(), config.app_name, app_name, exclude_dirs=["assets", ".web"]
|
||||||
|
)
|
||||||
|
|
||||||
|
full_path = importlib.util.find_spec(config.module).origin
|
||||||
|
rename_path_up_tree(full_path, config.app_name, app_name)
|
||||||
|
|
||||||
|
|
||||||
def create_config(app_name: str):
|
def create_config(app_name: str):
|
||||||
"""Create a new rxconfig file.
|
"""Create a new rxconfig file.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user