Add PropertyNamingPolicy support for JSON property naming#969
Conversation
Keaton (Architect): Feasibility confirmed. Recommend PropertyNamingPolicy enum.
Fenster (.NET Dev): Implementation path identified. CLI-only Phase 1, defer .refitter.
Hockney (Tester): Safety verified. Raw property names compile; edge-case tests required.
Consensus: APPROVED FOR IMPLEMENTATION. 6-7 hour effort, zero breaking changes.
Orchestration logs: 2026-03-25T08-07-15Z-{keaton,fenster,hockney}.md
Session log: 2026-03-25T08-07-15Z-issue-967-feasibility.md
Decision entry: decisions.md#9 (consolidated from inbox, inbox files deleted)
- Write orchestration logs for Fenster (implementation), Hockney (tests), Keaton (review) - Merge 4 decisions from inbox to decisions.md (PRD, implementation, tests, review) - Delete processed inbox files - Append cross-agent updates to agent history.md files - Stage 10 .squad/ files for commit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…aming - Add PropertyNamingPolicy enum to RefitGeneratorSettings - Implement CreatePropertyNameGenerator() to select appropriate property name generator based on setting - Support PascalCase (default) and PreserveOriginal policies - Update CSharpClientGeneratorFactory to use new policy-based generator selection Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add PropertyNamingPolicy option to Settings class with command-line mapping - Map property to RefitGeneratorSettings in GenerateCommand - Support PascalCase (default) and PreserveOriginal from CLI Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… validation - Add reserved C# keywords set for keyword detection and escaping - Implement proper Unicode character classification for identifier validation - Improve identifier sanitization logic for PreserveOriginal policy - Support keyword escaping with @ prefix for reserved C# keywords Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add test for default PropertyNamingPolicy value in SettingsTests - Add test for setting PropertyNamingPolicy in SettingsTests - Add CreateRefitGeneratorSettings mapping test in GenerateCommandTests - Add serialization/deserialization tests in SerializerTests - Include PropertyNamingPolicy.json resource in SourceGenerator.Tests.csproj Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add --property-naming-policy example to README.md CLI usage - Update README.md OPTIONS table with new --property-naming-policy - Add detailed Property Naming Policy section explaining behavior - Update .refitter file format examples in README.md - Update refitter-file-format.md with propertyNamingPolicy documentation - Update json-schema.json to include propertyNamingPolicy enum - Remove obsolete propertyNameGenerator references from schema Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merged user directive from Coordinator to always commit changes in small logical groups. Processed and deleted inbox file. Added session and orchestration logs documenting final .squad/ state after issue #967 implementation phase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📝 WalkthroughWalkthroughThis pull request implements Issue Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant CLI as GenerateCommand
participant Factory as CSharpClientGeneratorFactory
participant Policy as PropertyNamingPolicy
participant Generator as Property Name Generator
participant Utils as IdentifierUtils
participant Code as Generated C# Code
User->>CLI: --property-naming-policy PreserveOriginal
CLI->>CLI: Parse CLI option into Settings
CLI->>CLI: CreateRefitGeneratorSettings(settings)
Note over CLI: Map PropertyNamingPolicy to RefitGeneratorSettings
CLI->>Factory: Create(generatorSettings)
Factory->>Policy: Check settings.PropertyNamingPolicy
alt PreserveOriginal Policy
Factory->>Generator: CreatePropertyNameGenerator()
Note over Factory: Return PreserveOriginalPropertyNameGenerator
else PascalCase (or other)
Factory->>Generator: CreatePropertyNameGenerator()
Note over Factory: Return CustomCSharpPropertyNameGenerator
end
Generator->>Utils: ToCompilableIdentifier(originalPropertyName)
Utils->>Utils: Validate identifier characters
Utils->>Utils: Check reserved keywords
alt Valid identifier
Utils-->>Generator: Return as-is
else Reserved keyword
Utils-->>Generator: Return `@keyword` (verbatim)
else Invalid identifier
Utils-->>Generator: Return sanitized with _ prefix/substitutions
end
Generator-->>Code: Apply [JsonPropertyName] attribute
Code-->>User: Generated contract with original or transformed property names
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly Related PRs
Suggested Labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #969 +/- ##
==========================================
- Coverage 93.37% 93.15% -0.22%
==========================================
Files 26 27 +1
Lines 1645 1797 +152
==========================================
+ Hits 1536 1674 +138
- Misses 40 49 +9
- Partials 69 74 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/docfx_project/articles/refitter-file-format.md (2)
353-356:⚠️ Potential issue | 🟡 MinorTrailing comma in JSON schema example.
Line 355 has a trailing comma after the
descriptionvalue which makes the JSON invalid.Proposed fix
"contractsOutputFolder": { "type": "string", - "description": "The output folder for the generated contracts code", + "description": "The output folder for the generated contracts code" },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docfx_project/articles/refitter-file-format.md` around lines 353 - 356, The JSON schema example contains an invalid trailing comma after the "description" value in the property object (the block with "type": "string" and "description": "The output folder for the generated contracts code"); remove the trailing comma after that "description" line so the object before "additionalNamespaces" is valid JSON, ensuring the property object correctly ends without an extra comma.
513-514:⚠️ Potential issue | 🟡 MinorInvalid JSON syntax in schema example.
Missing comma after the
descriptionproperty on line 513. The JSON block in the documentation will not parse correctly.Proposed fix
"codeGeneratorSettings": { "type": "object", - "description": "Settings for the code generator." + "description": "Settings for the code generator.", "properties": {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/docfx_project/articles/refitter-file-format.md` around lines 513 - 514, The JSON schema example has invalid syntax because the "description" property is missing a trailing comma before the "properties" key; in the doc block where the snippet shows "description": "Settings for the code generator." and then "properties": { }, add a comma after the description value so the JSON is valid (update the example containing the "description" and "properties" keys).
🧹 Nitpick comments (5)
.squad/agents/fenster/history.md (1)
197-287: Implementation plan references unimplemented enum values.The implementation plan at lines 202 and 210 mentions
CamelCaseandSnakeCaseas potential enum values, but the actual implementation only includesPascalCaseandPreserveOriginal. This is internal documentation, but updating it to reflect the final scope would improve accuracy.Consider updating lines 202 and 210 to reflect the actual implemented enum values (
PascalCase,PreserveOriginal) to keep historical documentation consistent with the shipped feature.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.squad/agents/fenster/history.md around lines 197 - 287, Update the implementation plan text so the enum values listed match the implemented PropertyNamingPolicy enum: remove or mark as deferred the entries for CamelCase and SnakeCase and replace "Preserve" with the actual implemented name "PreserveOriginal" and ensure "PascalCase" is present; search for mentions of PropertyNamingPolicy, PascalCase, PreserveOriginal, CamelCase, and SnakeCase in the document and edit the descriptions (the paragraphs referencing the enum and the "Recommended Implementation Shape" section) to reflect only the shipped values (PascalCase, PreserveOriginal) or explicitly note the other two as future work..squad/implementation-plan-issue-967.md (1)
25-27: Add language specifier to fenced code block.The fenced code block is missing a language specifier. Add
textorshellfor proper syntax highlighting and to satisfy markdownlint rules.📝 Suggested fix
-``` +```text --property-naming-policy [mode]</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In @.squad/implementation-plan-issue-967.md around lines 25 - 27, The fenced
code block containing the literal "--property-naming-policy [mode]" is missing a
language specifier; update the triple-backtick fence that wraps
"--property-naming-policy [mode]" to include a language such as text or shell
(e.g.,text orshell) so markdownlint and syntax highlighting are
satisfied.</details> </blockquote></details> <details> <summary>src/Refitter.Core/IdentifierUtils.cs (1)</summary><blockquote> `228-235`: **Minor: `IsValidIdentifier` returns `false` for valid verbatim keyword identifiers.** The condition `!IsReservedKeyword(unescapedIdentifier)` causes `IsValidIdentifier("@class")` to return `false`, even though `@class` is a valid C# identifier (the verbatim prefix exists specifically to allow reserved keywords as identifiers). This doesn't cause functional issues because `ToCompilableIdentifier` handles this correctly by rebuilding and re-escaping, but it means the method's semantics don't fully match its documented purpose of determining "whether the supplied value is already a valid C# identifier." <details> <summary>📝 Suggested fix to align semantics with documentation</summary> ```diff if (identifier[0] == '@') { var unescapedIdentifier = identifier.Substring(1); - return identifier.Length > 1 && - !IsReservedKeyword(unescapedIdentifier) && - IsValidIdentifierCore(unescapedIdentifier); + return identifier.Length > 1 && + IsValidIdentifierCore(unescapedIdentifier); } ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@src/Refitter.Core/IdentifierUtils.cs` around lines 228 - 235, The IsValidIdentifier method incorrectly rejects verbatim identifiers by checking !IsReservedKeyword on the unescaped identifier; update the logic so that when identifier starts with '@' you only validate the unescaped text with IsValidIdentifierCore (and the length check) and do not call IsReservedKeyword, e.g. make the verbatim branch return identifier.Length > 1 && IsValidIdentifierCore(unescapedIdentifier) so `@class` is considered valid; keep non-verbatim behavior unchanged. ``` </details> </blockquote></details> <details> <summary>src/Refitter.Tests/Examples/PropertyNamingPolicyTests.cs (1)</summary><blockquote> `11-57`: **Add OpenAPI 2.0 (Swagger) specification tests.** The tests only use OpenAPI 3.0.1 specification. Per coding guidelines, new code generation features should be tested with both OpenAPI 2.0 and 3.0 specifications to ensure compatibility across spec versions. Consider adding a parallel set of tests with a Swagger 2.0 spec to verify the `PropertyNamingPolicy` feature works correctly with both specification formats. As per coding guidelines: "Test new code generation features with both OpenAPI 2.0 and 3.0 specifications". <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In `@src/Refitter.Tests/Examples/PropertyNamingPolicyTests.cs` around lines 11 - 57, Add a parallel Swagger 2.0 spec and tests alongside the existing OpenApiSpec to validate PropertyNamingPolicy across spec versions: create a new constant (e.g., SwaggerV2Spec) in PropertyNamingPolicyTests mirroring the current OpenApiSpec but using OpenAPI/Swagger 2.0 format (swagger: "2.0", definitions instead of components/schemas, paths/responses adapted), then duplicate the existing test(s) to run against SwaggerV2Spec (call same test helper methods that consume OpenApiSpec) so the PropertyNamingPolicy behavior is asserted for both OpenAPI 3.0.1 (OpenApiSpec) and Swagger 2.0 (SwaggerV2Spec). ``` </details> </blockquote></details> <details> <summary>.squad/skills/raw-property-names/SKILL.md (1)</summary><blockquote> `93-104`: **Test design inconsistency with actual implementation.** Test 5 suggests that invalid identifiers with hyphens should throw an `InvalidOperationException`, but the actual implementation in `IdentifierUtils.ToCompilableIdentifier` sanitizes them instead (e.g., `pay-method` → `pay_method`). This is confirmed by `PropertyNamingPolicyTests.PreserveOriginal_Minimally_Sanitizes_Invalid_Identifiers` which expects `1st-payment-method` to become `_1st_payment_method`. The "Implemented Pattern" section (lines 159-172) correctly documents the actual behavior. Consider updating this test design section to align with the sanitization approach rather than rejection. <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In @.squad/skills/raw-property-names/SKILL.md around lines 93 - 104, Update the test Invalid_Property_Names_With_Hyphens_Are_Rejected to assert the sanitization behavior instead of expecting an InvalidOperationException: call GenerateCode(spec) (or the same code path) and verify the resulting property name matches the sanitized form (e.g., "pay-method" → "pay_method"), aligning with IdentifierUtils.ToCompilableIdentifier and existing PropertyNamingPolicyTests.PreserveOriginal_Minimally_Sanitizes_Invalid_Identifiers; replace the exception assertion with an assertion that the generated model contains the sanitized identifier. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.squad/decisions/fenster-plan-issue-967.md:
- Around line 15-18: The decision document is out of sync with the implemented
feature: update the CLI option enum names from Preserve/CamelCase/SnakeCase to
the shipped names (e.g., PreserveOriginal) and change the scope/phase text from
“CLI-only Phase 1” to reflect parity across CLI, .refitter, source generator,
and MSBuild; also update any stale file name references listed in the doc.
Locate the enum/CLI surface description (lines referencing
--property-naming-policyand the list of four values), the “Scope (Phase 1)”
paragraph, and any file name mentions, then replace the old policy names with
the actual shipped names, change the phase/scope wording to indicate feature
parity across all surfaces, and correct the referenced file names so the
decision log matches the implemented behavior.In
@src/Refitter/Settings.cs:
- Around line 33-37: Add XML documentation for the public CLI setting
PropertyNamingPolicy: add a triple-slash comment above the PropertyNamingPolicy
property that includes adescribing that it controls how generated
contract properties are named, mentions the allowed values (referencing
PropertyNamingPolicyValues and the Core.PropertyNamingPolicy enum), and
documents the default value (Core.PropertyNamingPolicy.PascalCase); optionally
include a or noting it is exposed as the
"--property-naming-policy" command-line option and any behavior/impact on
generated contracts.
Outside diff comments:
In@docs/docfx_project/articles/refitter-file-format.md:
- Around line 353-356: The JSON schema example contains an invalid trailing
comma after the "description" value in the property object (the block with
"type": "string" and "description": "The output folder for the generated
contracts code"); remove the trailing comma after that "description" line so the
object before "additionalNamespaces" is valid JSON, ensuring the property object
correctly ends without an extra comma.- Around line 513-514: The JSON schema example has invalid syntax because the
"description" property is missing a trailing comma before the "properties" key;
in the doc block where the snippet shows "description": "Settings for the code
generator." and then "properties": { }, add a comma after the description value
so the JSON is valid (update the example containing the "description" and
"properties" keys).
Nitpick comments:
In @.squad/agents/fenster/history.md:
- Around line 197-287: Update the implementation plan text so the enum values
listed match the implemented PropertyNamingPolicy enum: remove or mark as
deferred the entries for CamelCase and SnakeCase and replace "Preserve" with the
actual implemented name "PreserveOriginal" and ensure "PascalCase" is present;
search for mentions of PropertyNamingPolicy, PascalCase, PreserveOriginal,
CamelCase, and SnakeCase in the document and edit the descriptions (the
paragraphs referencing the enum and the "Recommended Implementation Shape"
section) to reflect only the shipped values (PascalCase, PreserveOriginal) or
explicitly note the other two as future work.In @.squad/implementation-plan-issue-967.md:
- Around line 25-27: The fenced code block containing the literal
"--property-naming-policy [mode]" is missing a language specifier; update the
triple-backtick fence that wraps "--property-naming-policy [mode]" to include a
language such as text or shell (e.g.,text orshell) so markdownlint and
syntax highlighting are satisfied.In @.squad/skills/raw-property-names/SKILL.md:
- Around line 93-104: Update the test
Invalid_Property_Names_With_Hyphens_Are_Rejected to assert the sanitization
behavior instead of expecting an InvalidOperationException: call
GenerateCode(spec) (or the same code path) and verify the resulting property
name matches the sanitized form (e.g., "pay-method" → "pay_method"), aligning
with IdentifierUtils.ToCompilableIdentifier and existing
PropertyNamingPolicyTests.PreserveOriginal_Minimally_Sanitizes_Invalid_Identifiers;
replace the exception assertion with an assertion that the generated model
contains the sanitized identifier.In
@src/Refitter.Core/IdentifierUtils.cs:
- Around line 228-235: The IsValidIdentifier method incorrectly rejects verbatim
identifiers by checking !IsReservedKeyword on the unescaped identifier; update
the logic so that when identifier starts with '@' you only validate the
unescaped text with IsValidIdentifierCore (and the length check) and do not call
IsReservedKeyword, e.g. make the verbatim branch return identifier.Length > 1 &&
IsValidIdentifierCore(unescapedIdentifier) so@classis considered valid; keep
non-verbatim behavior unchanged.In
@src/Refitter.Tests/Examples/PropertyNamingPolicyTests.cs:
- Around line 11-57: Add a parallel Swagger 2.0 spec and tests alongside the
existing OpenApiSpec to validate PropertyNamingPolicy across spec versions:
create a new constant (e.g., SwaggerV2Spec) in PropertyNamingPolicyTests
mirroring the current OpenApiSpec but using OpenAPI/Swagger 2.0 format (swagger:
"2.0", definitions instead of components/schemas, paths/responses adapted), then
duplicate the existing test(s) to run against SwaggerV2Spec (call same test
helper methods that consume OpenApiSpec) so the PropertyNamingPolicy behavior is
asserted for both OpenAPI 3.0.1 (OpenApiSpec) and Swagger 2.0 (SwaggerV2Spec).</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro **Run ID**: `b67dd2cc-d626-4bb2-a61c-4d51e55f5382` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 74a94d7b946d11d54dc4bbb3efcfff7b4c79a2af and d11468591f8d63cc38bb47d9981ef3ebaad44620. </details> <details> <summary>📒 Files selected for processing (31)</summary> * `.squad/agents/fenster/history.md` * `.squad/agents/hockney/history.md` * `.squad/agents/keaton/history.md` * `.squad/commit-message.txt` * `.squad/decisions.md` * `.squad/decisions/fenster-plan-issue-967.md` * `.squad/implementation-plan-issue-967.md` * `.squad/orchestration-log/2026-03-25T08-07-15Z-fenster.md` * `.squad/orchestration-log/2026-03-25T08-07-15Z-hockney.md` * `.squad/orchestration-log/2026-03-25T08-07-15Z-keaton.md` * `.squad/orchestration-log/2026-03-25T09-16-16Z-fenster.md` * `.squad/orchestration-log/2026-03-25T09-16-16Z-hockney.md` * `.squad/orchestration-log/2026-03-25T09-16-16Z-keaton.md` * `.squad/orchestration-log/2026-03-25T10-34-40Z-scribe.md` * `.squad/skills/raw-property-names/SKILL.md` * `README.md` * `docs/docfx_project/articles/refitter-file-format.md` * `docs/json-schema.json` * `src/Refitter.Core/CSharpClientGeneratorFactory.cs` * `src/Refitter.Core/IdentifierUtils.cs` * `src/Refitter.Core/PreserveOriginalPropertyNameGenerator.cs` * `src/Refitter.Core/Settings/PropertyNamingPolicy.cs` * `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` * `src/Refitter.SourceGenerator.Tests/Refitter.SourceGenerator.Tests.csproj` * `src/Refitter.SourceGenerator.Tests/Resources/PropertyNamingPolicy.json` * `src/Refitter.Tests/Examples/PropertyNamingPolicyTests.cs` * `src/Refitter.Tests/GenerateCommandTests.cs` * `src/Refitter.Tests/SerializerTests.cs` * `src/Refitter.Tests/SettingsTests.cs` * `src/Refitter/GenerateCommand.cs` * `src/Refitter/Settings.cs` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| 1. **CLI Surface:** `--property-naming-policy` enum option with 4 values: `PascalCase` (default), `Preserve`, `CamelCase`, `SnakeCase` | ||
| 2. **Implementation:** Pluggable `IPropertyNameGenerator` hierarchy; inject correct generator based on policy | ||
| 3. **Scope (Phase 1):** CLI only; defer `.refitter` file support to Phase 2 (source generator/MSBuild) | ||
| 4. **Default Behavior:** `PascalCase` (backward compatible, no breaking changes) |
There was a problem hiding this comment.
Decision log is out of sync with the implemented feature.
This plan still describes Preserve/CamelCase/SnakeCase and “CLI-only Phase 1”, but the PR implements PreserveOriginal and parity across CLI, .refitter, source generator, and MSBuild. The listed file names are also stale in places. Please update this doc so it reflects the shipped behavior.
Suggested doc update
-1. **CLI Surface:** `--property-naming-policy` enum option with 4 values: `PascalCase` (default), `Preserve`, `CamelCase`, `SnakeCase`
+1. **CLI Surface:** `--property-naming-policy` enum option with 2 values: `PascalCase` (default), `PreserveOriginal`
-3. **Scope (Phase 1):** CLI only; defer `.refitter` file support to Phase 2 (source generator/MSBuild)
+3. **Scope:** CLI, `.refitter`, Source Generator, and MSBuild are all supported
-**Out of Scope (Phase 2):**
-- `.refitter` file support
-- Source generator integration
-- MSBuild task integration
-- Schema evolution for polymorphic `IPropertyNameGenerator` deserialization
+**Out of Scope (Future):**
+- Additional naming policies beyond `PascalCase` and `PreserveOriginal`
-- `src/Refitter.Core/PropertyNamingPolicy.cs` — Enum
-- `src/Refitter.Core/PreservingPropertyNameGenerator.cs` — Generator
+ - `src/Refitter.Core/Settings/PropertyNamingPolicy.cs` — Enum
+ - `src/Refitter.Core/PreserveOriginalPropertyNameGenerator.cs` — GeneratorAlso applies to: 44-48, 55-59
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.squad/decisions/fenster-plan-issue-967.md around lines 15 - 18, The
decision document is out of sync with the implemented feature: update the CLI
option enum names from Preserve/CamelCase/SnakeCase to the shipped names (e.g.,
PreserveOriginal) and change the scope/phase text from “CLI-only Phase 1” to
reflect parity across CLI, .refitter, source generator, and MSBuild; also update
any stale file name references listed in the doc. Locate the enum/CLI surface
description (lines referencing `--property-naming-policy` and the list of four
values), the “Scope (Phase 1)” paragraph, and any file name mentions, then
replace the old policy names with the actual shipped names, change the
phase/scope wording to indicate feature parity across all surfaces, and correct
the referenced file names so the decision log matches the implemented behavior.
| [Description($"Controls how generated contract properties are named. May be one of {PropertyNamingPolicyValues}")] | ||
| [CommandOption("--property-naming-policy")] | ||
| [DefaultValue(Core.PropertyNamingPolicy.PascalCase)] | ||
| public Core.PropertyNamingPolicy PropertyNamingPolicy { get; set; } = Core.PropertyNamingPolicy.PascalCase; | ||
|
|
There was a problem hiding this comment.
Add XML documentation for the new public CLI setting.
PropertyNamingPolicy is public API but is missing XML doc comments.
✏️ Suggested patch
+ /// <summary>
+ /// Controls how generated contract properties are named.
+ /// </summary>
[Description($"Controls how generated contract properties are named. May be one of {PropertyNamingPolicyValues}")]
[CommandOption("--property-naming-policy")]
[DefaultValue(Core.PropertyNamingPolicy.PascalCase)]
public Core.PropertyNamingPolicy PropertyNamingPolicy { get; set; } = Core.PropertyNamingPolicy.PascalCase;As per coding guidelines, "Include XML documentation for public APIs in C# code".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [Description($"Controls how generated contract properties are named. May be one of {PropertyNamingPolicyValues}")] | |
| [CommandOption("--property-naming-policy")] | |
| [DefaultValue(Core.PropertyNamingPolicy.PascalCase)] | |
| public Core.PropertyNamingPolicy PropertyNamingPolicy { get; set; } = Core.PropertyNamingPolicy.PascalCase; | |
| /// <summary> | |
| /// Controls how generated contract properties are named. | |
| /// </summary> | |
| [Description($"Controls how generated contract properties are named. May be one of {PropertyNamingPolicyValues}")] | |
| [CommandOption("--property-naming-policy")] | |
| [DefaultValue(Core.PropertyNamingPolicy.PascalCase)] | |
| public Core.PropertyNamingPolicy PropertyNamingPolicy { get; set; } = Core.PropertyNamingPolicy.PascalCase; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/Refitter/Settings.cs` around lines 33 - 37, Add XML documentation for the
public CLI setting PropertyNamingPolicy: add a triple-slash comment above the
PropertyNamingPolicy property that includes a <summary> describing that it
controls how generated contract properties are named, mentions the allowed
values (referencing PropertyNamingPolicyValues and the Core.PropertyNamingPolicy
enum), and documents the default value (Core.PropertyNamingPolicy.PascalCase);
optionally include a <remarks> or <example> noting it is exposed as the
"--property-naming-policy" command-line option and any behavior/impact on
generated contracts.
Updated [refitter](https://github.com/christianhelle/refitter) from 1.7.1 to 2.0.0. <details> <summary>Release notes</summary> _Sourced from [refitter's releases](https://github.com/christianhelle/refitter/releases)._ ## 2.0.0 ## What's Changed * Fix numeric format with pattern quirk - infer type from format for all numeric types by @Copilot in christianhelle/refitter#869 * Read group documentation from document tags. by @DJ4ddi in christianhelle/refitter#887 * Fix null reference and XML escaping in XmlDocumentationGenerator by @Copilot in christianhelle/refitter#890 * Fix build workflow: add dotnet restore before dotnet msbuild in Prepare step by @Copilot in christianhelle/refitter#892 christianhelle/refitter#895 * Fix MSBuild workflow by @christianhelle in christianhelle/refitter#898 * Add support for generating a single client from multiple OpenAPI specifications by @Copilot in christianhelle/refitter#904 * Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by @vgmello in christianhelle/refitter#907 * Improve Smoke Tests execution time by @christianhelle in christianhelle/refitter#915 * Fix #580: Nullable strings marked correctly by @christianhelle in christianhelle/refitter#921 * Fix #672: MultipleInterfaces ByTag method naming scoped per-interface by @christianhelle in christianhelle/refitter#922 * Fix #635: Refactor source generator to use context.AddSource() by @christianhelle in christianhelle/refitter#923 * Add custom format mappings configuration by @christianhelle in christianhelle/refitter#927 * Fix multipart form-data parameter extraction by @christianhelle in christianhelle/refitter#928 christianhelle/refitter#911 christianhelle/refitter#902 * Fix smoke tests: --interface-only variant missing using directive for contract types by @Copilot in christianhelle/refitter#933 * Fix SonarCloud Code Quality Issues by @Copilot in christianhelle/refitter#932 * Add debug logging for source generator when searching for .refitter files by @codymullins in christianhelle/refitter#743 * Fix: Base type not generated for types using oneOf with discriminator by @Copilot in christianhelle/refitter#906 * Add option for Method Level Authorization header attribute by @Roflincopter in christianhelle/refitter#897 * Fix PR #897 review feedback and add comprehensive bearer auth tests by @christianhelle in christianhelle/refitter#936 * Fix numeric suffix added to interface method names in ByTag mode by @Copilot in christianhelle/refitter#914 * Improve OpenAPI parse + codegen throughput by removing avoidable allocations and repeated regex work by @Copilot in christianhelle/refitter#937 * Move [JsonConverter] from enum properties to enum types by @christianhelle in christianhelle/refitter#938 * Fix broken CLI tool help text by @christianhelle in christianhelle/refitter#940 * Improve code coverage to >90% by @christianhelle in christianhelle/refitter#941 * Microsoft.OpenApi v3.4 by @christianhelle in christianhelle/refitter#945 * Add Unicode support for XML doc comment generation by @christianhelle in christianhelle/refitter#948 * Add PropertyNamingPolicy support for JSON property naming by @christianhelle in christianhelle/refitter#969 christianhelle/refitter#966 * Fix recursive schema stack overflows by @christianhelle in christianhelle/refitter#971 * Made Header Parameters for Security Schemes safe to use as C# variable name by @smoerijf in christianhelle/refitter#977 * Enhance schema alias handling and property name generation by @christianhelle in christianhelle/refitter#996 * Verify alias handling and sanitize PascalCase properties by @christianhelle in christianhelle/refitter#997 * Harden .refitter settings deserialization and output path handling by @christianhelle in christianhelle/refitter#1000 * Special-case the default .refitter filename before deriving OutputFilename by @coderabbitai[bot] in christianhelle/refitter#1002 * [v2.0 audit] Fix pre-release regressions from #1057 by @christianhelle in christianhelle/refitter#1064 * Resolve high-severity audit findings from #1057 by @christianhelle in christianhelle/refitter#1067 * [v2.0 audit] Close remaining verified #1057 regressions by @christianhelle in christianhelle/refitter#1070 * Harden generation flows by @christianhelle in christianhelle/refitter#1071 * Breaking changes and Migration Guide for v2.0.0 by @christianhelle in christianhelle/refitter#1009 * Handle equivalent duplicate schemas in multi-spec merge by @christianhelle in christianhelle/refitter#1076 * Tighten warning handling across Refitter builds by @christianhelle in christianhelle/refitter#1079 * Fix default solution path and update .NET version in VS Code config by @christianhelle in christianhelle/refitter#1082 * Fix docker smoke tests by @christianhelle in christianhelle/refitter#1081 * Sanitize malformed schema type names without renaming clean schemas by @christianhelle in christianhelle/refitter#1085 ... (truncated) ## 1.7.3 ## What's Changed * Add support for systems running only .NET 10.0 (without .NET 8.0 or 9.0) in Refitter.MSBuild by @christianhelle in christianhelle/refitter#882 * Update to return HttpResponseMessage for file downloads by @frogcrush in christianhelle/refitter#877 ## New Contributors * @frogcrush made their first contribution in christianhelle/refitter#877 **Full Changelog**: christianhelle/refitter@1.7.2...1.7.3 ## 1.7.2 **Implemented enhancements:** - Improve Immutable Records ergonomics [\#844](christianhelle/refitter#844) - Omit certain operation headers and include all others [\#840](christianhelle/refitter#840) - Create .refitter settings file as part of output [\#859](christianhelle/refitter#859) by @[christianhelle - Fix integerType enum deserialization issue [\#855](christianhelle/refitter#855) ([christianhelle](https://github.com/christianhelle)) - support custom nswag template directory \#844 [\#854](christianhelle/refitter#854) by @kmc059000 - Fix missing method parameter XML code-documentation [\#850](christianhelle/refitter#850) ([christianhelle](https://github.com/christianhelle)) **Fixed bugs:** - integerType parsing in settings file fails [\#851](christianhelle/refitter#851) - CS1573 : Method parameter has no matching XML comment [\#846](christianhelle/refitter#846) **Merged pull requests:** - docs: add frogcrush as a contributor for code [\#878](christianhelle/refitter#878) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - Migrate solution files from .sln to .slnx format [\#876](christianhelle/refitter#876) ([Copilot](https://github.com/apps/copilot-swe-agent)) - Fix issue with randomly failing tests to due parallel execution [\#872](christianhelle/refitter#872) ([christianhelle](https://github.com/christianhelle)) - chore\(deps\): update dependency tunit to 1.9.2 [\#863](christianhelle/refitter#863) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.7.7 [\#862](christianhelle/refitter#862) ([renovate[bot]](https://github.com/apps/renovate)) - Add unit tests for WriteRefitterSettingsFile functionality [\#860](christianhelle/refitter#860) ([Copilot](https://github.com/apps/copilot-swe-agent)) - chore\(deps\): update dependency ruby to v4 [\#858](christianhelle/refitter#858) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.6.28 [\#857](christianhelle/refitter#857) ([renovate[bot]](https://github.com/apps/renovate)) - docs: add 0x2badc0de as a contributor for bug [\#856](christianhelle/refitter#856) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - chore\(deps\): update dependency swashbuckle.aspnetcore to 10.1.0 [\#853](christianhelle/refitter#853) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.6.0 [\#852](christianhelle/refitter#852) ([renovate[bot]](https://github.com/apps/renovate)) - docs: add lilinus as a contributor for code [\#849](christianhelle/refitter#849) ([allcontributors[bot]](https://github.com/apps/allcontributors)) - chore\(deps\): update dependency ruby to v3.4.8 [\#845](christianhelle/refitter#845) ([renovate[bot]](https://github.com/apps/renovate)) - chore\(deps\): update dependency tunit to 1.5.70 [\#837](christianhelle/refitter#837) ([renovate[bot]](https://github.com/apps/renovate)) **Full Changelog**: christianhelle/refitter@1.7.1...1.7.2 Commits viewable in [compare view](christianhelle/refitter@1.7.1...2.0.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated [Refitter.MSBuild](https://github.com/christianhelle/refitter) from 1.7.3 to 2.0.0. <details> <summary>Release notes</summary> _Sourced from [Refitter.MSBuild's releases](https://github.com/christianhelle/refitter/releases)._ ## 2.0.0 ## What's Changed * Fix numeric format with pattern quirk - infer type from format for all numeric types by @Copilot in christianhelle/refitter#869 * Read group documentation from document tags. by @DJ4ddi in christianhelle/refitter#887 * Fix null reference and XML escaping in XmlDocumentationGenerator by @Copilot in christianhelle/refitter#890 * Fix build workflow: add dotnet restore before dotnet msbuild in Prepare step by @Copilot in christianhelle/refitter#892 christianhelle/refitter#895 * Fix MSBuild workflow by @christianhelle in christianhelle/refitter#898 * Add support for generating a single client from multiple OpenAPI specifications by @Copilot in christianhelle/refitter#904 * Migrate from Microsoft.OpenApi.Readers 1.x to Microsoft.OpenApi 3.x by @vgmello in christianhelle/refitter#907 * Improve Smoke Tests execution time by @christianhelle in christianhelle/refitter#915 * Fix #580: Nullable strings marked correctly by @christianhelle in christianhelle/refitter#921 * Fix #672: MultipleInterfaces ByTag method naming scoped per-interface by @christianhelle in christianhelle/refitter#922 * Fix #635: Refactor source generator to use context.AddSource() by @christianhelle in christianhelle/refitter#923 * Add custom format mappings configuration by @christianhelle in christianhelle/refitter#927 * Fix multipart form-data parameter extraction by @christianhelle in christianhelle/refitter#928 christianhelle/refitter#911 christianhelle/refitter#902 * Fix smoke tests: --interface-only variant missing using directive for contract types by @Copilot in christianhelle/refitter#933 * Fix SonarCloud Code Quality Issues by @Copilot in christianhelle/refitter#932 * Add debug logging for source generator when searching for .refitter files by @codymullins in christianhelle/refitter#743 * Fix: Base type not generated for types using oneOf with discriminator by @Copilot in christianhelle/refitter#906 * Add option for Method Level Authorization header attribute by @Roflincopter in christianhelle/refitter#897 * Fix PR #897 review feedback and add comprehensive bearer auth tests by @christianhelle in christianhelle/refitter#936 * Fix numeric suffix added to interface method names in ByTag mode by @Copilot in christianhelle/refitter#914 * Improve OpenAPI parse + codegen throughput by removing avoidable allocations and repeated regex work by @Copilot in christianhelle/refitter#937 * Move [JsonConverter] from enum properties to enum types by @christianhelle in christianhelle/refitter#938 * Fix broken CLI tool help text by @christianhelle in christianhelle/refitter#940 * Improve code coverage to >90% by @christianhelle in christianhelle/refitter#941 * Microsoft.OpenApi v3.4 by @christianhelle in christianhelle/refitter#945 * Add Unicode support for XML doc comment generation by @christianhelle in christianhelle/refitter#948 * Add PropertyNamingPolicy support for JSON property naming by @christianhelle in christianhelle/refitter#969 christianhelle/refitter#966 * Fix recursive schema stack overflows by @christianhelle in christianhelle/refitter#971 * Made Header Parameters for Security Schemes safe to use as C# variable name by @smoerijf in christianhelle/refitter#977 * Enhance schema alias handling and property name generation by @christianhelle in christianhelle/refitter#996 * Verify alias handling and sanitize PascalCase properties by @christianhelle in christianhelle/refitter#997 * Harden .refitter settings deserialization and output path handling by @christianhelle in christianhelle/refitter#1000 * Special-case the default .refitter filename before deriving OutputFilename by @coderabbitai[bot] in christianhelle/refitter#1002 * [v2.0 audit] Fix pre-release regressions from #1057 by @christianhelle in christianhelle/refitter#1064 * Resolve high-severity audit findings from #1057 by @christianhelle in christianhelle/refitter#1067 * [v2.0 audit] Close remaining verified #1057 regressions by @christianhelle in christianhelle/refitter#1070 * Harden generation flows by @christianhelle in christianhelle/refitter#1071 * Breaking changes and Migration Guide for v2.0.0 by @christianhelle in christianhelle/refitter#1009 * Handle equivalent duplicate schemas in multi-spec merge by @christianhelle in christianhelle/refitter#1076 * Tighten warning handling across Refitter builds by @christianhelle in christianhelle/refitter#1079 * Fix default solution path and update .NET version in VS Code config by @christianhelle in christianhelle/refitter#1082 * Fix docker smoke tests by @christianhelle in christianhelle/refitter#1081 * Sanitize malformed schema type names without renaming clean schemas by @christianhelle in christianhelle/refitter#1085 ... (truncated) Commits viewable in [compare view](christianhelle/refitter@1.7.3...2.0.0). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>



This PR implements issue #967, adding full user-facing PropertyNamingPolicy support to Refitter.
Changes
PropertyNamingPolicyCLI option (--property-naming-policywith values:PascalCase(default) orPreserveOriginal).refitterfile format withpropertyNamingPolicysetting in JSON schemaPropertyNamingPolicyenum in RefitGeneratorSettings for CLI, Source Generator, and MSBuildGenerateCommand), Source Generator (RefitterSourceGenerator), and MSBuild (RefitterTask)README.md,refitter-file-format.md)json-schema.json)Related to