Skip to content

Commit 73170da

Browse files
committed
Add schema to configs that enables autocompletion
1 parent f8c910d commit 73170da

File tree

4 files changed

+315
-0
lines changed

4 files changed

+315
-0
lines changed

src/Nethermind/Nethermind.Runner/configs/op-mainnet.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"$schema": "https://gist.githubusercontent.com/flcl42/25b0396678b02cfc0c5dc1d68ea085a7/raw/2fda5155f38e9816bead94682eac92d3b7e74b8c/nethermind-config-schema.json",
23
"Init": {
34
"ChainSpecPath": "chainspec/op-mainnet.json",
45
"GenesisHash": "0x7ca38a1916c42007829c55e69d3e9a73265554b586a499015373241b8a3fa48b",

tools/SchemaGenerator/Program.cs

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
2+
using NJsonSchema;
3+
using System.Reflection;
4+
using System.Reflection.Emit;
5+
using Nethermind.Config;
6+
using Nethermind.Core.Collections;
7+
8+
Type iConfigType = typeof(IConfig);
9+
10+
Type[] types = [
11+
..Directory.GetFiles(".", "Nethermind.*.dll").SelectMany(f => GetConfigTypes(Assembly.LoadFrom(f))),
12+
];
13+
14+
var assemblyName = new AssemblyName("Nethermind.Config");
15+
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
16+
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
17+
18+
TypeBuilder typeBuilder = moduleBuilder.DefineType("NethermindConfig", TypeAttributes.Public);
19+
20+
foreach (Type configInterface in types)
21+
{
22+
CreateProperty(typeBuilder, configInterface);
23+
}
24+
25+
Type configType = typeBuilder.CreateType();
26+
27+
JsonSchema schema = JsonSchema.FromType(configType);
28+
29+
foreach (var def in schema.Definitions)
30+
{
31+
if(def.Value.Enumeration is { Count: > 0 })
32+
{
33+
def.Value.Type = JsonObjectType.String;
34+
def.Value.Enumeration.Clear();
35+
def.Value.Enumeration.AddRange(def.Value.EnumerationNames);
36+
}
37+
}
38+
39+
Console.WriteLine(schema.ToJson());
40+
41+
void CreateProperty(TypeBuilder typeBuilder, Type classType)
42+
{
43+
Type interfaceType = classType.GetInterfaces().First(i => iConfigType.IsAssignableFrom(i) && i != iConfigType);
44+
string propertyName = interfaceType.Name.Substring(1, interfaceType.Name.Length - 7);
45+
FieldBuilder fieldBuilder = typeBuilder.DefineField($"_{propertyName}", interfaceType, FieldAttributes.Private);
46+
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, interfaceType, null);
47+
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod($"get_{propertyName}",
48+
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
49+
interfaceType,
50+
Type.EmptyTypes);
51+
52+
ILGenerator getIL = getMethodBuilder.GetILGenerator();
53+
getIL.Emit(OpCodes.Ldarg_0);
54+
getIL.Emit(OpCodes.Ldfld, fieldBuilder);
55+
getIL.Emit(OpCodes.Ret);
56+
57+
// Define the 'set' accessor method
58+
MethodBuilder setMethodBuilder = typeBuilder.DefineMethod($"set_{propertyName}",
59+
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
60+
null,
61+
[interfaceType]);
62+
63+
ILGenerator setIL = setMethodBuilder.GetILGenerator();
64+
setIL.Emit(OpCodes.Ldarg_0);
65+
setIL.Emit(OpCodes.Ldarg_1);
66+
setIL.Emit(OpCodes.Stfld, fieldBuilder);
67+
setIL.Emit(OpCodes.Ret);
68+
69+
// Map the get and set methods to the property
70+
propertyBuilder.SetGetMethod(getMethodBuilder);
71+
propertyBuilder.SetSetMethod(setMethodBuilder);
72+
}
73+
74+
IEnumerable<Type> GetConfigTypes(Assembly assembly)
75+
{
76+
return assembly.GetTypes().Where(t => iConfigType.IsAssignableFrom(t) && t.IsClass && !t.IsAbstract);
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="NJsonSchema" Version="11.0.2" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Api\Nethermind.Api.csproj" />
16+
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Init.Snapshot\Nethermind.Init.Snapshot.csproj" />
17+
<ProjectReference Include="..\..\src\Nethermind\Nethermind.Optimism\Nethermind.Optimism.csproj" />
18+
</ItemGroup>
19+
20+
</Project>

0 commit comments

Comments
 (0)