@minonl/dia 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -0
- package/package.json +1 -1
- package/packages/wt/bin/dia-wt +65 -9
- package/packages/wt/tests/adopt.test.sh +29 -0
package/dist/cli.js
CHANGED
|
@@ -4313,6 +4313,7 @@ function registryCandidates() {
|
|
|
4313
4313
|
out.push(process.env.DIA_PLATFORMS_FILE);
|
|
4314
4314
|
const install = installDir();
|
|
4315
4315
|
out.push(join18(install, "registry", "platforms.json"));
|
|
4316
|
+
out.push(join18(install, "docs", "platforms", "registry.json"));
|
|
4316
4317
|
out.push(join18(process.cwd(), "docs", "platforms", "registry.json"));
|
|
4317
4318
|
return out;
|
|
4318
4319
|
}
|
|
@@ -4402,6 +4403,7 @@ function candidates() {
|
|
|
4402
4403
|
out.push(process.env.DIA_DEPS_FILE);
|
|
4403
4404
|
const install = installDir();
|
|
4404
4405
|
out.push(join19(install, "registry", "deps.jsonl"));
|
|
4406
|
+
out.push(join19(install, "docs", "deps.jsonl"));
|
|
4405
4407
|
out.push(join19(process.cwd(), "docs", "deps.jsonl"));
|
|
4406
4408
|
return out;
|
|
4407
4409
|
}
|
package/package.json
CHANGED
package/packages/wt/bin/dia-wt
CHANGED
|
@@ -461,7 +461,7 @@ cmd_prune_merged() {
|
|
|
461
461
|
local -a roots=()
|
|
462
462
|
[ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
|
|
463
463
|
[ -d "$rr" ] && roots+=("$rr")
|
|
464
|
-
[ ${#roots[@]} -gt 0 ] ||
|
|
464
|
+
[ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
|
|
465
465
|
local root sub
|
|
466
466
|
for root in "${roots[@]}"; do
|
|
467
467
|
for sub in "$root"/*; do
|
|
@@ -779,7 +779,7 @@ cmd_check() {
|
|
|
779
779
|
rr="${DIA_WT_REPOS_ROOT:-$HOME/repos/leyan}"
|
|
780
780
|
[ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
|
|
781
781
|
[ -d "$rr" ] && roots+=("$rr")
|
|
782
|
-
[ ${#roots[@]} -gt 0 ] ||
|
|
782
|
+
[ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
|
|
783
783
|
local root sub
|
|
784
784
|
for root in "${roots[@]}"; do
|
|
785
785
|
for sub in "$root"/*; do
|
|
@@ -1243,8 +1243,10 @@ PYGT
|
|
|
1243
1243
|
}
|
|
1244
1244
|
|
|
1245
1245
|
cmd_adopt() {
|
|
1246
|
-
local repo="" mode="dry" template="" def="" json=0
|
|
1246
|
+
local repo="" mode="dry" template="" def="" json=0 all=0
|
|
1247
|
+
local -a orig=("$@")
|
|
1247
1248
|
while [ $# -gt 0 ]; do case "$1" in
|
|
1249
|
+
--all) all=1; shift ;;
|
|
1248
1250
|
--apply) mode="apply"; shift ;;
|
|
1249
1251
|
--check) mode="check"; shift ;;
|
|
1250
1252
|
--revert) mode="revert"; shift ;;
|
|
@@ -1257,7 +1259,41 @@ cmd_adopt() {
|
|
|
1257
1259
|
-*) die "未知参数:$1" ;;
|
|
1258
1260
|
*) repo="$1"; shift ;;
|
|
1259
1261
|
esac; done
|
|
1260
|
-
[
|
|
1262
|
+
if [ "$all" = 1 ]; then
|
|
1263
|
+
[ -z "$repo" ] || die "--all 不能与 <repo> 同时给(要么单个仓,要么全量)"
|
|
1264
|
+
local -a roots=() repos=()
|
|
1265
|
+
local dr rr
|
|
1266
|
+
dr="$(dia_wt_data_root 2>/dev/null || true)"
|
|
1267
|
+
rr="${DIA_WT_REPOS_ROOT:-$HOME/repos}"
|
|
1268
|
+
[ -n "$dr" ] && [ -d "$dr/repos" ] && roots+=("$dr/repos")
|
|
1269
|
+
[ -d "$rr" ] && roots+=("$rr")
|
|
1270
|
+
[ ${#roots[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未找到仓根:${rr})" >&2; exit 2; }
|
|
1271
|
+
local root sub gd cd_
|
|
1272
|
+
for root in "${roots[@]}"; do
|
|
1273
|
+
while IFS= read -r -d '' gd; do
|
|
1274
|
+
sub="$(dirname "$gd")"
|
|
1275
|
+
case "$(basename "$sub")" in *-worktree--*) continue ;; esac
|
|
1276
|
+
cd_="$(git -C "$sub" rev-parse --git-common-dir 2>/dev/null || true)"
|
|
1277
|
+
# 统一物理路径(macOS /tmp → /private/tmp),否则等式比较会假失败
|
|
1278
|
+
gd="$(cd "$sub" 2>/dev/null && cd "$gd" 2>/dev/null && pwd -P)"
|
|
1279
|
+
cd_="$(cd "$sub" 2>/dev/null && cd "$cd_" 2>/dev/null && pwd -P)"
|
|
1280
|
+
[ -n "$gd" ] && [ "$gd" = "$cd_" ] || continue # 只处理主 checkout
|
|
1281
|
+
repos+=("$sub")
|
|
1282
|
+
done < <(find "$root" -maxdepth 3 -name .git -type d -print0 2>/dev/null)
|
|
1283
|
+
done
|
|
1284
|
+
[ ${#repos[@]} -gt 0 ] || { echo "usage: dia wt adopt --all(未匹配到任何主 checkout)" >&2; exit 2; }
|
|
1285
|
+
local -a pass=()
|
|
1286
|
+
local a
|
|
1287
|
+
for a in "${orig[@]}"; do [ "$a" = "--all" ] && continue; pass+=("$a"); done
|
|
1288
|
+
local okc=0 badc=0 r
|
|
1289
|
+
for r in "${repos[@]}"; do
|
|
1290
|
+
if cmd_adopt "$r" "${pass[@]}"; then okc=$((okc+1)); else badc=$((badc+1)); echo "FAIL $r" >&2; fi
|
|
1291
|
+
done
|
|
1292
|
+
[ "$json" = 1 ] && python3 -c 'import json,sys;print(json.dumps({"repos":int(sys.argv[1]),"ok":int(sys.argv[2]),"fail":int(sys.argv[3])},separators=(",",":")))' "${#repos[@]}" "$okc" "$badc"
|
|
1293
|
+
[ "$badc" = 0 ] || return 1
|
|
1294
|
+
return 0
|
|
1295
|
+
fi
|
|
1296
|
+
[ -n "$repo" ] || die "用法: dia wt adopt <repo>|--all [--apply|--check|--revert] [--template T] [--default-branch B] [--json]"
|
|
1261
1297
|
[ -d "$repo" ] || die "目录不存在:$repo"
|
|
1262
1298
|
git -C "$repo" rev-parse --git-dir >/dev/null 2>&1 || die "不是 git 仓库:$repo"
|
|
1263
1299
|
|
|
@@ -1343,6 +1379,11 @@ data = {
|
|
|
1343
1379
|
}
|
|
1344
1380
|
json.dump(data, open(cfg, "w"), ensure_ascii=False, indent=1)
|
|
1345
1381
|
PY
|
|
1382
|
+
# 提示:simple-git-hooks / husky 的 postinstall 会重写 core.hooksPath 下的钩子,
|
|
1383
|
+
# 每次 `pnpm/npm install` 后可能把守卫冲掉 → 用 `dia wt doctor --fix` 或重跑 adopt --apply 修复。
|
|
1384
|
+
if grep -qs '"simple-git-hooks"\|"husky"\|lefthook' "$repo/package.json" "$repo/.lefthook.yml" 2>/dev/null; then
|
|
1385
|
+
echo "[dia-wt] 注意:该仓使用 hook manager(simple-git-hooks/husky/lefthook),install 后若守卫被重写,跑 dia wt doctor --fix" >&2
|
|
1386
|
+
fi
|
|
1346
1387
|
wt_write_hook "$hooksdir" pre-commit "$def" "$chain"
|
|
1347
1388
|
wt_write_hook "$hooksdir" pre-push "$def" "$chain"
|
|
1348
1389
|
wt_write_hook "$hooksdir" post-checkout "$def" "$chain"
|
|
@@ -1351,11 +1392,12 @@ PY
|
|
|
1351
1392
|
}
|
|
1352
1393
|
|
|
1353
1394
|
cmd_doctor() {
|
|
1354
|
-
local json=0 all=0 repos=()
|
|
1395
|
+
local json=0 all=0 fix=0 repos=()
|
|
1355
1396
|
while [ $# -gt 0 ]; do case "$1" in
|
|
1356
1397
|
--json) json=1; shift ;;
|
|
1357
1398
|
--all) all=1; shift ;;
|
|
1358
|
-
--
|
|
1399
|
+
--fix) fix=1; shift ;;
|
|
1400
|
+
--strict) shift ;;
|
|
1359
1401
|
-*) die "未知参数:$1" ;;
|
|
1360
1402
|
*) repos+=("$1"); shift ;;
|
|
1361
1403
|
esac; done
|
|
@@ -1378,6 +1420,19 @@ cmd_doctor() {
|
|
|
1378
1420
|
def="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("defaultBranch") or "")' "$cfg" 2>/dev/null || true)"
|
|
1379
1421
|
fi
|
|
1380
1422
|
[ -n "$def" ] || def="$(wt_default_branch "$repo")"
|
|
1423
|
+
# --fix:无损修复(重写三个守卫钩子 + hooksPath 绝对路径)。只对已 adopt 的仓生效。
|
|
1424
|
+
if [ "$fix" = 1 ] && [ -f "$cfg" ]; then
|
|
1425
|
+
local fixChain=""
|
|
1426
|
+
fixChain="$(python3 -c 'import json,sys;print(json.load(open(sys.argv[1])).get("hooksChain") or "")' "$cfg" 2>/dev/null || true)"
|
|
1427
|
+
[ -n "$fixChain" ] || fixChain="$common/hooks"
|
|
1428
|
+
mkdir -p "$hooksdir"
|
|
1429
|
+
wt_write_hook "$hooksdir" pre-commit "$def" "$fixChain"
|
|
1430
|
+
wt_write_hook "$hooksdir" pre-push "$def" "$fixChain"
|
|
1431
|
+
wt_write_hook "$hooksdir" post-checkout "$def" "$fixChain"
|
|
1432
|
+
[ "$prev" = "$hooksdir" ] || git -C "$repo" config --local core.hooksPath "$hooksdir"
|
|
1433
|
+
prev="$hooksdir"
|
|
1434
|
+
[ "$json" = 0 ] && echo "FIX $repo 钩子已重装(chain=$fixChain)"
|
|
1435
|
+
fi
|
|
1381
1436
|
local bad=0
|
|
1382
1437
|
[ -f "$cfg" ] || { echo "FAIL D01 $repo 未 adopt"; bad=1; }
|
|
1383
1438
|
case "$prev" in /*) ;; *) echo "FAIL D02 $repo hooksPath 非绝对($prev)"; bad=1 ;; esac
|
|
@@ -1462,10 +1517,11 @@ dia wt —— worktree 目录形式选型 + 创建(唯一实现)
|
|
|
1462
1517
|
dia wt status [repo-path] # ★ 清理前必查:唯一工作副本 + 改动重叠(只读)
|
|
1463
1518
|
dia wt check [<repo>...] [--all] [--deep] [--quiet]
|
|
1464
1519
|
# ★ 依赖体检(R20):软链/逃逸/悬空;--all 扫全部仓
|
|
1465
|
-
dia wt adopt <repo
|
|
1466
|
-
# 配置路径模板 + 守卫钩子(默认 dry-run
|
|
1520
|
+
dia wt adopt <repo>|--all [--apply|--check|--revert] [--template T] [--default-branch B] [--json]
|
|
1521
|
+
# 配置路径模板 + 守卫钩子(默认 dry-run;--all 扫仓根)
|
|
1467
1522
|
# 守卫含推送前敏感扫描(DIA_WT_GUARD_SCAN=0 可临时关闭)
|
|
1468
|
-
dia wt doctor [<repo>...] [--all] [--json]
|
|
1523
|
+
dia wt doctor [<repo>...] [--all] [--json] [--fix]
|
|
1524
|
+
# 巡检:配置/钩子/探针/主 checkout/worktree 卫生;--fix 重装守卫钩子
|
|
1469
1525
|
dia wt gate <repo> <feature> # 提交 MR 前:check + doctor + 干净 + ahead>0
|
|
1470
1526
|
dia wt route <repo-path> # ★ 开工前必查:走 MR 还是直推(R1.7,配置驱动)
|
|
1471
1527
|
dia wt scope <repo|worktree> [--feature <slug>] [--session <id>] # ★ 产出作用域声明(设计 §4.5)
|
|
@@ -140,6 +140,35 @@ git -C "$TD/repo7-worktree--y" commit -qm feat-y >/dev/null 2>&1
|
|
|
140
140
|
bash "$WT" adopt "$R7" --revert >/dev/null 2>&1
|
|
141
141
|
[ "$(git -C "$R7" config --get core.hooksPath)" = ".githooks" ] && ok "revert 还原原 hooksPath(相对)" || bad "revert 未还原 .githooks"
|
|
142
142
|
|
|
143
|
+
# ── adopt --all:批量主 checkout,跳过 worktree 目录 ─────────────────────────
|
|
144
|
+
AR="$TD/allroot"; mkdir -p "$AR/a" "$AR/b"
|
|
145
|
+
for r in a b; do
|
|
146
|
+
git -C "$AR/$r" init -q -b main
|
|
147
|
+
git -C "$AR/$r" config user.email t@example.com; git -C "$AR/$r" config user.name t
|
|
148
|
+
echo x > "$AR/$r/x.txt"; git -C "$AR/$r" add -A; git -C "$AR/$r" commit -qm init --no-verify
|
|
149
|
+
done
|
|
150
|
+
git -C "$AR/a" worktree add -q -b feat/w "$AR/a-worktree--w" main
|
|
151
|
+
out="$(DIA_WT_REPOS_ROOT="$AR" DIA_WT_DATA_ROOT="$TD/dr2" bash "$WT" adopt --all --apply --json 2>&1)"
|
|
152
|
+
printf '%s' "$out" | grep -q '"repos":2,"ok":2,"fail":0' && ok "adopt --all 覆盖 2 个主 checkout" || bad "adopt --all: $out"
|
|
153
|
+
for r in a b; do
|
|
154
|
+
[ -n "$(git -C "$AR/$r" config --get core.hooksPath || true)" ] && ok "adopt --all: $r 已配 hooksPath" || bad "adopt --all: $r 未配置"
|
|
155
|
+
done
|
|
156
|
+
[ ! -d "$AR/a-worktree--w/.git/dia" ] && ok "adopt --all 跳过 worktree 目录" || bad "adopt --all 误改 worktree"
|
|
157
|
+
DIA_WT_REPOS_ROOT="$TD/empty-root" DIA_WT_DATA_ROOT="$TD/dr3" bash "$WT" adopt --all >/dev/null 2>&1
|
|
158
|
+
[ $? = 2 ] && ok "adopt --all 空结果 exit 2" || bad "adopt --all 空结果未 exit 2"
|
|
159
|
+
|
|
160
|
+
# ── doctor --fix:钩子被覆盖后能无损重建 ────────────────────────────────────
|
|
161
|
+
R8="$TD/repo8"; mkdir -p "$R8"; git -C "$R8" init -q -b main
|
|
162
|
+
git -C "$R8" config user.email t@example.com; git -C "$R8" config user.name t
|
|
163
|
+
echo a > "$R8/a.txt"; git -C "$R8" add -A; git -C "$R8" commit -qm init --no-verify
|
|
164
|
+
bash "$WT" adopt "$R8" --apply >/dev/null 2>&1
|
|
165
|
+
rm -f "$R8/.git/dia/hooks/post-checkout"
|
|
166
|
+
printf '#!/bin/sh\nexit 0\n' > "$R8/.git/dia/hooks/pre-commit"; chmod +x "$R8/.git/dia/hooks/pre-commit"
|
|
167
|
+
if bash "$WT" doctor "$R8" >/dev/null 2>&1; then bad "钩子被覆盖后 doctor 仍通过"; else ok "钩子被覆盖后 doctor 报失败"; fi
|
|
168
|
+
bash "$WT" doctor "$R8" --fix >/dev/null 2>&1 || bad "doctor --fix 失败"
|
|
169
|
+
bash "$WT" doctor "$R8" >/dev/null 2>&1 && ok "doctor --fix 后恢复 ok" || bad "doctor --fix 后仍失败"
|
|
170
|
+
[ -x "$R8/.git/dia/hooks/post-checkout" ] && ok "doctor --fix 补回 post-checkout" || bad "post-checkout 未补回"
|
|
171
|
+
|
|
143
172
|
# ── gate:成功 / 失败(P1-3 精确匹配)────────────────────────────────────────
|
|
144
173
|
bash "$WT" gate "$R5" x >/dev/null 2>&1 && ok "gate 成功" || bad "gate 失败"
|
|
145
174
|
if bash "$WT" gate "$R5" xb >/dev/null 2>&1; then bad "gate 子串误匹配(x 命中 xb)"; else ok "gate 精确匹配 feature"; fi
|