Skip to content

Commit 3dae1cf

Browse files
authored
Refactor LibKubernetesGenerator code structure (#1546)
* Refactor LibKubernetesGenerator code structure * clean up comment out code * No more locks * clean up dep * Update dependency paths in LibKubernetesGenerator.target
1 parent de7ecf1 commit 3dae1cf

24 files changed

+485
-692
lines changed

src/LibKubernetesGenerator/ApiGenerator.cs

+21-6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ namespace LibKubernetesGenerator
88
{
99
internal class ApiGenerator
1010
{
11+
private readonly ScriptObjectFactory scriptObjectFactory;
12+
13+
public ApiGenerator(ScriptObjectFactory scriptObjectFactory)
14+
{
15+
this.scriptObjectFactory = scriptObjectFactory;
16+
}
17+
1118
public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
1219
{
1320
var data = swagger.Operations
@@ -42,6 +49,8 @@ public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializa
4249
})
4350
.ToArray();
4451

52+
var sc = scriptObjectFactory.CreateScriptObject();
53+
4554
var groups = new List<string>();
4655

4756
foreach (var grouped in data.GroupBy(d => d.Operation.Tags.First()))
@@ -50,14 +59,20 @@ public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializa
5059
groups.Add(name);
5160

5261
var apis = grouped.ToArray();
53-
var gctx = new { name, apis };
54-
context.RenderToContext($"IOperations.cs.template", gctx, $"I{name}Operations.g.cs");
55-
context.RenderToContext("Operations.cs.template", gctx, $"{name}Operations.g.cs");
56-
context.RenderToContext("OperationsExtensions.cs.template", gctx, $"{name}OperationsExtensions.g.cs");
62+
63+
sc.SetValue("name", name, true);
64+
sc.SetValue("apis", apis, true);
65+
66+
context.RenderToContext($"IOperations.cs.template", sc, $"I{name}Operations.g.cs");
67+
context.RenderToContext("Operations.cs.template", sc, $"{name}Operations.g.cs");
68+
context.RenderToContext("OperationsExtensions.cs.template", sc, $"{name}OperationsExtensions.g.cs");
5769
}
5870

59-
context.RenderToContext($"IBasicKubernetes.cs.template", groups, $"IBasicKubernetes.g.cs");
60-
context.RenderToContext($"AbstractKubernetes.cs.template", groups, $"AbstractKubernetes.g.cs");
71+
sc = scriptObjectFactory.CreateScriptObject();
72+
sc.SetValue("groups", groups, true);
73+
74+
context.RenderToContext($"IBasicKubernetes.cs.template", sc, $"IBasicKubernetes.g.cs");
75+
context.RenderToContext($"AbstractKubernetes.cs.template", sc, $"AbstractKubernetes.g.cs");
6176
}
6277
}
6378
}

src/LibKubernetesGenerator/ClassNameHelper.cs

+7-30
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
using CaseExtensions;
22
using NJsonSchema;
33
using NSwag;
4-
using Nustache.Core;
4+
using Scriban.Runtime;
5+
using System;
56
using System.Collections.Generic;
67
using System.Linq;
78

89
namespace LibKubernetesGenerator
910
{
10-
internal class ClassNameHelper : INustacheHelper
11+
internal class ClassNameHelper : IScriptObjectHelper
1112
{
1213
private readonly Dictionary<string, string> classNameMap;
1314
private readonly Dictionary<JsonSchema, string> schemaToNameMapCooked;
@@ -18,9 +19,10 @@ public ClassNameHelper(OpenApiDocument swagger)
1819
schemaToNameMapCooked = GenerateSchemaToNameMapCooked(swagger);
1920
}
2021

21-
public void RegisterHelper()
22+
23+
public void RegisterHelper(ScriptObject scriptObject)
2224
{
23-
Helpers.Register(nameof(GetClassName), GetClassName);
25+
scriptObject.Import(nameof(GetClassName), new Func<JsonSchema, string>(GetClassNameForSchemaDefinition));
2426
}
2527

2628
private static Dictionary<JsonSchema, string> GenerateSchemaToNameMapCooked(OpenApiDocument swagger)
@@ -50,27 +52,7 @@ private Dictionary<string, string> InitClassNameMap(OpenApiDocument doc)
5052
return map;
5153
}
5254

53-
public void GetClassName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
54-
RenderBlock fn, RenderBlock inverse)
55-
{
56-
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiOperation)
57-
{
58-
context.Write(GetClassName(arguments[0] as OpenApiOperation));
59-
}
60-
else if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is JsonSchema)
61-
{
62-
context.Write(GetClassNameForSchemaDefinition(arguments[0] as JsonSchema));
63-
}
64-
}
65-
66-
public string GetClassName(OpenApiOperation operation)
67-
{
68-
var groupVersionKind =
69-
(Dictionary<string, object>)operation.ExtensionData["x-kubernetes-group-version-kind"];
70-
return GetClassName(groupVersionKind);
71-
}
72-
73-
public string GetClassName(Dictionary<string, object> groupVersionKind)
55+
private string GetClassName(Dictionary<string, object> groupVersionKind)
7456
{
7557
var group = (string)groupVersionKind["group"];
7658
var kind = (string)groupVersionKind["kind"];
@@ -98,10 +80,5 @@ public string GetClassNameForSchemaDefinition(JsonSchema definition)
9880

9981
return schemaToNameMapCooked[definition];
10082
}
101-
102-
private static Dictionary<JsonSchema, string> InitSchemaToNameCooked(OpenApiDocument swagger)
103-
{
104-
return swagger.Definitions.ToDictionary(x => x.Value, x => x.Key.Replace(".", "").ToPascalCase());
105-
}
10683
}
10784
}

src/LibKubernetesGenerator/GeneralNameHelper.cs

+13-48
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
using CaseExtensions;
22
using NJsonSchema;
33
using NSwag;
4-
using Nustache.Core;
4+
using Scriban.Runtime;
5+
using System;
56
using System.Collections.Generic;
67
using System.Linq;
78
using System.Text.RegularExpressions;
89

910
namespace LibKubernetesGenerator
1011
{
11-
internal class GeneralNameHelper : INustacheHelper
12+
internal class GeneralNameHelper : IScriptObjectHelper
1213
{
1314
private readonly ClassNameHelper classNameHelper;
1415

@@ -17,20 +18,12 @@ public GeneralNameHelper(ClassNameHelper classNameHelper)
1718
this.classNameHelper = classNameHelper;
1819
}
1920

20-
public void RegisterHelper()
21+
public void RegisterHelper(ScriptObject scriptObject)
2122
{
22-
Helpers.Register(nameof(GetInterfaceName), GetInterfaceName);
23-
Helpers.Register(nameof(GetMethodName), GetMethodName);
24-
Helpers.Register(nameof(GetDotNetName), GetDotNetName);
25-
}
26-
27-
public void GetInterfaceName(RenderContext context, IList<object> arguments,
28-
IDictionary<string, object> options, RenderBlock fn, RenderBlock inverse)
29-
{
30-
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is JsonSchema)
31-
{
32-
context.Write(GetInterfaceName(arguments[0] as JsonSchema));
33-
}
23+
scriptObject.Import(nameof(GetInterfaceName), new Func<JsonSchema, string>(GetInterfaceName));
24+
scriptObject.Import(nameof(GetMethodName), new Func<OpenApiOperation, string, string>(GetMethodName));
25+
scriptObject.Import(nameof(GetDotNetName), new Func<string, string, string>(GetDotNetName));
26+
scriptObject.Import(nameof(GetDotNetNameOpenApiParameter), new Func<OpenApiParameter, string, string>(GetDotNetNameOpenApiParameter));
3427
}
3528

3629
private string GetInterfaceName(JsonSchema definition)
@@ -68,44 +61,16 @@ private string GetInterfaceName(JsonSchema definition)
6861
return string.Join(", ", interfaces);
6962
}
7063

71-
public void GetMethodName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
72-
RenderBlock fn, RenderBlock inverse)
64+
public string GetDotNetNameOpenApiParameter(OpenApiParameter parameter, string init)
7365
{
74-
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiOperation)
75-
{
76-
string suffix = null;
77-
if (arguments.Count > 1)
78-
{
79-
suffix = arguments[1] as string;
80-
}
66+
var name = GetDotNetName(parameter.Name);
8167

82-
context.Write(GetMethodName(arguments[0] as OpenApiOperation, suffix));
83-
}
84-
}
85-
86-
public void GetDotNetName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
87-
RenderBlock fn, RenderBlock inverse)
88-
{
89-
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiParameter)
68+
if (init == "true" && !parameter.IsRequired)
9069
{
91-
var parameter = arguments[0] as OpenApiParameter;
92-
context.Write(GetDotNetName(parameter.Name));
93-
94-
if (arguments.Count > 1 && (arguments[1] as string) == "true" && !parameter.IsRequired)
95-
{
96-
context.Write(" = null");
97-
}
70+
name += " = null";
9871
}
99-
else if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is string)
100-
{
101-
var style = "parameter";
102-
if (arguments.Count > 1)
103-
{
104-
style = arguments[1] as string;
105-
}
10672

107-
context.Write(GetDotNetName((string)arguments[0], style));
108-
}
73+
return name;
10974
}
11075

11176
public string GetDotNetName(string jsonName, string style = "parameter")

src/LibKubernetesGenerator/GeneratorExecutionContextExt.cs

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.Text;
3-
using Nustache.Core;
3+
using Scriban;
4+
using Scriban.Runtime;
45
using System.Text;
56

67
namespace LibKubernetesGenerator
78
{
89
internal static class GeneratorExecutionContextExt
910
{
10-
public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, object data, string generatedfile)
11+
public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, ScriptObject sc, string generatedfile)
1112
{
12-
var template = EmbedResource.GetResource(templatefile);
13-
var generated = Render.StringToString(template, data);
13+
var tc = new TemplateContext();
14+
tc.PushGlobal(sc);
15+
context.RenderToContext(templatefile, tc, generatedfile);
16+
}
17+
18+
public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, TemplateContext tc, string generatedfile)
19+
{
20+
var template = Template.Parse(EmbedResource.GetResource(templatefile));
21+
var generated = template.Render(tc);
1422
context.AddSource(generatedfile, SourceText.From(generated, Encoding.UTF8));
1523
}
1624
}

src/LibKubernetesGenerator/INustacheHelper.cs

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using Scriban.Runtime;
2+
3+
namespace LibKubernetesGenerator;
4+
5+
internal interface IScriptObjectHelper
6+
{
7+
void RegisterHelper(ScriptObject scriptObject);
8+
}

src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs

+12-33
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,22 @@
11
using Autofac;
22
using Microsoft.CodeAnalysis;
33
using NSwag;
4-
using Nustache.Core;
54
#if GENERATE_AUTOMAPPER
5+
using System.Collections.Generic;
66
using System;
77
using System.IO;
88
using System.Linq;
99
#endif
10-
using System.Collections.Generic;
11-
using System.Reflection;
1210

1311
namespace LibKubernetesGenerator
1412
{
1513
[Generator]
1614
public class KubernetesClientSourceGenerator : IIncrementalGenerator
1715
{
18-
private static readonly object Execlock = new object();
19-
2016
private static (OpenApiDocument, IContainer) BuildContainer()
2117
{
2218
var swagger = OpenApiDocument.FromJsonAsync(EmbedResource.GetResource("swagger.json")).GetAwaiter().GetResult();
2319
var container = BuildContainer(swagger);
24-
// TODO move to Handlebars.Net
25-
// here is to clean up the custom helpers in static Nustache.Core.Helpers
26-
{
27-
var ch = typeof(Helpers).GetField("CustomHelpers", BindingFlags.Static | BindingFlags.NonPublic);
28-
((Dictionary<string, Helper>)ch.GetValue(null)).Clear();
29-
}
30-
31-
foreach (var helper in container.Resolve<IEnumerable<INustacheHelper>>())
32-
{
33-
helper.RegisterHelper();
34-
}
35-
3620
return (swagger, container);
3721
}
3822

@@ -77,6 +61,9 @@ private static IContainer BuildContainer(OpenApiDocument swagger)
7761
.AsImplementedInterfaces()
7862
;
7963

64+
builder.RegisterType<ScriptObjectFactory>()
65+
;
66+
8067
builder.RegisterType<ModelExtGenerator>();
8168
builder.RegisterType<ModelGenerator>();
8269
builder.RegisterType<ApiGenerator>();
@@ -92,31 +79,23 @@ public void Initialize(IncrementalGeneratorInitializationContext generatorContex
9279
#if GENERATE_BASIC
9380
generatorContext.RegisterPostInitializationOutput(ctx =>
9481
{
95-
lock (Execlock)
96-
{
97-
var (swagger, container) = BuildContainer();
98-
99-
container.Resolve<VersionGenerator>().Generate(swagger, ctx);
82+
var (swagger, container) = BuildContainer();
10083

101-
container.Resolve<ModelGenerator>().Generate(swagger, ctx);
102-
container.Resolve<ModelExtGenerator>().Generate(swagger, ctx);
103-
container.Resolve<VersionConverterStubGenerator>().Generate(swagger, ctx);
84+
container.Resolve<VersionGenerator>().Generate(swagger, ctx);
10485

105-
container.Resolve<ApiGenerator>().Generate(swagger, ctx);
106-
}
86+
container.Resolve<ModelGenerator>().Generate(swagger, ctx);
87+
container.Resolve<ModelExtGenerator>().Generate(swagger, ctx);
88+
container.Resolve<VersionConverterStubGenerator>().Generate(swagger, ctx);
89+
container.Resolve<ApiGenerator>().Generate(swagger, ctx);
10790
});
10891
#endif
10992

11093
#if GENERATE_AUTOMAPPER
11194
var automappersrc = generatorContext.CompilationProvider.Select((c, _) => c.SyntaxTrees.First(s => PathSuffixMath(s.FilePath, "AutoMapper/VersionConverter.cs")));
11295
generatorContext.RegisterSourceOutput(automappersrc, (ctx, srctree) =>
11396
{
114-
lock (Execlock)
115-
{
116-
var (swagger, container) = BuildContainer();
117-
118-
container.Resolve<VersionConverterAutoMapperGenerator>().Generate(swagger, ctx, srctree);
119-
}
97+
var (swagger, container) = BuildContainer();
98+
container.Resolve<VersionConverterAutoMapperGenerator>().Generate(swagger, ctx, srctree);
12099
});
121100
#endif
122101
}

0 commit comments

Comments
 (0)