diff --git a/TopModel.Generator/Program.cs b/TopModel.Generator/Program.cs index 0a47aa84..8f87f3a2 100644 --- a/TopModel.Generator/Program.cs +++ b/TopModel.Generator/Program.cs @@ -5,6 +5,7 @@ using System.Text; using System.Text.Encodings.Web; using System.Text.Json.Nodes; +using System.Text.RegularExpressions; using System.Xml; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -88,12 +89,30 @@ void HandleFile(FileInfo file) else { var dir = Directory.GetCurrentDirectory(); - var pattern = "topmodel*.config"; - foreach (var fileName in Directory.EnumerateFiles(dir, pattern, SearchOption.AllDirectories)) + var pattern = new Regex("topmodel\\.?([a-zA-Z-_.]*)\\.config$"); + + void SearchConfigFile(string dirName, int depth = 0) { - HandleFile(new FileInfo(fileName)); + if (depth > 3) + { + return; + } + + foreach (var entryName in Directory.EnumerateFileSystemEntries(dirName)) + { + if (Directory.Exists(entryName)) + { + SearchConfigFile(entryName, depth + 1); + } + else if (pattern.IsMatch(entryName)) + { + HandleFile(new FileInfo(entryName)); + } + } } + SearchConfigFile(dir); + if (configs.Count == 0) { var found = false; @@ -102,7 +121,7 @@ void HandleFile(FileInfo file) dir = Directory.GetParent(dir)?.FullName; if (dir != null) { - foreach (var fileName in Directory.EnumerateFiles(dir, pattern)) + foreach (var fileName in Directory.EnumerateFiles(dir).Where(f => pattern.IsMatch(f))) { HandleFile(new FileInfo(fileName)); found = true; @@ -233,30 +252,31 @@ void HandleFile(FileInfo file) foreach (var cg in config.CustomGenerators) { + var customDir = Path.GetFullPath(Path.Combine(new FileInfo(Path.GetFullPath(fullName)).DirectoryName!, cg)); + string GetCgHash() { return GetHash( - GetCustomAssemblies(cg, fullName).Select(f => f.FullName) - .Concat(Directory.EnumerateFiles( + Directory + .EnumerateFiles( Path.GetFullPath(cg, new FileInfo(fullName).DirectoryName!), "*.cs", SearchOption.AllDirectories) - .Where(f => !f.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}"))) - .ToList(), - cg) ?? string.Empty; + .Where(f => !f.Contains($"{Path.DirectorySeparatorChar}obj{Path.DirectorySeparatorChar}")), + customDir) ?? string.Empty; } var customHash = GetCgHash(); - if (!(topModelLock.Custom?.TryGetValue(cg, out var customLockHash) ?? false) || customHash != customLockHash) + if (!topModelLock.Custom.TryGetValue(cg, out var customLockHash) || customHash != customLockHash) { logger.LogInformation($"Build de '{cg}' en cours..."); var build = Process.Start(new ProcessStartInfo { CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, - FileName = "dotnet.exe", + FileName = "dotnet", Arguments = "build -v q", - WorkingDirectory = cg, + WorkingDirectory = customDir, RedirectStandardOutput = true, StandardOutputEncoding = Encoding.UTF8 }); @@ -285,13 +305,25 @@ string GetCgHash() config.CustomGenerators.AddRange(modules.Select(m => Path.GetRelativePath(new FileInfo(fullName).DirectoryName!, m).Replace("\\", "/"))); } + var modgenRoot = Path.GetFullPath(".modgen", config.ModelRoot); + if (updateMode == "all") { topModelLock.Modules = []; + + if (Directory.Exists(modgenRoot)) + { + Directory.Delete(modgenRoot, true); + } } else if (updateMode != null) { topModelLock.Modules.Remove(updateMode); + + foreach (var module in Directory.GetFileSystemEntries(modgenRoot).Where(p => p.Split('/').Last().Contains(updateMode))) + { + Directory.Delete(module, true); + } } foreach (var cg in config.CustomGenerators) @@ -351,7 +383,10 @@ string GetCgHash() if (returnCode == 0) { - var assemblies = GetCustomAssemblies(cg, fullName) + var assemblies = new DirectoryInfo(Path.Combine(Path.GetFullPath(cg, new FileInfo(fullName).DirectoryName!), "bin")) + .GetFiles($"*.dll", SearchOption.AllDirectories) + .Where(a => a.FullName.Contains(framework) && !modgenAssemblies.Contains(a.Name)) + .DistinctBy(a => a.Name) .Select(f => Assembly.LoadFrom(f.FullName)) .ToList(); @@ -397,19 +432,6 @@ string GetCgHash() } var hasInstalled = false; - var modgenRoot = Path.GetFullPath(".modgen", config.ModelRoot); - - if (updateMode == "all" && Directory.Exists(modgenRoot)) - { - Directory.Delete(modgenRoot, true); - } - else if (updateMode != null) - { - foreach (var module in Directory.GetFileSystemEntries(modgenRoot).Where(p => p.Split('/').Last().Contains(updateMode))) - { - Directory.Delete(module, true); - } - } if (deps.Count > 0) { @@ -674,25 +696,18 @@ string GetCgHash() return returnCode; -IEnumerable GetCustomAssemblies(string cg, string fullName) -{ - return new DirectoryInfo(Path.Combine(Path.GetFullPath(cg, new FileInfo(fullName).DirectoryName!), "bin")) - .GetFiles($"*.dll", SearchOption.AllDirectories) - .Where(a => a.FullName.Contains(framework) && !modgenAssemblies.Contains(a.Name)) - .DistinctBy(a => a.Name); -} - static string? GetFolderHash(string path) { - return GetHash(Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).OrderBy(p => p).ToList(), path); + return GetHash(Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories), path); } -static string? GetHash(IList files, string path) +static string? GetHash(IEnumerable f, string path) { var md5 = MD5.Create(); + var files = f.OrderBy(f => f).ToList(); foreach (var file in files) { - var relativePath = file[(path.Length + 1)..]; + var relativePath = Path.GetRelativePath(path, file).Replace("\\", "/"); var pathBytes = Encoding.UTF8.GetBytes(relativePath.ToLower()); md5.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0); diff --git a/TopModel.Utils/TopModelLock.cs b/TopModel.Utils/TopModelLock.cs index 26ca9990..4779b0e3 100644 --- a/TopModel.Utils/TopModelLock.cs +++ b/TopModel.Utils/TopModelLock.cs @@ -18,6 +18,7 @@ public class TopModelLock : TopModelLockFile private readonly string _modelRoot; private readonly ISerializer _serializer = new SerializerBuilder() + .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitEmptyCollections) .WithNamingConvention(CamelCaseNamingConvention.Instance) .WithIndentedSequences() .Build(); @@ -39,8 +40,8 @@ public TopModelLock(ILogger logger, string modelRoot, string lockFileName) var lf = _deserializer.Deserialize(file); Version = lf.Version; GeneratedFiles = lf.GeneratedFiles; - Modules = lf.Modules; - Custom = lf.Custom; + Modules = lf.Modules ?? []; + Custom = lf.Custom ?? []; } catch { diff --git a/TopModel.Utils/TopModelLockFile.cs b/TopModel.Utils/TopModelLockFile.cs index 0c6cab79..b25df1c5 100644 --- a/TopModel.Utils/TopModelLockFile.cs +++ b/TopModel.Utils/TopModelLockFile.cs @@ -6,7 +6,7 @@ public class TopModelLockFile public Dictionary Modules { get; set; } = []; - public Dictionary? Custom { get; set; } + public Dictionary Custom { get; set; } = []; public List GeneratedFiles { get; set; } = []; } diff --git a/samples/generators/open-api/tmdgen.lock b/samples/generators/open-api/tmdgen.lock index 4fdff8d4..8f8cd42c 100644 --- a/samples/generators/open-api/tmdgen.lock +++ b/samples/generators/open-api/tmdgen.lock @@ -3,7 +3,6 @@ # version: 1.6.9 -modules: {} generatedFiles: - ./Petstore/Model.tmd - ./Petstore/Pet.tmd diff --git a/samples/model/angular.topmodel.lock b/samples/model/angular.topmodel.lock index 6587c6fc..bfe27005 100644 --- a/samples/model/angular.topmodel.lock +++ b/samples/model/angular.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Javascript: e39801d826bcb9c740ebb356ac0b7fbb generatedFiles: - ../generators/angular/src/appgenerated/api/securite/profil/profil.service.ts - ../generators/angular/src/appgenerated/api/securite/utilisateur/utilisateur.service.ts diff --git a/samples/model/csharp.topmodel.lock b/samples/model/csharp.topmodel.lock index 307226eb..e2874f55 100644 --- a/samples/model/csharp.topmodel.lock +++ b/samples/model/csharp.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Csharp: 121e8b5ce6a8be344945262bf8960580 generatedFiles: - ../generators/csharp/src/Clients/CSharp.Clients.Db/generated/CSharpDbContext.comments.cs - ../generators/csharp/src/Clients/CSharp.Clients.Db/generated/CSharpDbContext.cs diff --git a/samples/model/focus.topmodel.lock b/samples/model/focus.topmodel.lock index a1a64cb8..113b0181 100644 --- a/samples/model/focus.topmodel.lock +++ b/samples/model/focus.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Javascript: e39801d826bcb9c740ebb356ac0b7fbb generatedFiles: - ../generators/focus/src/locale/common.ts - ../generators/focus/src/locale/securite.ts diff --git a/samples/model/jpa.topmodel.lock b/samples/model/jpa.topmodel.lock index e118026f..8a2a259a 100644 --- a/samples/model/jpa.topmodel.lock +++ b/samples/model/jpa.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Jpa: 3df4f5992b92ce79d5bfddf465926bd2 generatedFiles: - ../generators/jpa/src/main/javagen/topmodel/jpa/sample/demo/api/client/securite/profil/ProfilClient.java - ../generators/jpa/src/main/javagen/topmodel/jpa/sample/demo/api/client/securite/utilisateur/UtilisateurClient.java diff --git a/samples/model/pg.topmodel.lock b/samples/model/pg.topmodel.lock index 4fb106d2..18d79c98 100644 --- a/samples/model/pg.topmodel.lock +++ b/samples/model/pg.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Sql: a7d6d70714c8ee38aeac8e9447ed12fd generatedFiles: - ../generators/pg/src/01_tables.sql - ../generators/pg/src/02_fk_indexes.sql diff --git a/samples/model/php.topmodel.lock b/samples/model/php.topmodel.lock index 18896a3d..3bd91bbc 100644 --- a/samples/model/php.topmodel.lock +++ b/samples/model/php.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Php: 8029e36a5806c385b25b725c2e00ecdc generatedFiles: - ../generators/php/src/Entity/Securite/Profil/Droit.php - ../generators/php/src/Entity/Securite/Profil/Profil.php diff --git a/samples/model/ssdt.topmodel.lock b/samples/model/ssdt.topmodel.lock index 394af1a8..e769a685 100644 --- a/samples/model/ssdt.topmodel.lock +++ b/samples/model/ssdt.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Sql: a7d6d70714c8ee38aeac8e9447ed12fd generatedFiles: - ../generators/ssdt/src/init/DROIT.insert.sql - ../generators/ssdt/src/init/main.sql diff --git a/samples/model/translation.topmodel.lock b/samples/model/translation.topmodel.lock index fb84e822..bd0338b8 100644 --- a/samples/model/translation.topmodel.lock +++ b/samples/model/translation.topmodel.lock @@ -3,7 +3,8 @@ # version: 2.1.0 -modules: {} +custom: + ../../../TopModel.Generator.Translation: 9f15a161c1cd09a554e17eb18f624495 generatedFiles: - ../generators/translation/i18n/de_DE/out/common_de_DE.properties - ../generators/translation/i18n/de_DE/out/securite_de_DE.properties