import os import shutil import subprocess from pathlib import Path def build_and_harvest(): src_dir = Path("mxpic") release_dir = Path("mxpic_release/mxpic") print("๐Ÿง  Generating IDE Stub Files (.pyi)...") # 1. Run stubgen on the mxpic directory # -o . outputs the files directly next to their .py counterparts try: subprocess.run(["stubgen", "./mxpic", "-o", "."], check=True) print("โœ… Stubs generated successfully.") except subprocess.CalledProcessError: print("โŒ Failed to generate stubs. Is mypy installed?") return print("๐Ÿš€ Starting Wheel Build Process...") print("๐Ÿงน Cleaning old builds...") if release_dir.parent.exists(): shutil.rmtree(release_dir.parent) print("๐Ÿ”จ Compiling C-Extensions with Cython...") # Run the setup.py build command in-place subprocess.run(["python", "setup.py", "build_ext", "--inplace"], check=True) print("๐Ÿ“ฆ Harvesting compiled files into release package...") release_dir.mkdir(parents=True, exist_ok=True) # Walk through the original source directory for root, dirs, files in os.walk(src_dir): # Skip docs folder if 'docs' in dirs: dirs.remove('docs') current_root = Path(root) rel_path = current_root.relative_to(src_dir) target_dir = release_dir / rel_path # Ensure the mirrored directory exists target_dir.mkdir(parents=True, exist_ok=True) for file in files: file_path = current_root / file # Copy compiled binaries (.so for Linux/WSL, .pyd for Windows) if file.endswith((".so", ".pyd", ".pyi")): shutil.move(file_path, target_dir / file) # Copy __init__.py files so Python recognizes the packages # elif file == "__init__.py": # shutil.copy2(file_path, target_dir / file) # (Optional) Copy non-code assets like config files or templates elif file.endswith((".csv", ".json", ".yaml", ".yml")): shutil.copy2(file_path, target_dir / file) print("โœจ Cleanup: Removing intermediate .c files from source...") for c_file in src_dir.rglob("*.c"): c_file.unlink() print(f"\n๐Ÿš€ Success! Your secure package is ready in: {release_dir.parent.resolve()}") if __name__ == "__main__": build_and_harvest()