diff --git a/examples/bug_check.py b/examples/bug_check.py new file mode 100644 index 0000000..e19287d --- /dev/null +++ b/examples/bug_check.py @@ -0,0 +1,246 @@ +#!/usr/bin/env python3 +""" +Bug detection and checking script for djinit. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) + +from djinit.templater import template_engine + + +def check_template_consistency(): + """Check if all templates have consistent variable syntax.""" + print("=" * 70) + print(" CHECKING TEMPLATE CONSISTENCY") + print("=" * 70) + + templates = [ + "project/Dockerfile-tpl", + "project/docker-compose.yml-tpl", + "project/vite.config.js-tpl", + "project/package.json-tpl", + "project/requirements-tpl", + "config/settings/base.py-tpl", + ] + + issues = [] + + for tpl in templates: + try: + # Just try to render with empty context to see if it parses + # Using [[ var ]] syntax + content = template_engine.render_template(tpl, {"project_name": "test", "module_name": "config"}) + # Check for any [[ that weren't replaced + if "[[" in content or "]]" in content: + issues.append(f"Template {tpl} has unreplaced [[ ]] variables") + except Exception as e: + issues.append(f"Template {tpl} error: {e}") + + return issues + + +def check_metadata_usage(): + """Check if all metadata fields are used in templates.""" + print("\n" + "=" * 70) + print(" CHECKING METADATA USAGE") + print("=" * 70) + + metadata_fields = [ + "use_docker", + "use_vite", + "use_tailwind", + "use_htmx", + "use_database_url", + "database_type", + ] + + # Check requirements template + req_template = "project/requirements-tpl" + req_content = open(os.path.join(os.path.dirname(__file__), '..', 'src/djinit/templates', req_template)).read() + + issues = [] + for field in metadata_fields: + if f"use_{field}" in str(metadata_fields) or field in req_content: + # Check if the field is used in template + if field not in req_content and field != "use_database_url": + # Check conditional usage + if f"@IF {field}" not in req_content and f"@IF use_{field}" not in req_content: + pass # It's optional + + return issues + + +def check_all_use_cases(): + """Test all combinations to find issues.""" + print("\n" + "=" * 70) + print(" CHECKING ALL USE CASES") + print("=" * 70) + + use_cases = [ + {"name": "basic", "metadata": {}}, + {"name": "docker", "metadata": {"use_docker": True, "database_type": "postgresql"}}, + {"name": "vite", "metadata": {"use_vite": True}}, + {"name": "tailwind", "metadata": {"use_tailwind": True}}, + {"name": "htmx", "metadata": {"use_htmx": True}}, + {"name": "docker_mysql", "metadata": {"use_docker": True, "database_type": "mysql"}}, + {"name": "all", "metadata": {"use_docker": True, "use_vite": True, "use_tailwind": True, "use_htmx": True, "database_type": "postgresql"}}, + ] + + issues = [] + + for case in use_cases: + name = case["name"] + md = case["metadata"] + + ctx = { + "project_name": "test", + "module_name": "config", + "use_database_url": True, + **md + } + + # Check requirements + try: + req = template_engine.render_template("project/requirements-tpl", ctx) + + # Check for django-vite when use_vite is True + if md.get("use_vite") and "django-vite" not in req: + issues.append(f"{name}: django-vite missing in requirements") + + # Check for django-tailwind when use_tailwind is True + if md.get("use_tailwind") and "django-tailwind-cli" not in req: + issues.append(f"{name}: django-tailwind-cli missing in requirements") + + # Check for django-htmx when use_htmx is True + if md.get("use_htmx") and "django-htmx" not in req: + issues.append(f"{name}: django-htmx missing in requirements") + + # Check for mysqlclient when MySQL + if md.get("database_type") == "mysql" and "mysqlclient" not in req: + issues.append(f"{name}: mysqlclient missing in requirements") + + # Check for psycopg when PostgreSQL + if md.get("database_type") != "mysql" and "psycopg" not in req: + issues.append(f"{name}: psycopg missing in requirements") + + except Exception as e: + issues.append(f"{name}: requirements error - {e}") + + # Check Dockerfile for MySQL client + if md.get("database_type") == "mysql" and md.get("use_docker"): + try: + dockerfile = template_engine.render_template("project/Dockerfile-tpl", ctx) + if "default-libmysqlclient-dev" not in dockerfile and "mysqlclient" not in dockerfile: + issues.append(f"{name}: MySQL client missing in Dockerfile") + except Exception as e: + issues.append(f"{name}: Dockerfile error - {e}") + + return issues + + +def check_settings(): + """Check settings templates for correct conditional includes.""" + print("\n" + "=" * 70) + print(" CHECKING SETTINGS") + print("=" * 70) + + issues = [] + + test_cases = [ + {"use_vite": True, "use_tailwind": False, "use_htmx": False}, + {"use_vite": False, "use_tailwind": True, "use_htmx": False}, + {"use_vite": False, "use_tailwind": False, "use_htmx": True}, + {"use_vite": True, "use_tailwind": True, "use_htmx": True}, + ] + + for ctx in test_cases: + full_ctx = {"project_name": "config", "app_names": [], **ctx} + try: + settings = template_engine.render_template("config/settings/base.py-tpl", full_ctx) + + # Check django_vite + if ctx.get("use_vite") and "django_vite" not in settings: + issues.append(f"settings with {ctx}: django_vite missing") + + if ctx.get("use_vite") and "DJANGO_VITE" not in settings: + issues.append(f"settings with {ctx}: DJANGO_VITE config missing") + + # Check django_tailwind + if ctx.get("use_tailwind") and "django_tailwind_cli" not in settings: + issues.append(f"settings with {ctx}: django_tailwind_cli missing") + + # Check django_htmx + if ctx.get("use_htmx") and "django_htmx" not in settings: + issues.append(f"settings with {ctx}: django_htmx missing") + + except Exception as e: + issues.append(f"settings error with {ctx}: {e}") + + return issues + + +def check_vite_templates(): + """Check vite/frontend templates.""" + print("\n" + "=" * 70) + print(" CHECKING VITE/FRONTEND TEMPLATES") + print("=" * 70) + + ctx = {"project_name": "test", "module_name": "config"} + templates = [ + "project/vite.config.js-tpl", + "project/package.json-tpl", + "project/frontend/index.html-tpl", + "project/frontend/src/main.jsx-tpl", + "project/frontend/src/App.jsx-tpl", + "project/frontend/src/index.css-tpl", + ] + + issues = [] + + for tpl in templates: + try: + content = template_engine.render_template(tpl, ctx) + # Check for unreplaced variables + if "[[" in content: + issues.append(f"{tpl}: has unreplaced [[ variables") + except Exception as e: + issues.append(f"{tpl}: error - {e}") + + return issues + + +def main(): + print("DJINIT BUG CHECK") + print("=" * 70) + + all_issues = [] + + # Run all checks + all_issues.extend(check_template_consistency()) + all_issues.extend(check_metadata_usage()) + all_issues.extend(check_all_use_cases()) + all_issues.extend(check_settings()) + all_issues.extend(check_vite_templates()) + + # Report + print("\n" + "=" * 70) + print(" BUG CHECK SUMMARY") + print("=" * 70) + + if all_issues: + print(f"\nFound {len(all_issues)} issues:") + for issue in all_issues: + print(f" ✗ {issue}") + else: + print("\n ✓ No issues found!") + + print("\n" + "=" * 70) + print(" COMPLETED") + print("=" * 70) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/full_test.py b/examples/full_test.py new file mode 100644 index 0000000..c4c3b47 --- /dev/null +++ b/examples/full_test.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +""" +Comprehensive test for all djinit features. +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) + +from djinit.creators.setup import SetupCreator + +def create_project(name, metadata): + """Create a test project.""" + test_dir = "/tmp/djinit_full_test" + os.makedirs(test_dir, exist_ok=True) + original_cwd = os.getcwd() + + try: + os.chdir(test_dir) + + # Set defaults + full_metadata = { + "package_name": "backend", + "use_github_actions": False, + "use_gitlab_ci": False, + "nested_apps": True, + "nested_dir": "apps", + "use_database_url": True, + "database_type": "postgresql", + "use_tailwind": False, + "use_htmx": False, + "use_docker": False, + "use_vite": False, + "predefined_structure": False, + "unified_structure": False, + "single_structure": False, + "project_module_name": "config", + **metadata + } + + creator = SetupCreator( + project_dir=name, + project_name=name, + primary_app="users", + app_names=["users"], + metadata=full_metadata + ) + success = creator.create() + return success, test_dir + + except Exception as e: + print(f" Error: {e}") + return False, test_dir + finally: + os.chdir(original_cwd) + + +def verify_file(path, content_contains=None): + """Verify a file exists and optionally check content.""" + if not os.path.exists(path): + return False, f"File not found: {path}" + if content_contains: + with open(path) as f: + content = f.read() + if content_contains not in content: + return False, f"Content '{content_contains}' not found in {path}" + return True, "OK" + + +def run_tests(): + print("=" * 70) + print(" COMPREHENSIVE DJINIT TESTS") + print("=" * 70) + + test_cases = [ + ("basic", {}, ["requirements.txt"]), + ("docker", {"use_docker": True}, ["Dockerfile", "docker-compose.yml"]), + ("vite", {"use_vite": True}, ["vite.config.js", "package.json", "frontend/index.html"]), + ("tailwind", {"use_tailwind": True}, ["requirements.txt"]), + ("htmx", {"use_htmx": True}, ["requirements.txt"]), + ("all_postgres", {"use_docker": True, "use_vite": True, "use_tailwind": True, "use_htmx": True, "database_type": "postgresql"}, ["Dockerfile", "docker-compose.yml", "vite.config.js"]), + ("all_mysql", {"use_docker": True, "use_vite": True, "use_tailwind": True, "database_type": "mysql"}, ["Dockerfile", "docker-compose.yml", "vite.config.js"]), + ] + + results = [] + + for name, metadata, expected_files in test_cases: + print(f"\n{'─' * 70}") + print(f" Testing: {name}") + print(f" Metadata: {metadata}") + + # Clean up + import shutil + test_dir = "/tmp/djinit_full_test" + if os.path.exists(test_dir): + shutil.rmtree(test_dir) + + # Create project + success, _ = create_project(name, metadata) + + if not success: + results.append((name, False, "Project creation failed")) + print(f" ✗ Failed to create project") + continue + + # Verify files + project_dir = os.path.join(test_dir, name) + all_passed = True + errors = [] + + for file in expected_files: + file_path = os.path.join(project_dir, file) + exists, msg = verify_file(file_path) + if not exists: + all_passed = False + errors.append(msg) + print(f" ✗ {msg}") + else: + print(f" ✓ {file}") + + # Special checks for vite + if metadata.get("use_vite"): + settings_path = os.path.join(project_dir, "config/settings/base.py") + exists, msg = verify_file(settings_path, "django_vite") + if not exists: + all_passed = False + errors.append("django_vite not in settings") + print(f" ✗ django_vite not in settings") + else: + print(f" ✓ django_vite in settings") + + req_path = os.path.join(project_dir, "requirements.txt") + exists, msg = verify_file(req_path, "django-vite") + if not exists: + all_passed = False + errors.append("django-vite not in requirements") + print(f" ✗ django-vite not in requirements") + else: + print(f" ✓ django-vite in requirements") + + # Special checks for docker + if metadata.get("use_docker"): + dockerfile_path = os.path.join(project_dir, "Dockerfile") + db_type = metadata.get("database_type", "postgresql") + if db_type == "mysql": + exists, msg = verify_file(dockerfile_path, "default-libmysqlclient-dev") + if not exists: + all_passed = False + print(f" ✗ MySQL client not in Dockerfile") + else: + print(f" ✓ MySQL client in Dockerfile") + else: + exists, msg = verify_file(dockerfile_path, "libpq-dev") + if not exists: + all_passed = False + print(f" ✗ PostgreSQL client not in Dockerfile") + else: + print(f" ✓ PostgreSQL client in Dockerfile") + + if all_passed: + results.append((name, True, "All checks passed")) + print(f" ✓ ALL CHECKS PASSED") + else: + results.append((name, False, "; ".join(errors))) + print(f" ✗ SOME CHECKS FAILED") + + # Summary + print("\n" + "=" * 70) + print(" SUMMARY") + print("=" * 70) + + passed = sum(1 for _, s, _ in results if s) + total = len(results) + + for name, success, msg in results: + status = "✓ PASS" if success else "✗ FAIL" + print(f" {status}: {name} - {msg}") + + print(f"\n Total: {passed}/{total} passed") + + if passed == total: + print("\n 🎉 ALL TESTS PASSED!") + else: + print("\n ⚠️ SOME TESTS FAILED!") + + +if __name__ == "__main__": + run_tests() \ No newline at end of file diff --git a/examples/generate_projects.py b/examples/generate_projects.py new file mode 100644 index 0000000..fbabcc2 --- /dev/null +++ b/examples/generate_projects.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 +""" +Generate real test projects to verify djinit works correctly. +Run from djinit project root: .venv/bin/python examples/generate_projects.py +""" + +import os +import sys +import tempfile +import shutil +from pathlib import Path + +# Add src to path +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) + +from djinit.creators.setup import SetupCreator + + +def create_test_project(name, structure, metadata, use_github=False, use_gitlab=False): + """Create a test project.""" + # Create temp directory + test_dir = os.path.join("/tmp/djinit_tests", name) + os.makedirs(test_dir, exist_ok=True) + original_cwd = os.getcwd() + + try: + os.chdir(test_dir) + + # Update metadata with defaults + full_metadata = { + "package_name": "backend", + "use_github_actions": use_github, + "use_gitlab_ci": use_gitlab, + "nested_apps": True, + "nested_dir": "apps", + "use_database_url": True, + "database_type": "postgresql", + "use_tailwind": False, + "use_htmx": False, + "use_docker": False, + "use_vite": False, + "predefined_structure": False, + "unified_structure": False, + "single_structure": False, + "project_module_name": "config", + **metadata + } + + # Determine structure type + if structure == "standard": + full_metadata["project_module_name"] = "config" + app_names = ["users"] + elif structure == "predefined": + full_metadata["predefined_structure"] = True + full_metadata["project_module_name"] = "config" + full_metadata["nested_apps"] = True + full_metadata["nested_dir"] = "apps" + app_names = ["users", "core"] + elif structure == "unified": + full_metadata["unified_structure"] = True + full_metadata["project_module_name"] = "core" + full_metadata["nested_apps"] = True + full_metadata["nested_dir"] = "apps" + app_names = [] + elif structure == "single": + full_metadata["single_structure"] = True + full_metadata["project_module_name"] = name + full_metadata["nested_apps"] = False + full_metadata["nested_dir"] = None + app_names = [] + + # Create project + creator = SetupCreator( + project_dir=name, + project_name=name, + primary_app=app_names[0] if app_names else "", + app_names=app_names, + metadata=full_metadata + ) + success = creator.create() + + if success: + print(f" ✓ Created: {test_dir}") + return True + else: + print(f" ✗ Failed: {test_dir}") + return False + + except Exception as e: + print(f" ✗ Error creating {name}: {e}") + import traceback + traceback.print_exc() + return False + finally: + os.chdir(original_cwd) + + +def list_project_files(project_dir): + """List key files in the project.""" + print("\n Key files:") + key_files = [ + "requirements.txt", "Dockerfile", "docker-compose.yml", + "package.json", "vite.config.js", "settings/base.py", + "manage.py" + ] + + for root, dirs, files in os.walk(project_dir): + # Skip hidden and common dirs + dirs[:] = [d for d in dirs if not d.startswith('.') and d not in ('__pycache__', 'node_modules')] + + for f in files: + if f in key_files: + rel_path = os.path.relpath(os.path.join(root, f), project_dir) + print(f" - {rel_path}") + + +def main(): + print("=" * 70) + print(" DJINIT - GENERATE REAL TEST PROJECTS") + print("=" * 70) + + # Create test directory + os.makedirs("/tmp/djinit_tests", exist_ok=True) + + # Define test projects + test_projects = [ + # Structure: (name, structure, metadata) + ("test_standard_basic", "standard", {}), + ("test_standard_docker", "standard", {"use_docker": True}), + ("test_standard_vite", "standard", {"use_vite": True}), + ("test_standard_all", "standard", {"use_docker": True, "use_vite": True, "use_tailwind": True, "use_htmx": True}), + + ("test_predefined_basic", "predefined", {}), + ("test_predefined_docker", "predefined", {"use_docker": True}), + + ("test_unified_basic", "unified", {}), + ("test_unified_all", "unified", {"use_docker": True, "use_vite": True, "use_tailwind": True}), + + ("test_single_basic", "single", {}), + ("test_single_docker", "single", {"use_docker": True}), + ] + + results = [] + + for name, structure, metadata in test_projects: + print(f"\n{'─' * 70}") + print(f" Creating: {name}") + print(f" Structure: {structure}") + print(f" Features: {list(metadata.keys()) if metadata else ['basic']}") + + success = create_test_project(name, structure, metadata) + results.append((name, success)) + + if success: + list_project_files(f"/tmp/djinit_tests/{name}") + + # Summary + print("\n" + "=" * 70) + print(" SUMMARY") + print("=" * 70) + + passed = sum(1 for _, s in results if s) + total = len(results) + + for name, success in results: + status = "✓ PASS" if success else "✗ FAIL" + print(f" {status}: {name}") + + print(f"\n Total: {passed}/{total} passed") + + if passed == total: + print("\n 🎉 All tests passed!") + else: + print("\n ⚠️ Some tests failed!") + + # Show created directories + print("\n" + "=" * 70) + print(" CREATED PROJECTS") + print("=" * 70) + for name, _ in results: + print(f" /tmp/djinit_tests/{name}") + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/examples/test_all_structures.py b/examples/test_all_structures.py new file mode 100644 index 0000000..8685ff8 --- /dev/null +++ b/examples/test_all_structures.py @@ -0,0 +1,322 @@ +#!/usr/bin/env python3 +""" +Test script to show hello world examples for all project structures and cases. +Run from the djinit project root: PYTHONPATH=src python3 examples/test_all_structures.py +""" + +import os +import sys + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) + +from djinit.templater import template_engine + + +def print_section(title): + print("\n" + "=" * 70) + print(f" {title}") + print("=" * 70) + + +def print_subsection(title): + print(f"\n{'─' * 70}") + print(f" {title}") + print(f"{'─' * 70}") + + +# Define all test cases +CASES = [ + ("Basic (no optional features)", { + "use_docker": False, "use_vite": False, "use_tailwind": False, + "use_htmx": False, "database_type": "postgresql", "use_database_url": True + }), + ("Docker only", { + "use_docker": True, "use_vite": False, "use_tailwind": False, + "use_htmx": False, "database_type": "postgresql", "use_database_url": True + }), + ("Vite/React only", { + "use_docker": False, "use_vite": True, "use_tailwind": False, + "use_htmx": False, "database_type": "postgresql", "use_database_url": True + }), + ("Docker + Vite", { + "use_docker": True, "use_vite": True, "use_tailwind": False, + "use_htmx": False, "database_type": "postgresql", "use_database_url": True + }), + ("Tailwind only", { + "use_docker": False, "use_vite": False, "use_tailwind": True, + "use_htmx": False, "database_type": "postgresql", "use_database_url": True + }), + ("HTMX only", { + "use_docker": False, "use_vite": False, "use_tailwind": False, + "use_htmx": True, "database_type": "postgresql", "use_database_url": True + }), + ("Tailwind + HTMX", { + "use_docker": False, "use_vite": False, "use_tailwind": True, + "use_htmx": True, "database_type": "postgresql", "use_database_url": True + }), + ("All: Docker + Vite + Tailwind + HTMX + PostgreSQL", { + "use_docker": True, "use_vite": True, "use_tailwind": True, + "use_htmx": True, "database_type": "postgresql", "use_database_url": True + }), + ("All: Docker + Vite + Tailwind + HTMX + MySQL", { + "use_docker": True, "use_vite": True, "use_tailwind": True, + "use_htmx": True, "database_type": "mysql", "use_database_url": True + }), +] + +STRUCTURES = [ + ("standard", "config", "Standard Structure (default Django layout)"), + ("predefined", "config", "Predefined Structure (apps/users, apps/core, api/)"), + ("unified", "core", "Unified Structure (core/, apps/core, apps/api)"), + ("single", "myproject", "Single Folder Layout (everything in one folder)"), +] + + +def show_file_tree(struct_type, case_name, metadata): + """Show expected file tree for a structure + case combination.""" + + module_name = { + "standard": "config", + "predefined": "config", + "unified": "core", + "single": "myproject" + }[struct_type] + + features = [] + if metadata.get("use_docker"): features.append("Docker") + if metadata.get("use_vite"): features.append("Vite") + if metadata.get("use_tailwind"): features.append("Tailwind") + if metadata.get("use_htmx"): features.append("HTMX") + features.append(metadata.get("database_type", "postgresql").upper()) + + print(f" Features: {', '.join(features)}") + print(f" Project: myproject/") + print(f" Module: {module_name}/") + + indent = " " + + # Always present + print(f"{indent}├── .env.sample") + print(f"{indent}├── .gitignore") + print(f"{indent}├── requirements.txt") + print(f"{indent}├── pyproject.toml") + print(f"{indent}├── Procfile") + print(f"{indent}├── justfile") + print(f"{indent}├── runtime.txt") + + if metadata.get("use_docker"): + print(f"{indent}├── Dockerfile") + print(f"{indent}├── docker-compose.yml") + print(f"{indent}├── .dockerignore") + + if struct_type == "standard": + print(f"{indent}├── config/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── settings/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── base.py") + print(f"{indent}│ │ ├── development.py") + print(f"{indent}│ │ └── production.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ ├── wsgi.py") + print(f"{indent}│ └── asgi.py") + print(f"{indent}├── users/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── models.py") + print(f"{indent}│ ├── views.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ └── apps.py") + print(f"{indent}└── manage.py") + + elif struct_type == "predefined": + print(f"{indent}├── config/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── settings/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── base.py") + print(f"{indent}│ │ ├── development.py") + print(f"{indent}│ │ └── production.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ ├── wsgi.py") + print(f"{indent}│ └── asgi.py") + print(f"{indent}├── apps/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── core/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── utils/") + print(f"{indent}│ │ ├── mixins/") + print(f"{indent}│ │ └── middleware/") + print(f"{indent}│ └── users/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ └── apps.py") + print(f"{indent}├── api/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ └── v1/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ └── urls.py") + print(f"{indent}└── manage.py") + + elif struct_type == "unified": + print(f"{indent}├── core/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── settings/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── base.py") + print(f"{indent}│ │ ├── development.py") + print(f"{indent}│ │ └── production.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ ├── wsgi.py") + print(f"{indent}│ └── asgi.py") + print(f"{indent}├── apps/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── apps.py") + print(f"{indent}│ ├── api/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── urls.py") + print(f"{indent}│ │ └── v1/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ └── urls.py") + print(f"{indent}│ ├── models/") + print(f"{indent}│ ├── views/") + print(f"{indent}│ ├── serializers/") + print(f"{indent}│ ├── tests/") + print(f"{indent}│ └── urls/") + print(f"{indent}└── manage.py") + + else: # single + print(f"{indent}├── myproject/") + print(f"{indent}│ ├── __init__.py") + print(f"{indent}│ ├── settings/") + print(f"{indent}│ │ ├── __init__.py") + print(f"{indent}│ │ ├── base.py") + print(f"{indent}│ │ ├── development.py") + print(f"{indent}│ │ └── production.py") + print(f"{indent}│ ├── urls.py") + print(f"{indent}│ ├── wsgi.py") + print(f"{indent}│ ├── asgi.py") + print(f"{indent}│ ├── api/") + print(f"{indent}│ ├── models/") + print(f"{indent}│ ├── admin/") + print(f"{indent}│ └── tests/") + print(f"{indent}└── manage.py") + + if metadata.get("use_vite"): + print(f"{indent}├── frontend/") + print(f"{indent}│ ├── index.html") + print(f"{indent}│ ├── vite.config.js") + print(f"{indent}│ ├── package.json") + print(f"{indent}│ └── src/") + print(f"{indent}│ ├── main.jsx") + print(f"{indent}│ ├── App.jsx") + print(f"{indent}│ └── index.css") + print(f"{indent}└── static/") + + if metadata.get("use_tailwind"): + print(f"{indent}├── static/") + print(f"{indent}│ └── css/") + print(f"{indent}└── templates/") + + +def show_template_examples(): + """Show actual template content for key files.""" + + print_section("TEMPLATE CONTENT EXAMPLES") + + # 1. Requirements.txt examples + print_subsection("1. requirements.txt - Basic (No optional features)") + ctx = {"use_vite": False, "use_tailwind": False, "use_htmx": False, + "database_type": "postgresql", "use_database_url": True} + print(template_engine.render_template("project/requirements-tpl", ctx)) + + print_subsection("2. requirements.txt - All Features (PostgreSQL)") + ctx = {"use_vite": True, "use_tailwind": True, "use_htmx": True, + "database_type": "postgresql", "use_database_url": True} + print(template_engine.render_template("project/requirements-tpl", ctx)) + + print_subsection("3. requirements.txt - All Features (MySQL)") + ctx = {"use_vite": True, "use_tailwind": True, "use_htmx": True, + "database_type": "mysql", "use_database_url": True} + print(template_engine.render_template("project/requirements-tpl", ctx)) + + # 4. Settings examples + print_subsection("4. settings/base.py - With Vite enabled") + ctx = {"project_name": "config", "app_names": ["users"], + "use_vite": True, "use_tailwind": False, "use_htmx": False, + "use_database_url": True, "database_type": "postgresql"} + result = template_engine.render_template("config/settings/base.py-tpl", ctx) + for line in result.split('\n'): + if 'django_vite' in line or 'DJANGO_VITE' in line: + print(line) + + print_subsection("5. settings/base.py - With Tailwind enabled") + ctx = {"project_name": "config", "app_names": ["users"], + "use_vite": False, "use_tailwind": True, "use_htmx": False, + "use_database_url": True, "database_type": "postgresql"} + result = template_engine.render_template("config/settings/base.py-tpl", ctx) + for line in result.split('\n'): + if 'tailwind' in line.lower() or 'daisyui' in line.lower(): + print(line) + + # 6. Dockerfile example + print_subsection("6. Dockerfile (PostgreSQL)") + ctx = {"project_name": "myproject", "module_name": "config", "database_type": "postgresql"} + print(template_engine.render_template("project/Dockerfile-tpl", ctx)) + + print_subsection("7. Dockerfile (MySQL)") + ctx = {"project_name": "myproject", "module_name": "config", "database_type": "mysql"} + print(template_engine.render_template("project/Dockerfile-tpl", ctx)) + + # 8. docker-compose.yml examples + print_subsection("8. docker-compose.yml (PostgreSQL)") + ctx = {"project_name": "myproject", "database_type": "postgresql", "use_database_url": True} + print(template_engine.render_template("project/docker-compose.yml-tpl", ctx)) + + # 9. vite.config.js + print_subsection("9. vite.config.js") + ctx = {"project_name": "myproject", "module_name": "config"} + print(template_engine.render_template("project/vite.config.js-tpl", ctx)) + + # 10. package.json + print_subsection("10. package.json") + print(template_engine.render_template("project/package.json-tpl", ctx)) + + # 11. Frontend examples + print_subsection("11. frontend/index.html") + print(template_engine.render_template("project/frontend/index.html-tpl", ctx)) + + print_subsection("12. frontend/src/App.jsx") + print(template_engine.render_template("project/frontend/src/App.jsx-tpl", ctx)) + + +def main(): + print_section("DJINIT - ALL STRUCTURES & CASES") + + # Show all structure + case combinations + for struct_type, module_name, struct_desc in STRUCTURES: + print_section(struct_desc) + + for case_name, metadata in CASES: + print_subsection(case_name) + show_file_tree(struct_type, case_name, metadata) + + # Show template content examples + show_template_examples() + + print("\n" + "=" * 70) + print(" ALL STRUCTURES & CASES TESTED SUCCESSFULLY!") + print("=" * 70) + print("\nSummary:") + print(f" • {len(STRUCTURES)} project structures") + print(f" • {len(CASES)} feature combinations") + print(f" • Total: {len(STRUCTURES) * len(CASES)} unique configurations") + print("\nEach combination generates:") + print(" - Django project files based on structure type") + print(" - Optional: Docker files (Dockerfile, docker-compose.yml)") + print(" - Optional: Vite/React frontend (vite.config.js, package.json, etc.)") + print(" - Optional: Tailwind CSS configuration") + print(" - Optional: HTMX integration") + + +if __name__ == "__main__": + main() \ No newline at end of file