Run architectural mutations defined in a simulation scenario JSON file and view the resulting architecture metrics.
(
config_path: str = typer.Argument(..., help="Path to the simulation JSON configuration file."),
path: Optional[str] = typer.Argument(None, help="Path to the directory to simulate. Defaults to the current directory."),
context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"),
)
| 119 | |
| 120 | @simulate_app.command("run") |
| 121 | def simulate_run( |
| 122 | config_path: str = typer.Argument(..., help="Path to the simulation JSON configuration file."), |
| 123 | path: Optional[str] = typer.Argument(None, help="Path to the directory to simulate. Defaults to the current directory."), |
| 124 | context: Optional[str] = typer.Option(None, "--context", "-c", help="Specific context to use"), |
| 125 | ): |
| 126 | """ |
| 127 | Run architectural mutations defined in a simulation scenario JSON file and view the resulting architecture metrics. |
| 128 | """ |
| 129 | load_cgc_credentials(context) |
| 130 | repo_path = get_repo_path(path) |
| 131 | |
| 132 | cfg_file = Path(config_path) |
| 133 | if not cfg_file.exists(): |
| 134 | console.print(f"[bold red]Scenario configuration file not found:[/bold red] {config_path}") |
| 135 | raise typer.Exit(code=1) |
| 136 | |
| 137 | try: |
| 138 | with open(cfg_file, "r") as f: |
| 139 | scenario = json.load(f) |
| 140 | except Exception as e: |
| 141 | console.print(f"[bold red]Failed to parse scenario JSON file:[/bold red] {e}") |
| 142 | raise typer.Exit(code=1) |
| 143 | |
| 144 | services = _initialize_services(context) |
| 145 | db_manager = services[0] |
| 146 | |
| 147 | try: |
| 148 | twin = CodeGraphTwin(repo_path).load_from_db(db_manager) |
| 149 | |
| 150 | # Apply steps |
| 151 | steps = scenario.get("steps", []) |
| 152 | for step in steps: |
| 153 | stype = step.get("type") |
| 154 | if stype == "decompose": |
| 155 | twin.decompose_service(step.get("mapping", {})) |
| 156 | elif stype == "remove_dependency": |
| 157 | twin.remove_dependency(step.get("source"), step.get("target"), step.get("rel_type")) |
| 158 | elif stype == "add_dependency": |
| 159 | twin.add_dependency(step.get("source"), step.get("target"), step.get("rel_type")) |
| 160 | elif stype == "remove_node": |
| 161 | twin.remove_node(step.get("node_id")) |
| 162 | |
| 163 | summary = twin.get_metrics_summary() |
| 164 | print_metrics(summary, f"Simulated Twin: {scenario.get('name', 'Custom Scenario')}") |
| 165 | except Exception as e: |
| 166 | console.print(f"[bold red]Simulation Error:[/bold red] {e}") |
| 167 | finally: |
| 168 | db_manager.close_driver() |
| 169 | |
| 170 | |
| 171 | @simulate_app.command("compare") |
nothing calls this directly
no test coverage detected