Skip to content

support custom nswag template directory #844#854

Merged
christianhelle merged 3 commits into
christianhelle:mainfrom
kmc059000:844/draft-custom-templates
Jan 13, 2026
Merged

support custom nswag template directory #844#854
christianhelle merged 3 commits into
christianhelle:mainfrom
kmc059000:844/draft-custom-templates

Conversation

@kmc059000

@kmc059000 kmc059000 commented Dec 20, 2025

Copy link
Copy Markdown
Contributor

Solving #844 by supporting providing a custom template directory. This puts the power in users hands to customize the generated code however they want.

With this, it is possible to provide a subset of templates and the remaining templates will fallback to the default templates in NSwag.

By default, custom templates are disabled and require explicitly specifying the directory to enable. Due to this, this is a non breaking change for existing users.

Design considerations

On the one hand, this allows the generated code to be highly customizable by end users, which may minimizes the number of configuration values refitter must support as explicit configuration points.

On the other hand it can be risky from a refitter standpoint when users use custom templates.

  • NSwag could introduces changes that cause templates to break, which could cause undue burden on refitter as it may seem like a refitter issue and lead to unnecessary support burden.
  • leaking of Nswag concerns into refitter adds complexity to refitter
  • May not be compatible with certain refitter settings. It is possible that users can break refitter features through custom templates.

Personally I find the tradeoffs acceptable. Users are unlikely to implement custom templates, and if they do, there is a level of ownership. This is very similar to NSwag's decision to support custom templates themselves.

Summary by CodeRabbit

  • New Features

    • Added --custom-template-directory CLI option and matching customTemplateDirectory config to allow specifying custom NSwag template directories for code generation.
  • Documentation

    • Updated CLI help, README examples, and configuration/schema docs to document the new option and config field.
  • Tests

    • Added tests covering custom template usage and polymorphic serialization; included a sample custom template asset.
  • Chores

    • Test build adjusted to ensure template assets are copied to test output.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 20, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a new CustomTemplateDirectory configuration and CLI option, wires it through Settings → RefitGeneratorSettings → CSharpClientGeneratorFactory to set NSwag template directory, updates docs/schema, and adds tests and a sample liquid template to validate custom template usage.

Changes

Cohort / File(s) Summary
CLI & Top-level Settings
src/Refitter/Settings.cs, src/Refitter/GenerateCommand.cs
Added CustomTemplateDirectory CLI option/property and map it into RefitGeneratorSettings during generator setup.
Core Generator Settings
src/Refitter.Core/Settings/CodeGeneratorSettings.cs, src/Refitter.Core/Settings/RefitGeneratorSettings.cs, src/Refitter.Core/CSharpClientGeneratorFactory.cs
Added CustomTemplateDirectory property and set TemplateDirectory = settings.CustomTemplateDirectory when creating C# client generator settings.
Documentation & Schema
Docs: .github/copilot-instructions.md, README.md, docs/docfx_project/articles/cli-tool.md, docs/docfx_project/articles/refitter-file-format.md, docs/json-schema.json, src/Refitter.MSBuild/README.md, src/Refitter.SourceGenerator/README.md, src/Refitter/README.md
Documented new --custom-template-directory CLI option and customTemplateDirectory config field; updated examples and JSON schema.
Tests & Test Assets
src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs, src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs, src/Refitter.Tests/Refitter.Tests.csproj, src/Refitter.Tests/Templates/Class.Annotations.liquid
Added tests validating custom-template generation (including polymorphic scenario), included sample liquid template, and updated test project to copy template to output. (One test method appears duplicated.)
Repo guidance
.github/copilot-instructions.md
Minor formatting and reflow tweaks to CLI/help examples and code blocks.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer/CLI
    participant CLI as GenerateCommand
    participant Settings as Settings / RefitGeneratorSettings
    participant Factory as CSharpClientGeneratorFactory
    participant NSwag as NSwag Template Loader
    participant Test as Test Runner / Output

    Dev->>CLI: invoke generate with --custom-template-directory /path
    CLI->>Settings: set CustomTemplateDirectory
    CLI->>Settings: build RefitGeneratorSettings (include CustomTemplateDirectory)
    CLI->>Factory: Create generator with RefitGeneratorSettings
    Factory->>NSwag: assign TemplateDirectory = CustomTemplateDirectory
    NSwag->>Test: render templates (custom directory or defaults)
    Test->>Test: assert custom-template marker and compile generated code
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect duplicated test method in src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs.
  • Verify correct propagation: SettingsRefitGeneratorSettingsCSharpClientGeneratorFactory.
  • Check MSBuild copy item and test asset path: src/Refitter.Tests/Refitter.Tests.csproj and src/Refitter.Tests/Templates/Class.Annotations.liquid.

Possibly related PRs

Suggested labels

enhancement, .NET

Suggested reviewers

  • christianhelle

Poem

🐰 Hop, hop — a template path I bring,

Liquid crumbs for code to spring.
Flag to CLI, through settings sped,
Templates render — tests are fed.
🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'support custom nswag template directory #844' clearly and specifically describes the main feature added in this changeset: support for custom NSwag template directories. It is concise, directly related to the primary objective of the PR, and would be understandable in a commit history.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
src/Refitter.MSBuild/README.md (1)

245-245: Consider wrapping bare URL in angle brackets.

For better markdown formatting, wrap the URL in angle brackets: <https://github.com/RicoSuter/NSwag/wiki/Templates>

🔎 Proposed fix
-  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See https://github.com/RicoSuter/NSwag/wiki/Templates
+  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See <https://github.com/RicoSuter/NSwag/wiki/Templates>
src/Refitter.Core/Settings/CodeGeneratorSettings.cs (1)

275-281: Align terminology for NSwag templates ("liquid" vs "fluid")

The XML summary calls them “liquid templates” while the Description attribute says “fluid templates”. Consider standardizing this wording (and matching the NSwag docs) so the property description is consistent with the CLI and schema text.

src/Refitter/README.md (1)

328-328: Wrap the URL in angle brackets to satisfy markdownlint (MD034)

The new customTemplateDirectory bullet uses a bare URL; elsewhere in this README URLs are typically written as <https://...>. Consider wrapping this one similarly to avoid MD034 and keep the style consistent.

Suggested markdown tweak
-  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See https://github.com/RicoSuter/NSwag/wiki/Templates
+  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See <https://github.com/RicoSuter/NSwag/wiki/Templates>
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ebbdc3b and 039754c.

📒 Files selected for processing (17)
  • .github/copilot-instructions.md (4 hunks)
  • README.md (2 hunks)
  • docs/docfx_project/articles/cli-tool.md (1 hunks)
  • docs/docfx_project/articles/refitter-file-format.md (1 hunks)
  • docs/json-schema.json (1 hunks)
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs (1 hunks)
  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs (1 hunks)
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs (1 hunks)
  • src/Refitter.MSBuild/README.md (2 hunks)
  • src/Refitter.SourceGenerator/README.md (1 hunks)
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs (1 hunks)
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (1 hunks)
  • src/Refitter.Tests/Refitter.Tests.csproj (1 hunks)
  • src/Refitter.Tests/Templates/Class.Annotations.liquid (1 hunks)
  • src/Refitter/GenerateCommand.cs (1 hunks)
  • src/Refitter/README.md (3 hunks)
  • src/Refitter/Settings.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.cs: Use PascalCase for public members and camelCase for parameters and local variables in C# code
Include XML documentation for public APIs in C# code
Use meaningful variable and method names in C# code
Follow existing C# coding conventions defined in .editorconfig

Files:

  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs
  • src/Refitter/Settings.cs
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
src/Refitter.Core/**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Implement new CLI option logic in src/Refitter.Core/RefitInterfaceGenerator.cs or related generator classes

Files:

  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
src/Refitter/Settings.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add new CLI options as properties in src/Refitter/Settings.cs with [CommandOption("--option-name")] attribute

Files:

  • src/Refitter/Settings.cs
README.md

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update README.md documentation with new CLI options

Files:

  • README.md
src/Refitter/GenerateCommand.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Update CreateRefitGeneratorSettings() method in src/Refitter/GenerateCommand.cs when adding new CLI options

Files:

  • src/Refitter/GenerateCommand.cs
src/Refitter.Core/Settings/RefitGeneratorSettings.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Add corresponding property to src/Refitter.Core/Settings/RefitGeneratorSettings.cs for each new CLI option

Files:

  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
src/Refitter.Tests/**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/Refitter.Tests/**/*.cs: All new code must include unit tests following the pattern in Refitter.Tests.Examples namespace with test classes containing [Fact] methods
Test CLI changes with real OpenAPI specifications to ensure generation works correctly
Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
🧠 Learnings (14)
📓 Common learnings
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/**/*.cs : Implement new CLI option logic in `src/Refitter.Core/RefitInterfaceGenerator.cs` or related generator classes
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option

Applied to files:

  • src/Refitter.MSBuild/README.md
  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs
  • src/Refitter/Settings.cs
  • README.md
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • docs/json-schema.json
  • src/Refitter/README.md
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • src/Refitter.SourceGenerator/README.md
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
  • docs/docfx_project/articles/refitter-file-format.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/**/*.cs : Implement new CLI option logic in `src/Refitter.Core/RefitInterfaceGenerator.cs` or related generator classes

Applied to files:

  • src/Refitter.MSBuild/README.md
  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs
  • src/Refitter.Tests/Refitter.Tests.csproj
  • README.md
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • src/Refitter/README.md
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • src/Refitter.SourceGenerator/README.md
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
  • docs/docfx_project/articles/refitter-file-format.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Update `CreateRefitGeneratorSettings()` method in `src/Refitter/GenerateCommand.cs` when adding new CLI options

Applied to files:

  • src/Refitter.Core/Settings/CodeGeneratorSettings.cs
  • src/Refitter/Settings.cs
  • README.md
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • src/Refitter/README.md
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
  • docs/docfx_project/articles/refitter-file-format.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/Settings.cs : Add new CLI options as properties in `src/Refitter/Settings.cs` with `[CommandOption("--option-name")]` attribute

Applied to files:

  • src/Refitter/Settings.cs
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/Settings/RefitGeneratorSettings.cs
  • src/Refitter/README.md
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test CLI changes with real OpenAPI specifications to ensure generation works correctly

Applied to files:

  • src/Refitter.Tests/Refitter.Tests.csproj
  • README.md
  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • src/Refitter/README.md
  • src/Refitter.Core/CSharpClientGeneratorFactory.cs
  • docs/docfx_project/articles/cli-tool.md
  • src/Refitter.Tests/Templates/Class.Annotations.liquid
  • .github/copilot-instructions.md
  • docs/docfx_project/articles/refitter-file-format.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : All new code must include unit tests following the pattern in `Refitter.Tests.Examples` namespace with test classes containing [Fact] methods

Applied to files:

  • src/Refitter.Tests/Refitter.Tests.csproj
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • src/Refitter.Tests/Templates/Class.Annotations.liquid
  • .github/copilot-instructions.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Applied to files:

  • src/Refitter.Tests/Refitter.Tests.csproj
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Always run `dotnet format src/Refitter.sln` before committing to ensure CI compliance

Applied to files:

  • src/Refitter.Tests/Refitter.Tests.csproj
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to README.md : Update README.md documentation with new CLI options

Applied to files:

  • README.md
  • src/Refitter/README.md
  • docs/docfx_project/articles/cli-tool.md
  • .github/copilot-instructions.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Generated code must compile successfully with the C# compiler

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Set timeout to 60+ seconds for build operations (`dotnet build -c Release src/Refitter.sln`)

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Set timeout to 90+ seconds for package restore operation (`dotnet restore src/Refitter.sln`)

Applied to files:

  • .github/copilot-instructions.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Set timeout to 480+ seconds for test execution (`dotnet test -c Release src/Refitter.sln`)

Applied to files:

  • .github/copilot-instructions.md
🧬 Code graph analysis (3)
src/Refitter/Settings.cs (1)
src/Refitter.Core/Settings/CodeGeneratorSettings.cs (1)
  • Description (10-282)
src/Refitter.Core/Settings/RefitGeneratorSettings.cs (1)
src/Refitter.Core/Settings/CodeGeneratorSettings.cs (1)
  • Description (10-282)
src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (4)
src/Refitter/GenerateCommand.cs (5)
  • Task (27-269)
  • Task (321-381)
  • Task (397-541)
  • Task (664-771)
  • RefitGeneratorSettings (271-320)
src/Refitter.Tests/Build/BuildHelper.cs (2)
  • BuildHelper (6-53)
  • BuildCSharp (8-45)
src/Refitter.Tests/TestUtilities/SwaggerFileHelper.cs (1)
  • SwaggerFileHelper (9-36)
src/Refitter.Core/RefitGenerator.cs (1)
  • RefitGenerator (10-311)
🪛 markdownlint-cli2 (0.18.1)
src/Refitter.MSBuild/README.md

245-245: Bare URL used

(MD034, no-bare-urls)

src/Refitter/README.md

328-328: Bare URL used

(MD034, no-bare-urls)

.github/copilot-instructions.md

155-155: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: script
  • GitHub Check: 👌 Verify build
  • GitHub Check: 👌 Verify build
  • GitHub Check: 👌 Verify build
🔇 Additional comments (15)
src/Refitter.Tests/Refitter.Tests.csproj (1)

18-20: LGTM!

Correctly configures the test template to be copied to the output directory, enabling custom template tests.

src/Refitter/GenerateCommand.cs (1)

313-319: LGTM!

Correctly wires the CustomTemplateDirectory from CLI settings into RefitGeneratorSettings, following the established pattern for new CLI options. Based on learnings, this aligns with the guideline to update CreateRefitGeneratorSettings() when adding new CLI options.

src/Refitter.SourceGenerator/README.md (1)

129-130: LGTM!

Documentation clearly shows the new optional field with appropriate reference to NSwag's template documentation.

src/Refitter.Core/Settings/RefitGeneratorSettings.cs (1)

391-396: LGTM!

The new property follows proper C# conventions with clear XML documentation and Description attribute. Based on learnings, this correctly adds the corresponding property to RefitGeneratorSettings for the new CLI option.

docs/docfx_project/articles/refitter-file-format.md (1)

125-126: LGTM!

Documentation correctly adds the new optional field with helpful reference link to NSwag's template documentation.

src/Refitter.MSBuild/README.md (1)

168-169: LGTM!

Documentation correctly adds the new optional field with helpful reference link.

src/Refitter.Core/CSharpClientGeneratorFactory.cs (1)

45-45: CustomTemplateDirectory is properly handled as an optional nullable property.

The assignment TemplateDirectory = settings.CustomTemplateDirectory is correct—NSwag expects this property to accept null values and uses default templates when null. The property is properly defined as nullable throughout Refitter (Settings.cs, CodeGeneratorSettings.cs, RefitGeneratorSettings.cs), and the documentation confirms: "If null or empty, uses default templates."

Error handling for invalid or non-existent directories is NSwag's responsibility, not Refitter's. If you need additional validation before passing to NSwag, that could be considered, but the current approach of delegating to NSwag is appropriate.

README.md (2)

140-141: CLI docs for --custom-template-directory look consistent

The new option description matches the Settings attribute text and intended behavior (optional path, defaults to NSwag templates), so the CLI help here is in good shape.


300-302: .refitter example correctly documents codeGeneratorSettings.customTemplateDirectory

The added customTemplateDirectory field in the codeGeneratorSettings example is syntactically valid JSON and clearly explains how to point at a custom NSwag template directory.

src/Refitter/Settings.cs (1)

272-275: --custom-template-directory CLI option wiring looks correct

The CustomTemplateDirectory property is properly exposed via [CommandOption("--custom-template-directory")] with a nullable string and default null, matching the documented behavior.

docs/json-schema.json (1)

196-199: JSON schema update for codeGeneratorSettings.customTemplateDirectory is accurate

The new customTemplateDirectory property is correctly added as a string under CodeGeneratorSettings, keeping the public JSON schema aligned with the new configuration surface.

docs/docfx_project/articles/cli-tool.md (1)

51-124: CLI help text (including --custom-template-directory) is consistent with implementation

The reflowed OPTIONS section and the new --custom-template-directory entry match the current Settings definitions and root README, so the CLI article remains accurate.

src/Refitter/README.md (1)

118-119: Top-level CLI README entry for --custom-template-directory is well-aligned

The new option in the OPTIONS table is consistent with the CLI implementation and higher-level README, so users get a clear description of how to point at custom NSwag templates.

src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs (1)

146-159: Good coverage for custom template directory across OpenAPI 2.0 and 3.0

This test exercises CustomTemplateDirectory against all sample specs and validates both the custom template marker and a generated Pet class, giving solid regression coverage for the new setting.

src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (1)

189-244: Comprehensive tests for polymorphic serialization + custom templates + buildability

The new example suite does a nice job of:

  • Verifying the switch from NSwag JsonInheritance* to JsonPolymorphic/JsonDerivedType attributes,
  • Ensuring the custom template directory is actually used, and
  • Guarding that the generated code still compiles via BuildHelper.

This gives strong end-to-end coverage of the new feature in a realistic OpenAPI 3.0 scenario.

Comment thread .github/copilot-instructions.md Outdated
Comment thread src/Refitter.Tests/Templates/Class.Annotations.liquid Outdated
@codecov

codecov Bot commented Dec 20, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.76%. Comparing base (bcf6b6f) to head (83d3d4d).
⚠️ Report is 34 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #854   +/-   ##
=======================================
  Coverage   92.75%   92.76%           
=======================================
  Files          23       23           
  Lines        1947     1949    +2     
=======================================
+ Hits         1806     1808    +2     
  Misses         48       48           
  Partials       93       93           
Flag Coverage Δ
unittests 92.76% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (2)

219-221: Minor: Extra blank line.

There's an extra blank line between Use_CustomTemplates and Can_Build_Generated_Code tests.

🔎 Proposed fix
     }

-
     [Test]
     public async Task Can_Build_Generated_Code()

8-9: Consider adding XML documentation for the test class.

Per coding guidelines, public APIs should include XML documentation. While this is a test class, a brief summary would help clarify that this tests the combination of polymorphic serialization with custom NSwag templates.

🔎 Proposed addition
+/// <summary>
+/// Tests code generation with polymorphic serialization enabled and custom NSwag templates.
+/// </summary>
 public class UsePolymorphicSerializationAndCustomTemplatesTests
 {
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 039754c and b11710b.

📒 Files selected for processing (10)
  • .github/copilot-instructions.md (4 hunks)
  • README.md (2 hunks)
  • docs/docfx_project/articles/cli-tool.md (1 hunks)
  • docs/docfx_project/articles/refitter-file-format.md (1 hunks)
  • src/Refitter.MSBuild/README.md (2 hunks)
  • src/Refitter.SourceGenerator/README.md (1 hunks)
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs (1 hunks)
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (1 hunks)
  • src/Refitter.Tests/Templates/Class.Annotations.liquid (1 hunks)
  • src/Refitter/README.md (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (7)
  • src/Refitter.Tests/CustomCSharpGeneratorSettingsTests.cs
  • README.md
  • src/Refitter/README.md
  • docs/docfx_project/articles/cli-tool.md
  • src/Refitter.Tests/Templates/Class.Annotations.liquid
  • docs/docfx_project/articles/refitter-file-format.md
  • .github/copilot-instructions.md
🧰 Additional context used
📓 Path-based instructions (2)
src/Refitter.Tests/**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/Refitter.Tests/**/*.cs: All new code must include unit tests following the pattern in Refitter.Tests.Examples namespace with test classes containing [Fact] methods
Test CLI changes with real OpenAPI specifications to ensure generation works correctly
Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.cs: Use PascalCase for public members and camelCase for parameters and local variables in C# code
Include XML documentation for public APIs in C# code
Use meaningful variable and method names in C# code
Follow existing C# coding conventions defined in .editorconfig

Files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Update `CreateRefitGeneratorSettings()` method in `src/Refitter/GenerateCommand.cs` when adding new CLI options
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option

Applied to files:

  • src/Refitter.SourceGenerator/README.md
  • src/Refitter.MSBuild/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/**/*.cs : Implement new CLI option logic in `src/Refitter.Core/RefitInterfaceGenerator.cs` or related generator classes

Applied to files:

  • src/Refitter.SourceGenerator/README.md
  • src/Refitter.MSBuild/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Update `CreateRefitGeneratorSettings()` method in `src/Refitter/GenerateCommand.cs` when adding new CLI options

Applied to files:

  • src/Refitter.MSBuild/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test CLI changes with real OpenAPI specifications to ensure generation works correctly

Applied to files:

  • src/Refitter.MSBuild/README.md
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/Settings.cs : Add new CLI options as properties in `src/Refitter/Settings.cs` with `[CommandOption("--option-name")]` attribute

Applied to files:

  • src/Refitter.MSBuild/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Applied to files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : All new code must include unit tests following the pattern in `Refitter.Tests.Examples` namespace with test classes containing [Fact] methods

Applied to files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: script
  • GitHub Check: 👌 Verify build
  • GitHub Check: 👌 Verify build
  • GitHub Check: 👌 Verify build
🔇 Additional comments (4)
src/Refitter.MSBuild/README.md (1)

165-170: Documentation for customTemplateDirectory is complete and well-placed.

The property is properly documented in both the JSON example and the detailed property documentation section. The explanation clearly describes the purpose, default value, and provides a reference link.

Also applies to: 244-245

src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (3)

1-6: LGTM!

The imports are appropriate and the namespace follows the Refitter.Tests.Examples pattern as per coding guidelines.


10-187: Well-structured OpenAPI spec for polymorphic serialization testing.

The spec appropriately covers discriminator-based polymorphism with multiple derived types (Warehouse, WarehouseResponse, LoadingAddress, UserComponent, UserComponent2). While coding guidelines suggest testing with both OpenAPI 2.0 and 3.0, the discriminator feature being tested here is specific to OpenAPI 3.0, so testing only 3.0 is reasonable for this scenario.


231-244: No action needed. The custom template directory and required template files are properly configured and present in the test project.

Likely an incorrect or invalid review comment.

Comment on lines 126 to +130
"excludedTypeNames": [
"ExcludedTypeFoo",
"ExcludedTypeBar"
]
],
"customTemplateDirectory": "./path/to/directory/" // Optional. See <https://github.com/RicoSuter/NSwag/wiki/Templates>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add detailed documentation for customTemplateDirectory property.

The JSON example includes the new customTemplateDirectory property, but unlike the MSBuild README, this file lacks a detailed explanation in the documentation section. Add an entry in the codeGeneratorSettings documentation (after the excludedTypeNames explanation at line 206) to match the documentation provided in src/Refitter.MSBuild/README.md.

🔎 Proposed documentation entry

Add the following after line 206:

  - `excludedTypeNames` - Default is empty
+  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See <https://github.com/RicoSuter/NSwag/wiki/Templates>

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/Refitter.SourceGenerator/README.md around line 206, add a documentation
entry for the customTemplateDirectory property (to match the MSBuild README)
immediately after the excludedTypeNames explanation: describe that
customTemplateDirectory is optional, accepts a relative or absolute path to a
folder containing NSwag templates, show an example path (e.g.
"./path/to/directory/" and note trailing slash is allowed), explain it overrides
the built-in templates and will be used by the generator when present, and
mention behavior/precedence (custom templates take priority over embedded
defaults) and any tips about resolving paths relative to the project root or CI
environments.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (2)

237-237: Consider extracting the template path to a constant.

The template directory path "./Templates/" is hardcoded. Extracting it to a class-level constant would improve maintainability and make it easier to update if the path changes.

🔎 Proposed refactor

Add a constant at the class level:

 public class UsePolymorphicSerializationAndCustomTemplatesTests
 {
     private const string OpenApiSpec = @"
+    private const string CustomTemplateDirectory = "./Templates/";

Then use it in the settings:

         var settings = new RefitGeneratorSettings
         {
             OpenApiPath = swaggerFile,
             UsePolymorphicSerialization = true,
-            CustomTemplateDirectory = "./Templates/",
+            CustomTemplateDirectory = CustomTemplateDirectory,
         };

8-243: Consider adding OpenAPI 2.0 test coverage.

The coding guidelines specify that tests should cover both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications. The current test suite only validates the custom templates feature with OpenAPI 3.0.1.

Based on coding guidelines: "Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications"

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b11710b and 83d3d4d.

📒 Files selected for processing (2)
  • src/Refitter.SourceGenerator/README.md (2 hunks)
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/Refitter.Tests/**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/Refitter.Tests/**/*.cs: All new code must include unit tests following the pattern in Refitter.Tests.Examples namespace with test classes containing [Fact] methods
Test CLI changes with real OpenAPI specifications to ensure generation works correctly
Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.cs: Use PascalCase for public members and camelCase for parameters and local variables in C# code
Include XML documentation for public APIs in C# code
Use meaningful variable and method names in C# code
Follow existing C# coding conventions defined in .editorconfig

Files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Update `CreateRefitGeneratorSettings()` method in `src/Refitter/GenerateCommand.cs` when adding new CLI options
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/**/*.cs : Implement new CLI option logic in `src/Refitter.Core/RefitInterfaceGenerator.cs` or related generator classes
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test CLI changes with real OpenAPI specifications to ensure generation works correctly
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/Settings.cs : Add new CLI options as properties in `src/Refitter/Settings.cs` with `[CommandOption("--option-name")]` attribute
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to `src/Refitter.Core/Settings/RefitGeneratorSettings.cs` for each new CLI option

Applied to files:

  • src/Refitter.SourceGenerator/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Core/**/*.cs : Implement new CLI option logic in `src/Refitter.Core/RefitInterfaceGenerator.cs` or related generator classes

Applied to files:

  • src/Refitter.SourceGenerator/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Update `CreateRefitGeneratorSettings()` method in `src/Refitter/GenerateCommand.cs` when adding new CLI options

Applied to files:

  • src/Refitter.SourceGenerator/README.md
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test CLI changes with real OpenAPI specifications to ensure generation works correctly

Applied to files:

  • src/Refitter.SourceGenerator/README.md
  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : Test with both OpenAPI 2.0 and 3.0 specifications when working with OpenAPI specifications

Applied to files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
📚 Learning: 2025-12-04T23:11:05.599Z
Learnt from: CR
Repo: christianhelle/refitter PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-12-04T23:11:05.599Z
Learning: Applies to src/Refitter.Tests/**/*.cs : All new code must include unit tests following the pattern in `Refitter.Tests.Examples` namespace with test classes containing [Fact] methods

Applied to files:

  • src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
🧬 Code graph analysis (1)
src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (2)
src/Refitter/GenerateCommand.cs (5)
  • Task (27-269)
  • Task (321-381)
  • Task (397-541)
  • Task (664-771)
  • RefitGeneratorSettings (271-320)
src/Refitter.Core/RefitGenerator.cs (1)
  • RefitGenerator (10-311)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: 👌 Verify build
  • GitHub Check: script
  • GitHub Check: 👌 Verify build
  • GitHub Check: 👌 Verify build
🔇 Additional comments (6)
src/Refitter.SourceGenerator/README.md (1)

130-130: Documentation for customTemplateDirectory successfully added.

The addition of the customTemplateDirectory property to both the JSON schema example (line 130) and the documentation section (line 208) addresses the earlier feedback. The documentation entry correctly describes the property's purpose, default behavior, and provides a reference link to NSwag's template documentation.

Optional enhancement for more detailed documentation

The documentation is clear and covers the essentials. If you'd like to provide more guidance for users, consider expanding line 208 slightly to clarify path resolution behavior:

-  - `customTemplateDirectory` - Custom directory with NSwag fluid templates for code generation. Default is null which uses the default NSwag templates. See <https://github.com/RicoSuter/NSwag/wiki/Templates>
+  - `customTemplateDirectory` - Path to a directory containing custom NSwag fluid templates. Relative paths are resolved from the project root. Default is null, which uses NSwag's built-in templates. Custom templates override built-in ones; omitted templates fall back to NSwag defaults. See <https://github.com/RicoSuter/NSwag/wiki/Templates> for template details.

This is optional and meant only as a suggestion if you'd like to provide more comprehensive guidance for users unfamiliar with NSwag's template system.

Also applies to: 208-208

src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs (5)

1-9: LGTM!

The imports and class structure follow the expected patterns for test files in this project.


189-194: LGTM!

This smoke test appropriately verifies that code generation succeeds with the custom template configuration.


196-210: LGTM!

The test correctly validates that polymorphic serialization uses modern JsonPolymorphic and JsonDerivedType attributes instead of legacy converters.


220-228: LGTM!

Build validation ensures the generated code is syntactically valid and can be compiled, which is essential for verifying the custom template functionality.


212-218: The custom template directory exists and is properly configured. The src/Refitter.Tests/Templates/ directory contains Class.Annotations.liquid with the placeholder text /* Example Custom Template Text */, so the test will work as expected.

Likely an incorrect or invalid review comment.

Comment on lines +18 to +23
parameters:
- name: 'token'
in: 'query'
description: 'Some Token'
required: false
type: 'string'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix OpenAPI 3.0 parameter syntax.

The parameter definition uses OpenAPI 2.0 syntax (type: 'string' directly on the parameter), but the spec is declared as OpenAPI 3.0.1. In OpenAPI 3.0, parameters must use a schema property.

🔎 Proposed fix for OpenAPI 3.0 compliance
       parameters:
       - name: 'token'
         in: 'query'
         description: 'Some Token'
         required: false
-        type: 'string'
+        schema:
+          type: string
📝 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.

Suggested change
parameters:
- name: 'token'
in: 'query'
description: 'Some Token'
required: false
type: 'string'
parameters:
- name: 'token'
in: 'query'
description: 'Some Token'
required: false
schema:
type: string
🤖 Prompt for AI Agents
In
src/Refitter.Tests/Examples/UsePolymorphicSerializationAndCustomTemplatesTests.cs
around lines 18 to 23, the OpenAPI parameter uses Swagger 2.0 syntax by
specifying type: 'string' directly on the parameter; update it to OpenAPI 3.0
syntax by replacing the top-level type with a schema object (e.g., remove "type:
'string'" and add "schema: { type: 'string' }"), keeping name, in, description
and required as-is so the parameter is valid under OpenAPI 3.0.1.

@christianhelle christianhelle self-assigned this Jan 12, 2026
@christianhelle christianhelle added enhancement New feature, bug fix, or request .NET Pull requests that contain changes to .NET code labels Jan 12, 2026
@christianhelle

Copy link
Copy Markdown
Owner

@kmc059000 Sorry for the delayed feedback. I needed to disconnect for a bit

First of all, thanks for taking the time to implement this. This look good and great job with keeping the docs up to date as well

I won't really use this myself, but if you find this useful then I think that we should merge this in. As you mentioned, if the user decides to use custom templates, then its on them if the templates don't work

@christianhelle christianhelle linked an issue Jan 13, 2026 that may be closed by this pull request
@christianhelle
christianhelle merged commit 1275ff9 into christianhelle:main Jan 13, 2026
9 checks passed
@kmc059000

Copy link
Copy Markdown
Contributor Author

@christianhelle are you planning on releasing a new version soon?

Thank you for merging this in too! I wasn't expecting a review until after the holidays.

@christianhelle

Copy link
Copy Markdown
Owner

@kmc059000 I wasn't planning on releasing any time soon but I can always do a minor release if you need this change. I can this tonight

@kmc059000

kmc059000 commented Jan 22, 2026 via email

Copy link
Copy Markdown
Contributor Author

hwinther pushed a commit to hwinther/test that referenced this pull request May 6, 2026
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>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=refitter&package-manager=nuget&previous-version=1.7.1&new-version=2.0.0)](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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature, bug fix, or request .NET Pull requests that contain changes to .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve Immutable Records ergonomics

2 participants