Skip to content

Add model-name-request-suffix linter rule#4460

Draft
haiyuazhang wants to merge 1 commit into
mainfrom
haiyzhan/linter-request-suffix-rename
Draft

Add model-name-request-suffix linter rule#4460
haiyuazhang wants to merge 1 commit into
mainfrom
haiyzhan/linter-request-suffix-rename

Conversation

@haiyuazhang
Copy link
Copy Markdown
Member

Summary

New lint rule that flags model names ending with Request and suggests using Content suffix instead, per Azure SDK .NET Mgmt Naming Conventions.

Closes #4448

Changes

  • Rule: model-name-request-suffix in @azure-tools/typespec-client-generator-core
    • Checks C#-scoped model name (respects @clientName overrides)
    • Auto-fix codefix: inserts @clientName("<Name>Content", "csharp")
  • Ruleset: Added to resource-manager mega-ruleset (management plane only)
  • Tests: 9 tests covering positive/negative cases, @clientName overrides, case sensitivity, and codefix
  • Docs: Rule documentation page
  • Changelog: .chronus/changes entry

New lint rule that flags model names ending with Request and suggests
using Content suffix instead, per Azure SDK .NET naming conventions.
Includes auto-fix codefix that inserts @clientName with Content suffix.

Registered in TCGC best-practices:csharp ruleset and resource-manager
mega-ruleset.

Closes #4448

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added lib:tcgc Issues for @azure-tools/typespec-client-generator-core library meta:website TypeSpec.io updates labels May 19, 2026
@azure-sdk
Copy link
Copy Markdown
Collaborator

All changed packages have been documented.

  • @azure-tools/typespec-azure-rulesets
  • @azure-tools/typespec-client-generator-core
Show changes

@azure-tools/typespec-client-generator-core - feature ✏️

Add model-name-request-suffix linter rule that flags model names ending with Request and suggests using Content suffix instead, per Azure SDK .NET naming conventions. Includes auto-fix via @clientName.

@azure-tools/typespec-azure-rulesets - feature ✏️

Add model-name-request-suffix linter rule that flags model names ending with Request and suggests using Content suffix instead, per Azure SDK .NET naming conventions. Includes auto-fix via @clientName.

@github-actions
Copy link
Copy Markdown
Contributor

⚡ Benchmark Results

⚠️ 27 metric(s) regressed above the +5% threshold:

Metric Baseline Current Change
total 🔴 581.2ms 🔴 806.0ms +38.7% 🔴
loader 🟢 108.4ms 🟢 163.7ms +51.0% 🔴
resolver 🟢 13.5ms 🟢 16.5ms +21.7% 🔴
checker 🟢 135.4ms 🟢 192.2ms +42.0% 🔴
validation 🟢 32.0ms 🟢 41.9ms +30.8% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟢 4.4ms 🟢 6.4ms +44.8% 🔴
 ↳ validation/@typespec/http 🟢 3.8ms 🟢 5.4ms +44.3% 🔴
 ↳ validation/@typespec/versioning 🔴 21.6ms 🔴 27.6ms +27.8% 🔴
linter 🟢 93.5ms 🟢 135.6ms +45.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 4.1ms 🟢 5.9ms +41.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🟡 12.7ms 🟡 19.6ms +55.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🟡 13.0ms 🔴 20.7ms +59.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🟡 16.6ms 🔴 23.6ms +41.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 3.5ms 🟢 5.7ms +63.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🟡 15.5ms 🔴 22.6ms +46.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 3.3ms 🟢 5.2ms +55.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 3.0ms 🟢 4.3ms +45.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 3.8ms 🟢 5.5ms +46.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟢 3.4ms 🟢 4.6ms +35.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 3.6ms 🟢 5.1ms +41.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟢 9.2ms 🟡 14.6ms +58.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🟡 14.6ms 🔴 23.0ms +57.5% 🔴
emit 🟢 192.6ms 🟡 250.6ms +30.1% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 120.0ms 🟢 156.9ms +30.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 107.7ms 🟢 140.4ms +30.4% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 96.5ms 🟢 126.0ms +30.6% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 11.0ms 🟢 14.4ms +31.6% 🔴
Full details – comparing feac912 vs baseline 213d2b2
Metric Baseline Current Change
total 🔴 581.2ms 🔴 806.0ms +38.7% 🔴
loader 🟢 108.4ms 🟢 163.7ms +51.0% 🔴
resolver 🟢 13.5ms 🟢 16.5ms +21.7% 🔴
checker 🟢 135.4ms 🟢 192.2ms +42.0% 🔴
validation 🟢 32.0ms 🟢 41.9ms +30.8% 🔴
 ↳ validation/@azure-tools/typespec-azure-core 🟢 4.4ms 🟢 6.4ms +44.8% 🔴
 ↳ validation/@typespec/http 🟢 3.8ms 🟢 5.4ms +44.3% 🔴
 ↳ validation/@typespec/rest 🟢 0.4ms 🟢 0.5ms +20.9%
 ↳ validation/@typespec/versioning 🔴 21.6ms 🔴 27.6ms +27.8% 🔴
 ↳ validation/compiler 🟢 1.3ms 🟢 1.4ms +9.7%
linter 🟢 93.5ms 🟢 135.6ms +45.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/auth-required 🟢 0.0ms 🟢 0.0ms +12.6%
 ↳ linter/@azure-tools/typespec-azure-core/bad-record-type 🟢 0.1ms 🟢 0.2ms +30.7%
 ↳ linter/@azure-tools/typespec-azure-core/byos 🟢 4.1ms 🟢 5.9ms +41.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/casing-style 🟢 0.4ms 🟢 0.6ms +32.6%
 ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance 🟢 0.1ms 🟢 0.1ms +11.2%
 ↳ linter/@azure-tools/typespec-azure-core/documentation-required 🟢 0.6ms 🟢 0.8ms +20.5%
 ↳ linter/@azure-tools/typespec-azure-core/friendly-name 🟢 0.4ms 🟢 0.6ms +25.8%
 ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required 🟢 0.1ms 🟢 0.1ms +28.2%
 ↳ linter/@azure-tools/typespec-azure-core/known-encoding 🟢 0.2ms 🟢 0.2ms +10.7%
 ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required 🟢 0.2ms 🟢 0.3ms +38.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch 🟢 0.2ms 🟢 0.2ms +15.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union 🟢 0.2ms 🟢 0.2ms +25.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-enum 🟢 0.0ms 🟢 0.0ms +21.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes 🟢 0.1ms 🟢 0.1ms +25.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops 🟢 0.1ms 🟢 0.1ms +25.6%
 ↳ linter/@azure-tools/typespec-azure-core/no-format 🟢 0.3ms 🟢 0.4ms +31.9%
 ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric 🟢 0.3ms 🟢 0.4ms +16.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-header-explode 🟡 12.7ms 🟡 19.6ms +55.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage 🟢 0.8ms 🟢 1.1ms +33.3%
 ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator 🟢 0.0ms 🟢 0.1ms +38.5%
 ↳ linter/@azure-tools/typespec-azure-core/no-nullable 🟢 0.2ms 🟢 0.2ms +34.4%
 ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime 🟢 0.9ms 🟢 1.2ms +26.1%
 ↳ linter/@azure-tools/typespec-azure-core/no-openapi 🟢 1.4ms 🟢 1.7ms +17.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-private-usage 🟢 1.4ms 🟢 1.7ms +20.7%
 ↳ linter/@azure-tools/typespec-azure-core/no-query-explode 🟡 13.0ms 🔴 20.7ms +59.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-response-body 🟡 16.6ms 🔴 23.6ms +41.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces 🟢 0.0ms 🟢 0.0ms +5.0%
 ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch 🟢 3.5ms 🟢 5.7ms +63.2% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params 🟢 0.1ms 🟢 0.2ms +58.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator 🟢 0.0ms 🟢 0.0ms +28.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-unknown 🟢 0.1ms 🟢 0.2ms +39.2%
 ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union 🟢 0.2ms 🟢 0.3ms +36.8%
 ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version 🟢 0.1ms 🟢 0.2ms +14.9%
 ↳ linter/@azure-tools/typespec-azure-core/request-body-problem 🟢 0.2ms 🟢 0.2ms +11.5%
 ↳ linter/@azure-tools/typespec-azure-core/require-versioned 🟢 0.0ms 🟢 0.0ms -2.9%
 ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem 🟡 15.5ms 🔴 22.6ms +46.3% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body 🟢 0.2ms 🟢 0.3ms +51.5%
 ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model 🟢 0.2ms 🟢 0.2ms +25.8%
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-names 🟢 3.3ms 🟢 5.2ms +55.7% 🔴
 ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations 🟢 0.1ms 🟢 0.1ms +51.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version 🟢 3.0ms 🟢 4.3ms +45.0% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key 🟢 0.1ms 🟢 0.1ms +49.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage 🟢 0.0ms 🟢 0.1ms +37.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes 🟢 3.8ms 🟢 5.5ms +46.8% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts 🟢 3.4ms 🟢 4.6ms +35.9% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record 🟢 0.3ms 🟢 0.3ms +24.6%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes 🟢 0.4ms 🟢 0.5ms +44.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes 🟢 0.0ms 🟢 0.0ms -18.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment 🟢 0.2ms 🟢 0.2ms +47.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property 🟢 0.1ms 🟢 0.1ms +42.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator 🟢 0.0ms 🟢 0.0ms +21.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb 🟢 0.1ms 🟢 0.1ms +28.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property 🟢 0.1ms 🟢 0.1ms +38.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format 🟢 0.0ms 🟢 0.0ms +24.5%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars 🟢 0.2ms 🟢 0.2ms +37.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern 🟢 0.0ms 🟢 0.0ms +8.9%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation 🟢 0.1ms 🟢 0.2ms +20.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response 🟢 3.6ms 🟢 5.1ms +41.1% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch 🟢 0.2ms 🟢 0.3ms +40.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars 🟢 0.1ms 🟢 0.2ms +34.7%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state 🟢 0.1ms 🟢 0.1ms +36.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels 🟢 0.1ms 🟢 0.1ms +43.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties 🟢 0.1ms 🟢 0.1ms +39.1%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation 🟢 0.0ms 🟢 0.0ms +4.8%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header 🟢 9.2ms 🟡 14.6ms +58.6% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint 🟢 0.0ms 🟢 0.0ms +17.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers 🟢 0.2ms 🟢 0.3ms +24.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model 🟢 0.1ms 🟢 0.1ms +29.0%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation 🟢 0.1ms 🟢 0.2ms +64.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body 🟡 14.6ms 🔴 23.0ms +57.5% 🔴
 ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope 🟢 0.1ms 🟢 0.1ms +36.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name 🟢 0.1ms 🟢 0.1ms +34.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop 🟢 1.9ms 🟢 2.1ms +9.2%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type 🟢 0.3ms 🟢 0.4ms +30.4%
 ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression 🟢 0.0ms 🟢 0.0ms +27.6%
 ↳ linter/@azure-tools/typespec-client-generator-core/model-name-request-suffix 🟢 0.0ms 🟢 0.7ms +100.0%
 ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict 🟢 0.7ms 🟢 0.9ms +23.6%
 ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix 🟢 0.2ms 🟢 0.2ms +0.3%
emit 🟢 192.6ms 🟡 250.6ms +30.1% 🔴
 ↳ emit/@azure-tools/typespec-autorest 🟢 120.0ms 🟢 156.9ms +30.7% 🔴
 ↳ emit/@typespec/openapi3 🟢 107.7ms 🟢 140.4ms +30.4% 🔴
 ↳ emit/@typespec/openapi3/compute 🟢 96.5ms 🟢 126.0ms +30.6% 🔴
 ↳ emit/@typespec/openapi3/write 🟢 11.0ms 🟢 14.4ms +31.6% 🔴

Averaged across 3 specs (azure-arm-resource-manager, azure-core-dataplane, azure-full).
Threshold: changes > ±5% are highlighted.
🟢 Fast · 🟡 Moderate (stages >200ms, rules >10ms) · 🔴 Slow (stages >400ms, rules >20ms)

@azure-sdk
Copy link
Copy Markdown
Collaborator

You can try these changes here

🛝 Playground 🌐 Website

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 19, 2026

Open in StackBlitz

npm i https://pkg.pr.new/@azure-tools/typespec-azure-rulesets@4460
npm i https://pkg.pr.new/@azure-tools/typespec-client-generator-core@4460

commit: e353b81

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lib:tcgc Issues for @azure-tools/typespec-client-generator-core library meta:website TypeSpec.io updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linter: model suffix Request must be renamed to Content

2 participants