Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for customizable type and contract generator settings #188

Merged
merged 23 commits into from
Oct 12, 2023

Conversation

christianhelle
Copy link
Owner

@christianhelle christianhelle commented Oct 11, 2023

The changes here allow customization of the NSwag type and contracts generator through the .refitter settings file. This is done by specifying the codeGeneratorSettings property, which is documented in the README files and will be included documentation site (https://refitter.github.io) after this is merged

The following OpenAPI spec:

{
  "swagger": "2.0",
  "info": {
    "title": "Dummy API",
    "version": "0.0.0"
  },
  "host": "x.io",
  "basePath": "/",
  "schemes": [
    "https"
  ],
  "paths": {
    "/dummy/{id}": {
      "get": {
        "operationId": "Get Dummy",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "the specific dummy",
            "required": true,
            "format": "int64",
            "type": "integer"
          },
          {
            "name": "valid_from",
            "in": "query",
            "description": "the start of the period",
            "required": true,
            "format": "date",
            "type": "string"
          },
          {
            "name": "valid_to",
            "in": "query",
            "description": "the end of the period",
            "required": true,
            "format": "date",
            "type": "string"
          },
          {
            "name": "test_time",
            "in": "query",
            "description": "test parameter",
            "required": true,
            "format": "time",
            "type": "string"
          }
        ],
        "responses": {
          "200": {
            "description": "No response was specified"
          }
        }
      }
    }
  }
}

used with the following .refitter settings file

{
  "contractsGeneratorSettings": {
    "dateType": "System.DateTime",
    "dateTimeType": "System.DateTime"
  }
}

will generated an interface like this:

[System.CodeDom.Compiler.GeneratedCode("Refitter", "1.0.0.0")]
public partial interface IDummyAPI
{
    [Get("/t/dummy/{employee_id}")]
    Task GetDummy(
        long employee_id, 
        [Query] System.DateTime valid_from, 
        [Query] System.DateTime valid_to, 
        [Query] System.TimeSpan test_time);
}

This implements #186 suggested by @bielik01

codeGeneratorSettings exposes the following properties with the following default values:

"codeGeneratorSettings": {
    "namespace": "GeneratedCode",
    "requiredPropertiesMustBeDefined": true,
    "generateDataAnnotations": true,
    "anyType": "object",
    "dateType": "System.DateTimeOffset",
    "dateTimeType": "System.DateTimeOffset",
    "timeType": "System.TimeSpan",
    "timeSpanType": "System.TimeSpan",
    "arrayType": "System.Collections.Generic.ICollection",
    "dictionaryType": "System.Collections.Generic.IDictionary",
    "arrayInstanceType": "System.Collections.ObjectModel.Collection",
    "dictionaryInstanceType": "System.Collections.Generic.Dictionary",
    "arrayBaseType": "System.Collections.ObjectModel.Collection",
    "dictionaryBaseType": "System.Collections.Generic.Dictionary",
    "propertySetterAccessModifier": "",
    "generateImmutableArrayProperties": false,
    "generateImmutableDictionaryProperties": false,
    "handleReferences": false,
    "jsonSerializerSettingsTransformationMethod": null,
    "generateJsonMethods": false,
    "enforceFlagEnums": false,
    "inlineNamedDictionaries": false,
    "inlineNamedTuples": true,
    "inlineNamedArrays": false,
    "generateOptionalPropertiesAsNullable": false,
    "generateNullableReferenceTypes": false,
    "generateNativeRecords": false,
    "generateDefaultValues": true,
    "inlineNamedAny": false,
    "excludedTypeNames": [ ]
  }

A new property `ContractsGeneratorSettings` was added to the `RefitGeneratorSettings` class. This change was made to provide customizable settings for generating contracts using NSwag. This enhancement provides users more control over contract generation.
Adjusted the deserialization of JSON files across the project from NewtonSoft.Json to System.Text.Json. The primary changes include adjustments to deserialization methods in "GenerateCommand.cs" and "RefitterSourceGenerator" where weaker camel-case is now used to serialize/deserialize, and property name case insensitivity is allowed. This change also involved removing all attributes related to Newtonsoft's JsonProperty from the "RefitGeneratorSettings.cs". The switch to System.Text.Json provides more native performance benefits and tight integration with the .NET ecosystem.
The name of `ContractsGeneratorSettings` is changed to `CodeGeneratorSettings` throughout the project files. This name is more reflective of the setting's usage, as it influences the generation of all types, not just contracts. The NSwag configuration JSON property is also updated from `contractsGeneratorSettings` to `codeGeneratorSettings` to reflect this change and maintain consistency.
CodeGeneratorSettings have been added to the configuration in petstore.refitter. This was necessary to set the package-specific types for Date, DateTime and Arrays in the generated code. Consequently, the setup becomes more compatible with the .NET environment.
The serialization process was refactored to use a new Serializer class, which was included in a standalone 'Refitter.Core' namespace. The purpose of this change is to eliminate redundancy and improve the manageability of the serialization settings applied in different parts of the project. This new Serializer class leverages the JsonSerializerOptions for consistency and ease of maintainability.
CodeGeneratorSettings' type was changed from 'CSharpGeneratorSettings' to 'NSwagCodeGeneratorSettings'. This change was necessary to better accommodate NSwag specifications for generating types. Added class 'NSwagCodeGeneratorSettings' to handle a broad range of .NET type settings for NSwag, improving configurability. Furthermore, organization of JsonPropertyName and corresponding enum was simplified for clearer readability.
Changed the generator settings type reference in the MapCSharpGeneratorSettings method. Instead of referring to the CSharpGeneratorSettings type, changed to NSwagCodeGeneratorSettings type. This change is necessary to align with NSwag, which is the library used for generating clients.
Added new tests to verify the default value of date, datetime, array type in the RefitGeneratorSettings class. System.Text.Json namespace has also been added to support these tests. Additionally, replaced instances of CSharpGeneratorSettings with NSwagCodeGeneratorSettings to improve test consistency. These changes are crucial to ensure the code generator settings are working as expected for different data types.
Added spacing between methods in `CustomCSharpGeneratorSettingsTests.cs` to improve code readability. No changes to logic or functionality were made. This change purely enhances the structure and legibility of the code making it easier for developers to navigate and understand.
Refactored `RefitGeneratorSettings.cs` into different classes, each encapsulating settings related to distinct functionalities such as `NSwagCodeGeneratorSettings.cs`, `DependencyInjectionSettings.cs`, `NamingSettings.cs`, `TypeAccessibility.cs`, and `MultipleInterfaces.cs`. This overhaul would enhance maintainability of the settings configuration by segregating settings based on their respective areas of concern. Any future modifications or additions can now be applied to the respective class directly, thereby minimizing the potential impact radius of the change.
This commit removes several class properties from NSwagCodeGeneratorSettings. This includes ClassStyle, JsonLibrary and TypeAccessModifier properties. These properties were not being used and removing them helps to declutter the class and improve code readability without impacting functionality.
This commit introduces a new "codeGeneratorSettings" section to our project README and documentation. These settings allow users to tailor the output of our code generator to meet their specific requirements. Update not only provides more granular control over the code generation process but also improves adaptability for a variety of project architectures and coding standards.
The JsonNamingPolicy.CamelCase was removed from JsonSerializerOptions since the case-insensitivity setting simplifies our JSON handling. Detailed comments have also been added to improve readability and code understanding.
Added detailed `codeGeneratorSettings` to README.md and refitter-file-format.md. This update provides information about NSwag code generation customization, improving users' understanding of how they can manipulate the generated types and contracts.
Added basic explanations for each property in the Refitter file format. This update enhances clarity for users reading the documentation, helping them understand each property's purpose.
The class NSwagCodeGeneratorSettings has been renamed to CodeGeneratorSettings. This refactoring intends to make the class more generic, eliminating the reference to NSwag in its naming, given it's used for setting code generation parameters without depending specifically on NSwag. This change affects also its instances and references within both the test and core files within the Refitter project.
A new test class, CustomCodeGeneratorWithDateTimeTests, is introduced in the Refitter.Tests/Examples suite. This class includes tests to validate the correct generation of custom code that handles date and time. These tests confirm that generation code should contain the specific date format, TimeSpan parameter, DateTime parameter, while not containing DateTimeOffset parameter. This helps to ensure the generator is properly supporting date and time types.
@christianhelle christianhelle added the enhancement New feature, bug fix, or request label Oct 11, 2023
@christianhelle christianhelle self-assigned this Oct 11, 2023
@christianhelle
Copy link
Owner Author

Does this work for you @bielik01 ?

@codecov
Copy link

codecov bot commented Oct 11, 2023

Codecov Report

Merging #188 (a4f5799) into main (6960270) will increase coverage by 0.15%.
Report is 9 commits behind head on main.
The diff coverage is 100.00%.

❗ Current head a4f5799 differs from pull request most recent head e2c24b8. Consider uploading reports for the commit e2c24b8 to get more accurate results

@@            Coverage Diff             @@
##             main     #188      +/-   ##
==========================================
+ Coverage   98.48%   98.64%   +0.15%     
==========================================
  Files          47       52       +5     
  Lines        1651     1841     +190     
==========================================
+ Hits         1626     1816     +190     
  Misses          9        9              
  Partials       16       16              
Flag Coverage Δ
unittests 98.64% <100.00%> (+0.15%) ⬆️

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

Files Coverage Δ
src/Refitter.Core/CSharpClientGeneratorFactory.cs 100.00% <100.00%> (ø)
src/Refitter.Core/Serializer.cs 100.00% <100.00%> (ø)
...rc/Refitter.Core/Settings/CodeGeneratorSettings.cs 100.00% <100.00%> (ø)
...itter.Core/Settings/DependencyInjectionSettings.cs 100.00% <100.00%> (ø)
...fitter.Tests/CustomCSharpGeneratorSettingsTests.cs 100.00% <100.00%> (ø)
...s/Examples/CustomCodeGeneratorWithDateTimeTests.cs 100.00% <100.00%> (ø)
src/Refitter.Tests/SerializerTests.cs 100.00% <100.00%> (ø)

@christianhelle christianhelle changed the title Customizable NSwag type and contract generator settings Add support for customizable type and contract generator settings Oct 11, 2023
@christianhelle christianhelle linked an issue Oct 11, 2023 that may be closed by this pull request
…imeTests

The UseIsoDateFormat setting has been removed from the CustomCodeGeneratorWithDateTimeTests.cs file under the Refitter.Tests project. This attribute was redundant, as the default settings already set date type as System.DateTime, making the specification of using ISO date format unnecessary and potentially confusing.
The test case `GeneratedCode_Contains_Date_Format_String` was removed from `CustomCodeGeneratorWithDateTimeTests.cs`. It was unnecessary as the date format is not a concern of the code generator and therefore does not need to be tested here.
@bielik01
Copy link

that's more like it, thanks!

@bielik01
Copy link

although you could also add CodeGeneratorSettingsBase properties, because I'll need ExcludedTypeNames as well

@christianhelle
Copy link
Owner Author

although you could also add CodeGeneratorSettingsBase properties, because I'll need ExcludedTypeNames as well

Sure

Added three new properties to CodeGeneratorSettings: GenerateDefaultValues, InlineNamedAny, and ExcludedTypeNames. GenerateDefaultValues will manage whether to generate default values for properties, InlineNamedAny indicates whether to inline any named/referenced schemas or generate them as a class, and ExcludedTypeNames will store excluded type names. These changes give users more control over code generation, making the tool more flexible to accommodate different project requirements. The README files have been updated to include these new options.
@sonarcloud
Copy link

sonarcloud bot commented Oct 12, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 1 Code Smell

No Coverage information No Coverage information
0.0% 0.0% Duplication

@bielik01
Copy link

perfect ❤

@christianhelle christianhelle merged commit be561bb into main Oct 12, 2023
2 checks passed
@christianhelle christianhelle deleted the code-generator-settings branch October 12, 2023 08:56
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

NSwag contracts
2 participants