diff --git a/CHANGELOG.md b/CHANGELOG.md index a168a2ea69..e1cea00cd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Fixed a when generating a plugin when only an operation is selected in the root node in the extension. [#5300](https://github.com/microsoft/kiota/issues/5300) + ## [1.18.0] - 2024-09-05 ### Added diff --git a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs index b414e4fd7a..f3c11d6bb8 100644 --- a/src/Kiota.Builder/Plugins/PluginsGenerationService.cs +++ b/src/Kiota.Builder/Plugins/PluginsGenerationService.cs @@ -131,6 +131,9 @@ private OpenApiDocument GetDocumentWithTrimmedComponentsAndResponses(OpenApiDocu requestUrls[key] = path.Value.Operations.Keys.Select(static key => key.ToString().ToUpperInvariant()).ToList(); } + if (requestUrls.Count == 0) + throw new InvalidOperationException("No paths found in the OpenAPI document."); + var predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: doc); return OpenApiFilterService.CreateFilteredDocument(doc, predicate); } diff --git a/src/kiota/Handlers/Plugin/AddHandler.cs b/src/kiota/Handlers/Plugin/AddHandler.cs index 2a3e02c210..7a4a661308 100644 --- a/src/kiota/Handlers/Plugin/AddHandler.cs +++ b/src/kiota/Handlers/Plugin/AddHandler.cs @@ -104,10 +104,10 @@ public override async Task InvokeAsync(InvocationContext context) catch (Exception ex) { #if DEBUG - logger.LogCritical(ex, "error adding the client: {exceptionMessage}", ex.Message); + logger.LogCritical(ex, "error adding the plugin: {exceptionMessage}", ex.Message); throw; // so debug tools go straight to the source of the exception when attached #else - logger.LogCritical("error adding the client: {exceptionMessage}", ex.Message); + logger.LogCritical("error adding the plugin: {exceptionMessage}", ex.Message); return 1; #endif } diff --git a/src/kiota/Handlers/Plugin/EditHandler.cs b/src/kiota/Handlers/Plugin/EditHandler.cs index 6bb8b0d273..a228fed51a 100644 --- a/src/kiota/Handlers/Plugin/EditHandler.cs +++ b/src/kiota/Handlers/Plugin/EditHandler.cs @@ -129,10 +129,10 @@ public override async Task InvokeAsync(InvocationContext context) catch (Exception ex) { #if DEBUG - logger.LogCritical(ex, "error adding the plugin: {exceptionMessage}", ex.Message); + logger.LogCritical(ex, "error editing the plugin: {exceptionMessage}", ex.Message); throw; // so debug tools go straight to the source of the exception when attached #else - logger.LogCritical("error adding the plugin: {exceptionMessage}", ex.Message); + logger.LogCritical("error editing the plugin: {exceptionMessage}", ex.Message); return 1; #endif } diff --git a/src/kiota/Handlers/Plugin/GenerateHandler.cs b/src/kiota/Handlers/Plugin/GenerateHandler.cs index cb04febcc1..d62e3d5525 100644 --- a/src/kiota/Handlers/Plugin/GenerateHandler.cs +++ b/src/kiota/Handlers/Plugin/GenerateHandler.cs @@ -74,10 +74,10 @@ public override async Task InvokeAsync(InvocationContext context) catch (Exception ex) { #if DEBUG - logger.LogCritical(ex, "error adding the client: {ExceptionMessage}", ex.Message); + logger.LogCritical(ex, "error generating the plugin: {ExceptionMessage}", ex.Message); throw; // so debug tools go straight to the source of the exception when attached #else - logger.LogCritical("error adding the client: {ExceptionMessage}", ex.Message); + logger.LogCritical("error generating the plugin: {ExceptionMessage}", ex.Message); return 1; #endif } diff --git a/src/kiota/Rpc/Server.cs b/src/kiota/Rpc/Server.cs index 66634daed2..e866eab942 100644 --- a/src/kiota/Rpc/Server.cs +++ b/src/kiota/Rpc/Server.cs @@ -218,7 +218,7 @@ public async Task> GeneratePluginAsync(string openAPIFilePath, st } catch (Exception ex) { - globalLogger.LogCritical(ex, "error adding the client: {exceptionMessage}", ex.Message); + globalLogger.LogCritical(ex, "error generating the plugin: {exceptionMessage}", ex.Message); } return globalLogger.LogEntries; } diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs index 6518143681..f71ecc98c4 100644 --- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs +++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs @@ -5994,6 +5994,73 @@ public void SetsReadonlyProperties(bool isReadonly) var nameProperty = objectClass.Properties.First(static x => "name".Equals(x.Name, StringComparison.OrdinalIgnoreCase)); Assert.Equal(isReadonly, nameProperty.ReadOnly); } + [Theory] + [InlineData("#GET", 0)] + [InlineData("/#GET", 1)] + public void SupportsIncludeFilterOnRootPath(string inputPattern, int expectedPathsCount) + { + var myObjectSchema = new OpenApiSchema + { + Type = "object", + Properties = new Dictionary { + { + "name", new OpenApiSchema { + Type = "string", + } + } + }, + Reference = new OpenApiReference + { + Id = "myobject", + Type = ReferenceType.Schema + }, + UnresolvedReference = false, + }; + var document = new OpenApiDocument + { + Paths = new OpenApiPaths + { + ["/"] = new OpenApiPathItem + { + Operations = { + [OperationType.Get] = new OpenApiOperation + { + Responses = new OpenApiResponses + { + ["200"] = new OpenApiResponse { + Content = { + ["application/json"] = new OpenApiMediaType { + Schema = myObjectSchema + } + } + }, + } + } + } + }, + }, + Components = new() + { + Schemas = new Dictionary { + { + "myobject", myObjectSchema + } + } + } + }; + var mockLogger = new Mock>(); + var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration + { + ClientClassName = "TestClient", + ClientNamespaceName = "TestSdk", + ApiRootUrl = "https://localhost", + IncludePatterns = new() { + inputPattern + } + }, _httpClient); + builder.FilterPathsByPatterns(document); + Assert.Equal(expectedPathsCount, document.Paths.Count); + } [Fact] public void SupportsIncludeFilter() { diff --git a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs index 9beb4bed9f..0cfd7e9d9c 100644 --- a/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs +++ b/tests/Kiota.Builder.Tests/Plugins/PluginsGenerationServiceTests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net.Http; using System.Text.Json; +using System.Threading; using System.Threading.Tasks; using Kiota.Builder.Configuration; using Kiota.Builder.Plugins; @@ -115,6 +116,40 @@ public async Task GeneratesManifestAsync(string inputPluginName, string expected private const string OpenAIPluginFileName = "openai-plugins.json"; private const string OpenApiFileName = "client-openapi.yml"; + [Fact] + public async Task ThrowsOnEmptyPathsAfterFilteringAsync() + { + var simpleDescriptionContent = @"openapi: 3.0.0 +info: + title: test + version: 1.0 +servers: + - url: http://localhost/ + description: There's no place like home +paths: + /test: + get: + description: description for test path + responses: + '200': + description: test"; + var workingDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); + var simpleDescriptionPath = Path.Combine(workingDirectory) + "description.yaml"; + await File.WriteAllTextAsync(simpleDescriptionPath, simpleDescriptionContent); + var outputDirectory = Path.Combine(workingDirectory, "output"); + var generationConfiguration = new GenerationConfiguration + { + OutputPath = outputDirectory, + OpenAPIFilePath = simpleDescriptionPath, + PluginTypes = [PluginType.APIPlugin, PluginType.APIManifest, PluginType.OpenAI], + ClientClassName = "testPlugin", + IncludePatterns = ["test/id"]// this would filter out all paths + }; + var kiotaBuilder = new KiotaBuilder(new Mock>().Object, generationConfiguration, _httpClient, true); + var exception = await Assert.ThrowsAsync(async () => await kiotaBuilder.GeneratePluginAsync(CancellationToken.None)); + Assert.Equal("No paths found in the OpenAPI document.", exception.Message); + } + [Fact] public async Task GeneratesManifestAndCleansUpInputDescriptionAsync() { diff --git a/vscode/microsoft-kiota/src/openApiTreeProvider.ts b/vscode/microsoft-kiota/src/openApiTreeProvider.ts index 1c852d698e..f48718c35a 100644 --- a/vscode/microsoft-kiota/src/openApiTreeProvider.ts +++ b/vscode/microsoft-kiota/src/openApiTreeProvider.ts @@ -267,7 +267,11 @@ export class OpenApiTreeProvider implements vscode.TreeDataProvider