feat: add app creation command and app management module
This commit is contained in:
2 files changed
+230
No files matched your search
@@ -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
|
||||
@@ -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)
|
||||
Reference in new issue
Block a user