mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-06-10 22:12:49 +00:00
121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Convenience script: runs the codegen pipeline.
|
|
|
|
1. Compile .proto -> binary descriptor set (protoc)
|
|
2. Generate C++ from descriptors (config_codegen.py)
|
|
3. Validate output against original
|
|
|
|
Usage:
|
|
python tools/run_codegen.py # full pipeline
|
|
python tools/run_codegen.py --validate-only # just validate
|
|
"""
|
|
|
|
import argparse
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
PROTO_DIR = ROOT / "src" / "PrintConfigs"
|
|
CODEGEN_OUT = ROOT / "src" / "slic3r" / "GUI" / "generated"
|
|
DESC_FILE = ROOT / "config.desc"
|
|
LAYOUT_YAML = PROTO_DIR / "layout.yaml"
|
|
|
|
|
|
def _ensure_pyyaml():
|
|
"""Install pyyaml if not present — needed for tab layout generation."""
|
|
try:
|
|
import yaml # noqa: F401
|
|
return True
|
|
except ImportError:
|
|
print(" Installing pyyaml (required for tab layout generation)...")
|
|
result = subprocess.run(
|
|
[sys.executable, "-m", "pip", "install", "pyyaml", "-q"],
|
|
capture_output=True)
|
|
if result.returncode != 0:
|
|
print(" ERROR: failed to install pyyaml")
|
|
return False
|
|
return True
|
|
|
|
|
|
def run(cmd, **kwargs):
|
|
print(f" $ {' '.join(str(c) for c in cmd)}")
|
|
result = subprocess.run(cmd, **kwargs)
|
|
if result.returncode != 0:
|
|
print(f" FAILED (exit code {result.returncode})")
|
|
return False
|
|
return True
|
|
|
|
|
|
def _protoc_cmd():
|
|
"""Return the protoc command list. Prefers standalone protoc, falls back to grpc_tools."""
|
|
if shutil.which("protoc"):
|
|
return ["protoc"]
|
|
try:
|
|
import grpc_tools.protoc # noqa: F401
|
|
return [sys.executable, "-m", "grpc_tools.protoc"]
|
|
except ImportError:
|
|
pass
|
|
print(" ERROR: protoc not found. Install protoc or run: pip install grpcio-tools")
|
|
return None
|
|
|
|
|
|
def step_compile():
|
|
print("\n=== Step 1: Compile .proto -> descriptor set ===")
|
|
proto_files = [f for f in PROTO_DIR.glob("*.proto") if not f.name.endswith("_gen.proto") and f.name != "config_metadata.proto"]
|
|
if not proto_files:
|
|
print(" ERROR: No .proto files found")
|
|
return False
|
|
|
|
protoc = _protoc_cmd()
|
|
if protoc is None:
|
|
return False
|
|
|
|
return run(protoc + [
|
|
f"--proto_path={PROTO_DIR}",
|
|
f"--descriptor_set_out={DESC_FILE}",
|
|
"--include_imports",
|
|
] + [str(f) for f in proto_files])
|
|
|
|
|
|
def step_generate():
|
|
print("\n=== Step 2: Generate C++ from descriptors + layout.yaml ===")
|
|
_ensure_pyyaml() # tab layout generation requires pyyaml
|
|
return run([sys.executable, str(ROOT / "tools" / "config_codegen.py"),
|
|
str(DESC_FILE), str(CODEGEN_OUT)])
|
|
|
|
|
|
def step_validate():
|
|
print("\n=== Step 3: Validate ===")
|
|
return run([sys.executable, str(ROOT / "tools" / "validate_codegen.py")])
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description="Run OrcaSlicer config codegen pipeline")
|
|
parser.add_argument("--validate-only", action="store_true",
|
|
help="Only run validation")
|
|
parser.add_argument("--no-validate", action="store_true",
|
|
help="Skip validation step (used by cmake build)")
|
|
args = parser.parse_args()
|
|
|
|
if args.validate_only:
|
|
sys.exit(0 if step_validate() else 1)
|
|
|
|
for name, fn in [("Compile", step_compile), ("Generate", step_generate)]:
|
|
if not fn():
|
|
print(f"\n*** Pipeline FAILED at: {name} ***")
|
|
sys.exit(1)
|
|
|
|
if not args.no_validate:
|
|
if not step_validate():
|
|
print("\n*** Validate FAILED (run with --no-validate to skip) ***")
|
|
sys.exit(1)
|
|
|
|
print("\n=== Pipeline completed successfully ===")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|