From 5c53e793189089bcd0c53550d53b184fc954774b Mon Sep 17 00:00:00 2001 From: Damien Date: Mon, 2 Sep 2024 15:51:34 +0200 Subject: [PATCH] Initialisation lock file dans modgen au lieu de core --- TopModel.Core/ModelStore.cs | 25 ++------- TopModel.Core/ServiceExtensions.cs | 22 ++++---- TopModel.Core/TopModel.Core.csproj | 1 - .../JpaModelPropertyGenerator.cs | 44 +++++++-------- TopModel.Generator/Program.cs | 15 ++++-- TopModel.LanguageServer/Program.cs | 3 +- TopModel.ModelGenerator/Program.cs | 26 ++------- TopModel.UI/Program.cs | 3 +- TopModel.Utils/TopModel.Utils.csproj | 1 + TopModel.Utils/TopModelLock.cs | 54 ++++++++++++++----- TopModel.Utils/TopModelLockFile.cs | 8 +++ 11 files changed, 107 insertions(+), 95 deletions(-) create mode 100644 TopModel.Utils/TopModelLockFile.cs diff --git a/TopModel.Core/ModelStore.cs b/TopModel.Core/ModelStore.cs index 32eaabc0..7a4800b2 100644 --- a/TopModel.Core/ModelStore.cs +++ b/TopModel.Core/ModelStore.cs @@ -20,11 +20,11 @@ public class ModelStore private readonly HashSet _pendingUpdates = []; private readonly object _puLock = new(); - private readonly TopModelLock _topModelLock = new(); private readonly TranslationStore _translationStore; private LoggingScope? _storeConfig; + private TopModelLock? _topModelLock; public ModelStore(IMemoryCache fsCache, ModelFileLoader modelFileLoader, ILogger logger, ModelConfig config, IEnumerable modelWatchers, TranslationStore translationStore) { @@ -34,20 +34,6 @@ public ModelStore(IMemoryCache fsCache, ModelFileLoader modelFileLoader, ILogger _modelFileLoader = modelFileLoader; _translationStore = translationStore; _modelWatchers = modelWatchers.Where(mw => !mw.Disabled); - - var lockFile = new FileInfo(Path.Combine(_config.ModelRoot, _config.LockFileName)); - if (lockFile.Exists) - { - try - { - using var file = lockFile.OpenText(); - _topModelLock = new FileChecker().Deserialize(file); - } - catch - { - logger.LogError($"Erreur à la lecture du fichier {_config.LockFileName}. Merci de rétablir la version générée automatiquement."); - } - } } public event Action? OnResolve; @@ -97,14 +83,13 @@ public Dictionary GetReferencedClasses(ModelFile modelFile) .ToDictionary(c => c.Key, c => c.First()); } - public IDisposable? LoadFromConfig(bool watch = false, LoggingScope? storeConfig = null) + public IDisposable? LoadFromConfig(bool watch = false, TopModelLock? topModelLock = null, LoggingScope? storeConfig = null) { _storeConfig = storeConfig; + _topModelLock = topModelLock; using var scope = _logger.BeginScope(_storeConfig!); - _topModelLock.Init(_logger); - var watchers = _modelWatchers.Select(mw => mw.FullName.Split("@")).GroupBy(split => split[0]).Select(grp => $"{grp.Key}@{{{string.Join(",", grp.Select(split => split[1]))}}}"); _logger.LogInformation($"Watchers enregistrés : \n - {string.Join("\n - ", watchers.OrderBy(x => x))}"); @@ -225,9 +210,9 @@ public void TryApplyUpdates() }); var generatedFiles = _modelWatchers.Where(m => m.GeneratedFiles != null).SelectMany(m => m.GeneratedFiles!); - if (generatedFiles.Any() && !DisableLockfile) + if (generatedFiles.Any() && !DisableLockfile && _topModelLock != null) { - _topModelLock.Update(_config.ModelRoot, _config.LockFileName, _logger, generatedFiles); + _topModelLock.Update(generatedFiles); } _logger.LogInformation($"Mise à jour terminée avec succès."); diff --git a/TopModel.Core/ServiceExtensions.cs b/TopModel.Core/ServiceExtensions.cs index 4483cc13..e6cbf43a 100644 --- a/TopModel.Core/ServiceExtensions.cs +++ b/TopModel.Core/ServiceExtensions.cs @@ -6,7 +6,7 @@ namespace TopModel.Core; public static class ServiceExtensions { - public static IServiceCollection AddModelStore(this IServiceCollection services, FileChecker fileChecker, ModelConfig? config = null, string? rootDir = null) + public static IServiceCollection AddModelStore(this IServiceCollection services, FileChecker fileChecker, ModelConfig config) { services .AddMemoryCache() @@ -21,17 +21,17 @@ public static IServiceCollection AddModelStore(this IServiceCollection services, .AddSingleton() .AddSingleton() .AddSingleton() - .AddSingleton(); - - if (config != null && rootDir != null) - { - config.ModelRoot ??= string.Empty; - ModelUtils.TrimSlashes(config, c => c.ModelRoot); - ModelUtils.CombinePath(rootDir, config, c => c.ModelRoot); - ModelUtils.CombinePath(rootDir, config.I18n, c => c.RootPath); - services.AddSingleton(config); - } + .AddSingleton() + .AddSingleton(config); return services; } + + public static void FixConfig(this ModelConfig config, string rootDir) + { + config.ModelRoot ??= string.Empty; + ModelUtils.TrimSlashes(config, c => c.ModelRoot); + ModelUtils.CombinePath(rootDir, config, c => c.ModelRoot); + ModelUtils.CombinePath(rootDir, config.I18n, c => c.RootPath); + } } \ No newline at end of file diff --git a/TopModel.Core/TopModel.Core.csproj b/TopModel.Core/TopModel.Core.csproj index b33bb293..023abf6b 100644 --- a/TopModel.Core/TopModel.Core.csproj +++ b/TopModel.Core/TopModel.Core.csproj @@ -44,7 +44,6 @@ - diff --git a/TopModel.Generator.Jpa/JpaModelPropertyGenerator.cs b/TopModel.Generator.Jpa/JpaModelPropertyGenerator.cs index 7d969c6e..d844aede 100644 --- a/TopModel.Generator.Jpa/JpaModelPropertyGenerator.cs +++ b/TopModel.Generator.Jpa/JpaModelPropertyGenerator.cs @@ -89,20 +89,6 @@ public void WriteCompositePrimaryKeyClass(JavaWriter fw, Class classe, string ta fw.WriteLine(1, "}"); } - private string GetterToCompareCompositePkPk(IProperty pk) - { - if (pk is AssociationProperty ap) - { - return $".get{ap.Property.NamePascal}()"; - } - else if (pk is AliasProperty al && al.Property is AssociationProperty asp) - { - return $".get{asp.Property.NamePascal}()"; - } - - return string.Empty; - } - public void WriteCompositionProperty(JavaWriter fw, CompositionProperty property, string tag) { fw.WriteDocEnd(1); @@ -209,6 +195,20 @@ private static void WriteValidationAnnotations(JavaWriter fw, string javaOrJakar fw.AddImport($"{javaOrJakarta}.validation.constraints.NotNull"); } + private string GetterToCompareCompositePkPk(IProperty pk) + { + if (pk is AssociationProperty ap) + { + return $".get{ap.Property.NamePascal}()"; + } + else if (pk is AliasProperty al && al.Property is AssociationProperty asp) + { + return $".get{asp.Property.NamePascal}()"; + } + + return string.Empty; + } + private bool ShouldWriteColumnAnnotation(Class classe, IProperty property) { return (classe.IsPersistent || _config.UseJdbc) && (property.Domain is null || !_config.GetImplementation(property.Domain)!.Annotations @@ -275,14 +275,6 @@ private void WriteAliasProperty(JavaWriter fw, Class classe, AliasProperty prope fw.WriteLine(1, $"private {_config.GetType(property, useClassForAssociation: useClassForAssociation)} {(isAssociationNotPersistent && !shouldWriteAssociation ? property.NameCamel : property.NameByClassCamel)}{suffix};"); } - private void WriteConvertAnnotation(JavaWriter fw, CompositionProperty property, int indentLevel, string tag) - { - var javaOrJakarta = _config.PersistenceMode.ToString().ToLower(); - fw.AddImport($"{javaOrJakarta}.persistence.Convert"); - fw.AddImport(_config.CompositionConverterCanonicalName.Replace("{class}", property.Class.Name).Replace("{package}", _config.GetPackageName(property.Class, tag))); - fw.WriteLine(indentLevel, $"@Convert(converter = {_config.CompositionConverterSimpleName.Replace("{class}", property.Class.Name)}.class)"); - } - private void WriteAssociationAnnotations(JavaWriter fw, Class classe, AssociationProperty property, int indentLevel) { switch (property.Type) @@ -429,6 +421,14 @@ private void WriteColumnAnnotation(JavaWriter fw, IProperty property, int indent fw.WriteLine(indentLevel, column); } + private void WriteConvertAnnotation(JavaWriter fw, CompositionProperty property, int indentLevel, string tag) + { + var javaOrJakarta = _config.PersistenceMode.ToString().ToLower(); + fw.AddImport($"{javaOrJakarta}.persistence.Convert"); + fw.AddImport(_config.CompositionConverterCanonicalName.Replace("{class}", property.Class.Name).Replace("{package}", _config.GetPackageName(property.Class, tag))); + fw.WriteLine(indentLevel, $"@Convert(converter = {_config.CompositionConverterSimpleName.Replace("{class}", property.Class.Name)}.class)"); + } + private void WriteDomainAnnotations(JavaWriter fw, IProperty property, string tag, int indentLevel) { foreach (var annotation in _config.GetDomainAnnotations(property, tag)) diff --git a/TopModel.Generator/Program.cs b/TopModel.Generator/Program.cs index f71fd84d..bc1b72f2 100644 --- a/TopModel.Generator/Program.cs +++ b/TopModel.Generator/Program.cs @@ -188,6 +188,13 @@ void HandleFile(FileInfo file) { var (config, fullName, dn) = configs[i]; + config.FixConfig(dn); + + var storeConfig = new LoggingScope(i + 1, colors[i % colors.Length]); + var logger = loggerProvider.CreateLogger("TopModel.Generator"); + using var scope = logger.BeginScope(storeConfig); + var topModelLock = new TopModelLock(logger, config.ModelRoot, config.LockFileName); + Console.WriteLine(); var generators = baseGenerators @@ -248,7 +255,7 @@ void HandleFile(FileInfo file) .AddTransient(typeof(ILogger<>), typeof(Logger<>)) .AddTransient() .AddSingleton(loggerProvider) - .AddModelStore(fileChecker, config, dn); + .AddModelStore(fileChecker, config); var hasError = false; @@ -278,9 +285,7 @@ void HandleFile(FileInfo file) var instance = Activator.CreateInstance(generator); instance!.GetType().GetMethod("Register")! - .Invoke( - instance, - new object[] { services, genConfig, number }); + .Invoke(instance, [services, genConfig, number]); } catch (ModelException me) { @@ -310,7 +315,7 @@ void HandleFile(FileInfo file) hasErrors[k] = hasError; }; - var watcher = modelStore.LoadFromConfig(watchMode, new(i + 1, colors[i % colors.Length])); + var watcher = modelStore.LoadFromConfig(watchMode, topModelLock, storeConfig); if (watcher != null) { disposables.Add(watcher); diff --git a/TopModel.LanguageServer/Program.cs b/TopModel.LanguageServer/Program.cs index 8d841b8b..c1e1f48b 100644 --- a/TopModel.LanguageServer/Program.cs +++ b/TopModel.LanguageServer/Program.cs @@ -18,9 +18,10 @@ var configFile = new FileInfo(args.Length > 0 ? args[0] : "topmodel.config"); var config = fileChecker.Deserialize(configFile.OpenText().ReadToEnd()); var dn = configFile.DirectoryName; + config.FixConfig(dn!); services - .AddModelStore(fileChecker, config, dn) + .AddModelStore(fileChecker, config) .AddSingleton() .AddSingleton(); }) diff --git a/TopModel.ModelGenerator/Program.cs b/TopModel.ModelGenerator/Program.cs index 7efd16da..9aae25c7 100644 --- a/TopModel.ModelGenerator/Program.cs +++ b/TopModel.ModelGenerator/Program.cs @@ -17,9 +17,9 @@ var configs = new List<(ModelGeneratorConfig Config, string FullPath, string DirectoryName)>(); var serializer = new Serializer(new() { NamingConvention = new CamelCaseNamingConvention() }); -var fileOption = new Option>(new[] { "-f", "--file" }, "Chemin vers un fichier de config."); -var watchOption = new Option(new[] { "-w", "--watch" }, "Lance le générateur en mode 'watch'"); -var checkOption = new Option(new[] { "-c", "--check" }, "Vérifie que le modèle généré est conforme aux sources."); +var fileOption = new Option>(["-f", "--file"], "Chemin vers un fichier de config."); +var watchOption = new Option(["-w", "--watch"], "Lance le générateur en mode 'watch'"); +var checkOption = new Option(["-c", "--check"], "Vérifie que le modèle généré est conforme aux sources."); command.AddOption(fileOption); command.AddOption(watchOption); command.AddOption(checkOption); @@ -210,23 +210,7 @@ async Task StartGeneration(string filePath, string directoryName, int i) mainLogger.LogInformation($"Générateurs enregistrés :\n {string.Join("\n ", generators.Select(g => $"- {g.Name}@{{{g.Number}}}"))}"); - TopModelLock tmdLock = new(); - var lockFile = new FileInfo(Path.Combine(config.ModelRoot, config.LockFileName)); - if (lockFile.Exists) - { - try - { - using var file = lockFile.OpenText(); - tmdLock = serializer.Deserialize(file)!; - } - catch - { - mainLogger.LogError($"Erreur à la lecture du fichier {config.LockFileName}. Merci de rétablir la version générée automatiquement."); - } - } - - tmdLock.Init(mainLogger); - + var tmdLock = new TopModelLock(mainLogger, config.ModelRoot, config.LockFileName); var generatedFiles = new List(); foreach (var generator in generators) @@ -234,7 +218,7 @@ async Task StartGeneration(string filePath, string directoryName, int i) generatedFiles.AddRange(await generator.Generate(loggingScope)); } - tmdLock.Update(config.ModelRoot, config.LockFileName, mainLogger, generatedFiles); + tmdLock.Update(generatedFiles); mainLogger.LogInformation("Mise à jour terminée avec succès."); } diff --git a/TopModel.UI/Program.cs b/TopModel.UI/Program.cs index 6fc2f1e4..f9260e06 100644 --- a/TopModel.UI/Program.cs +++ b/TopModel.UI/Program.cs @@ -18,9 +18,10 @@ public static void Main(string[] args) var configFile = new FileInfo(args[0]); var config = fileChecker.Deserialize(configFile.OpenText().ReadToEnd()); var dn = configFile.DirectoryName; + config.FixConfig(dn!); services - .AddModelStore(fileChecker, config, dn) + .AddModelStore(fileChecker, config) .AddHostedService() .AddSingleton() .AddSingleton(p => p.GetRequiredService()); diff --git a/TopModel.Utils/TopModel.Utils.csproj b/TopModel.Utils/TopModel.Utils.csproj index 75bbca33..58e5e99d 100644 --- a/TopModel.Utils/TopModel.Utils.csproj +++ b/TopModel.Utils/TopModel.Utils.csproj @@ -43,6 +43,7 @@ + diff --git a/TopModel.Utils/TopModelLock.cs b/TopModel.Utils/TopModelLock.cs index 9dcc43d7..a7ba40b0 100644 --- a/TopModel.Utils/TopModelLock.cs +++ b/TopModel.Utils/TopModelLock.cs @@ -1,19 +1,47 @@ -using System.Reflection; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; using System.Runtime.InteropServices; using Microsoft.Extensions.Logging; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; namespace TopModel.Utils; -public class TopModelLock +public class TopModelLock : TopModelLockFile { -#nullable disable - public string Version { get; set; } -#nullable enable + private readonly IDeserializer _deserializer = new DeserializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); - public List GeneratedFiles { get; set; } = new(); + private readonly string _lockFileName; + private readonly ILogger _logger; + private readonly string _modelRoot; - public void Init(ILogger logger) + [SetsRequiredMembers] + public TopModelLock(ILogger logger, string modelRoot, string lockFileName) { + _lockFileName = lockFileName; + _logger = logger; + _modelRoot = modelRoot; + + var lockFile = new FileInfo(Path.Combine(modelRoot, lockFileName)); + + if (lockFile.Exists) + { + try + { + using var file = lockFile.OpenText(); + var lf = _deserializer.Deserialize(file); + Version = lf.Version; + GeneratedFiles = lf.GeneratedFiles; + } + catch + { + _logger.LogError($"Erreur à la lecture du fichier {lockFileName}. Merci de rétablir la version générée automatiquement."); + throw; + } + } + var assembly = Assembly.GetEntryAssembly()!.GetName()!; var version = $"{assembly.Version!.Major}.{assembly.Version!.Minor}.{assembly.Version!.Build}"; @@ -25,12 +53,12 @@ public void Init(ILogger logger) Version = version; } - public void Update(string modelRoot, string lockFileName, ILogger logger, IEnumerable generatedFiles) + public void Update(IEnumerable generatedFiles) { - GeneratedFiles ??= new(); + GeneratedFiles ??= []; var generatedFilesList = generatedFiles - .Select(f => f.ToRelative(modelRoot)) + .Select(f => f.ToRelative(_modelRoot)) .Distinct() .OrderBy(f => f) .ToList(); @@ -39,17 +67,17 @@ public void Update(string modelRoot, string lockFileName, ILogger logger, IEnume var filesToPrune = GeneratedFiles .Select(f => f.Replace("\\", "/")) .Where(f => !generatedFilesList.Select(gf => isWindows ? gf.ToLowerInvariant() : gf).Contains(isWindows ? f.ToLowerInvariant() : f)) - .Select(f => Path.Combine(modelRoot, f)); + .Select(f => Path.Combine(_modelRoot, f)); Parallel.ForEach(filesToPrune.Where(File.Exists), fileToPrune => { File.Delete(fileToPrune); - logger.LogInformation($"Supprimé: {fileToPrune.ToRelative()}"); + _logger.LogInformation($"Supprimé: {fileToPrune.ToRelative()}"); }); GeneratedFiles = generatedFilesList; - using var fw = new FileWriter(Path.Combine(modelRoot, lockFileName), logger) + using var fw = new FileWriter(Path.Combine(_modelRoot, _lockFileName), _logger) { StartCommentToken = "#" }; diff --git a/TopModel.Utils/TopModelLockFile.cs b/TopModel.Utils/TopModelLockFile.cs new file mode 100644 index 00000000..b2179c79 --- /dev/null +++ b/TopModel.Utils/TopModelLockFile.cs @@ -0,0 +1,8 @@ +namespace TopModel.Utils; + +public class TopModelLockFile +{ + public required string Version { get; set; } + + public List GeneratedFiles { get; set; } = []; +}