-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.py
More file actions
85 lines (75 loc) · 3.08 KB
/
Copy pathbuild.py
File metadata and controls
85 lines (75 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import os
import sys
import subprocess
def run_build():
print("=========================================")
print("🚀 Starting Claude Code Proxy Packaging...")
print("=========================================")
# Define path constants
base_dir = os.path.dirname(os.path.abspath(__file__))
app_entry = os.path.join(base_dir, "app.py")
ui_folder = os.path.join(base_dir, "ui")
if not os.path.exists(app_entry):
print(f"❌ Error: app.py not found at {app_entry}")
sys.exit(1)
# Clean previous build artifacts
print("🧹 Cleaning old build workspace...")
for folder in ["build", "dist"]:
folder_path = os.path.join(base_dir, folder)
if os.path.exists(folder_path):
import shutil
try:
shutil.rmtree(folder_path)
except Exception as e:
print(f"Warning: could not delete {folder_path}: {e}")
# Build PyInstaller parameters
# '--onefile' generates single double-clickable binary
# '--windowed' / '--noconsole' ensures no ugly console window pops up upon start
params = [
app_entry,
"--name=ClaudeCodeProxy",
"--onefile",
"--windowed",
"--clean",
"--collect-data=litellm",
"--collect-data=tiktoken",
"--hidden-import=tiktoken_ext",
"--hidden-import=tiktoken_ext.openai_public",
]
# Include static UI files
# PyInstaller maps path separator on Windows as ';' and on Mac/Linux as ':'
path_sep = os.pathsep
params.append(f"--add-data={ui_folder}{path_sep}ui")
# Optional native application icons integration
assets_dir = os.path.join(base_dir, "assets")
if os.path.exists(assets_dir):
if sys.platform == "darwin":
mac_icon = os.path.join(assets_dir, "icon.icns")
if os.path.exists(mac_icon):
params.append(f"--icon={mac_icon}")
elif sys.platform == "win32":
win_icon = os.path.join(assets_dir, "icon.ico")
if os.path.exists(win_icon):
params.append(f"--icon={win_icon}")
print(f"📦 Compiling workspace with options: {' '.join(params)}")
# Execute PyInstaller compiler
try:
import PyInstaller.__main__
PyInstaller.__main__.run(params)
print("\n=========================================")
print("🎉 Packaging completed successfully!")
print(f"📍 Binary output path: {os.path.join(base_dir, 'dist')}")
print("=========================================")
except ImportError:
print("\n⚠️ PyInstaller is not installed in current environment.")
print("Installing pyinstaller dynamically...")
try:
subprocess.check_call([sys.executable, "-m", "pip", "install", "pyinstaller"])
import PyInstaller.__main__
PyInstaller.__main__.run(params)
print("\n🎉 Compiling succeeded after installing dependencies!")
except Exception as err:
print(f"❌ Dynamic build failed: {err}")
sys.exit(1)
if __name__ == "__main__":
run_build()