Files
ykxmz/_tests/check_version_consistency.py
T
xmz7891 de5018bbbe 按用户规矩升到 1.9.0(有新内容+重构,不是只修 bug)+ 加版本号一致性检查
用户定的规矩:
    只修 bug        -> 最后一位 +1    1.8.2 -> 1.8.3
    加新内容/重构    -> 第二位 +1,最后一位清 0    1.8.2 -> 1.9.0

这一轮既有新东西(设置窗口的中转服务器字段、允许新设备接入开关、
双击开设置窗口)又有重构(手表面板切换收成 showOnly()),
所以是 **1.9.0**,不是我之前说的 1.8.3。

== 顺手加了个「版本号一致性」检查(回归阶段 3a8)==

版本号散落在 8 个地方,靠脚本+人工替换很容易漏。实测漏了两个,
而且**漏了不报错**,只是用户看到一个对不上的版本号:

  * windows/version_info.txt 写着 1.7.1
    -> 用户在「文件属性 -> 详细信息」里看到的版本,错了三个版本
  * docs/LICENSE.txt 写着 1.7.1
    -> 安装时许可页上显示 1.7.1

第二个的根因值得记:installer/build_installer.py 会从 docs/ 里三份
文档**重新生成** license-combined.txt,所以光改生成物没用 ——
下次构建又变回去(我第一次就是这么被骗的)。改成在 build_license()
里**统一注入当前版本**,源文档写什么都不影响。

新增:
  _tests/check_version_consistency.py   检查 8 处版本号一致
  _build/add_verify_stage.py            给套件加阶段(不经 shell,
                                        不会被 PowerShell 吃掉 \$ 变量)
  _build/fix_license_version.py         按行精确修 license

== 另外修了两个我自己的坑 ==

1. verify_all.ps1 被 PowerShell heredoc 吃掉了 \ / \,
   整个脚本语法错。**同一个坑踩了两次**(3a7 和 3a8)。
   以后给 .ps1 加含 \$ 的内容一律写 Python 脚本文件再跑。

2. build_exe.ps1 被 edit 工具吃掉了 UTF-8 BOM
   (PowerShell 5.1 会按 GBK 读,中文注释乱码)。

全量回归 43 个阶段全部通过。
2026-10-07 22:10:14 +08:00

124 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
r'''检查全仓的产品版本号是不是**一致**的。
== 为什么需要这个 ==
版本号散落在至少 8 个地方,靠脚本 + 人工替换,很容易漏。
实测就漏了两个:
windows/version_info.txt 写着 1.7.1(EXE 属性里显示的版本)
installer/license-combined.txt 写着 1.7.1
漏了不会报错 —— 只是用户在"文件属性 → 详细信息"里看到一个
对不上的版本号,或者安装时许可页写着旧版本。很难发现。
== 判定规则(用户定的)==
只查**产品版本号**,不碰这两类"看着像版本号但其实不是"的:
* HTTP User-Agent "LanRemote/1.4.0" —— 协议标识,
20 多个测试在断言它,动它要同步改一大片
* _tests / _build 里当测试数据或历史记录用的版本串
真正要一致的:
windows/lanremote/__init__.py __version__
windows/version_info.txt FileVersion
android/AndroidManifest.xml versionName
android/build_apk.ps1 APK 文件名
installer/ykxmz.iss MyAppVersion
installer/license-combined.txt 许可页上写的版本
relay/relay.py VERSION
_build/package_remote.py VERSION
'''
from __future__ import annotations
import re
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parent.parent
# (文件, 正则, 说明)
SPOTS = [
("windows/lanremote/__init__.py", r'__version__\s*=\s*"([^"]+)"',
"被控端 __version__"),
("windows/version_info.txt", r'StringStruct\("FileVersion",\s*"([^"]+)"\)',
"EXE 文件属性里的版本"),
("android/AndroidManifest.xml", r'versionName="([^"]+)"',
"手表 App 版本"),
("android/build_apk.ps1", r'ykxmz-watch-([\d.]+)\.apk',
"APK 文件名"),
("installer/ykxmz.iss", r'MyAppVersion\s+"([^"]+)"',
"安装包版本"),
("installer/license-combined.txt", r'版本:\s*([\d.]+)',
"安装许可页上的版本"),
("relay/relay.py", r'VERSION\s*=\s*"([^"]+)"',
"中转服务端版本"),
("_build/package_remote.py", r'VERSION\s*=\s*"([^"]+)"',
"打包脚本版本"),
]
def norm(v: str) -> str:
"""把 1.9.0.0 这种四段式归一成三段(Windows 的文件版本要求四段)。"""
parts = v.strip().split(".")
while len(parts) > 3 and parts[-1] == "0":
parts.pop()
return ".".join(parts[:3])
def main() -> int:
found = {}
problems = []
for rel, pat, note in SPOTS:
p = ROOT / rel
if not p.is_file():
problems.append("%s 不存在(应该改路径或删掉这条)" % rel)
continue
try:
text = p.read_text(encoding="utf-8-sig")
except Exception as exc: # noqa: BLE001
problems.append("%s 读不了:%s" % (rel, exc))
continue
m = re.search(pat, text)
if not m:
problems.append("%s 里找不到版本号(正则:%s)" % (rel, pat))
continue
found[rel] = (m.group(1), note)
if not found:
print(" 一个版本号都没找到 —— 正则可能全过时了")
return 1
versions = {norm(v): v for v, _n in found.values()}
print(" ── 各处的版本号 ──")
for rel, (v, note) in found.items():
print(" %-40s %-10s %s" % (rel, v, note))
print()
if len(versions) == 1:
only = list(versions.values())[0]
print(" ✓ 全部一致:%s" % only)
else:
print(" ✗ **版本号不一致**:")
for rel, (v, _n) in found.items():
print(" %-40s %s" % (rel, v))
print()
print(" 版本号散落在多处,用脚本统一改:")
print(" python _build\\bump_version_generic.py <旧> <新>")
print(" 但那个脚本**漏了** installer/ykxmz.iss 和")
print(" installer/license-combined.txt,改完要手动补。")
return 1
if problems:
print(" ⚠ 另外还有 %d 个地方要处理:" % len(problems))
for x in problems:
print(" %s" % x)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())