Files
dsh_mcn_agent/scripts/fix_deps.py
T
admin 856e632807 baseline: dsh 工作区基线快照(2026-09-10,全新历史起点)
本提交为 dsh_mcn_workshop 仓库的首个提交(旧仓 dsh_MCNProject 已停用),
完整固化 C:/Users/Administrator/.dsh 当前磁盘状态。

1) 临时数据清理:移出 sessions/(81M)、logs/、skill-backup-20260906/(14M)、
   scripts/__pycache__、storages/workspace.json.bak —— 合计 94M(.dsh 162M → 68M)
2) 凭据脱敏:.credentials.yaml(含明文 DEEPSEEK_API_KEY)移出 git 跟踪并加入
   .gitignore;mcn-data-insight/scripts/setup_redfox_key.py 中真实 key 示例改为占位符
3) .gitignore 增补 logs/、skill-backup-*/ 规则
4) 技能结构以当前磁盘状态为准:skills/ = mcn-short-video / impeccable / taste-skill /
   dsh-multi-user-migration;旧技能目录(mcn-dou-analysis、storyboard-prompt、
   short-video-script、browser-harness、mcn-data-insight)与
   profiles/web/node_modules/dsh-vision-router 本地已不存在,本提交记为删除
2026-09-10 22:31:45 +08:00

114 lines
3.9 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 -*-
"""
补缺脚本:扫描 D:\dsh-install 下所有已装包的 dependencies,
把缺失的包(新版 dsh 新增的依赖)从 npmmirror 下载补上。
用法: python -S fix_deps.py [版本号]
"""
import urllib.request, tarfile, io, json, os, shutil, sys, glob
# 自动检测 D:\dsh-install 下最新部署目录(避免硬编码 hash,换机器/升级通用)
_install_dirs = sorted(glob.glob(r'D:\dsh-install\*'), key=os.path.getmtime, reverse=True)
if _install_dirs:
NM = os.path.join(_install_dirs[0], 'node_modules')
else:
print('错误: D:\dsh-install 下无部署目录,先跑 dsh_upgrade.py'); sys.exit(1)
REG = 'https://registry.npmmirror.com'
VERSION = sys.argv[1] if len(sys.argv) > 1 else os.environ.get('DSH_UPGRADE_VERSION', '0.1.1-rc.2')
def log(m):
print(m, flush=True)
def get(url, timeout=60):
req = urllib.request.Request(url, headers={'User-Agent': 'python-fix-deps'})
with urllib.request.urlopen(req, timeout=timeout) as r:
return r.read()
def collect_pkg_map():
"""遍历所有已装包,返回 {包名: package.json 路径}"""
pmap = {}
for n in os.listdir(NM):
p = os.path.join(NM, n, 'package.json')
if n.startswith('@'):
d = os.path.join(NM, n)
if os.path.isdir(d):
for s in os.listdir(d):
q = os.path.join(d, s, 'package.json')
if os.path.exists(q):
pmap[f'{n}/{s}'] = q
elif os.path.exists(p):
pmap[n] = p
return pmap
def resolve_version(full_name):
if full_name.startswith('@deepseek-ai/'):
return VERSION
try:
d = json.loads(get(f'{REG}/{full_name}'))
return d['dist-tags']['latest']
except Exception:
return None
def install_pkg(full_name):
ver = resolve_version(full_name)
if not ver:
log(f' SKIP {full_name}(版本解析失败)')
return False
esc = full_name.replace('/', '%2F')
pkg_short = full_name.split('/')[-1]
url = f'{REG}/{esc}/-/{pkg_short}-{ver}.tgz'
try:
data = get(url)
except Exception as e:
log(f' FAIL {full_name}@{ver}: {e}')
return False
target = os.path.join(NM, *full_name.split('/'))
if os.path.exists(target):
shutil.rmtree(target)
os.makedirs(target, exist_ok=True)
tf = tarfile.open(fileobj=io.BytesIO(data), mode='r:gz')
for m in tf.getmembers():
if m.isdir() or not m.name.startswith('package/'):
continue
rel = m.name[len('package/'):]
dest = os.path.join(target, rel)
os.makedirs(os.path.dirname(dest), exist_ok=True)
src = tf.extractfile(m)
if src:
with open(dest, 'wb') as f:
f.write(src.read())
tf.close()
log(f' INSTALL {full_name}@{ver}')
return True
def main():
missing = {}
for round_no in range(1, 9):
pmap = collect_pkg_map()
have = set(pmap.keys())
missing = {}
for name, pj in pmap.items():
try:
with open(pj, encoding='utf-8') as f:
data = json.load(f)
except Exception:
continue
for dep_key in ('dependencies', 'optionalDependencies'):
for dep, spec in (data.get(dep_key) or {}).items():
if dep not in have:
missing[dep] = spec
if not missing:
log(f'第 {round_no} 轮: 无缺失,依赖完整')
break
log(f'第 {round_no} 轮: 缺 {len(missing)} 个依赖')
ok = sum(1 for dep in sorted(missing) if install_pkg(dep))
if ok == 0:
log('本轮 0 成功,停止')
break
have = collect_pkg_map()
final = sorted(d for d in missing if d not in have)
log('最终缺失: ' + (', '.join(final) if final else '无'))
log('DONE')
if __name__ == '__main__':
main()