K1Guitar/tools/gen_git_user_fw_ver.py

111 lines
3.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 -*-
"""Generate protocol/git_user_fw_ver.h from current git HEAD + branch.
用户固件版本 (01 0C) 线格式: {branch}_{short6}[optional '*']
例: develop_0aedb4 / feature-ui_57448b*
- short6 = git rev-parse --short=6 HEAD小写 hex
- branch 清洗为 [A-Za-z0-9.-],整串(不含 dirty '*') ≤ 24
- dirty working tree 时末尾追加 '*'
用法IAR Pre-build:
python \"$PROJ_DIR$\\..\\..\\tools\\gen_git_user_fw_ver.py\"
"""
from __future__ import annotations
import os
import re
import subprocess
ROOT = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
OUT = os.path.join(ROOT, "protocol", "git_user_fw_ver.h")
BUILD_ID_MAX = 24 # without trailing dirty '*'
def _git(*args: str) -> str | None:
try:
return subprocess.check_output(
["git", *args],
cwd=ROOT,
stderr=subprocess.DEVNULL,
text=True,
).strip()
except (subprocess.CalledProcessError, FileNotFoundError, OSError):
return None
def sanitize_branch(name: str) -> str:
if not name or name == "HEAD":
return "DETACHED"
# feature/foo → feature-foo去掉其它非法字符
s = name.replace("/", "-")
s = re.sub(r"[^A-Za-z0-9.-]+", "-", s)
s = re.sub(r"-{2,}", "-", s).strip("-.")
return s or "DETACHED"
def make_build_id(branch: str, short6: str) -> str:
"""Ensure '{branch}_{short6}' length ≤ BUILD_ID_MAX; keep commit suffix intact."""
short6 = short6.lower()[:6].ljust(6, "0")
suffix = "_" + short6
max_br = BUILD_ID_MAX - len(suffix)
if max_br < 1:
return short6[:BUILD_ID_MAX]
br = branch[:max_br]
return br + suffix
def main() -> int:
full = _git("rev-parse", "HEAD") or ("0" * 40)
if len(full) < 6 or not all(c in "0123456789abcdefABCDEF" for c in full):
full = "0" * 40
full = full.lower()
short6 = full[:6]
br_raw = _git("rev-parse", "--abbrev-ref", "HEAD") or "DETACHED"
branch = sanitize_branch(br_raw)
dirty = False
st = _git("status", "--porcelain")
if st:
dirty = True
build_id = make_build_id(branch, short6)
wire = build_id + ("*" if dirty else "")
# C string escape
wire_c = wire.replace("\\", "\\\\").replace('"', '\\"')
text = f"""/* Auto-generated by tools/gen_git_user_fw_ver.py — do not edit.
* git HEAD{' (dirty)' if dirty else ''}: {full}
* branch: {br_raw}{branch}
* 01 0C wire: {wire}
*/
#ifndef GIT_USER_FW_VER_H
#define GIT_USER_FW_VER_H
#define GIT_COMMIT_ID_FULL "{full}"
#define GIT_BRANCH_NAME "{branch}"
#define GIT_COMMIT_SHORT6 "{short6}"
#define GIT_DIRTY ({1 if dirty else 0})
#define GIT_BUILD_ID "{wire_c}"
#define GIT_BUILD_ID_LEN {len(wire)}u
#endif /* GIT_USER_FW_VER_H */
"""
os.makedirs(os.path.dirname(OUT), exist_ok=True)
old = ""
if os.path.isfile(OUT):
with open(OUT, "r", encoding="utf-8") as f:
old = f.read()
if old != text:
with open(OUT, "w", encoding="utf-8", newline="\n") as f:
f.write(text)
print(f"gen_git_user_fw_ver: wrote {OUT} ({wire})")
else:
print(f"gen_git_user_fw_ver: up-to-date ({wire})")
return 0
if __name__ == "__main__":
raise SystemExit(main())