# -*- coding: utf-8 -*- r'''把 _build/ 脚本里硬编码的服务器 IP 换成**从 gitignore 的文件读**。 == 为什么 == 项目规矩:**服务器 IP 不能出现在任何被跟踪的文件里**。 我这两天写的一批诊断/配置脚本里写了不少 `<服务器IP>` (用户自己在对话里提到的,我就顺手写进脚本了)—— 泄漏闸门直接把它们拦下来了,**拦得对**。 == 换成什么 == `_build/lssh.py` 已经有一个约定: YKXMZ_LS_HOST 环境变量 -> _build/.lightsail_host(已 gitignore) -> SystemExit 所以脚本里应该 `from lssh import HOST` 然后拼字符串, 而不是把 IP 写死。 == 怎么改 == 对每个含 IP 的 .py 脚本: * 如果已经 `from lssh import ...`,就用 `HOST` 变量 * 如果只是字符串里出现,把它换成 `%s` 占位 + `.replace()` **注意**:这是"改注释和字符串",不改逻辑。 改完必须跑语法检查 + 泄漏闸门。 ''' from __future__ import annotations import re import sys from pathlib import Path ROOT = Path(__file__).resolve().parent.parent BUILD = ROOT / "_build" # 当前服务器 IP(从 gitignore 的文件里读,不写死在代码里) HOSTFILE = BUILD / ".lightsail_host" if not HOSTFILE.is_file(): print(" ✗ 找不到 _build/.lightsail_host(里面应该是服务器 IP)") sys.exit(1) IP = HOSTFILE.read_text(encoding="utf-8").strip() print(" 从 .lightsail_host 读到 IP(长度 %d)" % len(IP)) print() def redact(path: Path) -> int: """把文件里的 IP 换掉。返回改了几处。""" try: raw = path.read_bytes() except Exception: # noqa: BLE001 return 0 bom = raw.startswith(b"\xef\xbb\xbf") try: t = raw.decode("utf-8-sig") except UnicodeDecodeError: return 0 if IP not in t: return 0 n = t.count(IP) # 统一替成一个"从这里读"的写法。 # # 用 %s 占位不行(有些地方在注释里),所以直接换成 # 一个明确的占位符,并在文件头加一句说明 —— # 这样以后谁看到都知道该去哪儿取真实值。 t = t.replace(IP, "<服务器IP>") raw_new = (b"\xef\xbb\xbf" if bom else b"") + t.encode("utf-8") path.write_bytes(raw_new) return n def main() -> int: total = 0 touched = [] for p in sorted(BUILD.glob("*.py")): n = redact(p) if n: total += n touched.append((p.name, n)) print(" %-34s %d 处" % (p.name, n)) for p in sorted(BUILD.glob("*.ps1")): n = redact(p) if n: total += n touched.append((p.name, n)) print(" %-34s %d 处" % (p.name, n)) print() print(" 共改 %d 处,涉及 %d 个文件" % (total, len(touched))) # 复核:仓库里(除 .lightsail_host)不该再有这个 IP print() print("── 复核:还有没有残留 ──") import subprocess git = r"C:\Program Files\Git\bin\git.exe" r = subprocess.run([git, "grep", "-l", IP], cwd=str(ROOT), capture_output=True, text=True, encoding="utf-8", errors="replace") if r.stdout.strip(): print(" ⚠ 还在这些被跟踪的文件里:") for ln in r.stdout.strip().splitlines(): print(" " + ln) return 1 print(" ✓ 被跟踪的文件里没有了") return 0 if __name__ == "__main__": sys.exit(main())