refactor: remove try-except blocks from command handlers and generators for cleaner code
This commit is contained in:
12 files changed
+195
-273
No files matched your search
+2
-6
@@ -105,9 +105,5 @@ class Cli:
|
||||
return True
|
||||
|
||||
def generate_secret_keys(self) -> bool:
|
||||
try:
|
||||
generate_secret_command()
|
||||
return True
|
||||
except Exception as e:
|
||||
UIFormatter.print_error(f"Failed to generate secret keys: {e}")
|
||||
return False
|
||||
generate_secret_command()
|
||||
return True
|
||||
+33
-42
@@ -25,58 +25,49 @@ def clear_screen() -> None:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
try:
|
||||
# Parse command line arguments
|
||||
args = parse_arguments()
|
||||
# Parse command line arguments
|
||||
args = parse_arguments()
|
||||
|
||||
# Handle secret command
|
||||
if args.command == "secret":
|
||||
handle_secret_command(args)
|
||||
return
|
||||
# Handle secret command
|
||||
if args.command == "secret":
|
||||
handle_secret_command(args)
|
||||
return
|
||||
|
||||
# Handle app command
|
||||
if args.command == "app":
|
||||
handle_app_command(args)
|
||||
return
|
||||
# Handle app command
|
||||
if args.command == "app":
|
||||
handle_app_command(args)
|
||||
return
|
||||
|
||||
# Default to setup command
|
||||
# Clear screen
|
||||
clear_screen()
|
||||
# Default to setup command
|
||||
# Clear screen
|
||||
clear_screen()
|
||||
|
||||
# Display welcome screen
|
||||
console.print()
|
||||
console.print(UIFormatter.create_welcome_panel())
|
||||
console.print()
|
||||
# Display welcome screen
|
||||
console.print()
|
||||
console.print(UIFormatter.create_welcome_panel())
|
||||
console.print()
|
||||
|
||||
# Get user input
|
||||
project_dir, project_name, primary_app, app_names, metadata = get_user_input()
|
||||
# Get user input
|
||||
project_dir, project_name, primary_app, app_names, metadata = get_user_input()
|
||||
|
||||
# Confirm setup
|
||||
if not confirm_setup(project_dir, project_name, app_names, metadata):
|
||||
UIFormatter.print_info("Setup cancelled by user.")
|
||||
return
|
||||
# Confirm setup
|
||||
if not confirm_setup(project_dir, project_name, app_names, metadata):
|
||||
UIFormatter.print_info("Setup cancelled by user.")
|
||||
return
|
||||
|
||||
# Run setup
|
||||
console.print()
|
||||
UIFormatter.print_info("Starting Django project setup...")
|
||||
console.print()
|
||||
# Run setup
|
||||
console.print()
|
||||
UIFormatter.print_info("Starting Django project setup...")
|
||||
console.print()
|
||||
|
||||
django_cli = Cli(project_dir, project_name, primary_app, app_names, metadata)
|
||||
success = django_cli.run_setup()
|
||||
django_cli = Cli(project_dir, project_name, primary_app, app_names, metadata)
|
||||
success = django_cli.run_setup()
|
||||
|
||||
# Display completion summary
|
||||
UIFormatter.create_summary_panel(project_dir, project_name, app_names, True)
|
||||
# Display completion summary
|
||||
UIFormatter.create_summary_panel(project_dir, project_name, app_names, True)
|
||||
|
||||
# Exit with appropriate code
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
UIFormatter.print_info("\nSetup cancelled by user.")
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
UIFormatter.print_error(f"Unexpected error: {str(e)}")
|
||||
console.print("[dim]Please check your environment and try again.[/dim]")
|
||||
sys.exit(1)
|
||||
# Exit with appropriate code
|
||||
sys.exit(0 if success else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -65,21 +65,12 @@ class AppManager:
|
||||
with change_cwd(apps_base_dir):
|
||||
UIFormatter.print_info(f"Creating app '{self.app_name}' in directory: {os.getcwd()}")
|
||||
|
||||
try:
|
||||
# Use django-admin instead of manage.py to avoid dependency issues
|
||||
result = subprocess.run(
|
||||
["django-admin", "startapp", self.app_name],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
UIFormatter.print_error(f"Failed to create app '{self.app_name}': {e}")
|
||||
if e.stderr:
|
||||
UIFormatter.print_error(f"Error details: {e.stderr}")
|
||||
if e.stdout:
|
||||
UIFormatter.print_info(f"Output: {e.stdout}")
|
||||
return False
|
||||
result = subprocess.run(
|
||||
["django-admin", "startapp", self.app_name],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
|
||||
UIFormatter.print_success(f"Created Django app '{self.app_name}' in {apps_base_dir}")
|
||||
return True
|
||||
@@ -228,22 +219,20 @@ class AppManager:
|
||||
# Create serializers.py
|
||||
context = {"app_name": self.app_name}
|
||||
serializers_content = template_engine.render_template("serializers.j2", context)
|
||||
if not create_file_with_content(
|
||||
create_file_with_content(
|
||||
os.path.join(app_path, "serializers.py"),
|
||||
serializers_content,
|
||||
f"Created {self.app_name}/serializers.py",
|
||||
should_format=True,
|
||||
):
|
||||
return False
|
||||
)
|
||||
|
||||
# Create routes.py
|
||||
routes_content = template_engine.render_template("routes.j2", context)
|
||||
if not create_file_with_content(
|
||||
create_file_with_content(
|
||||
os.path.join(app_path, "routes.py"),
|
||||
routes_content,
|
||||
f"Created {self.app_name}/routes.py",
|
||||
should_format=True,
|
||||
):
|
||||
return False
|
||||
)
|
||||
|
||||
return True
|
||||
@@ -19,24 +19,23 @@ class CICDConfigGenerator:
|
||||
github_dir = os.path.join(self.project_root, ".github", "workflows")
|
||||
os.makedirs(github_dir, exist_ok=True)
|
||||
|
||||
context = {"project_name": self.project_name}
|
||||
workflow_content = template_engine.render_template("github_actions_ci.j2", context)
|
||||
workflow_file = os.path.join(github_dir, "ci.yml")
|
||||
create_file_with_content(
|
||||
workflow_file,
|
||||
workflow_content,
|
||||
f"Created Github Actions workflow ({workflow_file})",
|
||||
)
|
||||
context = {"project_name": self.project_name}
|
||||
workflow_content = template_engine.render_template("github_actions_ci.j2", context)
|
||||
workflow_file = os.path.join(github_dir, "ci.yml")
|
||||
create_file_with_content(
|
||||
workflow_file,
|
||||
workflow_content,
|
||||
f"Created Github Actions workflow ({workflow_file})",
|
||||
)
|
||||
return True
|
||||
|
||||
def create_gitlab_ci(self) -> bool:
|
||||
with change_cwd(self.project_root):
|
||||
context = {"project_name": self.project_name}
|
||||
gitlab_ci_content = template_engine.render_template("gitlab_ci.j2", context)
|
||||
config_file = ".gitlab-ci.yml"
|
||||
create_file_with_content(
|
||||
config_file,
|
||||
".gitlab-ci.yml",
|
||||
gitlab_ci_content,
|
||||
f"Created GitLab CI configuration ({config_file})",
|
||||
f"Created GitLab CI configuration (.gitlab-ci.yml)",
|
||||
)
|
||||
return True
|
||||
return True
|
||||
@@ -33,80 +33,69 @@ def parse_arguments() -> argparse.Namespace:
|
||||
|
||||
|
||||
def handle_secret_command(args: argparse.Namespace) -> None:
|
||||
try:
|
||||
from src.scripts.secretkey_generator import display_secret_keys, generate_multiple_keys
|
||||
from src.scripts.secretkey_generator import display_secret_keys, generate_multiple_keys
|
||||
|
||||
# Generate keys
|
||||
keys = generate_multiple_keys(args.count, args.length)
|
||||
# Generate keys
|
||||
keys = generate_multiple_keys(args.count, args.length)
|
||||
|
||||
# Display results
|
||||
UIFormatter.print_info("")
|
||||
display_secret_keys(keys)
|
||||
# Display results
|
||||
UIFormatter.print_info("")
|
||||
display_secret_keys(keys)
|
||||
|
||||
# Show usage instructions
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
# Show usage instructions
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
|
||||
instructions = Text()
|
||||
instructions.append("📋 Usage Instructions:\n", style=UIColors.ACCENT)
|
||||
instructions.append("1. Copy the appropriate secret key for your environment\n")
|
||||
instructions.append("2. Add it to your .env file:\n")
|
||||
instructions.append(" SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("3. Or set it as an environment variable:\n")
|
||||
instructions.append(" export SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("4. Never commit secret keys to version control!\n", style=UIColors.WARNING)
|
||||
instructions = Text()
|
||||
instructions.append("📋 Usage Instructions:\n", style=UIColors.ACCENT)
|
||||
instructions.append("1. Copy the appropriate secret key for your environment\n")
|
||||
instructions.append("2. Add it to your .env file:\n")
|
||||
instructions.append(" SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("3. Or set it as an environment variable:\n")
|
||||
instructions.append(" export SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("4. Never commit secret keys to version control!\n", style=UIColors.WARNING)
|
||||
|
||||
console.print(Panel(instructions, title="💡 How to Use", border_style="blue"))
|
||||
console.print()
|
||||
|
||||
except Exception as e:
|
||||
UIFormatter.print_error(f"Failed to generate secret keys: {e}")
|
||||
sys.exit(1)
|
||||
console.print(Panel(instructions, title="💡 How to Use", border_style="blue"))
|
||||
console.print()
|
||||
|
||||
|
||||
def handle_app_command(args: argparse.Namespace) -> None:
|
||||
try:
|
||||
from src.scripts.app_generator import AppManager
|
||||
from src.scripts.app_generator import AppManager
|
||||
|
||||
# Display welcome message
|
||||
UIFormatter.print_info("")
|
||||
UIFormatter.print_header("Django App Creation")
|
||||
UIFormatter.print_info("")
|
||||
# Display welcome message
|
||||
UIFormatter.print_info("")
|
||||
UIFormatter.print_header("Django App Creation")
|
||||
UIFormatter.print_info("")
|
||||
|
||||
# Validate app name
|
||||
is_valid, error_msg = validate_app_name(args.app_name)
|
||||
if not is_valid:
|
||||
UIFormatter.print_error(error_msg)
|
||||
sys.exit(1)
|
||||
|
||||
# Create app manager
|
||||
app_manager = AppManager(args.app_name)
|
||||
|
||||
# Create the app
|
||||
success = app_manager.create_app()
|
||||
|
||||
if success:
|
||||
UIFormatter.print_success(f"Django app '{args.app_name}' created successfully!")
|
||||
|
||||
# Show next steps
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
|
||||
instructions = Text()
|
||||
instructions.append("🚀 Next Steps:\n", style=UIColors.ACCENT)
|
||||
instructions.append("1. The app has been added to INSTALLED_APPS in base.py\n")
|
||||
instructions.append("2. Create your models in the app's models.py\n")
|
||||
instructions.append("3. Run migrations: python manage.py makemigrations\n")
|
||||
instructions.append("4. Apply migrations: python manage.py migrate\n")
|
||||
instructions.append("5. Create views, serializers and routes(URLs) for your app\n")
|
||||
|
||||
console.print(Panel(instructions, title="💡 What's Next", border_style="green"))
|
||||
else:
|
||||
UIFormatter.print_error(f"Failed to create Django app '{args.app_name}'")
|
||||
sys.exit(1)
|
||||
|
||||
UIFormatter.print_info("")
|
||||
|
||||
except Exception as e:
|
||||
UIFormatter.print_error(f"Failed to create Django app: {e}")
|
||||
# Validate app name
|
||||
is_valid, error_msg = validate_app_name(args.app_name)
|
||||
if not is_valid:
|
||||
UIFormatter.print_error(error_msg)
|
||||
sys.exit(1)
|
||||
|
||||
# Create app manager
|
||||
app_manager = AppManager(args.app_name)
|
||||
|
||||
# Create the app
|
||||
success = app_manager.create_app()
|
||||
|
||||
if not success:
|
||||
UIFormatter.print_error(f"Failed to create Django app '{args.app_name}'")
|
||||
sys.exit(1)
|
||||
|
||||
UIFormatter.print_success(f"Django app '{args.app_name}' created successfully!")
|
||||
|
||||
# Show next steps
|
||||
from rich.panel import Panel
|
||||
from rich.text import Text
|
||||
|
||||
instructions = Text()
|
||||
instructions.append("🚀 Next Steps:\n", style=UIColors.ACCENT)
|
||||
instructions.append("1. The app has been added to INSTALLED_APPS in base.py\n")
|
||||
instructions.append("2. Create your models in the app's models.py\n")
|
||||
instructions.append("3. Run migrations: python manage.py makemigrations\n")
|
||||
instructions.append("4. Apply migrations: python manage.py migrate\n")
|
||||
instructions.append("5. Create views, serializers and routes(URLs) for your app\n")
|
||||
|
||||
console.print(Panel(instructions, title="💡 What's Next", border_style="green"))
|
||||
UIFormatter.print_info("")
|
||||
@@ -16,23 +16,23 @@ class DeploymentConfigGenerator:
|
||||
with change_cwd(self.project_root):
|
||||
context = {"project_name": self.project_name}
|
||||
justfile_content = template_engine.render_template("justfile.j2", context)
|
||||
result = create_file_with_content(
|
||||
create_file_with_content(
|
||||
"justfile",
|
||||
justfile_content,
|
||||
"Created justfile with Django development tasks",
|
||||
)
|
||||
return result
|
||||
return True
|
||||
|
||||
def create_procfile(self) -> bool:
|
||||
with change_cwd(self.project_root):
|
||||
context = {"project_name": self.project_name}
|
||||
procfile_content = template_engine.render_template("procfile.j2", context)
|
||||
result = create_file_with_content(
|
||||
create_file_with_content(
|
||||
"Procfile",
|
||||
procfile_content,
|
||||
"Created Procfile with Gunicorn configuration",
|
||||
)
|
||||
return result
|
||||
return True
|
||||
|
||||
def create_gunicorn_config(self) -> bool:
|
||||
with change_cwd(self.project_root):
|
||||
@@ -74,25 +74,23 @@ tmp_upload_dir = None
|
||||
# certfile = "/path/to/cert.pem"
|
||||
"""
|
||||
|
||||
config_file = "gunicorn_config.py"
|
||||
result = create_file_with_content(
|
||||
config_file,
|
||||
create_file_with_content(
|
||||
"gunicorn_config.py",
|
||||
gunicorn_config_content,
|
||||
f"Created {config_file} with Gunicorn configuration",
|
||||
f"Created gunicorn_config.py with Gunicorn configuration",
|
||||
)
|
||||
return result
|
||||
return True
|
||||
|
||||
def create_runtime_txt(self, python_version: str = "3.13") -> bool:
|
||||
with change_cwd(self.project_root):
|
||||
context = {"python_version": python_version}
|
||||
runtime_content = template_engine.render_template("runtime_txt.j2", context)
|
||||
runtime_file = "runtime.txt"
|
||||
result = create_file_with_content(
|
||||
runtime_file,
|
||||
create_file_with_content(
|
||||
"runtime.txt",
|
||||
runtime_content,
|
||||
f"Created {runtime_file} with Python version specification",
|
||||
f"Created runtime.txt with Python version specification",
|
||||
)
|
||||
return result
|
||||
return True
|
||||
|
||||
def create_nixpacks_toml(self) -> bool:
|
||||
with change_cwd(self.project_root):
|
||||
@@ -112,10 +110,9 @@ cmds = ["python manage.py collectstatic --noinput"]
|
||||
cmd = "gunicorn {self.project_name}.wsgi:application --bind 0.0.0.0:$PORT"
|
||||
"""
|
||||
|
||||
config_file = "nixpacks.toml"
|
||||
result = create_file_with_content(
|
||||
config_file,
|
||||
create_file_with_content(
|
||||
"nixpacks.toml",
|
||||
nixpacks_content,
|
||||
f"Created {config_file} for Nixpacks deployment",
|
||||
f"Created nixpacks.toml for Nixpacks deployment",
|
||||
)
|
||||
return result
|
||||
return True
|
||||
+24
-41
@@ -72,60 +72,43 @@ class FileManager:
|
||||
"Created pyproject.toml file for uv",
|
||||
)
|
||||
|
||||
def create_app_urls(self) -> bool:
|
||||
apps_base_dir = self.project_root
|
||||
def _get_apps_base_dir(self) -> str:
|
||||
"""Get the base directory for apps based on project structure."""
|
||||
if self.metadata.get("nested_apps") and self.metadata.get("nested_dir"):
|
||||
apps_base_dir = os.path.join(self.project_root, self.metadata.get("nested_dir"))
|
||||
return os.path.join(self.project_root, self.metadata.get("nested_dir"))
|
||||
return self.project_root
|
||||
|
||||
def _create_app_file(self, apps_base_dir: str, app_name: str, template_name: str, filename: str) -> None:
|
||||
"""Helper method to create app files."""
|
||||
app_path = os.path.join(apps_base_dir, app_name)
|
||||
with change_cwd(app_path):
|
||||
context = {"app_name": app_name}
|
||||
content = template_engine.render_template(template_name, context)
|
||||
create_file_with_content(
|
||||
filename,
|
||||
content,
|
||||
f"Created {app_name}/{filename}",
|
||||
should_format=True,
|
||||
)
|
||||
|
||||
def create_app_urls(self) -> bool:
|
||||
apps_base_dir = self._get_apps_base_dir()
|
||||
for app_name in self.app_names:
|
||||
app_path = os.path.join(apps_base_dir, app_name)
|
||||
with change_cwd(app_path):
|
||||
context = {"app_name": app_name}
|
||||
urls_content = template_engine.render_template("app_urls.j2", context)
|
||||
create_file_with_content(
|
||||
"urls.py",
|
||||
urls_content,
|
||||
f"Created {app_name}/urls.py",
|
||||
should_format=True,
|
||||
)
|
||||
self._create_app_file(apps_base_dir, app_name, "app_urls.j2", "urls.py")
|
||||
return True
|
||||
|
||||
def create_app_serializers(self) -> bool:
|
||||
"""Create serializers.py file for each app."""
|
||||
apps_base_dir = self.project_root
|
||||
if self.metadata.get("nested_apps") and self.metadata.get("nested_dir"):
|
||||
apps_base_dir = os.path.join(self.project_root, self.metadata.get("nested_dir"))
|
||||
|
||||
apps_base_dir = self._get_apps_base_dir()
|
||||
for app_name in self.app_names:
|
||||
app_path = os.path.join(apps_base_dir, app_name)
|
||||
with change_cwd(app_path):
|
||||
context = {"app_name": app_name}
|
||||
serializers_content = template_engine.render_template("serializers.j2", context)
|
||||
create_file_with_content(
|
||||
"serializers.py",
|
||||
serializers_content,
|
||||
f"Created {app_name}/serializers.py",
|
||||
should_format=True,
|
||||
)
|
||||
self._create_app_file(apps_base_dir, app_name, "serializers.j2", "serializers.py")
|
||||
return True
|
||||
|
||||
def create_app_routes(self) -> bool:
|
||||
"""Create routes.py file for each app."""
|
||||
apps_base_dir = self.project_root
|
||||
if self.metadata.get("nested_apps") and self.metadata.get("nested_dir"):
|
||||
apps_base_dir = os.path.join(self.project_root, self.metadata.get("nested_dir"))
|
||||
|
||||
apps_base_dir = self._get_apps_base_dir()
|
||||
for app_name in self.app_names:
|
||||
app_path = os.path.join(apps_base_dir, app_name)
|
||||
with change_cwd(app_path):
|
||||
context = {"app_name": app_name}
|
||||
routes_content = template_engine.render_template("routes.j2", context)
|
||||
create_file_with_content(
|
||||
"routes.py",
|
||||
routes_content,
|
||||
f"Created {app_name}/routes.py",
|
||||
should_format=True,
|
||||
)
|
||||
self._create_app_file(apps_base_dir, app_name, "routes.j2", "routes.py")
|
||||
return True
|
||||
|
||||
def update_project_urls(self) -> bool:
|
||||
|
||||
@@ -112,35 +112,27 @@ class InputCollector:
|
||||
console.print(f"[{UIColors.MUTED}]Please try again ({attempt}/{self.MAX_ATTEMPTS}).[/{UIColors.MUTED}]")
|
||||
|
||||
def get_app_names(self) -> list[str]:
|
||||
try:
|
||||
console.print(f"[{UIColors.HIGHLIGHT}]App Names[/{UIColors.HIGHLIGHT}]")
|
||||
console.print(
|
||||
f"[{UIColors.MUTED}]Enter app names separated by commas (no interactive prompts)[/{UIColors.MUTED}]"
|
||||
)
|
||||
console.print(f"[{UIColors.MUTED}]Example: users, products, orders[/{UIColors.MUTED}]")
|
||||
console.print(f"[{UIColors.HIGHLIGHT}]App Names[/{UIColors.HIGHLIGHT}]")
|
||||
console.print(
|
||||
f"[{UIColors.MUTED}]Enter app names separated by commas (no interactive prompts)[/{UIColors.MUTED}]"
|
||||
)
|
||||
console.print(f"[{UIColors.MUTED}]Example: users, products, orders[/{UIColors.MUTED}]")
|
||||
|
||||
user_input = console.input(
|
||||
f"[{UIColors.HIGHLIGHT}]Enter app names (comma-separated or single):[/{UIColors.HIGHLIGHT}] "
|
||||
)
|
||||
user_input = console.input(
|
||||
f"[{UIColors.HIGHLIGHT}]Enter app names (comma-separated or single):[/{UIColors.HIGHLIGHT}] "
|
||||
)
|
||||
|
||||
# Empty input - re-prompt (no interactive flow)
|
||||
if not user_input.strip():
|
||||
UIFormatter.print_error("At least one app name is required")
|
||||
return self.get_app_names()
|
||||
# Empty input - re-prompt (no interactive flow)
|
||||
if not user_input.strip():
|
||||
UIFormatter.print_error("At least one app name is required")
|
||||
return self.get_app_names()
|
||||
|
||||
# Comma-separated input
|
||||
if "," in user_input:
|
||||
return self._parse_comma_separated_apps(user_input)
|
||||
# Comma-separated input
|
||||
if "," in user_input:
|
||||
return self._parse_comma_separated_apps(user_input)
|
||||
|
||||
# Single app (no additional prompts)
|
||||
return self._get_apps_starting_with(user_input.strip())
|
||||
|
||||
except KeyboardInterrupt:
|
||||
UIFormatter.print_info("\nSetup cancelled by user.")
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
UIFormatter.print_error(f"Unexpected error: {str(e)}")
|
||||
return self.get_app_names() # Retry
|
||||
# Single app (no additional prompts)
|
||||
return self._get_apps_starting_with(user_input.strip())
|
||||
|
||||
def _parse_comma_separated_apps(self, user_input: str) -> list[str]:
|
||||
app_list = [app.strip() for app in user_input.split(",")]
|
||||
|
||||
+17
-21
@@ -51,20 +51,16 @@ class ProjectManager:
|
||||
with change_cwd(apps_base_dir):
|
||||
# Create each app
|
||||
for app_name in self.app_names:
|
||||
try:
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
os.path.join(self.project_root, "manage.py"),
|
||||
"startapp",
|
||||
app_name,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
UIFormatter.print_success(f"Django app '{app_name}' created successfully!")
|
||||
except subprocess.CalledProcessError as e:
|
||||
UIFormatter.print_error(f"Failed to create app '{app_name}': {e}")
|
||||
return False
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
os.path.join(self.project_root, "manage.py"),
|
||||
"startapp",
|
||||
app_name,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
UIFormatter.print_success(f"Django app '{app_name}' created successfully!")
|
||||
|
||||
return True
|
||||
|
||||
@@ -106,11 +102,11 @@ class ProjectManager:
|
||||
|
||||
missing_files = [file_path for file_path in required_files if not os.path.exists(file_path)]
|
||||
|
||||
if missing_files:
|
||||
UIFormatter.print_error("Project structure validation failed:")
|
||||
for file_path in missing_files:
|
||||
UIFormatter.print_error(f" Missing: {file_path}")
|
||||
return False
|
||||
if not missing_files:
|
||||
UIFormatter.print_success("Project structure validation passed")
|
||||
return True
|
||||
|
||||
UIFormatter.print_success("Project structure validation passed")
|
||||
return True
|
||||
UIFormatter.print_error("Project structure validation failed:")
|
||||
for file_path in missing_files:
|
||||
UIFormatter.print_error(f" Missing: {file_path}")
|
||||
return False
|
||||
@@ -50,12 +50,8 @@ def generate_secret_command():
|
||||
instructions.append("2. Add it to your .env file:\n")
|
||||
instructions.append(" SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("3. Or set it as an environment variable:\n")
|
||||
instructions.append(
|
||||
" export SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE
|
||||
)
|
||||
instructions.append(
|
||||
"4. Never commit secret keys to version control!\n", style=UIColors.WARNING
|
||||
)
|
||||
instructions.append(" export SECRET_KEY=your_secret_key_here\n", style=UIColors.CODE)
|
||||
instructions.append("4. Never commit secret keys to version control!\n", style=UIColors.WARNING)
|
||||
|
||||
console.print(Panel(instructions, title="💡 How to Use", border_style="blue"))
|
||||
console.print()
|
||||
|
||||
@@ -51,33 +51,36 @@ class SettingsManager:
|
||||
"app_names": effective_app_names,
|
||||
}
|
||||
base_content = template_engine.render_template("settings_base.j2", context)
|
||||
return create_file_with_content(
|
||||
create_file_with_content(
|
||||
"base.py",
|
||||
base_content,
|
||||
"Updated settings/base.py with comprehensive configuration",
|
||||
should_format=True,
|
||||
)
|
||||
return True
|
||||
|
||||
def update_development_settings(self) -> bool:
|
||||
"""Update development.py with development-specific settings."""
|
||||
with change_cwd(self.settings_folder):
|
||||
context = {"secret_key": self.secret_key}
|
||||
dev_content = template_engine.render_template("settings_development.j2", context)
|
||||
return create_file_with_content(
|
||||
create_file_with_content(
|
||||
"development.py",
|
||||
dev_content,
|
||||
"Updated settings/development.py",
|
||||
should_format=True,
|
||||
)
|
||||
return True
|
||||
|
||||
def update_production_settings(self) -> bool:
|
||||
"""Update production.py with production-specific settings."""
|
||||
with change_cwd(self.settings_folder):
|
||||
context = {"use_database_url": self.metadata.get("use_database_url", True)}
|
||||
prod_content = template_engine.render_template("settings_production.j2", context)
|
||||
return create_file_with_content(
|
||||
create_file_with_content(
|
||||
"production.py",
|
||||
prod_content,
|
||||
"Updated settings/production.py",
|
||||
should_format=True,
|
||||
)
|
||||
return True
|
||||
@@ -57,20 +57,11 @@ class TemplateEngine:
|
||||
return template.render(**context)
|
||||
|
||||
def get_template_names(self) -> list[str]:
|
||||
"""Get list of available template files.
|
||||
|
||||
Returns:
|
||||
List of template file names
|
||||
"""
|
||||
"""Get list of available template files."""
|
||||
if not os.path.exists(self.template_dir):
|
||||
return []
|
||||
|
||||
template_files = []
|
||||
for file in os.listdir(self.template_dir):
|
||||
if file.endswith(".j2"):
|
||||
template_files.append(file)
|
||||
|
||||
return sorted(template_files)
|
||||
return sorted([file for file in os.listdir(self.template_dir) if file.endswith(".j2")])
|
||||
|
||||
def template_exists(self, template_name: str) -> bool:
|
||||
"""Check if a template file exists.
|
||||
|
||||
Reference in new issue
Block a user