v3.6.0 同步发版

- 交互契约改对话式询问(禁点选工具、一次1~2问、先铺垫再问),规则库 3.6
- 盘面图默认生成+chart_shot 截图;品牌区、大运/流年小卡信息补全、交流群二维码卡
- day_boundary 子正换日;memory_save --update-chart 换盘留痕;share_export 事件简介+城市级地域
- share_push 失败诊断+代理引导;_runtime_guard;修 STAR_ORDER 三奇贵人 KeyError
- README 规则计数 541→542;manifest 重建(1275 文件);测试 142 项全绿
This commit is contained in:
2026-10-10 13:13:41 +08:00
parent f725df8ff6
commit 433c9b4a41
32 changed files with 1468 additions and 389 deletions
+45 -20
View File
@@ -9,7 +9,8 @@ ZIPING_SHARE_GITEA_REMOTE 覆盖)。两个远端逐个尝试,至少一个成
推送成功后:调 _license_gate.grant_uses(root, 10, 盘hash) 计励(同一盘只计一次),
并把该包移入 share/pushed/。推送失败保留 pending,退出码 3。
无 git 或无网络安静失败(不打栈)。
无 git 或无网络安静失败(不打栈);远端推送失败时在 stderr 带该远端
git 报错的末几行摘要,GitHub 线失败另附 HTTPS_PROXY 代理提示。
退出码:0 至少一包推送成功或无包可推;2 输入不可用;3 推送失败。
"""
@@ -26,6 +27,7 @@ from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import _runtime_guard # noqa: F401 import 即检查:Python < 3.10 时中文报错退出(码 3)
import _license_gate as gate
GRANT_USES = 10 # 每盘推送成功的计励次数
@@ -39,24 +41,38 @@ def _git(*args: str, cwd: str | None = None) -> subprocess.CompletedProcess:
capture_output=True, text=True, timeout=60)
def _push_to_remote(remote: str, pkg: Path, workdir: str) -> bool:
"""克隆远端 → 放入脱敏包 → commit+push。任一步失败返回 False(安静)。"""
def _err_tail(cp: subprocess.CompletedProcess, n: int = 2) -> str:
"""取 git 命令报错的末几行(stderr 优先,退而 stdout)。"""
for text in (cp.stderr, cp.stdout):
lines = [ln.strip() for ln in (text or "").splitlines() if ln.strip()]
if lines:
return " / ".join(lines[-n:])
return f"退出码 {cp.returncode}"
def _push_to_remote(remote: str, pkg: Path, workdir: str) -> tuple[bool, str]:
"""克隆远端 → 放入脱敏包 → commit+push。返回 (成功与否, 失败摘要)。"""
try:
if _git("clone", "--depth", "50", remote, workdir).returncode != 0:
return False
r = _git("clone", "--depth", "50", remote, workdir)
if r.returncode != 0:
return False, f"clone 失败:{_err_tail(r)}"
dst = Path(workdir) / pkg.name
shutil.copy2(pkg, dst)
if _git("add", pkg.name, cwd=workdir).returncode != 0:
return False
commit = _git("-c", "user.name=ziping-share",
"-c", "user.email=ziping-share@localhost",
"commit", "--allow-empty", "-m", f"share: {pkg.stem}",
cwd=workdir)
if commit.returncode != 0:
return False
return _git("push", "origin", "HEAD:main", cwd=workdir).returncode == 0
except (OSError, subprocess.SubprocessError):
return False
r = _git("add", pkg.name, cwd=workdir)
if r.returncode != 0:
return False, f"add 失败:{_err_tail(r)}"
r = _git("-c", "user.name=ziping-share",
"-c", "user.email=ziping-share@localhost",
"commit", "--allow-empty", "-m", f"share: {pkg.stem}",
cwd=workdir)
if r.returncode != 0:
return False, f"commit 失败:{_err_tail(r)}"
r = _git("push", "origin", "HEAD:main", cwd=workdir)
if r.returncode != 0:
return False, f"push 失败:{_err_tail(r)}"
return True, ""
except (OSError, subprocess.SubprocessError) as e:
return False, f"{type(e).__name__}: {e}"
def _remotes(root: Path) -> list[tuple[str, str]]:
@@ -106,13 +122,22 @@ def main() -> int:
for pkg in packages:
chart_hash = pkg.stem
ok_remotes = []
failures = []
for name, remote in remotes:
with tempfile.TemporaryDirectory(prefix="ziping-share-") as td:
if _push_to_remote(remote, pkg, td):
ok_remotes.append(name)
ok, why = _push_to_remote(remote, pkg, td)
if ok:
ok_remotes.append(name)
else:
if name == "github_remote":
why += (";若本机直连 GitHub 不通,可通过 HTTPS_PROXY "
"环境变量配置代理")
failures.append(f"{name}:{why}")
for f in failures:
print(f"WARN {pkg.name} {f}", file=sys.stderr)
if not ok_remotes:
print(f"FAIL {pkg.name}:所有远端推送失败(无网络或远端不可达),"
f"pending 保留。", file=sys.stderr)
print(f"FAIL {pkg.name}:所有远端推送失败,pending 保留。",
file=sys.stderr)
continue
granted = gate.grant_uses(root, GRANT_USES, chart_hash)
shutil.move(str(pkg), str(pushed / pkg.name))