Files
2026-07-10 23:12:15 +07:00

101 lines
4.0 KiB
Python

import os
import sys
import subprocess
import shutil
def run_command(command, env=None):
"""Helper to run system commands and stream the output to the console"""
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True,
text=True,
env=env
)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
if output:
print(output.strip())
return process.poll()
if __name__ == "__main__":
current_dir = os.path.dirname(os.path.realpath(__file__))
venv_dir = os.path.join(current_dir, "builder_env")
# Calculate the root folder path (my_universal_dropdowns)
# Moving up two levels from: .../my_universal_dropdowns/generator/build.py
root_dir = os.path.abspath(os.path.join(current_dir, ".."))
final_exe_path = os.path.join(root_dir, "Node Builder Assistant.exe")
print("🚀 Starting One-Click Standalone Executable Builder...\n")
# 1. Create Virtual Environment
if not os.path.exists(venv_dir):
print("📦 Step 1: Creating isolated virtual environment...")
if run_command(f'"{sys.executable}" -m venv builder_env') != 0:
print("❌ Failed to create virtual environment.")
sys.exit(1)
else:
print("✨ Virtual environment already exists, skipping creation.")
# Determine paths inside venv based on OS
if os.name == 'nt': # Windows
pip_path = os.path.join(venv_dir, "Scripts", "pip.exe")
pyinstaller_path = os.path.join(venv_dir, "Scripts", "pyinstaller.exe")
else: # Mac/Linux fallback
pip_path = os.path.join(venv_dir, "bin", "pip")
pyinstaller_path = os.path.join(venv_dir, "bin", "pyinstaller")
# 2. Upgrade pip and install requirements
print("\n📥 Step 2: Installing requirements into isolated environment...")
run_command(f'"{pip_path}" install --upgrade pip')
req_file = os.path.join(current_dir, "requirements.txt")
if os.path.exists(req_file):
if run_command(f'"{pip_path}" install -r "{req_file}"') != 0:
print("❌ Failed to install dependencies.")
sys.exit(1)
else:
print("❌ requirements.txt not found! Please create it first.")
sys.exit(1)
# 3. Compile with PyInstaller
print("\n🛠️ Step 3: Compiling hyper-lean executable via PyInstaller...")
build_cmd = f'"{pyinstaller_path}" --clean --noconsole --onefile --add-data "generator.html;." app.py'
if run_command(build_cmd) == 0:
print("\n✅ Compilation successful!")
# 4. Relocate and Rename the Executable
print("\n🚚 Step 4: Moving and renaming executable to root directory...")
compiled_exe = os.path.join(current_dir, "dist", "app.exe")
try:
# Overwrite if it already exists from a previous build
if os.path.exists(final_exe_path):
os.remove(final_exe_path)
shutil.move(compiled_exe, final_exe_path)
print(f"✨ Successfully deployed to: {final_exe_path}")
except Exception as e:
print(f"❌ Failed to move or rename executable: {e}")
# 5. Clean up temporary build clutter
print("\n扫 Step 5: Cleaning up temporary build clutter...")
build_folder = os.path.join(current_dir, "build")
dist_folder = os.path.join(current_dir, "dist")
spec_file = os.path.join(current_dir, "app.spec")
if os.path.exists(build_folder):
shutil.rmtree(build_folder)
if os.path.exists(dist_folder):
shutil.rmtree(dist_folder)
if os.path.exists(spec_file):
os.remove(spec_file)
print("✨ Temporary build cache deleted. Process complete!")
else:
print("\n❌ PyInstaller compilation failed.")