feat: add app creation command and app management module

This commit is contained in:
sankalp committed 2025-10-28 22:12:41 +05:45
1 parent 2705bbff61
commit d3729de3a0
2 files changed
+230

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
"""
App management for Django project setup.
Handles creation of Django apps and updating settings.
"""
import os
import subprocess
from typing import Optional
from src.scripts.console_ui import UIFormatter
class AppManager:
def __init__(self, app_name: str):
self.app_name = app_name
self.current_dir = os.getcwd()
self.manage_py_path = os.path.join(self.current_dir, "manage.py")
def create_app(self) -> bool:
if not self._is_django_project():
UIFormatter.print_error(
"Not in a Django project directory. Please run this command from your Django project root."
)
return False
if self._app_exists():
UIFormatter.print_error(f"Django app '{self.app_name}' already exists.")
return False
if not self._create_django_app():
return False
if not self._add_to_installed_apps():
return False
UIFormatter.print_success(f"Django app '{self.app_name}' created and configured successfully!")
return True
def _is_django_project(self) -> bool:
return os.path.exists(self.manage_py_path)
def _app_exists(self) -> bool:
app_path = os.path.join(self.current_dir, self.app_name)
return os.path.exists(app_path)
def _create_django_app(self) -> bool:
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}'")
return True
def _add_to_installed_apps(self) -> bool:
settings_path = self._find_settings_path()
if not settings_path:
UIFormatter.print_error("Could not find Django settings directory")
return False
base_settings_path = os.path.join(settings_path, "base.py")
if not os.path.exists(base_settings_path):
UIFormatter.print_error("Could not find base.py settings file")
return False
with open(base_settings_path) as f:
content = f.read()
if f'"{self.app_name}"' in content or f"'{self.app_name}'" in content:
UIFormatter.print_info(f"App '{self.app_name}' is already in INSTALLED_APPS")
return True
if "USER_DEFINED_APPS" not in content:
UIFormatter.print_error("Could not find USER_DEFINED_APPS section in base.py")
return False
lines = content.split("\n")
new_lines = []
in_user_apps = False
apps_added = False
for line in lines:
if "USER_DEFINED_APPS" in line and "=" in line:
in_user_apps = True
new_lines.append(line)
elif in_user_apps and line.strip() == "]":
new_lines.append(f' "{self.app_name}",')
new_lines.append(line)
in_user_apps = False
apps_added = True
else:
new_lines.append(line)
if not apps_added:
UIFormatter.print_error("Could not find USER_DEFINED_APPS section in base.py")
return False
with open(base_settings_path, "w") as f:
f.write("\n".join(new_lines))
UIFormatter.print_success(f"Added '{self.app_name}' to USER_DEFINED_APPS in base.py")
return True
def _find_settings_path(self) -> Optional[str]:
# Look for project directories that contain settings
for item in os.listdir(self.current_dir):
if os.path.isdir(item) and not item.startswith(".") and item != "__pycache__":
# Check if this directory contains Django project files
project_path = os.path.join(self.current_dir, item)
settings_path = os.path.join(project_path, "settings")
# Check if settings directory exists with base.py
if os.path.exists(settings_path) and os.path.exists(os.path.join(settings_path, "base.py")):
return settings_path
# Fallback: look for settings in current directory
settings_path = os.path.join(self.current_dir, "settings")
if os.path.exists(settings_path) and os.path.exists(os.path.join(settings_path, "base.py")):
return settings_path
return None
+112
View File
@@ -0,0 +1,112 @@
"""
Command handlers for Django project setup CLI.
Handles different commands like secret key generation and app creation.
"""
import argparse
import sys
from src.scripts.console_ui import UIColors, UIFormatter, console
from src.scripts.name_validator import validate_app_name
def parse_arguments() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Django project setup tool", prog="django-init")
subparsers = parser.add_subparsers(dest="command", help="Available commands")
# Setup command (default)
setup_parser = subparsers.add_parser("setup", help="Create a new Django project")
setup_parser.add_argument("--project", help="Django project name")
setup_parser.add_argument("--app", help="Django app name")
# Secret command
secret_parser = subparsers.add_parser("secret", help="Generate Django secret keys")
secret_parser.add_argument("--count", type=int, default=3, help="Number of keys to generate")
secret_parser.add_argument("--length", type=int, default=50, help="Length of each secret key")
# App command
app_parser = subparsers.add_parser("app", help="Create a new Django app")
app_parser.add_argument("app_name", help="Name of the Django app to create")
return parser.parse_args()
def handle_secret_command(args: argparse.Namespace) -> None:
try:
from src.scripts.secretkey_generator import display_secret_keys, generate_multiple_keys
# Generate keys
keys = generate_multiple_keys(args.count, args.length)
# Display results
UIFormatter.print_info("")
display_secret_keys(keys)
# 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)
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)
def handle_app_command(args: argparse.Namespace) -> None:
try:
from src.scripts.app_generator import AppManager
# 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 and 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}")
sys.exit(1)