97 行
4.2 KiB
Python
97 行
4.2 KiB
Python
# -*- coding: utf-8 -*-
|
||
u"""把 `.claude/` 下所有脚本指向的**载板 PCB 文档 uuid** 一次性换掉。
|
||
|
||
/c/Python314/python .claude/pcb2_retarget.py # 只看哪些文件会被改
|
||
/c/Python314/python .claude/pcb2_retarget.py <新uuid> --write # 真的改
|
||
|
||
## 为什么需要它
|
||
|
||
2026-09-07 的事故里 `PCB2-CARRIER`(`f126ffb2…`)这个**文档本身坏了**:
|
||
写得进去、同一次会话里读回来也对,但重开之后电气对象一律读回 0、渲染 API 挂死,
|
||
而且上一轮删掉并存过盘的图形重开后**又回来且翻倍**(1546 → 3091)——
|
||
说明对它的写入根本没有真正落盘。判据是**换一块板对照**:
|
||
同一次会话里 PCB1 读回 301 件 / 2951 线 / 944 孔完全正常。
|
||
|
||
⇒ 修不了,只能换一个干净的 PCB 文档重建。而载板的 uuid 硬编码在 20 多个脚本里,
|
||
手工改必漏,所以做成这个工具。
|
||
|
||
## 换完之后的重建流程(每一步都回查,顺序不能乱)
|
||
|
||
1. pcb2_place.py --layers 切 4 层(新建的 PCB 默认 2 层)
|
||
2. pcb2_rules.py 设计规则 + 11 对差分 + 网络指派
|
||
3. pcb1_import.py --board2 --probe / --apply 216 个元件全部「增加元件」
|
||
4. pcb2_place.py --push 摆位
|
||
5. pcb2_place.py --outline 板框 + 10 个穿线槽 + 8 个 M3 孔
|
||
6. pcb2_place.py --mech 30 个手机定位孔 + 5 个手机位丝印
|
||
7. pcb2_restore.py --copper --push 2039 段铜 + 896 个过孔(快照 + cfgsel 账本)
|
||
8. pcb2_pour.py --push 7 块铺铜
|
||
9. 对账:焊盘 1000 个逐个比、铜层逐条比、inner1_verify.py、drc_read.py --pcb2
|
||
|
||
⚠️ `pcb2_reload.py` 可以用,但有前提:**先存盘并回读验证,重载后必须过 `assert_alive()`**。
|
||
(2026-09-08 更正:把载板打进「Load Empty」的是**那个已损坏的文档**,不是 `location.reload()`;
|
||
在健康文档上重载完全正常,而且是清掉卡死后台任务、让铺铜能重建的唯一办法。)
|
||
"""
|
||
import io
|
||
import os
|
||
import re
|
||
import sys
|
||
|
||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||
OLD = '942ed1560d81c1e7'
|
||
|
||
# 只改脚本和缓存里的引用;`_*.json` 那些是数据快照,不含 uuid 也不该动。
|
||
SKIP_DIRS = {'obsolete', 'eda_src', 'skills', '__pycache__'}
|
||
|
||
|
||
def targets():
|
||
out = []
|
||
for root, dirs, files in os.walk(HERE):
|
||
dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
|
||
for fn in files:
|
||
if not (fn.endswith('.py') or fn.endswith('.json')):
|
||
continue
|
||
p = os.path.join(root, fn)
|
||
try:
|
||
s = io.open(p, encoding='utf-8').read()
|
||
except Exception:
|
||
continue
|
||
n = s.count(OLD)
|
||
if n:
|
||
out.append((p, n))
|
||
return sorted(out)
|
||
|
||
|
||
def main():
|
||
args = [a for a in sys.argv[1:] if not a.startswith('--')]
|
||
write = '--write' in sys.argv
|
||
tg = targets()
|
||
total = sum(n for _p, n in tg)
|
||
print(u'旧 uuid %s 出现在 %d 个文件、共 %d 处:' % (OLD, len(tg), total))
|
||
for p, n in tg:
|
||
print(u' %-52s ×%d' % (os.path.relpath(p, HERE), n))
|
||
if not args:
|
||
print(u'\n用法: pcb2_retarget.py <新uuid> --write')
|
||
return
|
||
new = args[0]
|
||
if not re.match(r'^[0-9a-f]{16}$', new):
|
||
sys.exit(u'⛔ uuid 看着不对(应为 16 位十六进制):%r' % new)
|
||
if new == OLD:
|
||
sys.exit(u'⛔ 新旧 uuid 一样')
|
||
if not write:
|
||
print(u'\n将把它们全部换成 %s —— 加 --write 执行' % new)
|
||
return
|
||
changed = 0
|
||
for p, _n in tg:
|
||
s = io.open(p, encoding='utf-8').read()
|
||
io.open(p, 'w', encoding='utf-8').write(s.replace(OLD, new))
|
||
changed += 1
|
||
# 回查:旧 uuid 必须一处不剩
|
||
left = targets()
|
||
if left:
|
||
sys.exit(u'⛔ 还剩 %d 个文件有旧 uuid:%s' % (len(left), [os.path.basename(p) for p, _ in left]))
|
||
print(u'\n✅ 已改 %d 个文件,旧 uuid 一处不剩;新目标 %s' % (changed, new))
|
||
print(u'⚠️ 本脚本自己的 OLD 常量也被换了 —— 下次再换目标时它就是新的起点,这是有意的。')
|
||
|
||
|
||
main()
|