mcpField
C
conformetry-validate

conformetry-validate

github.com/organizzolini测试与质量0585 次安装今天更新
代码仓库

关于 conformetry-validate

用于将生成代码与 conformetry 模板进行比对并解读报告的技能,帮助开发者处理差异、归属问题、评分,并决定手动修改还是重新生成实例。

主要功能

  1. 01将实例与模板进行校验
  2. 02按语言或模板筛选检查
  3. 03解读差异报告及修复建议
  4. 04诊断未匹配或存在歧义的实例
  5. 05理解评分与阈值
  6. 06不会自动修改文件

适用场景

  1. 01编辑后检查生成代码
  2. 02查找模板要求中缺失的内容
  3. 03追踪路径匹配到的模板
  4. 04决定手动修改还是重新生成

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/organizzolini/codebase --skill conformetry-validate

安装后在 Claude Code 中输入/conformetry-validate确认已加载。

附带文件references/languages.mdreferences/template-matching.md

详细介绍

检查符合性并修复差异

符合性用于衡量实例(磁盘上的生成代码)与其来源模板之间的匹配程度。差异是模板声明了、但实例缺少的内容。

适用于所有语言的唯一规则

实例必须包含模板声明的所有内容。实例额外添加的内容永远不算差异。

额外声明、额外键、额外行、额外文件、重新排序的类成员:都没问题。因此,修复差异时几乎总是应该补上缺少的内容,而不是删除多余的内容。试图通过删除内容让文件符合要求的 Agent,做法与机制背道而驰。

可以自由地在生成文件中进行实现。不会比较函数体。

运行

针对单个项目运行,或在整个工作区运行:

nx run <project>:conformetry-validate
nx run-many --targets=conformetry-validate

不使用 Nx 时,命令行主程序也可以完成相同的工作,但必须提供 --config <path>;该标志为必填项,不会假定存在默认文件:

conformetry validate --config configuration/conformetry.config.ts

在 Nx 工作区中,路径取自 nx.json 中 @conformetry/nx 插件的 configurationPath 选项;执行器和 sync 生成器也接受名为 configuration 的选项,且该选项优先。未提供路径的运行会被拒绝,并通过 ConfigurationPathRequiredError 指明缺少的标志或选项。

两者都接受语言筛选条件;命令行主程序还接受一次性 glob 覆盖,用于替代已配置的实例,并接受 --templates 筛选条件,以指定要对照哪些模板进行衡量。缩小范围有助于迭代;完整运行才是最终检查。

conformetry validate --config configuration/conformetry.config.ts --templates nestjs-service-module
conformetry validate --config configuration/conformetry.config.ts --templates nestjs-service-module --languages typescript

--templates 和 --instances 分别缩小配对的两侧,运行结果是两者的交集——其中一个不会覆盖另一个。指定不存在的模板时会被拒绝,并列出实际存在的名称;如果筛选结果不匹配任何实例,会报告 "no instances belong to …",而不是给出一份看似通过的报告,因此拼写错误不会被误认为通过。

如果模板的实例组带有 tags,命令行主程序就无法定位该模板。 这些 glob 会在每个被标签选中的项目内部读取,因此在与项目根目录拼接之前,src/modules/* 没有意义。主程序会跳过此类组,而不会从工作目录对其执行 glob;缩小范围运行时也会告知你这一点,而不是报告未找到任何内容。此时应使用 Nx targets,或通过 --instances 传入路径。这就是为什么 conformetry validate --config configuration/conformetry.config.ts --templates nestjs-service-module 可能报告没有要检查的内容,而 nx run <project>:conformetry-validate 却能检查大量内容。

Agent 的 shell 不是终端,因此在其中省略 --templates 会像该标志出现之前一样验证所有模板;它不会等待终端中会显示的选择器。--templates all 明确表示相同含义;all 是保留字,不能用作模板名称。

阅读报告

只要有任何项目的得分低于完美匹配,报告就会先显示得分摘要,然后列出每个文件、进行比较的实例和模板,以及每项差异和建议的修复方式:

  1. file: orders.service.ts
     Instance: packages/widgets/src/modules/orders/orders.service.ts
     Template: configuration/conformetry-templates/nestjs-service-module/…

     1. Missing Decorator "Injectable"
        Instance: Line 12, Column 1
        Template: Line 8, Column 1
        Fix     : Add the missing Decorator "Injectable" to the instance file.

在自行设想解决办法之前,先阅读 Fix 行。 每项差异都附有该行,它会指出具体的构造,而不是泛泛描述文件。

位置从 1 开始计数。JSON 差异会报告类似 scripts.build[0] 的路径,而不是行号,因为重新格式化的文件中,键没有有意义的行号。

有关特定文件类型中的差异含义——为何字符串字面量必须逐字匹配、为何标题级别固定、为何函数体不受限制——请参阅 references/languages.md。

差异的类型,以及每种差异需要你做什么

缺少文件或目录。 在比较任何内容之前进行检查;缺少_目录_时,会跳过报告其中的文件。因此,请创建该目录并重新运行,届时会看到一批列出其内容的新报告。这说明检查正常工作,并非回归。

缺少声明或注释。 请补上。注释按有序子序列进行比较,因此,即使文本已存在,位置不对的章节标记也会被视为缺失。

Could not infer {{…}}: no instance node aligned with the template text that uses it — 模板使用了一个没有任何替换项提供的占位符,而且没有实例节点与其周围的模板文本对齐,因此验证无法读取它的值。无论阈值如何,该实例都会验证失败;其他发现仍会照常报告。你可以在实例中恢复对应的模板文本,并在占位符所在位置填入实际值;也可以在实例组的 substitutions 中提供该值。如果已读取该值,而后续某处使用了不同的值,就会显示为普通差异——请修正错误的那一处。conformetry-configure 技能会说明如何读取该值。

无法匹配实例 — 没有模板能解释此路径。要么该路径不是生成代码,不应包含在实例 glob 中;要么它已经偏离得太远,以至于无法被识别。

实例匹配不明确 — 两个模板同样匹配,但都只部分匹配。请为模板指定可区分的文件,或缩小 glob 的范围,使其只匹配其中一个模板。

最后两种情况属于归属判断失败,而不是内容问题,因此仅凭报告最难采取行动。可以通过查看哪些模板能解释此路径来诊断:

conformetry templates --config configuration/conformetry.config.ts --instances packages/widgets/src/modules/orders
  nestjs-service-module (nsm)
    Generate a NestJS service module
    Template: configuration/conformetry-templates/nestjs-service-module
    Instances:
      packages/widgets/src/modules/orders 5/5 files 100%
  nestjs-command-module (ncm)
    Generate a NestJS command module
    Template: configuration/conformetry-templates/nestjs-command-module
    Instances:
      packages/widgets/src/modules/orders 3/5 files 60%

会列出所有能解释此路径的模板,而不仅仅是胜出的模板——这正是这样设计的原因。一个路径可能合理地属于多个模板,因此单一判定会掩盖导致差异的平局。请将结果视为排名:如果你预期排在前面的模板位于较低位置,说明其实例中的文件与该模板文件的位置不一致。

反向查询则会回答另一个方向的问题——存在哪些生成代码,以及每一部分对应什么:

conformetry instances --config configuration/conformetry.config.ts
conformetry instances --config configuration/conformetry.config.ts --templates nestjs-service-module

它打印的每个路径都可用作上文 --instances 的参数,因此这两个命令可以配合使用。--templates 会缩小范围,只显示某个模板能够解释的实例,这样就能找到修改该模板会影响的所有实例。

两者都支持用于解析的 --json。每条命令都必须指定 --config <path>;不会默认使用任何文件。references/template-matching.md 会说明归属判断的工作方式,以及如何解读排名。

三种看起来像 Bug、其实不是的行为

修复所有问题后,第二次运行仍可能报告新的差异。 每个文件只报告匹配程度最高的最小模板所要求的内容。满足这些要求后,较大模板独有的要求才会显现。请持续迭代,直到没有差异,而不要将第二次报告视为回归。

找不到 Python 解释器时会报告为差异,而不是崩溃。 如果 .py 文件出现差异,并提示 Python 不可用,解决方法是安装 python3,而不是修改模板。

不会自动修复任何内容。 没有自动修复功能,也没有写入模式;唯一会改变结果的标志是 --threshold,它改变的是通过条件,而非任何文件。补救方法是手动编辑实例,或重新生成——而重新生成会无条件覆盖,因此使用前请阅读 conformetry-generate。

决定编辑还是重新生成

差异不多,而且文件中包含你想保留的工作时,请编辑该实例。 几乎总是应该这样做。

只有当实例偏离太多、手动重建反而更糟时,才重新生成;而且只有在读过将被销毁的内容之后才这样做——生成过程不会检查内容是否已存在,不会合并,也不会检测冲突。

分数与阈值

一次运行不仅会说明实例是否符合要求,还会评估实例在多大程度上遵循其模板;如果分数低于适用于该实例的阈值,则运行会将其判定为失败。差异各有权重,分数就是已满足的加权要求所占的比例。

报告会在差异列表上方打印 Conformance scores: 摘要,列出每个未获满分的实例、它是否达到阈值,以及工作区的总分。

阈值默认为 1,即完美匹配,因此全新的工作区要求严格。 设置阈值有三个层级,范围最窄者优先:实例组的 threshold,然后是生成器的 threshold,最后是运行级别的 --threshold。

请牢记两点:

  • 降低阈值是允许偏离,并非隐藏偏离。 即使实例达到阈值,差异仍会打印出来。阅读报告时发现差异,并不意味着运行失败——请查看分数摘要。
  • 降低阈值是为了迁移,而不是为了掩盖问题。 该工具用于逐步将现有实例迁移到新模板。如果实例能够符合要求,就让它符合要求;仍然无法按差异逐项降低严重程度。

宣布工作完成之前

干净的符合性检查并非可有可无的润色——它用于确认生成的代码仍与其标准一致。在生成之后、编辑生成的文件之后,以及宣布实现完成之前,都要运行检查。

在沙箱中复现差异

conformetry-examples为每种差异提供了一个故意破坏的实例,让你无需受项目周边约定干扰,也能理解报告。

  • drift-catalogue——缺失文件、缺失目录、已删除的导出项、被移除的节注释和重命名的类,并附有完整报告引用。
  • structural-not-textual——格式重新整理后的实例仍能通过,而缺少单个导出项的实例则无法通过。
  • scoring-thresholds——实例达到降低后的阈值,但差异仍会打印;运行仍以零退出。
  • ambiguous-attribution——两个模板对同一个实例的解释同样合理。
  • failure-modes——两个因错误原因而符合要求的实例。

其 AGENTS.md将报告文本对应到能够复现该报告的示例,并列出对实例进行哪些更改会产生差异、哪些不会。那里的实例是故意破坏的——请不要修复它们。

评论

支持 Markdown