From 97e56793a6e0617582adc2ad31aa0ffefe8e407e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gild=C3=A9ric?= Date: Thu, 18 Dec 2025 18:12:25 +0100 Subject: [PATCH 1/2] =?UTF-8?q?#341=20cr=C3=A9ation=20modgen=20init?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TopModel.Generator/Program.cs | 62 ++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/TopModel.Generator/Program.cs b/TopModel.Generator/Program.cs index c8f15b433..3d1aa9cd2 100644 --- a/TopModel.Generator/Program.cs +++ b/TopModel.Generator/Program.cs @@ -1,4 +1,4 @@ -using System.CommandLine; +using System.CommandLine; using System.Diagnostics; using System.Reflection; using System.Security.Cryptography; @@ -33,6 +33,66 @@ var command = new RootCommand("Lance le générateur topmodel.") { Name = "modgen" }; +var initCommand = new Command("init", "Initialise un nouveau fichier de configuration topmodel."); +var initAppOption = new Option(["-a", "--app"], "Nom de l'application."); +var initFileOption = new Option(["-f", "--file"], "Nom du fichier de configuration à créer."); +initCommand.AddOption(initAppOption); +initCommand.AddOption(initFileOption); +initCommand.SetHandler( + (app, file) => + { + var fileName = file ?? "topmodel.config"; + var filePath = Path.GetFullPath(fileName); + + if (File.Exists(filePath)) + { + AnsiConsole.MarkupLine($"[red]Le fichier '{fileName}' existe déjà.[/]"); + returnCode = 1; + return; + } + + var appName = app ?? Path.GetFileName(Directory.GetCurrentDirectory()); + + var availableGenerators = new[] { "csharp", "jpa", "javascript", "sql" }; + var selectedGenerators = AnsiConsole.Prompt( + new MultiSelectionPrompt() + .Title("Sélectionnez les générateurs à utiliser :") + .NotRequired() + .PageSize(10) + .InstructionsText( + "[grey](Appuyez sur [blue][/] pour sélectionner, [green][/] pour valider)[/]" + ) + .AddChoices(availableGenerators) + ); + + var configBuilder = new StringBuilder(); + configBuilder.AppendLine("---"); + configBuilder.AppendLine($"app: {appName}"); + + foreach (var generator in selectedGenerators) + { + configBuilder.AppendLine(); + configBuilder.AppendLine($"{generator}:"); + configBuilder.AppendLine(" - tags:"); + configBuilder.AppendLine( + $" - {((generator == "csharp" || generator == "jpa" || generator == "sql") ? "back" : "front")}" + ); + configBuilder.AppendLine(" outputDirectory: ./generated"); + } + + File.WriteAllText(filePath, configBuilder.ToString()); + AnsiConsole.MarkupLine($"[green]Fichier de configuration '{fileName}' créé avec succès.[/]"); + AnsiConsole.MarkupLine($"[grey]Application : {appName}[/]"); + if (selectedGenerators.Count > 0) + { + AnsiConsole.MarkupLine($"[grey]Générateurs : {string.Join(", ", selectedGenerators)}[/]"); + } + }, + initAppOption, + initFileOption +); +command.AddCommand(initCommand); + var fileOption = new Option>(["-f", "--file"], "Chemin vers un fichier de config."); var excludeOption = new Option>(["-e", "--exclude"], "Tag à ignorer lors de la génération."); var watchOption = new Option(["-w", "--watch"], "Lance le générateur en mode 'watch'"); From 694cd7d01d3fb054864ea4d64db7b92f1078ac1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gild=C3=A9ric?= Date: Mon, 29 Dec 2025 11:52:21 +0100 Subject: [PATCH 2/2] =?UTF-8?q?[Tmdgen]=20Dans=20le=20cas=20d'un=20allOf,?= =?UTF-8?q?=20ne=20pas=20ajouter=20les=20propri=C3=A9t=C3=A9s=20en=20doubl?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TopModel.ModelGenerator/OpenApi/OpenApiUtils.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TopModel.ModelGenerator/OpenApi/OpenApiUtils.cs b/TopModel.ModelGenerator/OpenApi/OpenApiUtils.cs index 5560584f9..d760bd052 100644 --- a/TopModel.ModelGenerator/OpenApi/OpenApiUtils.cs +++ b/TopModel.ModelGenerator/OpenApi/OpenApiUtils.cs @@ -131,6 +131,7 @@ public static IDictionary GetProperties(this IOpenApiSch .Where(a => a.Type == JsonSchemaType.Object) .SelectMany(a => a.Properties ?? new Dictionary()) ) + .DistinctBy(a => a.Key) .ToDictionary(a => a.Key, a => a.Value) ?? []; }