85 lines
3.5 KiB
Python
85 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
组装 DLPilot 发布包: exe + 附属资产 → 一个文件夹 + 一个 zip(解压即用)
|
||
================================================================
|
||
先把 assets/ 的图案复制进 release/(与 exe 平铺), 使 release/ 本身就是
|
||
可直接使用的完整文件夹; 再原样压成 zip —— 两者内容始终一致。
|
||
|
||
zip 解压后根目录为 DLPilot/, 与 exe 运行目录结构一致:
|
||
DLPilot.exe 主程序(先运行 build_exe.py 打包)
|
||
pattern_slots.json 预置自定义栏位(指向前 3 张 bw 图案)
|
||
bw_*.png 640x360 黑白测试图 ×5(自定义栏位用)
|
||
solid_*.png 800x600 纯色测试图 ×10(RGB 位交换测试用)
|
||
README.md 使用说明
|
||
|
||
用法:
|
||
python package_release.py 版本号自动取最近 git tag(DLPilot-v*)
|
||
python package_release.py 0.1.0 手动指定版本号
|
||
产物: release/DLPilot-v<版本>-win64.zip(zip 不入库, 上传到 Gitea Release)
|
||
"""
|
||
|
||
import os
|
||
import re
|
||
import shutil
|
||
import subprocess
|
||
import sys
|
||
import zipfile
|
||
|
||
SRC = os.path.dirname(os.path.abspath(__file__))
|
||
BASE = os.path.dirname(SRC)
|
||
RELEASE = os.path.join(BASE, 'release')
|
||
ASSETS = os.path.join(BASE, 'assets')
|
||
|
||
PATTERN_GLOBS = ('bw_*.png', 'solid_*.png')
|
||
|
||
|
||
def detect_version():
|
||
"""从最近的 DLPilot-v* tag 推断版本号, 无 tag 则报错提示手动指定"""
|
||
try:
|
||
out = subprocess.check_output(
|
||
['git', 'describe', '--tags', '--abbrev=0', '--match', 'DLPilot-v*'],
|
||
cwd=BASE, stderr=subprocess.DEVNULL)
|
||
return out.decode().strip().removeprefix('DLPilot-v')
|
||
except Exception:
|
||
sys.exit('未能从 git tag 推断版本号, 请手动指定: python package_release.py <版本号>')
|
||
|
||
|
||
def main():
|
||
version = (sys.argv[1] if len(sys.argv) > 1 else detect_version()).lstrip('v')
|
||
exe = os.path.join(RELEASE, 'DLPilot.exe')
|
||
slots = os.path.join(RELEASE, 'pattern_slots.json')
|
||
readme = os.path.join(BASE, 'README.md')
|
||
if not os.path.exists(exe):
|
||
sys.exit('缺少 release/DLPilot.exe, 先运行: python build_exe.py')
|
||
for must in (slots, readme):
|
||
if not os.path.exists(must):
|
||
sys.exit(f'缺少 {must}')
|
||
|
||
# 依 pattern_slots.json 校验栏位引用的图片都在 assets/ 里
|
||
slot_files = re.findall(r'"file":\s*"([^"]+)"', open(slots, encoding='utf-8').read())
|
||
patterns = sorted(p for g in PATTERN_GLOBS
|
||
for p in os.listdir(ASSETS)
|
||
if re.fullmatch(g.replace('*', '.*'), p))
|
||
for f in slot_files:
|
||
if f not in patterns:
|
||
sys.exit(f'pattern_slots.json 引用的 {f} 不在 assets/ 中')
|
||
|
||
# 图案复制进 release/, 与 exe 平铺 -> release/ 即完整可用的发布文件夹
|
||
for p in patterns:
|
||
shutil.copy2(os.path.join(ASSETS, p), os.path.join(RELEASE, p))
|
||
shutil.copy2(readme, os.path.join(RELEASE, 'README.md'))
|
||
|
||
zip_name = f'DLPilot-v{version}-win64.zip'
|
||
zip_path = os.path.join(RELEASE, zip_name)
|
||
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as z:
|
||
for p in ['DLPilot.exe', 'pattern_slots.json', 'README.md'] + patterns:
|
||
z.write(os.path.join(RELEASE, p), f'DLPilot/{p}')
|
||
print(f'发布文件夹: {RELEASE} (exe+配置+说明+{len(patterns)} 张图案, 平铺即用)')
|
||
print(f'发布包: {zip_path} ({os.path.getsize(zip_path) / 1024 / 1024:.1f} MB)')
|
||
print('下一步上传: python publish_gitea.py', zip_name)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
main()
|