template.json 发布前校验实战:让 dotnet new 自定义模板不再静默失败

template.json 发布前校验实战:让 dotnet new 自定义模板不再静默失败 template.json 发布前校验实战让 dotnet new 自定义模板不再静默失败【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills本指南围绕 .NET Template Engine 的自定义模板校验展开系统讲解dotnet new模板发布前必须通过的 8 大验证类别、可执行修复原则与报告格式。文中规则沉淀于本仓库 dotnet-template-engine 插件 的 template-validation 技能读者掌握后可独立排查模板安装后不出现生成的项目残缺参数无效等典型问题并在发布到 NuGet 前完成一次完整的可发布性审查。为什么 template.json 需要系统性验证dotnet new的模板能力由.template.config/template.json清单驱动。这个 JSON 文件一旦出现字段缺失、类型错误或命名冲突失败方式往往是静默的模板既不会报编译错误也不会给出可读的安装提示而是表现为装完找不到模板--name没有重命名任何文件自定义参数不出现在--help中实例化时引擎直接抛异常。这些问题只在用户真正执行创建时才暴露代价远高于发布前的静态检查。template-validation 技能见 SKILL.md将散落的校验经验固化为一套确定性规则涵盖必填字段、identity 格式、shortName 冲突、符号symbol定义、sources 条件、post-action、constraint 与 tags 共 8 个类别并强制要求每条发现都附带具体可执行的修复而不是停留在这里有问题的层面。使用场景与边界何时使用用户要求检查或校验某个 template.json 文件用户反馈我的模板安装后不出现用户希望在打包发布到 NuGet 前审查模板用户遇到自定义模板的意外行为。何时不应使用需求应路由到的技能查找或使用已有模板template-discovery用模板创建项目template-instantiation从现有项目创建模板template-authoring这条边界在仓库的 agent 定义 template-engine.agent.md 中有完整的意图路由表例如Create a new project/app/service路由到template-instantiationValidate my custom template / check my template.json / my template doesnt show up after install路由到template-validation。agent 还定义了创建模板后的标准流程用template-validation校验 →dotnet new install本地安装 →dotnet new template --dry-run试运行 → 创建测试项目并验证构建。输入输入必填说明template.json 路径是template.json 文件的路径或包含.template.config/template.json的模板目录路径第一步解析门槛Parse Gate校验的第一原则是先解析后语义。在对 JSON 应用任何语义规则之前必须先完成语法解析。若解析失败报告解析器给出的行号line与列号column只展示最小且具体的语法修正停止不要基于一份无法解析的文档去臆造必填字段、symbol、post-action 或可发现性方面的结论应用修正后重新解析才能做出任何语义断言。仓库为这一场景准备了专门的 fixturemalformed-template其内容缺少逗号{ identity: Contoso.Templates.Api, name: Contoso API shortName: contoso-api }正确做法是报告JSON parse error at line N, column M并给出只包含确切修改的最小片段第 3 行末尾补逗号而不是附加一串语义建议或整份替换清单。对应的 eval 场景eval.yaml 中 Report a malformed template with its parse location明确校验两点响应必须指出解析错误的位置与具体修改匹配missing comma|expected.*comma|add.*comma等模式且不得在解析失败后继续给出投机性的语义发现。8 大验证类别解析通过后按以下 8 个类别系统性审查全部字段每条发现标记为 error、warning 或 suggestion 三种严重级别之一。1. 必填字段Required Fields字段级别规则identityERROR必须存在且非空nameERROR必须存在且非空shortNameERROR必须存在且非空sourceNameWARNING缺失时--name将无法定制生成的项目名authorWARNING提升模板可发现性descriptionSUGGESTION帮助用户理解模板用途classificationsSUGGESTION改进搜索与分类如[Web, API]defaultNameSUGGESTION未指定--name时提供回退的项目名级别差异很关键identity/name/shortName是模板能被引擎识别的基本前提而description、defaultName只是可选元数据。eval 的 Validate discoverability metadata severity 场景专门测试这种区分——缺失sourceName必须报为 warning而缺失description、defaultName只能作为可选的改进建议不得升格为 error。对应 fixture 见 discoverability-metadata它恰好没有sourceName、description和defaultName。2. Identity 格式Identity FormatERRORidentity 包含空格——应改用点号或短横线例如MyCompany.WebApi.CSharpWARNINGidentity 缺少命名空间分隔符.或-——推荐使用反向 DNS 风格reverse-DNS命名。3. ShortName 冲突ShortName ConflictsshortName若与某个dotnet new子命令同名dotnet new name会被解析为该子命令而非实例化模板模板将永远无法创建。权威来源是当前安装 SDK 的dotnet new --help输出中的Commands:一节——读取实际输出而非硬编码清单可以避免这条规则随 SDK 版本过时而失效。作为参考仅举例说明、随版本变化切勿硬编码以实际dotnet new --help为准当前 SDK 的子命令包括install、uninstall、update、list、search、details、create。注意顶层dotnet动词如build、run、test、publish不构成冲突——dotnet new test不会与dotnet test混淆。规则ERRORshortName 与dotnet new --help报告的任一子命令匹配大小写不敏感WARNINGshortName 仅 1 个字符——过短不利于可发现性注意shortName 可以是字符串或字符串数组数组中的每个值都要逐一检查。仓库为此提供了专门 fixture short-name-array模板声明了两个别名shortName: [ acme-service, search ]其中acme-service是安全的而search与dotnet new search子命令冲突必须重命名为独特的值如acme-svc。eval 场景 Check every short name in an alias array 要求逐个检查别名并拒绝错误的别名时给出具体替换方案同时不得误伤无冲突的别名。4. 符号验证Symbol Validation对symbols对象中的每个 symbolERRORsymbol 缺少type字段fixture incomplete-symbols 中的EnableCaching即缺type导致参数无法可靠出现在帮助中。type: parameterWARNING未指定datatype默认是stringSUGGESTION缺少description改善--help输出若datatype: choiceERROR未定义choicesERRORchoices为空数组ERRORdefaultValue不在 choices 列表中WARNING可选非isRequired且无defaultValue——用户会得到意外行为若datatype: boolERROR——defaultValue不是合法布尔值若datatype: intERROR——defaultValue不是合法整数合法 datatype 集合string、bool、choice、int、float、hex、textERRORdatatype 不在合法集合内。type: computedERROR缺少value表达式缺少时引擎会在实例化时直接抛异常。type: generatedERROR缺少generator字段合法 generator 集合casing、coalesce、constant、port、guid、now、random、regex、regexMatch、switch、join。一个合法的 choice 参数示例非空 choices 对象Color: { type: parameter, datatype: choice, defaultValue: Blue, choices: { Blue: { displayName: Blue }, Green: { displayName: Green } } }参数前缀碰撞WARNING——若某个参数名是另一参数名的前缀如Auth与AuthMode表达式上下文中会产生歧义解析。一个全部踩坑的模板见 fixture validate-template-with-multiple-errors它集中了 5 类典型符号错误可用来自测规则是否全部命中symbols: { targetFramework: { type: parameter, datatype: choice, defaultValue: net7.0, choices: { net8.0: { description: .NET 8 }, net9.0: { description: .NET 9 } } }, enableLogging: { type: parameter, datatype: bool, defaultValue: yes }, maxRetries: { type: parameter, datatype: int, defaultValue: abc }, computed1: { type: computed }, generated1: { type: generated } }对应的 5 个发现分别是defaultValue net7.0不在 choicesnet8.0/net9.0中yes不是合法布尔值abc不是合法整数computed1缺少valuegenerated1缺少generator。关于参数不出现在帮助里还有一个容易混淆的前提需要纠正自定义参数的帮助出现在dotnet new shortName --help而非全局dotnet new --help。先纠正这个前提再说明是哪些非法 symbol 定义导致参数无法可靠显示。5. Sources 验证Sources Validation针对 source 修改器source modifier的条件字符串WARNING条件字符串未用括号包裹符号名——期望格式是(symbolName)而不是裸的symbolName。6. Post-Action 验证Post-Action Validation对每个 post-actionERROR缺少actionIdWARNING缺少description——当动作需要手动步骤时这段文本会展示给用户SUGGESTION缺少manualInstructions——当动作无法自动执行例如在 IDE 中时展示。fixture post-action-and-constraint 演示了已存在的字段不被误报、缺失的字段单独报的原则该模板的 post-action 已有actionId210D431B-A78B-4D2F-B762-4ED3E3EA9025但缺少description与manualInstructions应分别报告为 warning 与 suggestion而不是把已有的actionId说成缺失。7. Constraint 验证Constraint Validation对每个 constraintERROR缺少type字段WARNING缺少args——多数 constraint 类型需要参数对于type: host缺args是ERROR。args是必填数组每个条目需要hostname。支持的内置标识符包括dotnetcli、vs、vs-mac、ide、dotnetcli-preview。可选的version使用 NuGet 版本/区间语法例如[10.0.100,)。引擎对参数键大小写不敏感因此文档中的hostName拼写同样有效。应拒绝无关字段如pattern和value对于type: sdk-versionargs是版本字符串或数组语法同上。前述 fixture post-action-and-constraint 中的 constraint 即为不完整的host约束——有type但缺argsconstraints: { sdk-only: { type: host } }修复方式是补上 hostname 数组与版本区间例如constraints: { sdk-only: { type: host, args: [{ hostname: dotnetcli, version: [10.0.100,) }] } }注意不要使用无效的dotnet-cli主机标识也不要传入pattern、value等无关字段。8. Tags 验证Tags ValidationSUGGESTION无language标签——补充tags.language如C#可改进dotnet new list --language的筛选SUGGESTION无type标签——补充tags.type如project或item可改进分类。三步验证工作流Step 1定位 template.json文件可能位于直接路径path/to/template.json模板目录内path/to/.template.config/template.json单独的.template.config目录path/.template.config/template.jsonStep 2解析并验证读取 JSON。若格式损坏报告带行号与列号的 JSON 解析错误。若按绝对路径读取失败先按用户提供的工作目录相对路径重试再下结论说文件不可用。解析成功后才运行上述全部 8 个类别的验证将错误、警告与建议分别收集对 schema 敏感的结论应核对已安装 SDK 或当前 template-engine schema 后再下判断不要仅凭字段名推断运行时故障。Step 3报告结果先给一行结论verdict再给一张 findings 汇总表。这个决定性结构是强制的——不要把发现散落在散文段落里。verdict 三选一❌ Not ready — N error(s), M warning(s)——存在错误⚠️ Publishable but N warning(s)——无错误但有警告✅ Ready to publish — 0 errors, 0 warnings——无错误无警告仍可能有可选建议随后输出一张按 errors → warnings → suggestions 排序的表格SeverityLocation (JSON path 或line:col)IssueFixERRORshortNamelist与dotnet new子命令冲突改为独特值如my-listERRORsymbols.maxRetries.defaultValueabc不是合法int设置数字默认值如3WARNINGsourceName缺少替换令牌设置为源项目名每条 ERROR 和 WARNING 都必须包含具体修复——修正后的值、JSON 片段或具体的编辑指令例如删除末尾逗号而不是复述问题。没有可操作修复的发现是不完整的这是区分有用的校验与泛泛而谈的 lint的关键。最后给出总数N error(s), M warning(s), K suggestion(s).对于格式损坏的 JSON输出刻意更小且只有两个部分❌ Not ready — JSON parse error at line N, column M: message.展示确切修改的最小修正片段在修正后的文件能成功解析之前不要附加 findings 表或语义总数。常见陷阱速查表陷阱影响shortName list 或 search模板永远无法创建——与dotnet new子命令冲突缺失sourceName--name MyProject不会重命名生成文件中的任何内容choice 参数无defaultValue可选 choice 参数的用户体验混乱非法datatype值模板引擎忽略该 symbol导致静默失败computed symbol 缺value模板引擎在实例化时抛异常参数前缀碰撞AuthvsAuthMode表达式求值歧义source 条件无括号条件可能无法正确求值JSON 解析失败后仍继续语义校验发现全是臆测。应报告确切的解析修复并停止host 约束用标量args、无效的dotnet-cli主机 ID 或无关字段应使用args: [{ hostname: dotnetcli, version: [10.0.100,) }]hostName拼写也按大小写不敏感方式接受仓库中的验证覆盖与自测入口规则的正确性由本仓库的 eval 套件背书。测试入口在 eval.yaml共 7 个场景每个场景把对应 fixture 拷入工作区并给出自然语言提示通过正则 grader 与 rubric 校验回答质量场景校验要点对应 fixtureValidate template with multiple errors覆盖缺失 identity、shortName 冲突、choice 默认值越界、bool/int 非法值、computed 缺 value、generated 缺 generator、post-action 缺 actionIdvalidate-template-with-multiple-errorsValidate correct template and suggest improvements确认无错误、必填字段齐全、shortName 不冲突、可给出可选建议validate-correct-template-and-suggest-improvementsReport a malformed template with its parse location精确定位解析错误、给出具体修正、不追加臆测语义malformed-templateValidate discoverability metadata severitysourceName 报 warningdescription/defaultName 报 suggestion级别不混淆discoverability-metadataCheck every short name in an alias arrayshortName 数组逐项检查拒绝冲突别名并给出替换值short-name-arrayFind incomplete symbol definitions缺 type 的 symbol、空 choices 对象报 error并给出具体补全建议incomplete-symbolsReview post-action and constraint completeness区分 post-action 的 description/manualInstructions 缺失补齐 host 约束 argspost-action-and-constraint对照上述 fixture 中最健康的模板 validate-correct-template-and-suggest-improvements可以看到一份Ready to publish的基线形态完整的identity反向 DNS 风格、name、shortName、sourceName、author、classifications、tags.language/tags.type以及带合法choices与在列defaultValue的 choice 参数——这正是上述 8 类规则全部通过后的模样。在 .NET templating 生态中本技能提及的 template.json 完整 schema、symbol generator 清单、post-action 注册表与 constraint 类型等权威参考均收录于 .NET Templating 项目的官方 wiki 文档template.json reference、Available Symbol Generators、Post-Action Registry、Constraints实践上建议将校验内联到模板发布流水线中先用本技能规则完成静态校验再执行dotnet new install本地安装、dotnet new shortName --dry-run预览与一次真实创建构建把静默失败消灭在发布之前。【免费下载链接】skillsRepository for skills to assist AI coding agents with .NET and C#项目地址: https://gitcode.com/GitHub_Trending/skills17/skills创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考