Files
cmautobuy/client/build_tools/release_manifest.py
T

80 lines
2.1 KiB
Python

"""生成可校验的 Client 发布清单。"""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
from typing import Any
MANIFEST_FILE_NAME = "autobuy——manifest.json"
def file_description(path: Path) -> dict[str, Any]:
"""返回发布文件的名称、字节大小和 SHA256。"""
digest = hashlib.sha256()
with path.open("rb") as file:
for block in iter(lambda: file.read(1024 * 1024), b""):
digest.update(block)
return {
"file": path.name,
"size": path.stat().st_size,
"sha256": digest.hexdigest(),
}
def build_manifest(version: str, update_zip: Path, portable_zip: Path) -> dict[str, Any]:
"""组装发布清单数据。"""
if not version.strip():
raise ValueError("版本号不能为空")
for path in (update_zip, portable_zip):
if not path.is_file():
raise FileNotFoundError(path)
return {
"schema_version": 1,
"product": "CMAutoBuy",
"version": version,
"update": file_description(update_zip),
"portable": file_description(portable_zip),
}
def write_manifest(
version: str,
update_zip: Path,
portable_zip: Path,
output: Path,
) -> None:
"""把发布清单写成不带 BOM 的 UTF-8 JSON。"""
manifest = build_manifest(version, update_zip, portable_zip)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(
json.dumps(manifest, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="生成 Client 发布清单")
parser.add_argument("--version", required=True)
parser.add_argument("--update", required=True, type=Path)
parser.add_argument("--portable", required=True, type=Path)
parser.add_argument("--output", required=True, type=Path)
return parser.parse_args()
def main() -> int:
args = parse_args()
write_manifest(args.version, args.update, args.portable, args.output)
return 0
if __name__ == "__main__":
raise SystemExit(main())