Extend arm-resource-patch rule with PATCH body schema diagnostics#4381
Extend arm-resource-patch rule with PATCH body schema diagnostics#4381Copilot wants to merge 19 commits into
Conversation
Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/8d5e1eda-4793-4990-923e-3863b9f28d83 Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
markcowl
left a comment
There was a problem hiding this comment.
Pull the latest from main, Reformulate ttests for the suggested changes, implement the changes, ensure that all tests pass, all files are formatted correctly and only the changes for this PR are in the PR diff.
…-body-schema-rule Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
…ew deprecation Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/713242e6-42ef-450f-adbc-fa7ec7dca99c Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
commit: |
markcowl
left a comment
There was a problem hiding this comment.
Pull the latest from main, make tests for the suggested changes, then imlement the changes. Ensure that all tests pass, that samples rebuild correctly and without error, that all files are correctly formatted and that your branch is up to date with mean and only changes that are part of this PR are in the PR diff.
Branch is up to date with Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
…Read-only required props Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/a4b1fbcd-d639-4dd2-bc82-f1dc449f07e6 Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
/azp run typespec-azure - PR Tools |
|
Azure Pipelines successfully started running 1 pipeline(s). |
⚡ Benchmark Results
Full details – comparing
|
| Metric | Baseline | Current | Change |
|---|---|---|---|
| total | 🔴 714.1ms | 🔴 787.5ms | +10.3% 🔴 |
| loader | 🟢 138.4ms | 🟢 155.9ms | +12.6% 🔴 |
| resolver | 🟢 16.1ms | 🟢 17.3ms | +7.0% 🔴 |
| checker | 🟢 167.8ms | 🟢 189.8ms | +13.1% 🔴 |
| validation | 🟢 38.9ms | 🟢 40.3ms | +3.4% |
| ↳ validation/@azure-tools/typespec-azure-core | 🟢 5.5ms | 🟢 6.3ms | +14.8% |
| ↳ validation/@typespec/http | 🟢 5.1ms | 🟢 5.7ms | +12.7% |
| ↳ validation/@typespec/rest | 🟢 0.5ms | 🟢 0.5ms | -11.0% |
| ↳ validation/@typespec/versioning | 🔴 26.1ms | 🔴 25.9ms | -0.6% |
| ↳ validation/compiler | 🟢 1.4ms | 🟢 1.4ms | -2.2% |
| linter | 🟢 116.4ms | 🟢 134.2ms | +15.3% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/auth-required | 🟢 0.0ms | 🟢 0.0ms | -3.7% |
| ↳ linter/@azure-tools/typespec-azure-core/bad-record-type | 🟢 0.2ms | 🟢 0.2ms | -4.0% |
| ↳ linter/@azure-tools/typespec-azure-core/byos | 🟢 5.1ms | 🟢 5.6ms | +8.3% |
| ↳ linter/@azure-tools/typespec-azure-core/casing-style | 🟢 0.5ms | 🟢 0.5ms | +2.3% |
| ↳ linter/@azure-tools/typespec-azure-core/composition-over-inheritance | 🟢 0.1ms | 🟢 0.1ms | +10.0% |
| ↳ linter/@azure-tools/typespec-azure-core/documentation-required | 🟢 0.7ms | 🟢 0.7ms | -6.5% |
| ↳ linter/@azure-tools/typespec-azure-core/friendly-name | 🟢 0.5ms | 🟢 0.5ms | +1.6% |
| ↳ linter/@azure-tools/typespec-azure-core/key-visibility-required | 🟢 0.1ms | 🟢 0.1ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-core/known-encoding | 🟢 0.2ms | 🟢 0.2ms | -7.5% |
| ↳ linter/@azure-tools/typespec-azure-core/long-running-polling-operation-required | 🟢 0.3ms | 🟢 0.3ms | +4.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-case-mismatch | 🟢 0.2ms | 🟢 0.2ms | +5.6% |
| ↳ linter/@azure-tools/typespec-azure-core/no-closed-literal-union | 🟢 0.2ms | 🟢 0.2ms | -0.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-enum | 🟢 0.0ms | 🟢 0.0ms | +7.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-error-status-codes | 🟢 0.1ms | 🟢 0.1ms | +10.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-explicit-routes-resource-ops | 🟢 0.1ms | 🟢 0.1ms | +0.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-format | 🟢 0.4ms | 🟢 0.4ms | -2.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-generic-numeric | 🟢 0.4ms | 🟢 0.3ms | -3.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-header-explode | 🟡 16.0ms | 🟡 19.6ms | +22.7% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-legacy-usage | 🟢 1.0ms | 🟢 1.0ms | -3.2% |
| ↳ linter/@azure-tools/typespec-azure-core/no-multiple-discriminator | 🟢 0.1ms | 🟢 0.1ms | -9.8% |
| ↳ linter/@azure-tools/typespec-azure-core/no-nullable | 🟢 0.2ms | 🟢 0.2ms | -0.5% |
| ↳ linter/@azure-tools/typespec-azure-core/no-offsetdatetime | 🟢 1.1ms | 🟢 1.1ms | +0.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-openapi | 🟢 1.7ms | 🟢 1.7ms | +0.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-private-usage | 🟢 1.7ms | 🟢 1.6ms | -4.4% |
| ↳ linter/@azure-tools/typespec-azure-core/no-query-explode | 🟡 16.8ms | 🔴 20.5ms | +22.0% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-response-body | 🔴 21.4ms | 🔴 23.7ms | +11.0% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-rest-library-interfaces | 🟢 0.0ms | 🟢 0.0ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-route-parameter-name-mismatch | 🟢 4.4ms | 🟢 5.9ms | +35.6% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/no-rpc-path-params | 🟢 0.2ms | 🟢 0.2ms | +20.1% |
| ↳ linter/@azure-tools/typespec-azure-core/no-string-discriminator | 🟢 0.0ms | 🟢 0.0ms | -0.3% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unknown | 🟢 0.1ms | 🟢 0.2ms | +8.9% |
| ↳ linter/@azure-tools/typespec-azure-core/no-unnamed-union | 🟢 0.3ms | 🟢 0.3ms | -5.1% |
| ↳ linter/@azure-tools/typespec-azure-core/operation-missing-api-version | 🟢 0.2ms | 🟢 0.1ms | -10.8% |
| ↳ linter/@azure-tools/typespec-azure-core/request-body-problem | 🟢 0.2ms | 🟢 0.2ms | -6.7% |
| ↳ linter/@azure-tools/typespec-azure-core/require-versioned | 🟢 0.0ms | 🟢 0.0ms | -12.6% |
| ↳ linter/@azure-tools/typespec-azure-core/response-schema-problem | 🟡 19.0ms | 🔴 22.4ms | +17.6% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-core/rpc-operation-request-body | 🟢 0.3ms | 🟢 0.3ms | +19.0% |
| ↳ linter/@azure-tools/typespec-azure-core/spread-discriminated-model | 🟢 0.2ms | 🟢 0.2ms | -6.8% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-names | 🟢 4.2ms | 🟢 5.1ms | +20.6% |
| ↳ linter/@azure-tools/typespec-azure-core/use-standard-operations | 🟢 0.1ms | 🟢 0.1ms | +11.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-common-types-version | 🟢 3.6ms | 🟢 4.7ms | +31.9% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-no-key | 🟢 0.1ms | 🟢 0.1ms | +8.1% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-custom-resource-usage-discourage | 🟢 0.1ms | 🟢 0.1ms | +5.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-delete-operation-response-codes | 🟢 4.6ms | 🟢 5.7ms | +24.0% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-path-casing-conflicts | 🟢 4.1ms | 🟢 5.0ms | +21.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-no-record | 🟢 0.3ms | 🟢 0.3ms | -7.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-post-operation-response-codes | 🟢 0.4ms | 🟢 0.5ms | +28.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-put-operation-response-codes | 🟢 0.0ms | 🟢 0.0ms | -22.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-action-no-segment | 🟢 0.2ms | 🟢 0.2ms | +1.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-duplicate-property | 🟢 0.1ms | 🟢 0.1ms | +4.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-interface-requires-decorator | 🟢 0.0ms | 🟢 0.0ms | +6.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-action-verb | 🟢 0.1ms | 🟢 0.1ms | +11.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-envelope-property | 🟢 0.1ms | 🟢 0.1ms | +7.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-invalid-version-format | 🟢 0.0ms | 🟢 0.0ms | -3.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-key-invalid-chars | 🟢 0.2ms | 🟢 0.2ms | +18.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-name-pattern | 🟢 0.0ms | 🟢 0.0ms | -7.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation | 🟢 0.1ms | 🟢 0.2ms | +4.9% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-operation-response | 🟢 4.1ms | 🟢 5.3ms | +29.1% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-patch | 🟢 0.3ms | 🟢 0.4ms | +46.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-path-segment-invalid-chars | 🟢 0.2ms | 🟢 0.2ms | +12.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/arm-resource-provisioning-state | 🟢 0.1ms | 🟢 0.1ms | +2.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/beyond-nesting-levels | 🟢 0.1ms | 🟢 0.1ms | +7.3% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/empty-updateable-properties | 🟢 0.1ms | 🟢 0.1ms | +17.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/improper-subscription-list-operation | 🟢 0.0ms | 🟢 0.0ms | -0.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/lro-location-header | 🟡 12.7ms | 🟡 14.7ms | +15.9% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-operations-endpoint | 🟢 0.0ms | 🟢 0.0ms | -18.4% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/missing-x-ms-identifiers | 🟢 0.3ms | 🟢 0.2ms | -7.6% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-empty-model | 🟢 0.1ms | 🟢 0.1ms | +9.0% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-resource-delete-operation | 🟢 0.2ms | 🟢 0.2ms | +1.5% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/no-response-body | 🟡 18.8ms | 🔴 22.0ms | +16.7% 🔴 |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/patch-envelope | 🟢 0.1ms | 🟢 0.1ms | +2.2% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/resource-name | 🟢 0.1ms | 🟢 0.1ms | +16.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/secret-prop | 🟢 2.2ms | 🟢 2.0ms | -7.8% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/unsupported-type | 🟢 0.3ms | 🟢 0.4ms | +5.7% |
| ↳ linter/@azure-tools/typespec-azure-resource-manager/version-progression | 🟢 0.0ms | 🟢 0.0ms | -12.6% |
| ↳ linter/@azure-tools/typespec-client-generator-core/property-name-conflict | 🟢 0.9ms | 🟢 1.0ms | +3.7% |
| ↳ linter/@azure-tools/typespec-client-generator-core/require-client-suffix | 🟢 0.2ms | 🟢 0.2ms | -2.7% |
| emit | 🟡 232.2ms | 🟡 243.2ms | +4.7% |
| ↳ emit/@azure-tools/typespec-autorest | 🟢 144.4ms | 🟢 152.0ms | +5.3% 🔴 |
| ↳ emit/@typespec/openapi3 | 🟢 129.9ms | 🟢 134.9ms | +3.8% |
| ↳ emit/@typespec/openapi3/compute | 🟢 115.7ms | 🟢 121.0ms | +4.6% |
| ↳ emit/@typespec/openapi3/write | 🟢 13.6ms | 🟢 13.9ms | +2.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)
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
There was a problem hiding this comment.
@copilot Pull the latest from main, then add some tests for the code fixes. Ensure all tests pass, all files are correctly formatted, samples rebuild cleanly, and only the changes associated withy this pull request are in the PR diff.
|
@copilot Note that, properties with default visibility have visibility (Lifecycle.Read, Lifecycle.Update, Lifecycle.Create). You seem to be marking these properties as not being updatable. Please change the way you look for the correct viisibility in a PATCH body - any property that has default visibility or create, update visibility, or create, update, read visibility, or read visibility can be included in a PATCH request. Update tests to validate this behavior, then implement the behavior, ensure all tests pass, all files are properly formatted, pull the latest from main and ensure that only changes associate with this pull request are in the pr diff. |
…-body-schema-rule Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
…ove comments, hoist lifecycle setup Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/da5ec04b-586d-41d4-9f2a-a6f06146326d Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
markcowl
left a comment
There was a problem hiding this comment.
Pull the latest from main
Make the suggested changes
Ensure all tests pass and all files are correctly formatted
Ensure that the PR diff contains only changes associated with this PR
| for (const property of patchModel) { | ||
| if ( | ||
| !property.optional && | ||
| !isReadOnlyOnly(context.program, property, lifecycleMembers, readOnlyOnlyCache) |
There was a problem hiding this comment.
use isReadOnly as the name of this method. isReadOnlyOnly reads as an unnatural repetition of only
There was a problem hiding this comment.
Renamed to isReadOnly.
…Cache Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/3879120b-c321-458c-a0ba-bd792913f361 Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
/azp run typespec-azure - PR Tools |
|
Azure Pipelines successfully started running 1 pipeline(s). |
markcowl
left a comment
There was a problem hiding this comment.
Pull the latest from main, make this change, ensure that all files are properly formatted, all tests pass, and only the changes associated with this PR are in the PR diff.
| }); | ||
| }); | ||
|
|
||
| it("emits requiredInPatch diagnostic when a PATCH body property is required", async () => { |
There was a problem hiding this comment.
Add a test that verifies that there is no diagnostic when the 'properties' property of a tracked resource is included as an optional property in the patch request body. Make any necessary changes to the implementaion to make this test pass
There was a problem hiding this comment.
Added a test that verifies no diagnostic is emitted when properties?: FooProperties is included as an optional property in the PATCH body of a tracked resource (with FooProperties containing both a default-visibility property and a @visibility(Lifecycle.Read) property). The existing implementation already handles this correctly — the properties field on TrackedResource has default visibility (so hasVisibility(Update) is true), and the recursive walk into FooProperties finds only updateable or read-only properties — so no implementation change was needed. All 23 patch-operations tests pass.
…-body-schema-rule Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
…valid Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/f133c0ec-6735-40c7-8b00-4dc5fad8927f Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
markcowl
left a comment
There was a problem hiding this comment.
Pull the latest, make these changes. validate that all tests pass and all files are correctly formatted. Ensure that only changes associated with this pr are in the pr diff.
| /** Resolved Lifecycle visibility members; computed once at rule activation. */ | ||
| lifecycleMembers: LifecycleMembers; | ||
| /** Pure per-source-property cache; safe to share across the entire traversal. */ | ||
| readOnlyCache: Map<ModelProperty, boolean>; |
There was a problem hiding this comment.
TypeScript is notoriously bad at hashing types, so I am skeptical this cache will work. If we are going to cahce this, I would expect us to use something like a fully-quqlified name (i.e. <fully-qualified-namespace-name>.<modelName>.<propertyName>) for the cache key (since these names are guaranteed to be unqiue in typespec).
There was a problem hiding this comment.
Switched the caches and the in-progress set to use fully-qualified names from getTypeName(...) as keys instead of ModelProperty/Model object identity. readOnlyCache is now Map<string, boolean> keyed by the source property's FQN, and modelHasNonUpdateableCache / inProgressModels are keyed by the model's FQN. All 23 patch-operations tests still pass.
Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/29be6145-5697-496e-981b-1b5ae105b329 Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
requiredInPatch,defaultInPatch,notUpdateableInPatch,nonMergePatchContentType)notUpdateableInPatchacross nested model +Record<Model>properties with cycle protectionhasVisibility(Lifecycle.Update) || isReadOnly(...)predicatecreate(context)propertiesfield included as optional in PATCH bodyreadOnlyCache,modelHasNonUpdateableCache,inProgressModels) to use fully-qualified names fromgetTypeName(...)as keys