-
Notifications
You must be signed in to change notification settings - Fork 345
/
pack.py
174 lines (155 loc) · 6.85 KB
/
pack.py
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import os, sys, shutil
sys.path.insert(1,"./COMTool/")
from COMTool import version, i18n
import zipfile
import shutil
import re
if sys.version_info < (3, 7):
print("only support python >= 3.7, but now is {}".format(sys.version_info))
sys.exit(1)
# when execute packed executable program(./dist/comtool) warning missing package, add here to resolve
hidden_imports = [
# "pyqtgraph.graphicsItems.PlotItem.plotConfigTemplate_pyqt5", # fixed in latest pyinstaller-hooks-contrib
# "pyqtgraph.graphicsItems.ViewBox.axisCtrlTemplate_pyqt5",
# "pyqtgraph.imageview.ImageViewTemplate_pyqt5",
"babel.numbers"
]
linux_out = "comtool_ubuntu_v{}.tar.xz".format(version.__version__)
macos_out = "comtool_macos_v{}.dmg".format(version.__version__)
windows_out = "comtool_windows_v{}.7z".format(version.__version__)
def zip(out, path):
out = os.path.abspath(out)
cwd = os.getcwd()
os.chdir(os.path.dirname(path))
with zipfile.ZipFile(out,'w', zipfile.ZIP_DEFLATED) as target:
for i in os.walk(os.path.basename(path)):
for n in i[2]:
target.write(os.path.join(i[0],n))
os.chdir(cwd)
def zip_7z(out, path):
out = os.path.abspath(out)
cwd = os.getcwd()
os.chdir(os.path.dirname(path))
ret = os.system(f"7z a -t7z -mx=9 {out} {os.path.basename(path)}")
if ret != 0:
raise Exception("7z compress failed")
os.chdir(cwd)
def upadte_spec_bundle(spec_path, items = {}, plist_items={}):
with open(spec_path) as f:
spec = f.read()
def BUNDLE(*args, **kw_args):
kw_args.update(items)
if "info_plist" in kw_args:
kw_args["info_plist"].update(plist_items)
else:
kw_args["info_plist"] = plist_items
bundle_str_args = ""
for arg in args:
if type(arg) == str and arg != "exe" and arg != "coll":
bundle_str_args += f'"{arg}", \n'
else:
bundle_str_args += f'{arg}, \n'
for k, v in kw_args.items():
if type(v) == str:
bundle_str_args += f'{k}="{v}",\n'
else:
bundle_str_args += f'{k}={v},\n'
return bundle_str_args
match = re.findall(r'BUNDLE\((.*?)\)', spec, flags=re.MULTILINE|re.DOTALL)
if len(match) <= 0:
raise Exception("no BUNDLE found in spec, please check code")
code =f'app = BUNDLE({match[0]})'
vars = {
"BUNDLE": BUNDLE,
"exe": "exe",
"coll": "coll"
}
exec(code, vars)
final_str = vars["app"]
def re_replace(c):
print(c[0])
return f'BUNDLE({final_str})'
final_str = re.sub(r'BUNDLE\((.*)\)', re_replace, spec, flags=re.I|re.MULTILINE|re.DOTALL)
print(final_str)
with open(spec_path, "w") as f:
f.write(spec)
def pack():
# update translate
i18n.main("finish")
if os.path.exists("COMTool/__pycache__"):
shutil.rmtree("COMTool/__pycache__")
hidden_imports_str = ""
for item in hidden_imports:
hidden_imports_str += f'--hidden-import {item} '
if sys.platform.startswith("win32"):
cmd = f'pyinstaller {hidden_imports_str} -p "COMTool" --add-data="COMTool/assets;assets" --add-data="COMTool/locales;locales" --add-data="COMTool/protocols;protocols" --add-data="README.MD;./" --add-data="README_ZH.MD;./" -i="COMTool/assets/logo.ico" -w COMTool/Main.py -n comtool'
elif sys.platform.startswith("darwin"):
# macos not case insensitive, so can not contain comtool file and COMTool dir, so we copy to binary root dir
cmd = f'pyi-makespec {hidden_imports_str} -p "COMTool" --add-data="COMTool/assets:assets" --add-data="COMTool/locales:locales" --add-data="COMTool/protocols:protocols" --add-data="README_ZH.MD:./" --add-data="README.MD:./" -i="COMTool/assets/logo.icns" -w COMTool/Main.py -n comtool'
ret = os.system(cmd)
if ret != 0:
raise Exception("pack failed")
print("-- update bundle for macos build")
upadte_spec_bundle("comtool.spec",
items = {
"version": version.__version__
},
plist_items = {
"LSMultipleInstancesProhibited": False,
"CFBundleShortVersionString": version.__version__
}) # enable multi instance support
print("-- update bundle for macos build complete")
cmd = 'pyinstaller comtool.spec'
else:
cmd = f'pyinstaller {hidden_imports_str} -p "COMTool" --add-data="COMTool/assets:assets" --add-data="COMTool/locales:locales" --add-data="COMTool/protocols:protocols" --add-data="README.MD:./" --add-data="README_ZH.MD:./" -i="COMTool/assets/logo.ico" -w COMTool/Main.py -n comtool'
print("-- execute:", cmd)
ret = os.system(cmd)
if ret != 0:
raise Exception("pack failed")
if sys.platform.startswith("darwin"):
if os.path.exists("./dist/comtool 0.0.0.dmg"):
os.remove("./dist/comtool 0.0.0.dmg")
ret = os.system('npm install --global create-dmg')
if ret != 0:
raise Exception("pack failed")
ret = os.system('create-dmg ./dist/comtool.app ./dist')
# not check ret, for create-dmg no certifacate will cause fail too, if generate fail
# the next copy command will fail
print("files in dist dir:", os.listdir("dist"))
shutil.copyfile("./dist/comtool 0.0.0.dmg", macos_out)
elif sys.platform.startswith("win32"):
# zip(windows_out, "dist/comtool")
zip_7z(windows_out, "dist/comtool")
else:
cmd = "cd dist && tar -Jcf {} comtool/ && mv {} ../ && cd ..".format(linux_out, linux_out)
ret = os.system(cmd)
if ret != 0:
raise Exception("pack failed")
if __name__ == "__main__":
if len(sys.argv) > 1:
os_name = sys.argv[1]
if os_name.startswith("ubuntu"):
if os_name != "ubuntu-latest":
linux_out_new = linux_out.replace("ubuntu", os_name.replace("-", "_"))
os.rename(linux_out, linux_out_new)
linux_out = linux_out_new
print(linux_out)
elif os_name.startswith("windows"):
if os_name != "windows-latest":
windows_out_new = windows_out.replace("windows", os_name.replace("-", "_"))
os.rename(windows_out, windows_out_new)
windows_out = windows_out_new
print(windows_out)
elif os_name.startswith("macos"):
macos_version = os_name.split("-")[1]
if macos_version.isdigit() and int(macos_version) < 14:
macos_out_new = macos_out.replace("macos", "macos_x64")
else: # github actions macos-latest is using M1 chip
macos_out_new = macos_out.replace("macos", "macos_arm64")
os.rename(macos_out, macos_out_new)
macos_out = macos_out_new
print(macos_out)
else:
sys.exit(1)
else:
pack()