Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move JSON Schema Generation to separate .csproj; Add shell script #463

Merged
merged 3 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions BO4E-dotnet.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBO4E.Reporting", "TestB
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestBO4E.Extensions", "TestBO4E.Extensions\TestBO4E.Extensions.csproj", "{BDA5224F-3C83-44F7-B96F-B873247E3245}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SchemaGenerator", "SchemaGenerator\SchemaGenerator.csproj", "{A178CA52-4DF3-4A12-8B84-FFF1EB3152F7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -48,6 +50,10 @@ Global
{BDA5224F-3C83-44F7-B96F-B873247E3245}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDA5224F-3C83-44F7-B96F-B873247E3245}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDA5224F-3C83-44F7-B96F-B873247E3245}.Release|Any CPU.Build.0 = Release|Any CPU
{A178CA52-4DF3-4A12-8B84-FFF1EB3152F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A178CA52-4DF3-4A12-8B84-FFF1EB3152F7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A178CA52-4DF3-4A12-8B84-FFF1EB3152F7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A178CA52-4DF3-4A12-8B84-FFF1EB3152F7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
13 changes: 2 additions & 11 deletions BO4ETestProject/TestJsonSchemaGeneration.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using BO4E.BO;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
Expand Down Expand Up @@ -48,20 +46,13 @@ public void TestJSchemaFileGenerationBo(int offset)
var relevantBusinessObjectTypes = typeof(BusinessObject).Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(BusinessObject)));
relevantBusinessObjectTypes.Count().Should().BeLessThan(LastDataRowOffset + MaxSchemasPerHour); // if this fails, add another data row to this test method
try
try // generate plain json schemas
{
foreach (var type in relevantBusinessObjectTypes.Skip(offset).Take(MaxSchemasPerHour))
{
var schema = BusinessObject.GetJsonSchema(type);
Assert.IsNotNull(schema);
var path = $"../../../../json-schema-files/{type}.json"; // not elegant but ok ;)
if (!File.Exists(path))
{
var stream = File.Create(path);
stream.Close();
}
var utf8WithoutByteOrderMark = new UTF8Encoding(false);
File.WriteAllText(path, schema.ToString(SchemaVersion.Draft7), utf8WithoutByteOrderMark);
// writing the schemas has moved to the SchemaGenerator project/generate-json-schemas.sh
}
}
catch (JSchemaException jse)
Expand Down
95 changes: 95 additions & 0 deletions SchemaGenerator/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System.Text;
using Newtonsoft.Json.Schema;
using BO4E.BO;

Console.WriteLine("Starting schema generation process...");

int offset;
string outputDirectory;

// Validate arguments
if (args.Length < 2)
{
Console.Error.WriteLine("Error: You must provide both an offset and an output directory.");
Console.Error.WriteLine("Usage: dotnet run -- <offset> <outputDirectory>");
Environment.Exit(1); // Exit with a specific error code for missing arguments
}

if (!int.TryParse(args[0], out offset))
{
Console.Error.WriteLine($"Error: Invalid argument '{args[0]}'. Please provide a valid integer offset.");
Environment.Exit(2); // Exit with a specific error code for invalid offset
}

// Get the output directory from the arguments
outputDirectory = args[1];

Console.WriteLine($"Offset provided: {offset}");
Console.WriteLine($"Output directory: {outputDirectory}");

// Generate schemas
try
{
JsonSchemaGenerator.GenerateSchemas(offset, outputDirectory);
Console.WriteLine("Schema generation completed successfully.");
}
catch (Exception ex)
{
Console.Error.WriteLine($"An unexpected error occurred: {ex.Message}");
Environment.Exit(4); // Exit with a specific error code for unexpected errors
}

Environment.Exit(0); // Success

/// <summary>
/// Generates plain JSON schemas from business object model classes.
/// </summary>
public class JsonSchemaGenerator
{
private const int LastDataRowOffset = 50;
private const int MaxSchemasPerHour = 10;

public static void GenerateSchemas(int offset, string outputDirectory)
{
var relevantBusinessObjectTypes = typeof(BusinessObject).Assembly
.GetTypes()
.Where(t => t.IsSubclassOf(typeof(BusinessObject)));

if (relevantBusinessObjectTypes.Count() > LastDataRowOffset + MaxSchemasPerHour)
{
throw new InvalidOperationException("Too many BusinessObject types. Increase the LastDataRowOffset or adjust the MaxSchemasPerHour.");
}

try
{
// Ensure the output directory exists
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
}

foreach (var type in relevantBusinessObjectTypes.Skip(offset).Take(MaxSchemasPerHour))
{
var schema = BusinessObject.GetJsonSchema(type);
var path = Path.Combine(outputDirectory, $"{type.Name}.json");

Console.WriteLine($"Generating schema for {type.Name} at {path}.");

if (!File.Exists(path))
{
using (File.Create(path))
{
}
}

var utf8WithoutByteOrderMark = new UTF8Encoding(false);
File.WriteAllText(path, schema.ToString(SchemaVersion.Draft7), utf8WithoutByteOrderMark);
}
}
catch (JSchemaException jse)
{
Console.Error.WriteLine($"Schema generation failed with error: {jse.Message}");
Environment.Exit(3); // Exit with a specific error code for schema generation failure
}
}
}
14 changes: 14 additions & 0 deletions SchemaGenerator/SchemaGenerator.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\BO4E\BO4E.csproj" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions SchemaGenerator/generate-json-schemas.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Cross-platform script to run the .NET console application with different offsets and an optional output directory
# Invoke it like this: powershell.exe C:/github/BO4E-dotnet2/SchemaGenerator/generate-json-schemas.sh

# Define the offsets
offsets=(10 20 30 40 50)

# Define the default output directory
default_output_directory="../json-schema-files" # json-schema-files in repo root

# Check if an output directory argument is provided
if [ $# -eq 1 ]; then
output_directory=$1
else
output_directory=$default_output_directory
fi

# Loop through the offsets and call the .NET application
for offset in "${offsets[@]}"
do
echo "Running schema generation with offset: $offset in directory: $output_directory"
# Run the .NET application
dotnet run -- $offset $output_directory
done
Loading
Loading