Skip to content

feat: surface fix convergence warnings (#98) - #100

Merged
luojiyin1987 merged 3 commits into
masterfrom
feat/fix-convergence-warnings
Jul 13, 2026
Merged

feat: surface fix convergence warnings (#98)#100
luojiyin1987 merged 3 commits into
masterfrom
feat/fix-convergence-warnings

Conversation

@luojiyin1987

Copy link
Copy Markdown
Contributor

适配 core #182(已随 @lint-md/core 2.1.5 发布)

FixedResult 新增 convergence: 'stable' | 'cycle' | 'max' 可选字段。CLI 之前只读 fixedResult.result,对未知字段天然兼容;本 PR 是功能增强而非兼容修复。

行为

  • cycle / max → 在 --fix 通过后输出 stderr 警告,文案:
    [lint-md] Fix did not fully converge for <path>: cycle.
    路径经 sanitizeTerminalText 清洗。默认不改变退出码(属质量警告,非硬错误)。
  • -dev 指标:主线程拿到 BatchLintItem[] 后输出,避开 worker 多线程日志交错:
    [lint-md] Fix metrics: <path>: convergence=<x>, rounds=<n>, wallTime=<x.xx>ms
  • stdin --fix:复用同一 warning helper,Markdown 写 stdout、warning 写 stderr,不混流。

关键决定

  • keepLintItem 增加 isIncompleteFix(item) 分支。显式判定 convergence === 'cycle' | 'max',不使用 convergence !== 'stable'——后者会让 pre-#182 core(convergence 为 undefined)被全部保留,破坏旧过滤语义。
  • isIncompleteFix 用 core 暴露的 FixConvergence 枚举做白名单,避免把中文文案当 API。
  • 不在 worker 内输出任何 dev 日志。
  • --fail-on-incomplete-fix 不在本 PR 范围,留作后续 issue:它会引入新的 CLI 契约、帮助文本与 CI 行为测试,与本期安全可观测性增强分开评审更稳。

验证

  • npm run build && npm test:15 套件 / 133 用例全过
  • npm run lint(tsc --noEmit + prettier --check):通过
  • 新增 __tests__/report-incomplete-fixes.spec.ts(11 用例)与 __tests__/keep-lint-item.spec.ts(7 用例),全部用构造 BatchLintItem——不依赖无法序列化函数的 .lintmdrc E2E,符合 issue 要求
  • 覆盖率:report-incomplete-fixes.ts 100%

文件

  • 新增:src/utils/report-incomplete-fixes.ts
  • 新增:__tests__/report-incomplete-fixes.spec.ts__tests__/keep-lint-item.spec.ts
  • 修改:src/utils/batch-lint.tssrc/lint-md.ts(2 处串入点)

Closes #98

Adapt @lint-md/core 2.1.5 (core #182) FixedResult.convergence
(stable | cycle | max) in the CLI:

- Report cycle / max as a stderr warning after the fix pass; exit
  code remains 0 (quality signal, not a hard error).
- keepLintItem now also retains cycle / max items so the warning
  has a target; older cores that predate the field are unaffected
  (undefined === not incomplete).
- --dev prints one Fix metrics line per file from the main thread
  to avoid interleaving with worker output.
- stdin --fix reuses the same warning helper, writing the warning
  to stderr after the fixed Markdown is written to stdout.

--fail-on-incomplete-fix is intentionally out of scope and tracked
separately.
Follow-up to #100.

- Drop the per-worker 'File 耗时' log and the LintWorkerOptions.isDev
  field; the worker no longer writes to stdout/stderr directly, which
  removes the multi-worker log interleaving, the duplicate-metric
  problem, and the unsanitized filePath terminal/CI injection.
- batchLint now returns { allResults, actionableResults }:
  * allResults keeps every file (including clean ones) for --dev
    fix metrics, so perf diagnostics are no longer silently filtered.
  * actionableResults is the keepLintItem-filtered view used for
    I/O, warnings, and reporting.
- --stdin --fix --dev now writes fix metrics to stderr (stdout stays
  pure Markdown) using the same helper as the file path.
- keepLintItem tests now cover fixedResult: null and fixedResult:
  undefined, not just the 'no overrides' case that always built an
  empty FixedResult.
@luojiyin1987

Copy link
Copy Markdown
Contributor Author

跟进 #100 评审反馈,P2-A/B/C + P3 全部处理:

P2-A:删除 worker 旧 dev 日志

  • src/utils/lint-worker.ts:删除 isDev 解构、计时、console.log('File 耗时', ...)
  • src/types.tsLintWorkerOptions.isDev 字段删除
  • src/utils/batch-lint.tsbatchLint 不再透传 isDev
  • 修复了多 worker 日志交错、旧"File 耗时"与新"Fix metrics"重复打印、原始 filePath 注入(无 sanitizeTerminalText)三个问题

P2-B:stdin --dev 也输出 metrics

  • src/lint-md.ts:stdin --fix 分支提取 stdinItem 变量,--dev 时复用 getFixDevMetrics([stdinItem])
  • 关键决定:metrics 写 stderrconsole.error),不污染 stdout 的纯 Markdown

P2-C:干净文件不被 keepLintItem 过滤

  • batchLint 返回结构改为 { allResults, actionableResults }
  • allResults:含全部 worker 结果(包括干净文件)→ 用于 --dev 性能诊断
  • actionableResultsallResults.filter(keepLintItem) → 用于写文件、warning、报告
  • 解决了 --fix --dev 实际只输出"被过滤后保留文件"的 metrics 问题
  • __tests__/batch-lint.spec.ts 新增 "allResults vs actionableResults" describe 块显式验证

P3:测试名实不符

  • __tests__/keep-lint-item.spec.ts 拆分为 fixedResult: nullfixedResult: undefined 两个独立用例
  • baseItem({}) 永远构造空 FixedResult,实际等价于"无 convergence 字段"用例

验证

  • npm run build
  • npm test:15 套件 / 125 用例全过 ✅
  • npm run lint(tsc --noEmit + prettier --check)✅

Follow-up to #100 review.

The previous commit trimmed the test file to focus on the new
batchLint signature, but in doing so deleted regression tests for
getMaxFileSize, resolveAdaptiveConcurrency, and STAT_CONCURRENCY_LIMIT
that pre-date this PR. The current 'clamps large file paths to a single
thread' test only used a single file, so the file-count clamp made it
pass even if the 5 MiB threshold logic broke.

Restore all 9 original describe blocks and adapt only the 10 batchLint
call sites to the new (threads, files, isFixMode, rules) signature
returning { allResults, actionableResults }.

This PR's contract is convergence + metrics; concurrency, file-size
boundaries, and stat() backpressure are out of scope but must remain
under test.
@luojiyin1987

Copy link
Copy Markdown
Contributor Author

跟进评审 P1 反馈。承认:上一版删减 __tests__/batch-lint.spec.ts 时一并移除了与本 PR 无关的回归保护。

恢复范围__tests__/batch-lint.spec.ts 469 → 469 行)
完整还原 getMaxFileSize / resolveAdaptiveConcurrency / STAT_CONCURRENCY_LIMIT 的 9 个 describe 块:

  • STAT_CONCURRENCY_LIMIT 用例(含 maxInFlight 断言)
  • getMaxFileSize:单文件大小、文件不存在应 reject、空入参
  • resolveAdaptiveConcurrency:数字线程为 0 下限、显式线程不受文件大小影响、小文件用 CPU 并发、max file 1.5 MiB caps at 2max file exactly 5 MiB forces 1max file 6 MiB forces 1、单文件 / 文件数小于并发上限

只动 batchLint 调用处(10 处)
仅把 batchLint(threads, files, isDev, isFixMode, rules) 改为 batchLint(threads, files, isFixMode, rules),并把消费侧从数组解构改成 { actionableResults }

为什么那个 clamps large file paths to a single thread 是空测试
你指出的问题成立:原版用单文件,return Math.min(Math.max(limit, 1), mdFilePaths.length) 中的 mdFilePaths.length === 1 会把任何 limit 都钳到 1,所以 5 MiB 阈值失效也照样绿。这正是恢复精确边界测试的原因。

验证

  • npm test 15 套件 / 134 用例全过(净增 9 个回归用例)
  • npm run lint

@luojiyin1987
luojiyin1987 merged commit 4b5bca2 into master Jul 13, 2026
4 checks passed
@luojiyin1987
luojiyin1987 deleted the feat/fix-convergence-warnings branch July 13, 2026 10:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 消费 fix convergence 状态并对未完全收敛给出警告 (#182 适配)

1 participant