Skip to content

Commit dc4e94d

Browse files
committed
Added unload_all function and --unload option to pycompiler_ark
1 parent 200cdfd commit dc4e94d

3 files changed

Lines changed: 94 additions & 3 deletions

File tree

Core/engines_loader/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
from . import registry as registry # re-export registry module
2424
from .base import CompilerEngine # re-export base type
25+
from .registry import unload_all # re-export unload_all function
2526
from .validator import (
2627
EngineCompatibilityCheckResult,
2728
check_engine_compatibility,
@@ -89,4 +90,4 @@ def _auto_discover() -> None:
8990
except Exception:
9091
pass
9192

92-
__all__ = ["CompilerEngine", "registry"]
93+
__all__ = ["CompilerEngine", "registry", "unload_all"]

Core/engines_loader/registry.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,40 @@ def unregister(eid: str) -> None:
121121
pass
122122

123123

124+
def unload_all() -> dict[str, Any]:
125+
"""Unload all registered engines and clean up all registry data.
126+
127+
Returns:
128+
dict with status and list of unloaded engine IDs
129+
"""
130+
unloaded = []
131+
try:
132+
# Collect all engine IDs before clearing
133+
unloaded = list(_ORDER)
134+
unloaded.extend(k for k in _REGISTRY.keys() if k not in unloaded)
135+
136+
# Clear all registry data
137+
_REGISTRY.clear()
138+
_ORDER.clear()
139+
_TAB_INDEX.clear()
140+
141+
# Clear instances
142+
_INSTANCES.clear()
143+
144+
except Exception as e:
145+
return {
146+
"status": "error",
147+
"message": str(e),
148+
"unloaded": unloaded
149+
}
150+
151+
return {
152+
"status": "success",
153+
"message": f"Unloaded {len(unloaded)} engine(s)",
154+
"unloaded": unloaded
155+
}
156+
157+
124158
def engine_register(engine_cls: type[CompilerEngine]):
125159
"""Register an engine class. Enforces a non-empty unique id.
126160

pycompiler_ark.py

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python3
22
# SPDX-License-Identifier: Apache-2.0
33
# Copyright 2026 Ague Samuel Amen
44
#
@@ -32,6 +32,7 @@
3232
python -m pycompiler_ark bcasl # Launch BCASL standalone
3333
python -m pycompiler_ark bcasl /path/to/ws # Launch BCASL with workspace
3434
python -m pycompiler_ark --completion bash # Generate bash completion
35+
python -m pycompiler_ark unload # Unload all engines
3536
"""
3637

3738
import multiprocessing
@@ -50,6 +51,7 @@
5051

5152
from main import main
5253
from Core import __version__ as APP_VERSION
54+
from Core.engines_loader import unload_all
5355

5456
# Configure logging
5557
logging.basicConfig(
@@ -330,8 +332,14 @@ def print_workspace_info():
330332
type=click.Choice(["bash", "zsh", "fish"]),
331333
help="Generate shell completion",
332334
)
335+
@click.option(
336+
"--unload",
337+
"unload_engines_flag",
338+
is_flag=True,
339+
help="Unload all registered engines before launching the application",
340+
)
333341
@click.pass_context
334-
def cli(ctx, version, help_all, info, completion):
342+
def cli(ctx, version, help_all, info, completion, unload_engines_flag):
335343
"""PyCompiler ARK++ — Cross-platform Python compiler with BCASL integration.
336344
337345
Launch the main application by default, or use subcommands for specific modes.
@@ -356,6 +364,17 @@ def cli(ctx, version, help_all, info, completion):
356364
click.echo("# Add this to your shell configuration file")
357365
ctx.exit(0)
358366

367+
if unload_engines_flag:
368+
result = unload_all()
369+
if result["status"] == "success":
370+
click.echo(f"✅ {result['message']}")
371+
if result["unloaded"]:
372+
click.echo(" Unloaded engines:")
373+
for eid in result["unloaded"]:
374+
click.echo(f" • {eid}")
375+
else:
376+
click.echo(f"❌ Error: {result['message']}", err=True)
377+
359378
if help_all:
360379
click.echo(ctx.get_help())
361380
click.echo("\n📚 Available Commands:")
@@ -457,6 +476,20 @@ def discover():
457476
else:
458477
click.echo("No workspaces discovered")
459478

479+
@cli.command(context_settings=dict(help_option_names=["-h", "--help"]), name="unload")
480+
def unload_engines_cmd():
481+
"""Unload all registered engines."""
482+
result = unload_all()
483+
if result["status"] == "success":
484+
click.echo(f"✅ {result['message']}")
485+
if result["unloaded"]:
486+
click.echo(" Unloaded engines:")
487+
for eid in result["unloaded"]:
488+
click.echo(f" • {eid}")
489+
else:
490+
click.echo(f"❌ Error: {result['message']}", err=True)
491+
sys.exit(0 if result["status"] == "success" else 1)
492+
460493

461494
if __name__ == "__main__":
462495
if click:
@@ -484,6 +517,17 @@ def discover():
484517
print_system_info()
485518
print_workspace_info()
486519
sys.exit(0)
520+
elif sys.argv[1] == "--unload":
521+
from Core.engines_loader import unload_all
522+
result = unload_all()
523+
if result["status"] == "success":
524+
print(f"✅ {result['message']}")
525+
if result["unloaded"]:
526+
print(" Unloaded engines:")
527+
for eid in result["unloaded"]:
528+
print(f" • {eid}")
529+
else:
530+
print(f"❌ Error: {result['message']}")
487531
elif sys.argv[1] == "bcasl":
488532
workspace_dir = sys.argv[2] if len(sys.argv) > 2 else None
489533
sys.exit(launch_bcasl_standalone(workspace_dir))
@@ -496,6 +540,18 @@ def discover():
496540
else:
497541
print("No workspaces discovered")
498542
sys.exit(0)
543+
elif sys.argv[1] == "unload":
544+
from Core.engines_loader import unload_all
545+
result = unload_all()
546+
if result["status"] == "success":
547+
print(f"✅ {result['message']}")
548+
if result["unloaded"]:
549+
print(" Unloaded engines:")
550+
for eid in result["unloaded"]:
551+
print(f" • {eid}")
552+
else:
553+
print(f"❌ Error: {result['message']}")
554+
sys.exit(0 if result["status"] == "success" else 1)
499555
else:
500556
print(f"Unknown command: {sys.argv[1]}")
501557
print(__doc__)

0 commit comments

Comments
 (0)