Files
AnyImage/tools/build_node.py
nan e7aeeb21d4 Add tools and tests for AnyImage model management and documentation
- Implement sync_models.py for preparing and uploading ONNX artifacts.
- Create build_node.py for building and validating Blender scripts.
- Add docs.py for building and previewing documentation with Mike or MkDocs.
- Introduce model_exports.py for exporting PyTorch models to ONNX format.
- Develop pack.py for packaging the project with dependencies for different platforms.
- Add test_sync_models.py to validate sync_models functionality.
- Add test_tool_commands.py to ensure repository tools have correct command scripts.
- Initialize tools package with __init__.py.
2026-08-31 15:15:33 +08:00

92 lines
2.5 KiB
Python

import argparse
import os
import shutil
import subprocess
import sys
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[1]
BLENDER_SCRIPTS = (
"build.py",
"validate.py",
"validate_mesh_plane.py",
"validate_cutout.py",
)
def project_env_value(name, path=None):
env_path = path or PROJECT_ROOT / ".env"
if not env_path.is_file():
return None
for raw_line in env_path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue
if line.startswith("export "):
line = line.removeprefix("export ").lstrip()
key, separator, value = line.partition("=")
if separator and key.strip() == name:
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'":
value = value[1:-1]
return value or None
return None
def blender_path(explicit=None):
candidate = (
explicit
or os.environ.get("BLENDER_BIN")
or project_env_value("BLENDER_BIN")
or shutil.which("blender")
)
if not candidate:
raise RuntimeError(
"Blender not found: pass --blender, set BLENDER_BIN, add it to .env, "
"or add blender to PATH"
)
path = Path(candidate).expanduser()
if not path.is_file():
raise RuntimeError(f"Blender executable does not exist: {path}")
return path
def run(command):
print("+", subprocess.list2cmdline([str(part) for part in command]), flush=True)
subprocess.run(command, cwd=PROJECT_ROOT, check=True)
def main():
parser = argparse.ArgumentParser(
description="Build and validate O_AnyImage.blend.",
)
parser.add_argument(
"--blender",
help="Blender executable; overrides BLENDER_BIN, .env, and PATH.",
)
parser.add_argument(
"--skip-tests",
action="store_true",
help="Skip the Python test suite.",
)
options = parser.parse_args()
executable = blender_path(options.blender)
for script_name in BLENDER_SCRIPTS:
run(
(
executable,
"--factory-startup",
"--background",
"--python",
PROJECT_ROOT / "tools" / "node_assets" / script_name,
)
)
if not options.skip_tests:
run((sys.executable, "-m", "pytest"))
if __name__ == "__main__":
main()