From 131233007f002571872b881dcd82d5c94c06f268 Mon Sep 17 00:00:00 2001 From: Jishnu-Nandhiath Date: Tue, 26 Dec 2023 00:14:01 +0530 Subject: [PATCH] add: reflex init app name validator, prevent invalid package names --- reflex/reflex.py | 4 ++-- reflex/utils/prerequisites.py | 23 +++++++++++++++++------ tests/utils/test_utils.py | 9 ++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/reflex/reflex.py b/reflex/reflex.py index dc0fb58eac..4ea16466c4 100644 --- a/reflex/reflex.py +++ b/reflex/reflex.py @@ -74,8 +74,8 @@ def _init( # Show system info exec.output_system_info() - # Get the app name. - app_name = prerequisites.get_default_app_name() if name is None else name + # Validate the app name. + app_name = prerequisites.validate_app_name(name) console.rule(f"[bold]Initializing {app_name}") prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME) diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py index 58bb6bdd28..71d5df8dc4 100644 --- a/reflex/utils/prerequisites.py +++ b/reflex/utils/prerequisites.py @@ -215,19 +215,23 @@ def get_production_backend_url() -> str: ) -def get_default_app_name() -> str: - """Get the default app name. +def validate_app_name(app_name: str | None = None) -> str: + """Validate the app name. The default app name is the name of the current directory. + Args: + app_name: the name passed by user during reflex init + Returns: - The default app name. + The app name after validation. Raises: - Exit: if the app directory name is reflex. + Exit: if the app directory name is reflex or if the name is not standard for a python package name. """ - app_name = os.getcwd().split(os.path.sep)[-1].replace("-", "_") - + app_name = ( + app_name if app_name else os.getcwd().split(os.path.sep)[-1].replace("-", "_") + ) # Make sure the app is not named "reflex". if app_name == constants.Reflex.MODULE_NAME: console.error( @@ -235,6 +239,13 @@ def get_default_app_name() -> str: ) raise typer.Exit(1) + # Make sure the app name is standard for a python package name. + if not re.match(r"^[a-zA-Z][a-zA-Z0-9_]*$", app_name): + console.error( + "The app directory name must start with a letter and can contain letters, numbers, and underscores." + ) + raise typer.Exit(1) + return app_name diff --git a/tests/utils/test_utils.py b/tests/utils/test_utils.py index 82085dd742..2700cf364d 100644 --- a/tests/utils/test_utils.py +++ b/tests/utils/test_utils.py @@ -306,8 +306,8 @@ def test_initialize_non_existent_gitignore(tmp_path, mocker, gitignore_exists): assert set(file_content) - expected == set() -def test_app_default_name(tmp_path, mocker): - """Test that an error is raised if the app name is reflex. +def test_validate_app_name(tmp_path, mocker): + """Test that an error is raised if the app name is reflex or if the name is not according to python package naming conventions. Args: tmp_path: Test working dir. @@ -319,7 +319,10 @@ def test_app_default_name(tmp_path, mocker): mocker.patch("reflex.utils.prerequisites.os.getcwd", return_value=str(reflex)) with pytest.raises(typer.Exit): - prerequisites.get_default_app_name() + prerequisites.validate_app_name() + + with pytest.raises(typer.Exit): + prerequisites.validate_app_name(app_name="1_test") def test_node_install_windows(tmp_path, mocker):