From 75f091e92135ea594b528317287ca541db93b9c2 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Tue, 30 Jan 2024 11:35:21 -0500 Subject: [PATCH] - adds support for none key for serializer arguments Signed-off-by: Vincent Biret --- CHANGELOG.md | 1 + src/Kiota.Builder/KiotaBuilder.cs | 10 ++++-- src/kiota/KiotaHost.cs | 10 +++--- .../Kiota.Builder.Tests/KiotaBuilderTests.cs | 36 +++++++++++++++++++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b746b9b1fb..7955a9f104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added 'none' key for serializer and deserializer arguments to enable portable clients generation. [#3796](https://github.com/microsoft/kiota/issues/3796) - Added Japanese translations to vscode extension. - Added support for deprecation annotations in Python. [#2798](https://github.com/microsoft/kiota/issues/2798) diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs index bd618c9e94..cc032871ef 100644 --- a/src/Kiota.Builder/KiotaBuilder.cs +++ b/src/Kiota.Builder/KiotaBuilder.cs @@ -941,8 +941,8 @@ private void CreateUrlManagement(CodeClass currentClass, OpenApiUrlTreeNode curr currentClass.AddProperty(pathParametersProperty); if (isApiClientClass) { - constructor.SerializerModules = config.Serializers; - constructor.DeserializerModules = config.Deserializers; + constructor.SerializerModules = ReplaceNoneSerializersByEmptySet(config.Serializers); + constructor.DeserializerModules = ReplaceNoneSerializersByEmptySet(config.Deserializers); constructor.BaseUrl = config.ApiRootUrl ?? string.Empty; pathParametersProperty.DefaultValue = $"new {pathParametersProperty.Type.Name}()"; } @@ -1007,6 +1007,12 @@ private void CreateUrlManagement(CodeClass currentClass, OpenApiUrlTreeNode curr currentClass.AddMethod(overloadCtor); } } + private static HashSet ReplaceNoneSerializersByEmptySet(HashSet serializers) + { + if (serializers.Count == 1 && serializers.Contains("none")) return []; + return serializers; + } + private static readonly Func shortestNamespaceOrder = x => x.GetNamespaceDepth(); /// /// Remaps definitions to custom types so they can be used later in generation or in refiners diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs index d62b428369..473a563fde 100644 --- a/src/kiota/KiotaHost.cs +++ b/src/kiota/KiotaHost.cs @@ -355,15 +355,15 @@ private static Command GetGenerateCommand() var serializerOption = new Option>( "--serializer", - () => defaultConfiguration.Serializers.ToList(), - "The fully qualified class names for serializers. Accepts multiple values."); + () => [.. defaultConfiguration.Serializers], + "The fully qualified class names for serializers. Accepts multiple values. Use `none` to generate a client without any serializer."); serializerOption.AddAlias("-s"); serializerOption.ArgumentHelpName = "classes"; var deserializerOption = new Option>( "--deserializer", - () => defaultConfiguration.Deserializers.ToList(), - "The fully qualified class names for deserializers. Accepts multiple values."); + () => [.. defaultConfiguration.Deserializers], + "The fully qualified class names for deserializers. Accepts multiple values. Use `none` to generate a client without any deserializer."); deserializerOption.AddAlias("--ds"); deserializerOption.ArgumentHelpName = "classes"; @@ -371,7 +371,7 @@ private static Command GetGenerateCommand() var structuredMimeTypesOption = new Option>( "--structured-mime-types", - () => defaultConfiguration.StructuredMimeTypes.ToList(), + () => [.. defaultConfiguration.StructuredMimeTypes], "The MIME types with optional priorities as defined in RFC9110 Accept header to use for structured data model generation. Accepts multiple values."); structuredMimeTypesOption.AddAlias("-m"); diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 8521c78141..228f8886d7 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -73,6 +73,42 @@ await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 Assert.Equal(expected, constructor.BaseUrl); } [Fact] + public async Task HonoursNoneKeyForSerialization() + { + var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName()); + await File.WriteAllTextAsync(tempFilePath, @$"openapi: 3.0.1 +info: + title: OData Service for namespace microsoft.graph + description: This OData service is located at https://graph.microsoft.com/v1.0 + version: 1.0.1 +servers: + - url: https://graph.microsoft.com/v1.0 +paths: + /enumeration: + get: + responses: + '200': + content: + application/json: + schema: + type: string"); + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = "https://graph.microsoft.com/description.yaml", Serializers = ["none"], Deserializers = ["none"] }, _httpClient); + await using var fs = new FileStream(tempFilePath, FileMode.Open); + var document = await builder.CreateOpenApiDocumentAsync(fs); + var node = builder.CreateUriSpace(document); + builder.SetApiRootUrl(); + var codeModel = builder.CreateSourceModel(node); + var rootNS = codeModel.FindNamespaceByName("ApiSdk"); + Assert.NotNull(rootNS); + var clientBuilder = rootNS.FindChildByName("Graph", false); + Assert.NotNull(clientBuilder); + var constructor = clientBuilder.Methods.FirstOrDefault(static x => x.IsOfKind(CodeMethodKind.ClientConstructor)); + Assert.NotNull(constructor); + Assert.Empty(constructor.SerializerModules); + Assert.Empty(constructor.DeserializerModules); + } + [Fact] public async Task DeduplicatesHostNames() { var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());