Skip to content

Commit a09fe91

Browse files
committed
Common
feat: global assembly cache added feat: more/better logging added feat: massive performance improvements feat: signed license handling and optional check added
1 parent 9a73da6 commit a09fe91

File tree

52 files changed

+438
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+438
-99
lines changed

Angular.Tests/KY.Generator.Angular.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="KY.Core.Common" Version="4.32.0" />
12+
<PackageReference Include="KY.Core.Common" Version="4.34.0" />
1313
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
1414
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
1515
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />

Angular/KY.Generator.Angular.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<Authors>KY-Programming</Authors>
66
<Company>KY-Programming</Company>
77
<Product>KY.Generator</Product>
8-
<Version>8.7.0</Version>
8+
<Version>8.8.0-preview.1</Version>
99
<Copyright>2023 - KY-Programming</Copyright>
1010
<Description>Angular Module for KY-Generator
1111
Download KY.Generator to use this module</Description>

Annotations/KY.Generator.Annotations.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<Company>KY-Programming</Company>
66
<Authors>KY-Programming</Authors>
7-
<Version>8.7.0</Version>
7+
<Version>8.8.0-preview.1</Version>
88
<Product>KY.Generator</Product>
99
<Description>Annotations for KY-Generator</Description>
1010
<Copyright>2023 - KY-Programming</Copyright>

AspDotNet.Tests/KY.Generator.AspDotNet.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="KY.Core.Common" Version="4.32.0" />
12+
<PackageReference Include="KY.Core.Common" Version="4.34.0" />
1313
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
1414
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
1515
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />

AspDotNet/KY.Generator.AspDotNet.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<Company>KY-Programming</Company>
66
<Authors>KY-Programming</Authors>
7-
<Version>8.7.0</Version>
7+
<Version>8.8.0-preview.1</Version>
88
<Product>KY.Generator</Product>
99
<Description>ASP.net Module for KY-Generator
1010
Download KY.Generator to use this module</Description>
@@ -29,7 +29,7 @@ Download KY.Generator to use this module</Description>
2929
</PropertyGroup>
3030

3131
<ItemGroup>
32-
<PackageReference Include="KY.Core.Common" Version="4.32.0" />
32+
<PackageReference Include="KY.Core.Common" Version="4.34.0" />
3333
</ItemGroup>
3434

3535
<ItemGroup>

CLI/KY.Generator.CLI.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@
4242
<HintPath>..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll</HintPath>
4343
<Private>True</Private>
4444
</Reference>
45-
<Reference Include="KY.Core.Common, Version=4.32.0.0, Culture=neutral, processorArchitecture=MSIL">
46-
<HintPath>..\packages\KY.Core.Common.4.32.0\lib\netstandard2.0\KY.Core.Common.dll</HintPath>
45+
<Reference Include="KY.Core.Common, Version=4.34.0.0, Culture=neutral, processorArchitecture=MSIL">
46+
<HintPath>..\packages\KY.Core.Common.4.34.0\lib\netstandard2.0\KY.Core.Common.dll</HintPath>
4747
</Reference>
4848
<Reference Include="Microsoft.Win32.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
4949
<HintPath>..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll</HintPath>

CLI/Properties/AssemblyInfo.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
[assembly: AssemblyTrademark("")]
1313
[assembly: AssemblyCulture("")]
1414
[assembly: AssemblyCompany("KY-Programming")]
15-
[assembly: AssemblyCopyright("Copyright © KY-Programming 2006-2022")]
15+
[assembly: AssemblyCopyright("2023 - KY-Programming")]
1616

1717
// Setting ComVisible to false makes the types in this assembly not visible
1818
// to COM components. If you need to access a type in this assembly from
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("8.7.0.0")]
36-
[assembly: AssemblyFileVersion("8.7.0.0")]
35+
[assembly: AssemblyVersion("8.8.0.0")]
36+
[assembly: AssemblyFileVersion("8.8.0.0")]

CLI/nuget.nuspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<metadata>
44
<id>KY.Generator.CLI</id>
55
<!-- Ensure nuget.targets version is also updated -->
6-
<version>8.7.0</version>
6+
<version>8.8.0-preview.1</version>
77
<title>KY.Generator.CLI</title>
88
<authors>KY-Programming</authors>
99
<owners>KY-Programming</owners>
@@ -16,7 +16,7 @@ Generate C# or TypeScript classes from .NET assemblies, JSON, TSQL or oData.
1616
Support for Angular, ASP.NET, ASP.NET Core, C# POCOs, TypeScript POCOs, Entity Framework and more.
1717
</description>
1818
<releaseNotes></releaseNotes>
19-
<copyright>Copyright 2022</copyright>
19+
<copyright>2023 - KY-Programming</copyright>
2020
<tags>KY-Generator KY.Generator CLI</tags>
2121
<readme>docs\README.md</readme>
2222
</metadata>

CLI/packages.config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<packages>
33
<package id="Costura.Fody" version="5.7.0" targetFramework="net461" developmentDependency="true" />
44
<package id="Fody" version="6.5.5" targetFramework="net461" developmentDependency="true" />
5-
<package id="KY.Core.Common" version="4.32.0" targetFramework="net461" />
5+
<package id="KY.Core.Common" version="4.34.0" targetFramework="net461" />
66
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net461" />
77
<package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net461" />
88
<package id="NETStandard.Library" version="1.6.1" targetFramework="net461" />

Common.Tests/KY.Generator.Common.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="KY.Core.Common" Version="4.32.0" />
12+
<PackageReference Include="KY.Core.Common" Version="4.34.0" />
1313
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
1414
<PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
1515
<PackageReference Include="MSTest.TestFramework" Version="2.0.0" />

Common/Client/ClientCommand.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
using System;
22
using System.Net.Http;
3-
using KY.Core;
4-
using KY.Core.DataAccess;
53
using KY.Generator.Command;
64
using KY.Generator.Output;
75

Common/Commands/ReadIdCommand.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using System.Linq;
34
using KY.Core;
45
using KY.Core.DataAccess;
@@ -33,13 +34,22 @@ public override IGeneratorCommandResult Run()
3334
project.Id = Guid.NewGuid();
3435
parser.SetProjectGuid(this.Parameters.Project, project.Id);
3536
}
37+
if (project != null && project.Name == null)
38+
{
39+
project.Name = projectFileName.Replace(Path.GetExtension(projectFileName), string.Empty);
40+
}
3641

3742
if (project == null || project.Id == Guid.Empty)
3843
{
3944
Logger.Warning($"Can not read project id. No solution for project '{this.Parameters.Project}' found. Automatic file cleanup deactivated!");
4045
return this.Success();
4146
}
42-
this.resolver.Get<IEnvironment>().OutputId = project.Id;
47+
IEnvironment environment = this.resolver.Get<IEnvironment>();
48+
environment.OutputId = project.Id;
49+
environment.Name = project.Name;
50+
environment.ProjectFile = this.Parameters.Project;
51+
AssemblyCache assemblyCache = this.resolver.Get<AssemblyCache>();
52+
assemblyCache.LoadLocal();
4353

4454
return this.Success().ForceRerunOnAsync();
4555
}

Common/Commands/StatisticsCommand.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using KY.Core.DataAccess;
21
using KY.Generator.Command;
32
using KY.Generator.Settings;
43
using KY.Generator.Statistics;

Common/Generator.cs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class Generator : IGeneratorRunSyntax
3434
private readonly List<IGeneratorCommand> commands = new();
3535
private readonly GeneratorEnvironment environment = new();
3636
private readonly StatisticsService statisticsService;
37+
private readonly LicenseService licenseService;
38+
private readonly AssemblyCache assemblyCache;
3739

3840
public Generator()
3941
{
@@ -45,10 +47,16 @@ public Generator()
4547
Logger.Trace("Current Directory: " + Environment.CurrentDirectory);
4648
Logger.Trace("Log Directory: " + Logger.File.Path);
4749

48-
NugetPackageDependencyLoader.Activate();
50+
Stopwatch runtimeStopwatch = new();
51+
runtimeStopwatch.Start();
52+
this.assemblyCache = new AssemblyCache(this.environment);
53+
runtimeStopwatch.Stop();
54+
Logger.Trace($"Installed runtimes searched in {runtimeStopwatch.ElapsedMilliseconds} ms");
55+
NugetPackageDependencyLoader.Activate(this.assemblyCache);
4956
NugetPackageDependencyLoader.ResolveDependencies(this.GetType().Assembly);
5057

5158
this.resolver = new DependencyResolver();
59+
this.resolver.Bind<AssemblyCache>().To(this.assemblyCache);
5260
this.resolver.Bind<ITypeMapping>().ToSingleton<TypeMapping>();
5361
this.resolver.Bind<CommandRunner>().ToSelf();
5462
this.resolver.Bind<ModuleFinder>().ToSingleton();
@@ -60,8 +68,10 @@ public Generator()
6068
this.resolver.Bind<StatisticsService>().ToSingleton();
6169
this.resolver.Bind<GlobalStatisticsService>().ToSingleton();
6270
this.resolver.Bind<GlobalSettingsService>().ToSingleton();
71+
this.resolver.Bind<GlobalLicenseService>().ToSingleton();
6372
this.resolver.Bind<LicenseService>().ToSingleton();
64-
this.resolver.Get<LicenseService>().Check();
73+
this.licenseService = this.resolver.Get<LicenseService>();
74+
this.licenseService.Check();
6575

6676
this.statisticsService = this.resolver.Get<StatisticsService>();
6777
this.statisticsService.ProgramStart(start);
@@ -146,10 +156,8 @@ public bool Run()
146156
IGeneratorCommandResult switchContext = null;
147157
bool switchAsync = false;
148158
this.commands.ForEach(command => command.Prepare());
149-
if (!this.resolver.Get<LicenseService>().Wait(TimeSpan.FromMilliseconds(250)))
150-
{
151-
Logger.Warning($"Can not check license. Some modules may be deactivated.");
152-
}
159+
this.statisticsService.Data.IsMsBuild = this.statisticsService.Data.IsMsBuild || this.commands.Any(x => x.Parameters.IsMsBuild);
160+
this.statisticsService.Data.IsBeforeBuild = this.statisticsService.Data.IsBeforeBuild || this.commands.Any(x => x.Parameters.IsBeforeBuild);
153161
foreach (IGeneratorCommand command in this.commands)
154162
{
155163
IGeneratorCommandResult result = runner.Run(command);
@@ -164,20 +172,37 @@ public bool Run()
164172
asyncCommands.Add(command);
165173
}
166174
}
167-
this.statisticsService.RunEnd(this.environment.OutputId);
175+
this.statisticsService.RunEnd(this.environment.OutputId, this.environment.Name);
168176
List<FileTemplate> files = this.resolver.Get<List<FileTemplate>>();
169177
if (files.Count > 0)
170178
{
171-
Logger.Trace("Generate code...");
172-
files.Write(this.output);
173-
this.statisticsService.GenerateEnd(this.output.Lines);
174-
files.ForEach(file => this.statisticsService.Count(file));
179+
this.licenseService.WaitOrKill();
180+
if (this.licenseService.IsValid)
181+
{
182+
Logger.Trace("Generate code...");
183+
files.Write(this.output);
184+
this.statisticsService.GenerateEnd(this.output.Lines);
185+
files.ForEach(file => this.statisticsService.Count(file));
186+
}
187+
else if (this.licenseService.ValidUntil > DateTime.MinValue)
188+
{
189+
Logger.Error("License has expired. Ensure that https://generator.ky-programming.de is reachable or generate a new offline license at https://generator.ky-programming.de/license");
190+
Logger.Error("Generate code canceled!");
191+
success = false;
192+
}
193+
else
194+
{
195+
Logger.Error("No valid license found. Ensure that https://generator.ky-programming.de is reachable or generate an offline license at https://generator.ky-programming.de/license");
196+
Logger.Error("Generate code canceled!");
197+
success = false;
198+
}
175199
}
176200
if (success)
177201
{
178202
this.output.Execute();
179203
this.commands.ForEach(command => command.FollowUp());
180204
}
205+
this.assemblyCache.Save();
181206
if (switchAsync)
182207
{
183208
return this.SwitchToAsync(asyncCommands);
@@ -187,6 +212,7 @@ public bool Run()
187212
return this.SwitchContext(switchContext, asyncCommands);
188213
}
189214
this.statisticsService.ProgramEnd(files.Count);
215+
this.licenseService.ShowMessages();
190216
if (!this.commands.OfType<StatisticsCommand>().Any() && this.resolver.Get<GlobalSettingsService>().Read().StatisticsEnabled)
191217
{
192218
string fileName = this.statisticsService.Write();
@@ -293,10 +319,22 @@ public static void InitializeLogger(string[] parameters)
293319
private void InitializeModules(IEnumerable<ModuleBase> modules)
294320
{
295321
List<ModuleBase> list = modules.ToList();
322+
Dictionary<ModuleBase, Stopwatch> stopwatches = list.ToDictionary(x => x, _ => new Stopwatch());
296323
this.statisticsService.Data.InitializedModules = list.Count;
297-
list.ForEach(module => this.resolver.Bind<ModuleBase>().To(module));
298-
list.ForEach(module => module.Initialize());
299-
list.ForEach(module => Logger.Trace($"{module.GetType().Name.Replace("Module", "")}-{module.GetType().Assembly.GetName().Version} module loaded"));
324+
foreach (ModuleBase module in list)
325+
{
326+
stopwatches[module].Start();
327+
this.resolver.Bind<ModuleBase>().To(module);
328+
stopwatches[module].Stop();
329+
}
330+
foreach (ModuleBase module in list)
331+
{
332+
Stopwatch stopwatch = stopwatches[module];
333+
stopwatch.Start();
334+
module.Initialize();
335+
stopwatch.Stop();
336+
Logger.Trace($"{module.GetType().Name.Replace("Module", "")}-{module.GetType().Assembly.GetName().Version} module loaded in {(stopwatch.ElapsedMilliseconds >= 1 ? stopwatch.ElapsedMilliseconds.ToString() : "<1")} ms");
337+
}
300338
}
301339
}
302340
}

Common/Helpers/AssemblyCache.cs

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Runtime.InteropServices;
4+
using KY.Core;
5+
using KY.Core.Crypt;
6+
using KY.Core.DataAccess;
7+
using KY.Generator.Models;
8+
using Newtonsoft.Json;
9+
10+
namespace KY.Generator;
11+
12+
public class AssemblyCache : IAssemblyCache
13+
{
14+
private readonly string globalCacheFileName = "global-assembly-cache.json";
15+
private string localCacheFileName;
16+
private readonly IEnvironment environment;
17+
private Dictionary<string, string> global = new();
18+
private Dictionary<string, string> local = new();
19+
private readonly List<string> globalPaths;
20+
21+
public AssemblyCache(IEnvironment environment)
22+
{
23+
this.environment = environment;
24+
this.LoadGlobal();
25+
this.globalPaths = InstalledRuntime.GetCurrent().Select(x => x.Path).ToList();
26+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
27+
{
28+
this.globalPaths.Add(NugetPackageDependencyLoader.WindowsNugetFallbackPath);
29+
this.globalPaths.Add(NugetPackageDependencyLoader.WindowsNugetCachePath);
30+
}
31+
else
32+
{
33+
this.globalPaths.Add(NugetPackageDependencyLoader.LinuxNugetCachePath);
34+
}
35+
}
36+
37+
public void Add(string name, string location)
38+
{
39+
if (name.StartsWith("KY.Generator"))
40+
{
41+
return;
42+
}
43+
if (this.globalPaths.Any(location.StartsWith))
44+
{
45+
this.global[name] = location;
46+
}
47+
else
48+
{
49+
this.local[name] = location;
50+
}
51+
}
52+
53+
public void LoadGlobal()
54+
{
55+
string fileName = FileSystem.Combine(this.environment.ApplicationData, this.globalCacheFileName);
56+
if (FileSystem.FileExists(fileName))
57+
{
58+
string json = FileSystem.ReadAllText(fileName);
59+
this.global = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
60+
}
61+
}
62+
63+
public void LoadLocal()
64+
{
65+
if (this.environment.ProjectFile == null)
66+
{
67+
return;
68+
}
69+
string hash = Sha1.Create(this.environment.ProjectFile).ToString().Substring(0, 8);
70+
this.localCacheFileName = $"{this.environment.Name}-{hash}-assembly-cache.json";
71+
string fileName = FileSystem.Combine(this.environment.ApplicationData, this.localCacheFileName);
72+
if (FileSystem.FileExists(fileName))
73+
{
74+
string json = FileSystem.ReadAllText(fileName);
75+
this.local = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
76+
}
77+
}
78+
79+
public string Resolve(string name)
80+
{
81+
if (this.global.TryGetValue(name, out string globalLocation))
82+
{
83+
Logger.Trace($"Assembly found in global assembly cache: {globalLocation}");
84+
return globalLocation;
85+
}
86+
if (this.local.TryGetValue(name, out string localLocation))
87+
{
88+
Logger.Trace($"Assembly found in local assembly cache: {localLocation}");
89+
return localLocation;
90+
}
91+
return null;
92+
}
93+
94+
public void Save()
95+
{
96+
if (this.global.Count > 0)
97+
{
98+
string fileName = FileSystem.Combine(this.environment.ApplicationData, this.globalCacheFileName);
99+
FileSystem.WriteAllText(fileName, JsonConvert.SerializeObject(this.global));
100+
}
101+
if (this.local.Count > 0 && this.localCacheFileName != null)
102+
{
103+
string fileName = FileSystem.Combine(this.environment.ApplicationData, this.localCacheFileName);
104+
FileSystem.WriteAllText(fileName, JsonConvert.SerializeObject(this.local));
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)