diff --git a/.vscode/launch.json b/.vscode/launch.json
index e5404b0746..e04fc3d4b1 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -266,7 +266,7 @@
"stopAtEntry": false
},
{
- "name": "Launch Migrate",
+ "name": "Launch Client Migrate",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
@@ -279,6 +279,41 @@
"KIOTA_CONFIG_PREVIEW": "true"
}
},
+ {
+ "name": "Launch Client Generate",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "program": "${workspaceFolder}/src/kiota/bin/Debug/net8.0/kiota.dll",
+ "args": ["client", "generate"],
+ "cwd": "${workspaceFolder}/samples/msgraph-mail/dotnet",
+ "console": "internalConsole",
+ "stopAtEntry": false,
+ "env": {
+ "KIOTA_CONFIG_PREVIEW": "true"
+ }
+ },
+ {
+ "name": "Launch Client Edit",
+ "type": "coreclr",
+ "request": "launch",
+ "preLaunchTask": "build",
+ "program": "${workspaceFolder}/src/kiota/bin/Debug/net8.0/kiota.dll",
+ "args": [
+ "client",
+ "edit",
+ "--client-name",
+ "GraphClient",
+ "--additional-data",
+ "true"
+ ],
+ "cwd": "${workspaceFolder}/samples/msgraph-mail/dotnet",
+ "console": "internalConsole",
+ "stopAtEntry": false,
+ "env": {
+ "KIOTA_CONFIG_PREVIEW": "true"
+ }
+ },
{
"name": "Launch Login (github - device)",
"type": "coreclr",
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 79f059e888..7d649bdd4a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
+### Changed
+
+## [1.12.0] - 2024-03-06
+
+### Added
+
+- Added support for the new kiota config commands under a feature flag. [#3356](https://github.com/microsoft/kiota/issues/3356)
- Added the init command as part of the experience revamp of [#3356](https://github.com/microsoft/kiota/issues/3356)
- Added uri-form encoded serialization for Python. [#2075](https://github.com/microsoft/kiota/issues/2075)
- Added support for multipart form data request body in Python. [#3030](https://github.com/microsoft/kiota/issues/3030)
@@ -1272,3 +1279,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
+
diff --git a/src/Kiota.Builder/Kiota.Builder.csproj b/src/Kiota.Builder/Kiota.Builder.csproj
index 55aa5449fa..67027af244 100644
--- a/src/Kiota.Builder/Kiota.Builder.csproj
+++ b/src/Kiota.Builder/Kiota.Builder.csproj
@@ -44,9 +44,9 @@
-
+
-
+
diff --git a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
index d47759564f..6ef6800a7c 100644
--- a/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
+++ b/src/Kiota.Builder/WorkspaceManagement/ApiClientConfiguration.cs
@@ -3,7 +3,6 @@
using System.IO;
using System.Linq;
using Kiota.Builder.Configuration;
-using Kiota.Builder.Lock;
using Microsoft.OpenApi.ApiManifest;
namespace Kiota.Builder.WorkspaceManagement;
diff --git a/src/Kiota.Builder/WorkspaceManagement/DescriptionStorageService.cs b/src/Kiota.Builder/WorkspaceManagement/DescriptionStorageService.cs
index 1bdd930b69..9a5e6006ce 100644
--- a/src/Kiota.Builder/WorkspaceManagement/DescriptionStorageService.cs
+++ b/src/Kiota.Builder/WorkspaceManagement/DescriptionStorageService.cs
@@ -59,4 +59,10 @@ public void RemoveDescription(string clientName, string extension = "yml")
if (File.Exists(descriptionFilePath))
File.Delete(descriptionFilePath);
}
+ public void Clean()
+ {
+ var kiotaDirectoryPath = Path.Combine(TargetDirectory, DescriptionsSubDirectoryRelativePath);
+ if (Path.Exists(kiotaDirectoryPath))
+ Directory.Delete(kiotaDirectoryPath, true);
+ }
}
diff --git a/src/Kiota.Builder/WorkspaceManagement/WorkspaceManagementService.cs b/src/Kiota.Builder/WorkspaceManagement/WorkspaceManagementService.cs
index 9a68d50f41..a010b2ec2f 100644
--- a/src/Kiota.Builder/WorkspaceManagement/WorkspaceManagementService.cs
+++ b/src/Kiota.Builder/WorkspaceManagement/WorkspaceManagementService.cs
@@ -143,6 +143,8 @@ public async Task RemoveClientAsync(string clientName, bool cleanOutput = false,
manifest?.ApiDependencies.Remove(clientName);
await workspaceConfigurationStorageService.UpdateWorkspaceConfigurationAsync(wsConfig, manifest, cancellationToken).ConfigureAwait(false);
descriptionStorageService.RemoveDescription(clientName);
+ if (wsConfig.Clients.Count == 0)
+ descriptionStorageService.Clean();
}
private static readonly JsonSerializerOptions options = new()
{
@@ -226,15 +228,11 @@ public async Task> MigrateFromLockFileAsync(string clientNam
}
var (stream, _) = await openApiDocumentDownloadService.LoadStreamAsync(generationConfiguration.OpenAPIFilePath, generationConfiguration, null, false, cancellationToken).ConfigureAwait(false);
#pragma warning disable CA2007 // Consider calling ConfigureAwait on the awaited task
- await using var msForOpenAPIDocument = new MemoryStream(); // openapi.net doesn't honour leave open
await using var ms = new MemoryStream();
#pragma warning restore CA2007 // Consider calling ConfigureAwait on the awaited task
- await stream.CopyToAsync(msForOpenAPIDocument, cancellationToken).ConfigureAwait(false);
- msForOpenAPIDocument.Seek(0, SeekOrigin.Begin);
- await msForOpenAPIDocument.CopyToAsync(ms, cancellationToken).ConfigureAwait(false);
+ await stream.CopyToAsync(ms, cancellationToken).ConfigureAwait(false);
ms.Seek(0, SeekOrigin.Begin);
- msForOpenAPIDocument.Seek(0, SeekOrigin.Begin);
- var document = await openApiDocumentDownloadService.GetDocumentFromStreamAsync(msForOpenAPIDocument, generationConfiguration, false, cancellationToken).ConfigureAwait(false);
+ var document = await openApiDocumentDownloadService.GetDocumentFromStreamAsync(ms, generationConfiguration, false, cancellationToken).ConfigureAwait(false);
if (document is null)
{
Logger.LogError("The client {ClientName} could not be migrated because the OpenAPI document could not be loaded", generationConfiguration.ClientClassName);
@@ -242,6 +240,7 @@ public async Task> MigrateFromLockFileAsync(string clientNam
continue;
}
generationConfiguration.ApiRootUrl = document.GetAPIRootUrl(generationConfiguration.OpenAPIFilePath);
+ ms.Seek(0, SeekOrigin.Begin);
await descriptionStorageService.UpdateDescriptionAsync(generationConfiguration.ClientClassName, ms, new Uri(generationConfiguration.OpenAPIFilePath).GetFileExtension(), cancellationToken).ConfigureAwait(false);
var clientConfiguration = new ApiClientConfiguration(generationConfiguration);
diff --git a/src/kiota/Handlers/BaseKiotaCommandHandler.cs b/src/kiota/Handlers/BaseKiotaCommandHandler.cs
index f22034eecf..5908458894 100644
--- a/src/kiota/Handlers/BaseKiotaCommandHandler.cs
+++ b/src/kiota/Handlers/BaseKiotaCommandHandler.cs
@@ -20,6 +20,12 @@ namespace kiota.Handlers;
internal abstract class BaseKiotaCommandHandler : ICommandHandler, IDisposable
{
+ protected static void DefaultSerializersAndDeserializers(GenerationConfiguration generationConfiguration)
+ { // needed until we have rollup packages
+ var defaultGenerationConfiguration = new GenerationConfiguration();
+ generationConfiguration.Serializers = defaultGenerationConfiguration.Serializers;
+ generationConfiguration.Deserializers = defaultGenerationConfiguration.Deserializers;
+ }
protected TempFolderCachingAccessTokenProvider GetGitHubDeviceStorageService(ILogger logger) => new()
{
Logger = logger,
diff --git a/src/kiota/Handlers/Client/AddHandler.cs b/src/kiota/Handlers/Client/AddHandler.cs
index deb60bb8a4..16cf680451 100644
--- a/src/kiota/Handlers/Client/AddHandler.cs
+++ b/src/kiota/Handlers/Client/AddHandler.cs
@@ -81,10 +81,10 @@ public override async Task InvokeAsync(InvocationContext context)
bool skipGeneration = context.ParseResult.GetValueForOption(SkipGenerationOption);
string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty;
string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty;
- List includePatterns = context.ParseResult.GetValueForOption(IncludePatternsOption) ?? new List();
- List excludePatterns = context.ParseResult.GetValueForOption(ExcludePatternsOption) ?? new List();
- List disabledValidationRules = context.ParseResult.GetValueForOption(DisabledValidationRulesOption) ?? new List();
- List structuredMimeTypes = context.ParseResult.GetValueForOption(StructuredMimeTypesOption) ?? new List();
+ List includePatterns = context.ParseResult.GetValueForOption(IncludePatternsOption) ?? [];
+ List excludePatterns = context.ParseResult.GetValueForOption(ExcludePatternsOption) ?? [];
+ List disabledValidationRules = context.ParseResult.GetValueForOption(DisabledValidationRulesOption) ?? [];
+ List structuredMimeTypes = context.ParseResult.GetValueForOption(StructuredMimeTypesOption) ?? [];
CancellationToken cancellationToken = context.BindingContext.GetService(typeof(CancellationToken)) is CancellationToken token ? token : CancellationToken.None;
AssignIfNotNullOrEmpty(output, (c, s) => c.OutputPath = s);
AssignIfNotNullOrEmpty(openapi, (c, s) => c.OpenAPIFilePath = s);
diff --git a/src/kiota/Handlers/Client/EditHandler.cs b/src/kiota/Handlers/Client/EditHandler.cs
new file mode 100644
index 0000000000..c989d270d0
--- /dev/null
+++ b/src/kiota/Handlers/Client/EditHandler.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.CommandLine;
+using System.CommandLine.Invocation;
+using System.IO;
+using System.Linq;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using Kiota.Builder;
+using Kiota.Builder.Configuration;
+using Kiota.Builder.Extensions;
+using Kiota.Builder.WorkspaceManagement;
+using Microsoft.Extensions.Logging;
+
+namespace kiota.Handlers.Client;
+
+internal class EditHandler : BaseKiotaCommandHandler
+{
+ public required Option ClassOption
+ {
+ get; init;
+ }
+ public required Option BackingStoreOption
+ {
+ get; init;
+ }
+ public required Option OutputOption
+ {
+ get; init;
+ }
+ public required Option LanguageOption
+ {
+ get; init;
+ }
+ public required Option DescriptionOption
+ {
+ get; init;
+ }
+ public required Option NamespaceOption
+ {
+ get; init;
+ }
+ public required Option AdditionalDataOption
+ {
+ get; init;
+ }
+ public required Option> DisabledValidationRulesOption
+ {
+ get; init;
+ }
+ public required Option> StructuredMimeTypesOption
+ {
+ get; init;
+ }
+ public required Option ExcludeBackwardCompatibleOption
+ {
+ get;
+ set;
+ }
+ public required Option> IncludePatternsOption
+ {
+ get; init;
+ }
+ public required Option> ExcludePatternsOption
+ {
+ get; init;
+ }
+ public required Option SkipGenerationOption
+ {
+ get; init;
+ }
+
+ public override async Task InvokeAsync(InvocationContext context)
+ {
+ string output = context.ParseResult.GetValueForOption(OutputOption) ?? string.Empty;
+ GenerationLanguage? language = context.ParseResult.GetValueForOption(LanguageOption);
+ string openapi = context.ParseResult.GetValueForOption(DescriptionOption) ?? string.Empty;
+ bool? backingStore = context.ParseResult.GetValueForOption(BackingStoreOption);
+ bool? excludeBackwardCompatible = context.ParseResult.GetValueForOption(ExcludeBackwardCompatibleOption);
+ bool? includeAdditionalData = context.ParseResult.GetValueForOption(AdditionalDataOption);
+ bool skipGeneration = context.ParseResult.GetValueForOption(SkipGenerationOption);
+ string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty;
+ string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty;
+ List? includePatterns = context.ParseResult.GetValueForOption(IncludePatternsOption);
+ List? excludePatterns = context.ParseResult.GetValueForOption(ExcludePatternsOption);
+ List? disabledValidationRules = context.ParseResult.GetValueForOption(DisabledValidationRulesOption);
+ List? structuredMimeTypes = context.ParseResult.GetValueForOption(StructuredMimeTypesOption);
+ CancellationToken cancellationToken = context.BindingContext.GetService(typeof(CancellationToken)) is CancellationToken token ? token : CancellationToken.None;
+
+ Configuration.Generation.SkipGeneration = skipGeneration;
+ Configuration.Generation.Operation = ClientOperation.Edit;
+
+ var (loggerFactory, logger) = GetLoggerAndFactory(context, Configuration.Generation.OutputPath);
+ using (loggerFactory)
+ {
+ await CheckForNewVersionAsync(logger, cancellationToken).ConfigureAwait(false);
+ logger.AppendInternalTracing();
+ logger.LogTrace("configuration: {configuration}", JsonSerializer.Serialize(Configuration, KiotaConfigurationJsonContext.Default.KiotaConfiguration));
+
+ try
+ {
+ var workspaceStorageService = new WorkspaceConfigurationStorageService(Directory.GetCurrentDirectory());
+ var (config, _) = await workspaceStorageService.GetWorkspaceConfigurationAsync(cancellationToken).ConfigureAwait(false);
+ if (config == null)
+ {
+ DisplayError("The workspace configuration is missing, please run the init command first.");
+ return 1;
+ }
+ if (!config.Clients.TryGetValue(className, out var clientConfiguration))
+ {
+ DisplayError($"No client found with the provided name {className}");
+ return 1;
+ }
+ clientConfiguration.UpdateGenerationConfigurationFromApiClientConfiguration(Configuration.Generation, className);
+ if (language.HasValue)
+ Configuration.Generation.Language = language.Value;
+ if (backingStore.HasValue)
+ Configuration.Generation.UsesBackingStore = backingStore.Value;
+ if (excludeBackwardCompatible.HasValue)
+ Configuration.Generation.ExcludeBackwardCompatible = excludeBackwardCompatible.Value;
+ if (includeAdditionalData.HasValue)
+ Configuration.Generation.IncludeAdditionalData = includeAdditionalData.Value;
+ AssignIfNotNullOrEmpty(output, (c, s) => c.OutputPath = s);
+ AssignIfNotNullOrEmpty(openapi, (c, s) => c.OpenAPIFilePath = s);
+ AssignIfNotNullOrEmpty(className, (c, s) => c.ClientClassName = s);
+ AssignIfNotNullOrEmpty(namespaceName, (c, s) => c.ClientNamespaceName = s);
+ if (includePatterns is { Count: > 0 })
+ Configuration.Generation.IncludePatterns = includePatterns.Select(static x => x.TrimQuotes()).ToHashSet(StringComparer.OrdinalIgnoreCase);
+ if (excludePatterns is { Count: > 0 })
+ Configuration.Generation.ExcludePatterns = excludePatterns.Select(static x => x.TrimQuotes()).ToHashSet(StringComparer.OrdinalIgnoreCase);
+ if (disabledValidationRules is { Count: > 0 })
+ Configuration.Generation.DisabledValidationRules = disabledValidationRules
+ .Select(static x => x.TrimQuotes())
+ .SelectMany(static x => x.Split(',', StringSplitOptions.RemoveEmptyEntries))
+ .ToHashSet(StringComparer.OrdinalIgnoreCase);
+ if (structuredMimeTypes is { Count: > 0 })
+ Configuration.Generation.StructuredMimeTypes = new(structuredMimeTypes.SelectMany(static x => x.Split(' ', StringSplitOptions.RemoveEmptyEntries))
+ .Select(static x => x.TrimQuotes()));
+
+ DefaultSerializersAndDeserializers(Configuration.Generation);
+ var builder = new KiotaBuilder(logger, Configuration.Generation, httpClient, true);
+ var result = await builder.GenerateClientAsync(cancellationToken).ConfigureAwait(false);
+ if (result)
+ DisplaySuccess("Generation completed successfully");
+ else if (skipGeneration)
+ {
+ DisplaySuccess("Generation skipped as --skip-generation was passed");
+ DisplayGenerateCommandHint();
+ }
+ else
+ {
+ DisplayWarning("Generation skipped as no changes were detected");
+ DisplayCleanHint("client generate", "--refresh");
+ }
+ var manifestPath = $"{GetAbsolutePath(WorkspaceConfigurationStorageService.ManifestFileName)}#{Configuration.Generation.ClientClassName}";
+ DisplayInfoHint(Configuration.Generation.Language, string.Empty, manifestPath);
+ DisplayGenerateAdvancedHint(includePatterns ?? [], excludePatterns ?? [], string.Empty, manifestPath, "client edit");
+ return 0;
+ }
+ catch (Exception ex)
+ {
+#if DEBUG
+ logger.LogCritical(ex, "error adding the client: {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);
+ return 1;
+#endif
+ }
+ }
+ }
+}
diff --git a/src/kiota/Handlers/Client/GenerateHandler.cs b/src/kiota/Handlers/Client/GenerateHandler.cs
index bf8d13a471..bde2dbb499 100644
--- a/src/kiota/Handlers/Client/GenerateHandler.cs
+++ b/src/kiota/Handlers/Client/GenerateHandler.cs
@@ -58,8 +58,10 @@ public override async Task InvokeAsync(InvocationContext context)
var generationConfiguration = new GenerationConfiguration();
var requests = !refresh && manifest is not null && manifest.ApiDependencies.TryGetValue(clientEntry.Key, out var value) ? value.Requests : [];
clientEntry.Value.UpdateGenerationConfigurationFromApiClientConfiguration(generationConfiguration, clientEntry.Key, requests);
+ DefaultSerializersAndDeserializers(generationConfiguration);
generationConfiguration.ClearCache = refresh;
generationConfiguration.CleanOutput = refresh;
+ generationConfiguration.Operation = ClientOperation.Generate;
var builder = new KiotaBuilder(logger, generationConfiguration, httpClient, true);
var result = await builder.GenerateClientAsync(cancellationToken).ConfigureAwait(false);
if (result)
diff --git a/src/kiota/Handlers/Client/RemoveHandler.cs b/src/kiota/Handlers/Client/RemoveHandler.cs
index 693c50f03d..a4e6a190b4 100644
--- a/src/kiota/Handlers/Client/RemoveHandler.cs
+++ b/src/kiota/Handlers/Client/RemoveHandler.cs
@@ -31,6 +31,7 @@ public override async Task InvokeAsync(InvocationContext context)
await CheckForNewVersionAsync(logger, cancellationToken).ConfigureAwait(false);
var workspaceManagementService = new WorkspaceManagementService(logger, httpClient, true);
await workspaceManagementService.RemoveClientAsync(className, cleanOutput, cancellationToken).ConfigureAwait(false);
+ DisplaySuccess($"Client {className} removed successfully!");
return 0;
}
catch (Exception ex)
diff --git a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
index 084bff1b97..d552a0ccb4 100644
--- a/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
+++ b/src/kiota/Handlers/KiotaGenerateCommandHandler.cs
@@ -77,13 +77,13 @@ public override async Task InvokeAsync(InvocationContext context)
bool includeAdditionalData = context.ParseResult.GetValueForOption(AdditionalDataOption);
string className = context.ParseResult.GetValueForOption(ClassOption) ?? string.Empty;
string namespaceName = context.ParseResult.GetValueForOption(NamespaceOption) ?? string.Empty;
- List serializer = context.ParseResult.GetValueForOption(SerializerOption) ?? new List();
- List deserializer = context.ParseResult.GetValueForOption(DeserializerOption) ?? new List();
- List includePatterns = context.ParseResult.GetValueForOption(IncludePatternsOption) ?? new List();
- List excludePatterns = context.ParseResult.GetValueForOption(ExcludePatternsOption) ?? new List();
- List disabledValidationRules = context.ParseResult.GetValueForOption(DisabledValidationRulesOption) ?? new List();
+ List serializer = context.ParseResult.GetValueForOption(SerializerOption) ?? [];
+ List deserializer = context.ParseResult.GetValueForOption(DeserializerOption) ?? [];
+ List includePatterns = context.ParseResult.GetValueForOption(IncludePatternsOption) ?? [];
+ List excludePatterns = context.ParseResult.GetValueForOption(ExcludePatternsOption) ?? [];
+ List disabledValidationRules = context.ParseResult.GetValueForOption(DisabledValidationRulesOption) ?? [];
bool cleanOutput = context.ParseResult.GetValueForOption(CleanOutputOption);
- List structuredMimeTypes = context.ParseResult.GetValueForOption(StructuredMimeTypesOption) ?? new List();
+ List structuredMimeTypes = context.ParseResult.GetValueForOption(StructuredMimeTypesOption) ?? [];
CancellationToken cancellationToken = context.BindingContext.GetService(typeof(CancellationToken)) is CancellationToken token ? token : CancellationToken.None;
AssignIfNotNullOrEmpty(output, (c, s) => c.OutputPath = s);
AssignIfNotNullOrEmpty(openapi, (c, s) => c.OpenAPIFilePath = s);
diff --git a/src/kiota/KiotaClientCommands.cs b/src/kiota/KiotaClientCommands.cs
index 0511a3bec9..ba3b54fff9 100644
--- a/src/kiota/KiotaClientCommands.cs
+++ b/src/kiota/KiotaClientCommands.cs
@@ -35,18 +35,17 @@ public static Command GetAddCommand()
var languageOption = KiotaHost.GetLanguageOption();
var outputOption = KiotaHost.GetOutputPathOption(defaultConfiguration.OutputPath);
var descriptionOption = KiotaHost.GetDescriptionOption(defaultConfiguration.OpenAPIFilePath, true);
- var namespaceOption = KiotaHost.GetNamespaceOption(defaultConfiguration);
+ var namespaceOption = KiotaHost.GetNamespaceOption(defaultConfiguration.ClientNamespaceName);
var logLevelOption = KiotaHost.GetLogLevelOption();
- var backingStoreOption = KiotaHost.GetBackingStoreOption(defaultConfiguration);
- var excludeBackwardCompatible = KiotaHost.GetExcludeBackwardCompatibleOption(defaultConfiguration);
- var additionalDataOption = KiotaHost.GetAdditionalDataOption(defaultConfiguration);
- var structuredMimeTypesOption = KiotaHost.GetStructuredMimeTypesOption(defaultConfiguration);
+ var backingStoreOption = KiotaHost.GetBackingStoreOption(defaultConfiguration.UsesBackingStore);
+ var excludeBackwardCompatible = KiotaHost.GetExcludeBackwardCompatibleOption(defaultConfiguration.ExcludeBackwardCompatible);
+ var additionalDataOption = KiotaHost.GetAdditionalDataOption(defaultConfiguration.IncludeAdditionalData);
+ var structuredMimeTypesOption = KiotaHost.GetStructuredMimeTypesOption([.. defaultConfiguration.StructuredMimeTypes]);
var (includePatterns, excludePatterns) = KiotaHost.GetIncludeAndExcludeOptions(defaultConfiguration.IncludePatterns, defaultConfiguration.ExcludePatterns);
var dvrOption = KiotaHost.GetDisableValidationRulesOption();
var skipGenerationOption = GetSkipGenerationOption();
var clientNameOption = GetClientNameOption();
-
var command = new Command("add", "Adds a new client to the Kiota configuration"){
descriptionOption,
outputOption,
@@ -104,8 +103,53 @@ public static Command GetRemoveCommand()
}
public static Command GetEditCommand()
{
- var command = new Command("edit", "Edits a client from the Kiota configuration");
- //TODO map the handler
+ var languageOption = KiotaHost.GetOptionalLanguageOption();
+ var outputOption = KiotaHost.GetOutputPathOption(string.Empty);
+ var descriptionOption = KiotaHost.GetDescriptionOption(string.Empty);
+ var namespaceOption = KiotaHost.GetNamespaceOption(string.Empty);
+ var logLevelOption = KiotaHost.GetLogLevelOption();
+ var backingStoreOption = KiotaHost.GetOptionalBackingStoreOption();
+ var excludeBackwardCompatible = KiotaHost.GetOptionalExcludeBackwardCompatibleOption();
+ var additionalDataOption = KiotaHost.GetOptionalAdditionalDataOption();
+ var structuredMimeTypesOption = KiotaHost.GetStructuredMimeTypesOption([]);
+ var (includePatterns, excludePatterns) = KiotaHost.GetIncludeAndExcludeOptions([], []);
+ var dvrOption = KiotaHost.GetDisableValidationRulesOption();
+ var skipGenerationOption = GetSkipGenerationOption();
+ var clientNameOption = GetClientNameOption();
+
+ var command = new Command("edit", "Edits a client from the Kiota configuration") {
+ descriptionOption,
+ outputOption,
+ languageOption,
+ clientNameOption,
+ namespaceOption,
+ logLevelOption,
+ backingStoreOption,
+ excludeBackwardCompatible,
+ additionalDataOption,
+ structuredMimeTypesOption,
+ includePatterns,
+ excludePatterns,
+ dvrOption,
+ skipGenerationOption,
+ };
+ command.Handler = new EditHandler
+ {
+ DescriptionOption = descriptionOption,
+ OutputOption = outputOption,
+ LanguageOption = languageOption,
+ ClassOption = clientNameOption,
+ NamespaceOption = namespaceOption,
+ LogLevelOption = logLevelOption,
+ BackingStoreOption = backingStoreOption,
+ ExcludeBackwardCompatibleOption = excludeBackwardCompatible,
+ AdditionalDataOption = additionalDataOption,
+ StructuredMimeTypesOption = structuredMimeTypesOption,
+ IncludePatternsOption = includePatterns,
+ ExcludePatternsOption = excludePatterns,
+ DisabledValidationRulesOption = dvrOption,
+ SkipGenerationOption = skipGenerationOption,
+ };
return command;
}
public static Command GetGenerateCommand()
diff --git a/src/kiota/KiotaHost.cs b/src/kiota/KiotaHost.cs
index 703b05ed47..ba985ba0dd 100644
--- a/src/kiota/KiotaHost.cs
+++ b/src/kiota/KiotaHost.cs
@@ -281,7 +281,7 @@ internal static Option GetOutputPathOption(string defaultValue)
internal static Option> GetDisableValidationRulesOption()
{
var parameterName = "--disable-validation-rules";
- var option = new Option>(parameterName, () => new List(), "The OpenAPI description validation rules to disable. Accepts multiple values.");
+ var option = new Option>(parameterName, () => [], "The OpenAPI description validation rules to disable. Accepts multiple values.");
option.AddAlias("--dvr");
var validationRules = new[] {
nameof(DivergentResponseSchema),
@@ -336,37 +336,62 @@ internal static Option GetLanguageOption()
AddEnumValidator(languageOption, "language");
return languageOption;
}
- internal static Option GetNamespaceOption(GenerationConfiguration defaultConfiguration)
+ internal static Option GetOptionalLanguageOption()
{
- var namespaceOption = new Option("--namespace-name", () => defaultConfiguration.ClientNamespaceName, "The namespace to use for the core client class specified with the --class-name option.");
+ var languageOption = new Option("--language", "The target language for the generated code files.");
+ languageOption.AddAlias("-l");
+ AddEnumValidator(languageOption, "language");
+ return languageOption;
+ }
+ internal static Option GetNamespaceOption(string defaultNamespaceName)
+ {
+ var namespaceOption = new Option("--namespace-name", () => defaultNamespaceName, "The namespace to use for the core client class specified with the --class-name option.");
namespaceOption.AddAlias("-n");
namespaceOption.ArgumentHelpName = "name";
- AddStringRegexValidator(namespaceOption, namespaceNameRegex(), "namespace name");
+ AddStringRegexValidator(namespaceOption, namespaceNameRegex(), "namespace name", string.IsNullOrEmpty(defaultNamespaceName));
return namespaceOption;
}
- internal static Option GetBackingStoreOption(GenerationConfiguration defaultConfiguration)
+ internal static Option GetBackingStoreOption(bool defaultValue = false)
+ {
+ var backingStoreOption = new Option("--backing-store", () => defaultValue, "Enables backing store for models.");
+ backingStoreOption.AddAlias("-b");
+ return backingStoreOption;
+ }
+ internal static Option GetOptionalBackingStoreOption()
{
- var backingStoreOption = new Option("--backing-store", () => defaultConfiguration.UsesBackingStore, "Enables backing store for models.");
+ var backingStoreOption = new Option("--backing-store", "Enables backing store for models.");
backingStoreOption.AddAlias("-b");
return backingStoreOption;
}
- internal static Option GetExcludeBackwardCompatibleOption(GenerationConfiguration defaultConfiguration)
+ internal static Option GetExcludeBackwardCompatibleOption(bool defaultValue = false)
{
- var excludeBackwardCompatible = new Option("--exclude-backward-compatible", () => defaultConfiguration.ExcludeBackwardCompatible, "Excludes backward compatible and obsolete assets from the generated result. Should be used for new clients.");
+ var excludeBackwardCompatible = new Option("--exclude-backward-compatible", () => defaultValue, "Excludes backward compatible and obsolete assets from the generated result. Should be used for new clients.");
excludeBackwardCompatible.AddAlias("--ebc");
return excludeBackwardCompatible;
}
- internal static Option GetAdditionalDataOption(GenerationConfiguration defaultConfiguration)
+ internal static Option GetOptionalExcludeBackwardCompatibleOption()
+ {
+ var excludeBackwardCompatible = new Option("--exclude-backward-compatible", "Excludes backward compatible and obsolete assets from the generated result. Should be used for new clients.");
+ excludeBackwardCompatible.AddAlias("--ebc");
+ return excludeBackwardCompatible;
+ }
+ internal static Option GetAdditionalDataOption(bool defaultValue = true)
+ {
+ var additionalDataOption = new Option("--additional-data", () => defaultValue, "Will include the 'AdditionalData' property for models.");
+ additionalDataOption.AddAlias("--ad");
+ return additionalDataOption;
+ }
+ internal static Option GetOptionalAdditionalDataOption()
{
- var additionalDataOption = new Option("--additional-data", () => defaultConfiguration.IncludeAdditionalData, "Will include the 'AdditionalData' property for models.");
+ var additionalDataOption = new Option("--additional-data", "Will include the 'AdditionalData' property for models.");
additionalDataOption.AddAlias("--ad");
return additionalDataOption;
}
- internal static Option> GetStructuredMimeTypesOption(GenerationConfiguration defaultConfiguration)
+ internal static Option> GetStructuredMimeTypesOption(List defaultValue)
{
var structuredMimeTypesOption = new Option>(
"--structured-mime-types",
- () => [.. defaultConfiguration.StructuredMimeTypes],
+ () => defaultValue,
"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");
return structuredMimeTypesOption;
@@ -386,15 +411,15 @@ private static Command GetGenerateCommand()
classOption.ArgumentHelpName = "name";
AddStringRegexValidator(classOption, classNameRegex(), "class name");
- var namespaceOption = GetNamespaceOption(defaultConfiguration);
+ var namespaceOption = GetNamespaceOption(defaultConfiguration.ClientNamespaceName);
var logLevelOption = GetLogLevelOption();
- var backingStoreOption = GetBackingStoreOption(defaultConfiguration);
+ var backingStoreOption = GetBackingStoreOption(defaultConfiguration.UsesBackingStore);
- var excludeBackwardCompatible = GetExcludeBackwardCompatibleOption(defaultConfiguration);
+ var excludeBackwardCompatible = GetExcludeBackwardCompatibleOption(defaultConfiguration.ExcludeBackwardCompatible);
- var additionalDataOption = GetAdditionalDataOption(defaultConfiguration);
+ var additionalDataOption = GetAdditionalDataOption(defaultConfiguration.IncludeAdditionalData);
var serializerOption = new Option>(
"--serializer",
@@ -412,7 +437,7 @@ private static Command GetGenerateCommand()
var cleanOutputOption = GetCleanOutputOption(defaultConfiguration.CleanOutput);
- var structuredMimeTypesOption = GetStructuredMimeTypesOption(defaultConfiguration);
+ var structuredMimeTypesOption = GetStructuredMimeTypesOption([.. defaultConfiguration.StructuredMimeTypes]);
var (includePatterns, excludePatterns) = GetIncludeAndExcludeOptions(defaultConfiguration.IncludePatterns, defaultConfiguration.ExcludePatterns);
@@ -517,11 +542,12 @@ private static Option GetClearCacheOption(bool defaultValue)
clearCacheOption.AddAlias("--cc");
return clearCacheOption;
}
- private static void AddStringRegexValidator(Option option, Regex validator, string parameterName)
+ private static void AddStringRegexValidator(Option option, Regex validator, string parameterName, bool allowEmpty = false)
{
option.AddValidator(input =>
{
var value = input.GetValueForOption(option);
+ if (string.IsNullOrEmpty(value) && allowEmpty) return;
if (string.IsNullOrEmpty(value) ||
!validator.IsMatch(value))
input.ErrorMessage = $"{value} is not a valid {parameterName} for the client, the {parameterName} must conform to {validator}";