关于 template-validation
面向自定义 `dotnet new` 模板作者的验证技能,可在打包或发布前检查模板清单及相关配置,并按错误、警告和建议报告问题。
主要功能
- 01解析并验证 template.json
- 02检查必填字段和标识
- 03审查符号及参数类型
- 04验证源、后续操作和约束
- 05按严重程度提供问题及修复方法
适用场景
- 01发布到 NuGet 前检查模板
- 02排查已安装模板未出现在列表中的原因
- 03审查符号和参数配置
- 04打包前查找清单错误
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dotnet/ skills --skill template-validation安装后在 Claude Code 中输入/template-validation确认已加载。
详细介绍
模板验证
此技能可帮助在发布前验证自定义 dotnet new 模板是否正确。它汇总了可发现常见创作错误的验证规则——这些问题会导致模板悄无声息地失效、生成损坏的项目,或无法显示在 dotnet new list 中。
适用场景
- 用户要求检查或验证 template.json 文件
- 用户反馈“安装后找不到我的模板”
- 用户想在打包并发布到 NuGet 之前检查模板
- 用户在使用自定义模板时遇到意外行为
不适用场景
- 用户想查找或使用现有模板——转到
template-discovery - 用户想创建项目——转到
template-instantiation - 用户想根据现有项目创建模板——转到
template-authoring
输入
| 输入 | 必需 | 描述 |
|---|---|---|
| template.json 路径 | 是 | template.json 文件的路径,或包含 .template.config/template.json 的模板目录 |
验证规则
检查 template.json 时,系统地检查以下所有类别。将每项发现报告为错误、警告或建议。
解析关卡——遇到语法错误时停止。 在应用任何语义规则之前先解析 JSON。如果 解析失败,请报告解析器给出的行号和列号,仅展示最小限度的具体语法修正,然后停止。不要根据未能 解析的文档推断必填字段、符号、后续操作或可发现性方面的问题。修正后重新解析,再提出任何 语义结论。
JSON 格式错误时的最终回复必须恰好包含两部分:一行解析结论,以及展示确切修改的 修正片段。不要附加语义建议、可选元数据或完整替换清单。
1. 必填字段
| 字段 | 严重程度 | 规则 |
|---|---|---|
identity | ERROR | 必须存在且非空 |
name | ERROR | 必须存在且非空 |
shortName | ERROR | 必须存在且非空 |
sourceName | WARNING | 若缺少此项,--name 将无法自定义生成的项目名称 |
author | WARNING | 有助于提升模板的可发现性 |
description | SUGGESTION | 帮助用户了解此模板会创建什么 |
classifications | SUGGESTION | 有助于搜索和分类(例如,["Web", "API"]) |
defaultName | SUGGESTION | 未指定 --name 时提供备用项目名称 |
2. Identity 格式
- 若 identity 包含空格,则为 ERROR——请使用点或连字符(例如,
MyCompany.WebApi.CSharp) - 若 identity 不含命名空间分隔符(
.或-),则为 WARNING——请使用反向 DNS 格式
3. ShortName 冲突
如果 shortName 与某个 dotnet new 子命令相同,就会产生冲突,因为 dotnet new <name> 会被解析为该子命令,而不是实例化模板。请从 dotnet new --help 的 Commands: 部分读取已安装 SDK 的保留名称集合——这是权威来源,也能避免此规则过时。
当前 SDK 的子命令包括(仅供说明,具体取决于版本,请勿将此列表硬编码;实时的 dotnet new --help 输出才是准确信息):install、uninstall、update、list、search、details、create。请注意,dotnet 的顶级动词,如 build、run、test 和 publish,不会产生冲突——dotnet new test 不会与 dotnet test 冲突。
- 如果 shortName 与
dotnet new --help报告的任何子命令相同(不区分大小写),则为 ERROR - 如果 shortName 只有 1 个字符,则为 WARNING——不利于用户发现
- 注意:shortName 可以是字符串,也可以是字符串数组;请检查所有值
4. 符号验证
对于 symbols 对象中的每个符号:
- 如果符号缺少
type字段,则报错 - 对于
type: "parameter":- 如果未指定
datatype,则发出警告(默认值为string) - 如果没有
description,则给出建议(可改善--help输出) - 如果
datatype: "choice":- 如果未定义
choices,则报错 - 如果
choices为空,则报错 - 如果
defaultValue不在 choices 列表中,则报错 - 如果该参数为可选参数(不是
isRequired),且没有defaultValue,则发出警告——用户可能会遇到意外行为
- 如果未定义
- 如果
datatype: "bool":- 如果
defaultValue不是有效的布尔值,则报错
- 如果
- 如果
datatype: "int":- 如果
defaultValue不是有效的整数,则报错
- 如果
- 有效的数据类型:
string、bool、choice、int、float、hex、text - 如果数据类型不在有效列表中,则报错
- 如果未指定
- 对于
type: "computed":- 如果缺少
value表达式,则报错
- 如果缺少
- 对于
type: "generated":- 如果缺少
generator字段,则报错 - 有效的生成器:
casing、coalesce、constant、port、guid、now、random、regex、regexMatch、switch、join
- 如果缺少
自定义参数帮助信息因模板而异:它显示在
dotnet new <shortName> --help 下,而非全局的 dotnet new --help 下。必要时请纠正这一前提,
然后说明哪些无效的符号定义会导致参数无法可靠地显示。
有效的 choice 参数使用非空的 choices 对象,例如:
"Color": {
"type": "parameter",
"datatype": "choice",
"defaultValue": "Blue",
"choices": {
"Blue": { "displayName": "Blue" },
"Green": { "displayName": "Green" }
}
}
参数前缀冲突:如果某个参数名称是另一个参数名称的前缀(例如,Auth 和 AuthMode),则发出警告——这会导致表达式上下文中的解析产生歧义。
5. Sources 验证
对于源修饰符条件:
- 如果条件字符串中的符号名称未用括号括起来,则发出警告——预期格式为
(symbolName),而不是不带括号的symbolName
6. 后续操作验证
对于每个后续操作:
- 如果缺少
actionId,则报错 - 如果缺少
description,则发出警告——当操作需要手动步骤时,这段文字会显示给用户 - 如果缺少
manualInstructions,则给出建议——当操作无法自动运行时(例如,在 IDE 中),系统会显示这些说明
7. 约束验证
对于每个约束:
- 如果缺少
type字段,则报错 - 如果缺少
args,则发出警告——大多数约束类型都需要参数 - 对于
type: "host",如果缺少args,则报错。args必须是一个数组,且每个条目都需要hostname。支持的内置标识符包括dotnetcli、vs、vs-mac、ide和dotnetcli-preview。可选的version使用 NuGet 版本/范围语法,例如[10.0.100,)。引擎会以不区分大小写的方式匹配参数键,因此文档中使用的hostName拼写也有效。拒绝pattern和value等无关字段。 - 对于
type: "sdk-version",args是采用相同语法的版本字符串或数组。
8. Tags 验证
- 如果没有
language标签,则给出建议——添加tags.language(例如,"C#")可改善dotnet new list --language的筛选效果 - 如果没有
type标签,则给出建议——添加tags.type(例如,"project"或"item")可改善分类效果
工作流
第 1 步:找到 template.json
文件可能位于:
- 直接路径:
path/to/template.json - 模板目录中:
path/to/.template.config/template.json .template.config目录中:path/.template.config/template.json
第 2 步:解析并验证
读取 JSON。如果格式错误,请报告 JSON 解析错误以及行号和列号。 如果使用绝对路径读取失败,请在判定文件不可用之前,重试从工作目录读取用户提供的相对路径。
只有解析成功后,才运行上述全部 8 类验证。分别汇总错误、警告和建议。 请对照已安装的 SDK 或当前模板引擎架构验证对架构敏感的说法;不要仅凭字段名称推断运行时会失败。
第 3 步:报告结果
先给出一行结论,然后是一个问题表。必须采用这种明确的结构——不要把问题分散在多个段落中。
结论标题(任选其一):
❌ 尚未就绪 — N 个错误,M 个警告— 存在错误⚠️ 可以发布,但有 N 个警告— 没有错误,但有警告✅ 可以发布 — 0 个错误,0 个警告— 没有错误或警告(仍可有可选建议)
然后给出一个表格,按错误 → 警告 → 建议排序:
| 严重程度 | 位置(JSON 路径或 line:col) | 问题 | 修复方法 |
|---|---|---|---|
| ERROR | shortName | "list" 与 dotnet new 子命令冲突 | 重命名为有辨识度的值,例如 "my-list" |
| ERROR | symbols.maxRetries.defaultValue | "abc" 不是有效的 int | 设置数值默认值,例如 "3" |
| WARNING | sourceName | 缺少替换令牌 | 将其设为源项目名称 |
每个 ERROR 和 WARNING 都必须包含具体的修复方法——更正后的值、JSON 片段或明确的编辑说明(例如“删除末尾的逗号”),不能只是重复问题本身。没有可执行修复方法的问题是不完整的。这是实用验证与泛泛 lint 之间最大的区别。
最后给出总计:“N 个错误,M 个警告,K 个建议。”
对于格式错误的 JSON,输出会刻意缩短,且必须恰好包含两部分:
❌ 尚未就绪 — JSON 解析错误,位于第 N 行、第 M 列:<message>。
<smallest corrected fragment showing the exact edit>
在更正后的文件通过解析之前,不要附加问题表或语义检查总计。
常见问题
| 问题 | 影响 |
|---|---|
| ShortName = "list" 或 "search" | 无法创建模板——与 dotnet new 子命令冲突 |
缺少 sourceName | --name MyProject 不会重命名生成文件中的任何内容 |
选择参数没有 defaultValue | 可选选择参数的用户体验令人困惑 |
datatype 值无效 | 模板引擎会忽略该符号,导致静默失败 |
计算符号没有 value | 模板引擎会在实例化时抛出错误 |
参数前缀冲突(Auth 与 AuthMode) | 表达式求值存在歧义 |
| 源条件没有括号 | 条件可能无法正确求值 |
| JSON 解析失败后仍继续进行语义验证 | 检查结果只是假设。报告确切的解析修复方法并停止。 |
主机约束使用标量 args、无效的 dotnet-cli 主机 ID 或无关字段 | 使用 args: [{ "hostname": "dotnetcli", "version": "[10.0.100,)" }];hostName 也可接受,且不区分大小写。 |
更多信息
- template.json 参考 — 完整架构
- 可用的符号生成器 — 生成器类型
- 后置操作注册表 — 操作 ID
- 约束 — 约束类型