Skip to content

Commit

Permalink
Refactor LibKubernetesGenerator code structure (#1546)
Browse files Browse the repository at this point in the history
* Refactor LibKubernetesGenerator code structure

* clean up comment out code

* No more locks

* clean up dep

* Update dependency paths in LibKubernetesGenerator.target
  • Loading branch information
tg123 committed Apr 15, 2024
1 parent de7ecf1 commit 3dae1cf
Show file tree
Hide file tree
Showing 24 changed files with 485 additions and 692 deletions.
27 changes: 21 additions & 6 deletions src/LibKubernetesGenerator/ApiGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ namespace LibKubernetesGenerator
{
internal class ApiGenerator
{
private readonly ScriptObjectFactory scriptObjectFactory;

public ApiGenerator(ScriptObjectFactory scriptObjectFactory)
{
this.scriptObjectFactory = scriptObjectFactory;
}

public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
{
var data = swagger.Operations
Expand Down Expand Up @@ -42,6 +49,8 @@ public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializa
})
.ToArray();

var sc = scriptObjectFactory.CreateScriptObject();

var groups = new List<string>();

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

var apis = grouped.ToArray();
var gctx = new { name, apis };
context.RenderToContext($"IOperations.cs.template", gctx, $"I{name}Operations.g.cs");
context.RenderToContext("Operations.cs.template", gctx, $"{name}Operations.g.cs");
context.RenderToContext("OperationsExtensions.cs.template", gctx, $"{name}OperationsExtensions.g.cs");

sc.SetValue("name", name, true);
sc.SetValue("apis", apis, true);

context.RenderToContext($"IOperations.cs.template", sc, $"I{name}Operations.g.cs");
context.RenderToContext("Operations.cs.template", sc, $"{name}Operations.g.cs");
context.RenderToContext("OperationsExtensions.cs.template", sc, $"{name}OperationsExtensions.g.cs");
}

context.RenderToContext($"IBasicKubernetes.cs.template", groups, $"IBasicKubernetes.g.cs");
context.RenderToContext($"AbstractKubernetes.cs.template", groups, $"AbstractKubernetes.g.cs");
sc = scriptObjectFactory.CreateScriptObject();
sc.SetValue("groups", groups, true);

context.RenderToContext($"IBasicKubernetes.cs.template", sc, $"IBasicKubernetes.g.cs");
context.RenderToContext($"AbstractKubernetes.cs.template", sc, $"AbstractKubernetes.g.cs");
}
}
}
37 changes: 7 additions & 30 deletions src/LibKubernetesGenerator/ClassNameHelper.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
using CaseExtensions;
using NJsonSchema;
using NSwag;
using Nustache.Core;
using Scriban.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;

namespace LibKubernetesGenerator
{
internal class ClassNameHelper : INustacheHelper
internal class ClassNameHelper : IScriptObjectHelper
{
private readonly Dictionary<string, string> classNameMap;
private readonly Dictionary<JsonSchema, string> schemaToNameMapCooked;
Expand All @@ -18,9 +19,10 @@ public ClassNameHelper(OpenApiDocument swagger)
schemaToNameMapCooked = GenerateSchemaToNameMapCooked(swagger);
}

public void RegisterHelper()

public void RegisterHelper(ScriptObject scriptObject)
{
Helpers.Register(nameof(GetClassName), GetClassName);
scriptObject.Import(nameof(GetClassName), new Func<JsonSchema, string>(GetClassNameForSchemaDefinition));
}

private static Dictionary<JsonSchema, string> GenerateSchemaToNameMapCooked(OpenApiDocument swagger)
Expand Down Expand Up @@ -50,27 +52,7 @@ public void RegisterHelper()
return map;
}

public void GetClassName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
RenderBlock fn, RenderBlock inverse)
{
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiOperation)
{
context.Write(GetClassName(arguments[0] as OpenApiOperation));
}
else if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is JsonSchema)
{
context.Write(GetClassNameForSchemaDefinition(arguments[0] as JsonSchema));
}
}

public string GetClassName(OpenApiOperation operation)
{
var groupVersionKind =
(Dictionary<string, object>)operation.ExtensionData["x-kubernetes-group-version-kind"];
return GetClassName(groupVersionKind);
}

public string GetClassName(Dictionary<string, object> groupVersionKind)
private string GetClassName(Dictionary<string, object> groupVersionKind)
{
var group = (string)groupVersionKind["group"];
var kind = (string)groupVersionKind["kind"];
Expand Down Expand Up @@ -98,10 +80,5 @@ public string GetClassNameForSchemaDefinition(JsonSchema definition)

return schemaToNameMapCooked[definition];
}

private static Dictionary<JsonSchema, string> InitSchemaToNameCooked(OpenApiDocument swagger)
{
return swagger.Definitions.ToDictionary(x => x.Value, x => x.Key.Replace(".", "").ToPascalCase());
}
}
}
61 changes: 13 additions & 48 deletions src/LibKubernetesGenerator/GeneralNameHelper.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using CaseExtensions;
using NJsonSchema;
using NSwag;
using Nustache.Core;
using Scriban.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace LibKubernetesGenerator
{
internal class GeneralNameHelper : INustacheHelper
internal class GeneralNameHelper : IScriptObjectHelper
{
private readonly ClassNameHelper classNameHelper;

Expand All @@ -17,20 +18,12 @@ public GeneralNameHelper(ClassNameHelper classNameHelper)
this.classNameHelper = classNameHelper;
}

public void RegisterHelper()
public void RegisterHelper(ScriptObject scriptObject)
{
Helpers.Register(nameof(GetInterfaceName), GetInterfaceName);
Helpers.Register(nameof(GetMethodName), GetMethodName);
Helpers.Register(nameof(GetDotNetName), GetDotNetName);
}

public void GetInterfaceName(RenderContext context, IList<object> arguments,
IDictionary<string, object> options, RenderBlock fn, RenderBlock inverse)
{
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is JsonSchema)
{
context.Write(GetInterfaceName(arguments[0] as JsonSchema));
}
scriptObject.Import(nameof(GetInterfaceName), new Func<JsonSchema, string>(GetInterfaceName));
scriptObject.Import(nameof(GetMethodName), new Func<OpenApiOperation, string, string>(GetMethodName));
scriptObject.Import(nameof(GetDotNetName), new Func<string, string, string>(GetDotNetName));
scriptObject.Import(nameof(GetDotNetNameOpenApiParameter), new Func<OpenApiParameter, string, string>(GetDotNetNameOpenApiParameter));
}

private string GetInterfaceName(JsonSchema definition)
Expand Down Expand Up @@ -68,44 +61,16 @@ private string GetInterfaceName(JsonSchema definition)
return string.Join(", ", interfaces);
}

public void GetMethodName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
RenderBlock fn, RenderBlock inverse)
public string GetDotNetNameOpenApiParameter(OpenApiParameter parameter, string init)
{
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiOperation)
{
string suffix = null;
if (arguments.Count > 1)
{
suffix = arguments[1] as string;
}
var name = GetDotNetName(parameter.Name);

context.Write(GetMethodName(arguments[0] as OpenApiOperation, suffix));
}
}

public void GetDotNetName(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
RenderBlock fn, RenderBlock inverse)
{
if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is OpenApiParameter)
if (init == "true" && !parameter.IsRequired)
{
var parameter = arguments[0] as OpenApiParameter;
context.Write(GetDotNetName(parameter.Name));

if (arguments.Count > 1 && (arguments[1] as string) == "true" && !parameter.IsRequired)
{
context.Write(" = null");
}
name += " = null";
}
else if (arguments != null && arguments.Count > 0 && arguments[0] != null && arguments[0] is string)
{
var style = "parameter";
if (arguments.Count > 1)
{
style = arguments[1] as string;
}

context.Write(GetDotNetName((string)arguments[0], style));
}
return name;
}

public string GetDotNetName(string jsonName, string style = "parameter")
Expand Down
16 changes: 12 additions & 4 deletions src/LibKubernetesGenerator/GeneratorExecutionContextExt.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
using Nustache.Core;
using Scriban;
using Scriban.Runtime;
using System.Text;

namespace LibKubernetesGenerator
{
internal static class GeneratorExecutionContextExt
{
public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, object data, string generatedfile)
public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, ScriptObject sc, string generatedfile)
{
var template = EmbedResource.GetResource(templatefile);
var generated = Render.StringToString(template, data);
var tc = new TemplateContext();
tc.PushGlobal(sc);
context.RenderToContext(templatefile, tc, generatedfile);
}

public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, TemplateContext tc, string generatedfile)
{
var template = Template.Parse(EmbedResource.GetResource(templatefile));
var generated = template.Render(tc);
context.AddSource(generatedfile, SourceText.From(generated, Encoding.UTF8));
}
}
Expand Down
7 changes: 0 additions & 7 deletions src/LibKubernetesGenerator/INustacheHelper.cs

This file was deleted.

8 changes: 8 additions & 0 deletions src/LibKubernetesGenerator/IScriptObjectHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Scriban.Runtime;

namespace LibKubernetesGenerator;

internal interface IScriptObjectHelper
{
void RegisterHelper(ScriptObject scriptObject);
}
45 changes: 12 additions & 33 deletions src/LibKubernetesGenerator/KubernetesClientSourceGenerator.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,22 @@
using Autofac;
using Microsoft.CodeAnalysis;
using NSwag;
using Nustache.Core;
#if GENERATE_AUTOMAPPER
using System.Collections.Generic;
using System;
using System.IO;
using System.Linq;
#endif
using System.Collections.Generic;
using System.Reflection;

namespace LibKubernetesGenerator
{
[Generator]
public class KubernetesClientSourceGenerator : IIncrementalGenerator
{
private static readonly object Execlock = new object();

private static (OpenApiDocument, IContainer) BuildContainer()
{
var swagger = OpenApiDocument.FromJsonAsync(EmbedResource.GetResource("swagger.json")).GetAwaiter().GetResult();
var container = BuildContainer(swagger);
// TODO move to Handlebars.Net
// here is to clean up the custom helpers in static Nustache.Core.Helpers
{
var ch = typeof(Helpers).GetField("CustomHelpers", BindingFlags.Static | BindingFlags.NonPublic);
((Dictionary<string, Helper>)ch.GetValue(null)).Clear();
}

foreach (var helper in container.Resolve<IEnumerable<INustacheHelper>>())
{
helper.RegisterHelper();
}

return (swagger, container);
}

Expand Down Expand Up @@ -77,6 +61,9 @@ private static IContainer BuildContainer(OpenApiDocument swagger)
.AsImplementedInterfaces()
;

builder.RegisterType<ScriptObjectFactory>()
;

builder.RegisterType<ModelExtGenerator>();
builder.RegisterType<ModelGenerator>();
builder.RegisterType<ApiGenerator>();
Expand All @@ -92,31 +79,23 @@ public void Initialize(IncrementalGeneratorInitializationContext generatorContex
#if GENERATE_BASIC
generatorContext.RegisterPostInitializationOutput(ctx =>
{
lock (Execlock)
{
var (swagger, container) = BuildContainer();
container.Resolve<VersionGenerator>().Generate(swagger, ctx);
var (swagger, container) = BuildContainer();
container.Resolve<ModelGenerator>().Generate(swagger, ctx);
container.Resolve<ModelExtGenerator>().Generate(swagger, ctx);
container.Resolve<VersionConverterStubGenerator>().Generate(swagger, ctx);
container.Resolve<VersionGenerator>().Generate(swagger, ctx);
container.Resolve<ApiGenerator>().Generate(swagger, ctx);
}
container.Resolve<ModelGenerator>().Generate(swagger, ctx);
container.Resolve<ModelExtGenerator>().Generate(swagger, ctx);
container.Resolve<VersionConverterStubGenerator>().Generate(swagger, ctx);
container.Resolve<ApiGenerator>().Generate(swagger, ctx);
});
#endif

#if GENERATE_AUTOMAPPER
var automappersrc = generatorContext.CompilationProvider.Select((c, _) => c.SyntaxTrees.First(s => PathSuffixMath(s.FilePath, "AutoMapper/VersionConverter.cs")));
generatorContext.RegisterSourceOutput(automappersrc, (ctx, srctree) =>
{
lock (Execlock)
{
var (swagger, container) = BuildContainer();
container.Resolve<VersionConverterAutoMapperGenerator>().Generate(swagger, ctx, srctree);
}
var (swagger, container) = BuildContainer();
container.Resolve<VersionConverterAutoMapperGenerator>().Generate(swagger, ctx, srctree);
});
#endif
}
Expand Down
Loading

0 comments on commit 3dae1cf

Please sign in to comment.