[Mgmt] Add 'resource-name' client option on Read operation#59335
[Mgmt] Add 'resource-name' client option on Read operation#59335haiyuazhang wants to merge 4 commits into
Conversation
Introduce a new 'resource-name' clientOption key, anchored on the ARM
resource Read operation, to override the generated SDK resource class
names. Supports two value forms:
- string: plain rename for an ordinary (single-resource) Read op, e.g.
@@clientoption(FooOps.get, "resource-name", "FooConfiguration", "csharp");
- Record<enumValue, string>: per-parent-type rename for an expandable
'{parentType}' Read op. Keys are the enum values substituted for
'{parentType}' (TypeSpec record literal keys must be identifiers):
@@clientoption(PrivateEndpointConnections.get, "resource-name",
#{ eventGridTopics: "EventGridTopicPrivateEndpointConnection",
eventGridDomains: "EventGridDomainPrivateEndpointConnection" },
"csharp");
The override is applied as a final pass over detected ARM resources in
both the legacy 'buildArmProviderSchema' and the modern
'resolveArmResources' paths, after parent inference and {parentType}
expansion. Diagnostics are emitted for empty values, string-on-
expandable misuse, unknown map keys, and post-rename name collisions.
Mgmt-TypeSpec test project exercises both forms end-to-end:
- foo.tsp: FooSettings -> FooConfiguration (plain string).
- routedoperations.tsp: per-parent rename for EventGridPrivateEndpointConnection.
Adds 4 emitter unit tests; documentation in docs/client-options.md.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a new resource-name @@clientOption (anchored on an ARM resource Read operation) to override generated C# resource class-name roots, including support for expandable {parentType} resources via a per-enum-value map.
Changes:
- Implemented
resource-nameoverride parsing and late-stage application in both legacy (buildArmProviderSchema) and modern (resolveArmResources) detection paths. - Added unit tests covering plain rename, expandable map rename, and diagnostics for misuse/unused keys.
- Updated Mgmt-TypeSpec test project inputs/outputs and added docs describing the new client option.
Reviewed changes
Copilot reviewed 8 out of 22 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/tspCodeModel.json | Updates expected codemodel decorators/metadata to reflect resource-name overrides. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Models/AzureGeneratorMgmtTypeSpecTestsContext.cs | Updates buildable model registrations to renamed resource types. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/FooSettingsResource.cs | Regenerates resource type with overridden name (FooConfigurationResource). |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/FooSettingsResource.Serialization.cs | Regenerates serialization partial for renamed Foo resource type. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Extensions/MockableAzureGeneratorMgmtTypeSpecTestsResourceGroupResource.cs | Updates mockable extension surface for renamed Foo resource accessor. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Extensions/MockableAzureGeneratorMgmtTypeSpecTestsArmClient.cs | Updates mockable ArmClient helpers for renamed Foo/EventGrid expanded resources. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/Extensions/AzureGeneratorMgmtTypeSpecTestsExtensions.cs | Updates public extension methods to match renamed resource types and mockable targets. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridTopicResource.cs | Updates collection/resource accessors to renamed expanded PEC types. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridTopicEventGridPrivateEndpointConnectionResource.cs | Regenerates expanded PEC resource type name for Topic parent. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridTopicEventGridPrivateEndpointConnectionResource.Serialization.cs | Regenerates serialization partial for expanded PEC resource (Topic/Domain). |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridTopicEventGridPrivateEndpointConnectionCollection.cs | Regenerates expanded PEC collection type name for Topic parent. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridDomainResource.cs | Updates collection/resource accessors to renamed expanded PEC types. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridDomainEventGridPrivateEndpointConnectionResource.cs | Regenerates expanded PEC resource type name for Domain parent. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridDomainEventGridPrivateEndpointConnectionResource.Serialization.cs | Regenerates serialization partial for expanded PEC resource (Topic/Domain). |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/src/Generated/EventGridDomainEventGridPrivateEndpointConnectionCollection.cs | Regenerates expanded PEC collection type name for Domain parent. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/routedoperations.tsp | Adds @@clientOption(..., "resource-name", #{...}) example for expandable {parentType} resource. |
| eng/packages/http-client-csharp-mgmt/generator/TestProjects/Local/Mgmt-TypeSpec/foo.tsp | Adds @@clientOption(..., "resource-name", "FooConfiguration") example for plain rename. |
| eng/packages/http-client-csharp-mgmt/emitter/test/resource-detection.test.ts | Adds 4 unit tests validating override behavior and diagnostics. |
| eng/packages/http-client-csharp-mgmt/emitter/src/resource-metadata.ts | Introduces override parsing/apply helpers and tracks expansion enum value for lookup. |
| eng/packages/http-client-csharp-mgmt/emitter/src/resource-detection.ts | Applies overrides as a final step in legacy resource detection. |
| eng/packages/http-client-csharp-mgmt/emitter/src/resolve-arm-resources-converter.ts | Applies overrides as a final step in modern resource detection. |
| eng/packages/http-client-csharp-mgmt/docs/client-options.md | Documents the new resource-name client option and its supported forms. |
…able Read op When @@clientoption(op, "resource-name", #{...}, "csharp") is used on a Read operation that does not produce expanded {parentType} resources, emit a single, clearer diagnostic explaining the misuse instead of one 'unused entry' diagnostic per map key. Adds a unit test asserting exactly one diagnostic fires and the per-entry 'did not match any expanded resource' diagnostic is suppressed in this case. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
haiyuazhang
left a comment
There was a problem hiding this comment.
Phase 1 versioning: passed/not applicable (no SDK package csproj, changelog, or ApiCompatBaseline changes). Phase 2 API review: no SDK package API surface changes; reviewed the mgmt emitter logic/tests and found one non-blocking diagnostic wording issue. Phase 3 ApiCompat: skipped because this PR does not change a released management package. Total inline comments: 1.
Address review comments on PR Azure#59335: - Move resource-name application into legacy step 2 (expansion) instead of running it as a late post-pass. - Remove the auxiliary expansionTypeValue field from ResourceMetadata; expansion now consumes the override map directly via ExpandArmResourcesOptions.resourceNameOverrides. - Drop applyResourceNameOverrides / findReadMethod helpers and remove the call from resolve-arm-resources-converter.ts. Modern path no longer supports this clientOption (per offline agreement). - Fix misuse diagnostic wording: Record<string, string> -> Record<enumValue, string>. - Adjust unit tests to match the new flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
375d6ed to
a148029
Compare
| if (clientOptionOverride !== undefined) { | ||
| const isExpandable = detectDynamicTypeSegments(path).length > 0; | ||
| if (typeof clientOptionOverride === "string") { | ||
| if (isExpandable) { | ||
| reportWarning( | ||
| `@@clientOption(..., "resource-name", "${clientOptionOverride}", ...) is a plain string but its Read operation's path '${path.path}' contains a {parentType} segment (expandable). Use a Record<enumValue, string> map form instead.` | ||
| ); | ||
| } else { | ||
| // Plain string override on an ordinary Read op. Folds into the | ||
| // existing explicit-name mechanism so it's applied uniformly with | ||
| // legacy decorators in step 3. | ||
| explicitResourceName = clientOptionOverride; | ||
| } | ||
| } else { | ||
| if (!isExpandable) { | ||
| reportWarning( | ||
| `@@clientOption(..., "resource-name", ...) value is a Record but its Read operation's path '${path.path}' does not contain a {parentType} segment (non-expandable). Use a plain string instead.` | ||
| ); | ||
| } else { | ||
| resourceNameOverrideMap = clientOptionOverride; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
could we move the diagnostic reporting when we are expanding the resources? this could make the code here more clear.
There was a problem hiding this comment.
Good call on cleaning this up. After investigating I went with a slightly different approach than relocating into expansion — relocating would force expandDynamicParentResourcesInSchema to know about the user-facing decorator's string-vs-map shape (and the map on non-expandable case wouldn't naturally enter the expansion loop, since non-expandable resources hit continue immediately), which felt like the wrong layering.
Instead I adopted the canonical TypeSpec $lib diagnostic pattern that's already used in this emitter (e.g. resource-model-not-associated-with-arm-resource). All six resource-name diagnostics added by this PR are now registered codes in lib/lib.ts with paramMessage templates:
resource-name-empty-stringresource-name-bad-entryresource-name-empty-recordresource-name-bad-typeresource-name-string-on-expandableresource-name-map-on-non-expandable
extractResourceNameOverride now takes program?: Program directly. Step 2a's two misuse diagnostics emit via $lib.reportDiagnostic directly, which collapses each call site from a multi-line template literal to ~5 lines, and message text now lives in the central catalog. Net result: the step-2a block is materially shorter and clearer, layering is preserved, and we have proper registered diagnostic codes (useful for future suppression rules and tooling).
Done in 01cefba.
Address ArcturusZhang's review comment on resource-detection.ts:190 (`could we move the diagnostic reporting when we are expanding the resources? this could make the code here more clear`). Rather than relocating diagnostics into expansion (which would force expansion to know about the user-facing decorator's string-vs-map shape), this commit adopts the canonical TypeSpec `\` diagnostic pattern that's already used elsewhere in the emitter (resource-model-not-associated-with-arm-resource, malformed-resource- detected). The six resource-name diagnostics added by this PR are now registered codes in lib/lib.ts with paramMessage templates: - resource-name-empty-string - resource-name-bad-entry - resource-name-empty-record - resource-name-bad-type - resource-name-string-on-expandable - resource-name-map-on-non-expandable extractResourceNameOverride now takes `program?: Program` instead of the free-form callback. Step 2a in resource-detection.ts emits the two misuse diagnostics via \.reportDiagnostic directly, collapsing each call site to ~5 lines and moving message text to the central catalog. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c3da6fc to
01cefba
Compare
Summary
Introduces a new
resource-nameclientOption key, anchored on the ARM resource Read operation, to override the generated SDK resource class names. Supersedes the model-keyedresource-name-mappingsdesign from #59282 per @ArcturusZhang's review feedback.Decorator surface
Plain rename (ordinary resource):
Per-parent rename (expandable
{parentType}resource):Map keys are the enum values substituted for
{parentType}(TypeSpec record literal keys must be identifiers).Implementation notes
extractResourceNameOverride/applyResourceNameOverrides/findReadMethodinresource-metadata.ts.ResourceMetadata.expansionTypeValuerecords the enum value that was substituted for{parentType}per expanded resource — that's the override lookup key.buildArmProviderSchema(legacy) andresolveArmResources(modern) detection paths.SdkMethod(aDecoratedType) togetClientOptions; not__raw(TypeSpecOperationdoes not satisfyDecoratedType).Test coverage
foo.tsp:FooSettings*→FooConfiguration*.routedoperations.tsp: per-parent rename of EventGrid private endpoint connection.dotnet buildclean, regen clean.Related