a2ae74d582
- Backend: auth refresh reuse, schedule/retry/sync/agent/files fixes - Frontend: push WS, files ETag browse, vite build assets - Docs: audit/changelog, production deploy gate, bug scan registry B7-77 - Deploy: deploy-production.sh, prune assets, gate logs
4.6 KiB
4.6 KiB
编码 / 换行审查 — Ubuntu 工作区(阶段 1)
| 项 | 内容 |
|---|---|
| 日期 | 2026-06-04 |
| 范围 | Git 索引 vs 工作区、运行时 UTF-8/EOL、Windows 遗留路径 |
| 前置 | docs/audit/2026-06-02-windows-ubuntu-encoding-deep-dive.md |
阶段 1 结论(摘要)
| 维度 | Git 索引(部署真相) | 本机工作区(tar/检出) |
|---|---|---|
check_text_eol.py |
PASS(206 路径无 CR) | — |
check_shell_eol.sh |
PASS | — |
check_worktree_eol.py |
— | FAIL(约 171 个跟踪文件磁盘含 \r) |
运行时写 .env |
install.py / sync_mysql_mcp_env 已用 text_io |
— |
新脚本 proxy-env.sh 等 |
未入库前曾 CRLF | 已 sed 去 CR |
核心区分:Ubuntu 生产以 git pull 的索引 blob 为准;离线 tar 解压到本机后,工作区可能是 CRLF,会导致 source *.sh 报 未找到命令(行尾 \r)。
1. 已有防护(保持)
| 组件 | 路径 |
|---|---|
| SSOT | server/utils/text_io.py |
| 索引门控 | scripts/check_text_eol.py |
| Shell 门控 | deploy/check_shell_eol.sh |
| 编辑器 | .editorconfig → charset=utf-8, eol=lf |
| Git | .gitattributes → *.py/sh/vue/ts = eol=lf |
| 部署 Pre-flight | deploy/pre_deploy_check.sh 调用上述门控 |
2. 本轮发现(按严重度)
P1 — 工作区 CRLF vs 索引 LF
- 现象:
grep -l $'\r'在server/**/*.py等约 171 个已跟踪文件命中;file scripts/proxy-env.sh显示CRLF line terminators。 - 影响:bash
source scripts/proxy-env.sh出现:未找到命令;不影响已从 Git 拉取的 Ubuntu 服务器(索引为 LF)。 - 修复:
git config core.autocrlf false bash scripts/normalize_worktree_lf.sh python3 scripts/check_worktree_eol.py
P2 — docker/sync_root_env.py 未走 text_io(已修)
- 问题:
read_text/write_text未归一化 CRLF,Windows 生成的docker/.env可能把\r带进NEXUS_*。 - 修复:改用
read_utf8_lf/write_utf8_lf。
P2 — linux_mcp_mysql.sh 读 .env 未去 \r(已修)
- 问题:
export MYSQL_PASSWORD=xxx\r导致 MCP 连库失败。 - 修复:
line="${line%$'\r'}"。
P3 — web/agent/agent.py 读 /etc/os-release 无 encoding(已修)
- 修复:
read_text(encoding="utf-8")(Linux 标准 UTF-8)。
合理设计(非缺陷)
| 位置 | 说明 |
|---|---|
servers.py CSV 导入 |
utf-8-sig → 失败则 gbk(中文 Excel) |
sync_v2.read_file |
detect_text_eol + 前端 stripCr / serializeContent |
sync_v2.write_file |
content.encode("utf-8") 字节写入远程 |
posix_paths.py |
拒绝远程路径中的 \ |
auth_jwt / main |
HTTP header latin-1(RFC 7230) |
文档 / 配置中的 Windows 路径(仅文档,不影响运行)
docs/handoff-*.md、mysql-mcp-setup.md仍含C:\Users\...— 阶段 2 可改为$NEXUS_ROOT/~/Nexus。
3. 远程文件链(复查)
read-file: SSH cat → str → detect_text_eol → JSON { content, eol }
write-file: JSON → .encode("utf-8") → SFTP/tee(不经本机换行转换)
经典 Mac \r 在 API 层标为 eol: LF;前端 stripCr 统一编辑为 LF。
4. 阶段 2(已完成 — 见 phase2 文档)
frontend/工作区 LF 清零(check_worktree_eolOK).cursor/rules/*.mdc归一化 + 门控扩展web/agent/agent.pyI/O 审查mysql-mcp-setup.mdLinux/WSL 路径vue-tsc3 处类型错误(非编码)- 历史 handoff 文档 Windows 路径(可选)
详见:docs/audit/2026-06-04-encoding-review-ubuntu-phase2.md
5. Closure
| H | 判定 | 依据 |
|---|---|---|
| H-index-LF | PASS | check_text_eol + check_shell_eol |
| H-worktree-CRLF | FIXED | normalize_worktree_lf.sh + check_worktree_eol OK |
| H-sync-root-env | FIXED | docker/sync_root_env.py → text_io |
| H-mcp-sh-env | FIXED | linux_mcp_mysql.sh strip \r |
| H-agent-os-release | FIXED | encoding=utf-8 |
DoD(阶段 1)
- 跑通双门控 + 工作区扫描
- 修复本轮 3 处代码
- 新增
check_worktree_eol.py/normalize_worktree_lf.sh - 审计记录与 changelog
验证
python3 scripts/check_text_eol.py
bash deploy/check_shell_eol.sh
bash scripts/normalize_worktree_lf.sh
python3 scripts/check_worktree_eol.py
pytest tests/test_text_io.py -q
python3 docker/sync_root_env.py