bmc_hub/scripts/create_module.py

190 lines
6.7 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
Create Module Script
Generer et nyt BMC Hub modul fra template
"""
import os
import sys
import json
import shutil
from pathlib import Path
def create_module(module_name: str, description: str = ""):
"""
Opret nyt modul baseret _template
Args:
module_name: Navn nyt modul (fx "my_module")
description: Beskrivelse af modul
"""
# Validate module name
if not module_name.replace("_", "").isalnum():
print(f"❌ Ugyldigt modul navn: {module_name}")
print(" Brug kun bogstaver, tal og underscore")
sys.exit(1)
# Paths
project_root = Path(__file__).parent.parent
modules_dir = project_root / "app" / "modules"
template_dir = modules_dir / "_template"
new_module_dir = modules_dir / module_name
# Check if template exists
if not template_dir.exists():
print(f"❌ Template directory ikke fundet: {template_dir}")
sys.exit(1)
# Check if module already exists
if new_module_dir.exists():
print(f"❌ Modul '{module_name}' eksisterer allerede")
sys.exit(1)
print(f"📦 Opretter modul: {module_name}")
print(f" Placering: {new_module_dir}")
# Copy template
try:
shutil.copytree(template_dir, new_module_dir)
print(f"✅ Kopieret template struktur")
except Exception as e:
print(f"❌ Kunne ikke kopiere template: {e}")
sys.exit(1)
# Update module.json
manifest_path = new_module_dir / "module.json"
try:
with open(manifest_path, 'r', encoding='utf-8') as f:
manifest = json.load(f)
manifest["name"] = module_name
manifest["description"] = description or f"BMC Hub module: {module_name}"
manifest["table_prefix"] = f"{module_name}_"
manifest["api_prefix"] = f"/api/v1/{module_name}"
manifest["tags"] = [module_name.replace("_", " ").title()]
with open(manifest_path, 'w', encoding='utf-8') as f:
json.dump(manifest, f, indent=2, ensure_ascii=False)
print(f"✅ Opdateret module.json")
except Exception as e:
print(f"❌ Kunne ikke opdatere module.json: {e}")
sys.exit(1)
# Update README.md
readme_path = new_module_dir / "README.md"
try:
with open(readme_path, 'r', encoding='utf-8') as f:
readme = f.read()
# Replace template references
readme = readme.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module")
readme = readme.replace("template_module", module_name)
readme = readme.replace("my_module", module_name)
readme = readme.replace("mymod_", f"{module_name}_")
readme = readme.replace("template_", f"{module_name}_")
with open(readme_path, 'w', encoding='utf-8') as f:
f.write(readme)
print(f"✅ Opdateret README.md")
except Exception as e:
print(f"⚠️ Kunne ikke opdatere README: {e}")
# Update backend/router.py
router_path = new_module_dir / "backend" / "router.py"
try:
with open(router_path, 'r', encoding='utf-8') as f:
router_code = f.read()
router_code = router_code.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module")
router_code = router_code.replace("template_module", module_name)
router_code = router_code.replace("template_items", f"{module_name}_items")
router_code = router_code.replace("/template/", f"/{module_name}/")
with open(router_path, 'w', encoding='utf-8') as f:
f.write(router_code)
print(f"✅ Opdateret backend/router.py")
except Exception as e:
print(f"⚠️ Kunne ikke opdatere router: {e}")
# Update frontend/views.py
views_path = new_module_dir / "frontend" / "views.py"
try:
with open(views_path, 'r', encoding='utf-8') as f:
views_code = f.read()
views_code = views_code.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module")
views_code = views_code.replace("template_module", module_name)
views_code = views_code.replace("template_items", f"{module_name}_items")
views_code = views_code.replace("/template", f"/{module_name}")
views_code = views_code.replace("_template", module_name)
with open(views_path, 'w', encoding='utf-8') as f:
f.write(views_code)
print(f"✅ Opdateret frontend/views.py")
except Exception as e:
print(f"⚠️ Kunne ikke opdatere views: {e}")
# Update migration SQL
migration_path = new_module_dir / "migrations" / "001_init.sql"
try:
with open(migration_path, 'r', encoding='utf-8') as f:
migration_sql = f.read()
migration_sql = migration_sql.replace("Template Module", f"{module_name.replace('_', ' ').title()} Module")
migration_sql = migration_sql.replace("template_items", f"{module_name}_items")
migration_sql = migration_sql.replace("template_module", module_name)
with open(migration_path, 'w', encoding='utf-8') as f:
f.write(migration_sql)
print(f"✅ Opdateret migrations/001_init.sql")
except Exception as e:
print(f"⚠️ Kunne ikke opdatere migration: {e}")
print()
print("🎉 Modul oprettet successfully!")
print()
print("Næste steps:")
print(f"1. Kør database migration:")
print(f" psql -U bmc_hub -d bmc_hub -f app/modules/{module_name}/migrations/001_init.sql")
print()
print(f"2. Enable modulet:")
print(f" Rediger app/modules/{module_name}/module.json og sæt 'enabled': true")
print()
print(f"3. Restart API:")
print(f" docker-compose restart api")
print()
print(f"4. Test endpoints:")
print(f" http://localhost:8000/api/docs#{module_name.replace('_', '-').title()}")
print(f" http://localhost:8000/{module_name}")
print()
print(f"5. Tilføj modul-specifik konfiguration til .env:")
print(f" MODULES__{module_name.upper()}__READ_ONLY=false")
print(f" MODULES__{module_name.upper()}__DRY_RUN=false")
print()
def main():
"""Main entry point"""
if len(sys.argv) < 2:
print("Usage: python scripts/create_module.py <module_name> [description]")
print()
print("Eksempel:")
print(' python scripts/create_module.py my_feature "My awesome feature"')
sys.exit(1)
module_name = sys.argv[1]
description = sys.argv[2] if len(sys.argv) > 2 else ""
create_module(module_name, description)
if __name__ == "__main__":
main()