nerushfgbhjkze4ghbieurzdh789izouehzbugk4789ziogh

This commit is contained in:
Mira 2024-01-20 13:52:52 +01:00
parent 8f4df05ac8
commit d2f03874f5
Signed by untrusted user who does not match committer: Xorog
GPG key ID: 983798ED9C3E7C36
11 changed files with 451 additions and 0 deletions

View file

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>embedded</DebugType>
</PropertyGroup>
</Project>

BIN
GetGitDir/GetGitDir.exe Normal file

Binary file not shown.

25
GetGitDir/GetGitDir.sln Normal file
View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34511.84
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GetGitDir", "GetGitDir.csproj", "{13C3220F-81E4-46E1-9D45-BFE51D425C7A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{13C3220F-81E4-46E1-9D45-BFE51D425C7A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F57CB7EB-01A8-4A5D-ABDF-F6A655B99AE5}
EndGlobalSection
EndGlobal

20
GetGitDir/Program.cs Normal file
View file

@ -0,0 +1,20 @@
try
{
if (!new FileInfo(".git").Exists)
return 1;
var content = File.ReadAllLines(".git");
if (!content.Any(x => x.StartsWith("gitdir: ")))
return 1;
var gitDirLine = content.First(x => x.StartsWith("gitdir: "));
Console.WriteLine(gitDirLine[8..]);
return 0;
}
catch (Exception)
{
return 1;
}

View file

@ -0,0 +1,9 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "<Pending>", Scope = "member", Target = "~P:TranslationSourceGenerator.Log._logger")]
[assembly: SuppressMessage("GeneratedRegex", "SYSLIB1045:Convert to 'GeneratedRegexAttribute'.", Justification = "<Pending>")]

View file

@ -0,0 +1,15 @@
// Project Makoto
// Copyright (C) 2023 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
namespace TranslationSourceGenerator;
internal class Log
{
internal static LoggerClient _logger { get; set; }
}

View file

@ -0,0 +1,295 @@
// Project Makoto
// Copyright (C) 2023 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
global using Xorog.Logger;
global using Xorog.UniversalExtensions;
global using Xorog.UniversalExtensions.Entities;
global using static TranslationSourceGenerator.Log;
global using static Xorog.UniversalExtensions.UniversalExtensions;
global using Newtonsoft.Json;
using System.Reflection;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
namespace TranslationSourceGenerator;
internal class Program
{
public string MakotoSourceOrigin => $@"
// Project Makoto
// Copyright (C) 2023 Fortunevale
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY
namespace {this.Namespace};
#pragma warning disable CS8981
#pragma warning disable CS8618
#pragma warning disable IDE1006
public class Translations : ITranslations
{{
public Dictionary<string, int> Progress = new();
public CommandTranslation[] CommandList {{ get; set; }}
#region AutoGenerated
// InsertPoint
#endregion AutoGenerated
}}
";
public string StringsJson { get; set; }
public string TranslationCs { get; set; }
public string Namespace { get; set; }
static void Main(string[] args)
=> new Program().Execute(args).GetAwaiter().GetResult();
public async Task Execute(string[] args)
{
if (!Directory.Exists($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs"))
_ = Directory.CreateDirectory($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs");
_logger = LoggerClient.StartLogger($"{new FileInfo(Assembly.GetExecutingAssembly().FullName).Directory.FullName}/logs/{DateTime.UtcNow:dd-MM-yyyy_HH-mm-ss}.log", CustomLogLevel.Debug, DateTime.UtcNow.AddDays(-3), false);
_ = Task.Run(async () =>
{
if (!File.Exists(args.Length > 0 ? args[0] : "e252zru2rjb2rtb23jbrj2bthj2bthjb2jtb4jbtb2jtb4hj"))
{
_logger.LogError("Translation json expected as arg0");
return;
}
if (!File.Exists(args.Length > 1 ? args[1] : "e252zru2rjb2rtb23jbrj2bthj2bthjb2jtb4jbtb2jtb4hj"))
{
_logger.LogError("Translation json expected as arg1");
return;
}
if (args.Length < 2)
{
_logger.LogError("Namespace expected as arg2");
return;
}
this.StringsJson = args[0];
this.TranslationCs = args[1];
this.Namespace = args[2];
_logger.LogDebug("Project Makoto Translation Source Generator started up.");
_logger.LogDebug("Strings.json Location: {0}", Path.GetFullPath(this.StringsJson));
_logger.LogDebug("Translation.cs Location: {0}", Path.GetFullPath(this.TranslationCs));
DateTime lastModify = new();
while (true)
{
try
{
Dictionary<string, List<string>> addedFields = new();
FileInfo fileInfo = new(this.StringsJson);
if (lastModify != fileInfo.LastWriteTimeUtc)
{
try
{
List<string> Warnings = new();
var Insert = "";
_logger.LogDebug("Translation file updated. Updating Translations.cs..");
var jsonFile = (JObject)JsonConvert.DeserializeObject(File.ReadAllText(this.StringsJson));
string CreateValidValueName(string str)
=> Regex.Replace(str, @"[^a-zA-Z0-9]", "_");
void RecursiveHandle(JObject token, string ParentPath, int depth)
{
foreach (var item in token)
{
var className = CreateValidValueName($"{item.Key.First().ToString().ToLower()}{item.Key.Remove(0, 1)}");
switch (className)
{
case "object":
className = $"@{className}";
break;
default:
break;
}
var fieldName = CreateValidValueName(item.Key.FirstLetterToUpper());
var entryPoint = $"{ParentPath}/{className}";
var IndexPath = $"// {ParentPath} InsertPoint";
var InsertPosition = 0;
if (!ParentPath.IsNullOrWhiteSpace())
{
InsertPosition = Insert.IndexOf(IndexPath) + IndexPath.Length;
}
if (!addedFields.ContainsKey(IndexPath))
addedFields.Add(IndexPath, new());
switch (item.Value.Type)
{
case JTokenType.Object:
{
var containsLocaleCode = false;
var localeCodeIsArray = false;
List<KeyValuePair<string, JToken?>> tokens = new();
foreach (var subItem in item.Value.ToObject<JObject>())
{
tokens.Add(subItem);
if (subItem.Key == "en")
{
containsLocaleCode = true;
localeCodeIsArray = subItem.Value.Type == JTokenType.Array;
}
}
if (containsLocaleCode)
{
if (!localeCodeIsArray)
{
var line = $"{new string(' ', depth * 4)}public SingleTranslationKey {CreateValidValueName(item.Key)};";
if (addedFields[IndexPath].Contains(line))
continue;
_logger.LogDebug("Found SingleKey '{0}'", item.Key);
Insert = Insert.Insert(InsertPosition, $"\n{line}");
addedFields[IndexPath].Add(line);
if (!tokens.Any(x => x.Key == "de"))
Warnings.Add($"String at path {entryPoint} has no de translation");
}
else
{
var line = $"{new string(' ', depth * 4)}public MultiTranslationKey {CreateValidValueName(item.Key)};";
if (addedFields[IndexPath].Contains(line))
continue;
_logger.LogDebug("Found MultiKey '{0}'", item.Key);
Insert = Insert.Insert(InsertPosition, $"\n{line}");
addedFields[IndexPath].Add(line);
if (!tokens.Any(x => x.Key == "de"))
Warnings.Add($"String at path {entryPoint} has no de translation");
}
continue;
}
else
{
_logger.LogDebug("Found Group '{0}'", item.Key);
var line = $"\n{new string(' ', depth * 4)}public {className} {fieldName};\n" +
$"{new string(' ', depth * 4)}public sealed class {className}\n" +
$"{new string(' ', depth * 4)}{{\n" +
$"{new string(' ', depth * 4)}// {entryPoint} InsertPoint\n" +
$"{new string(' ', depth * 4)}}}\n";
if (addedFields[IndexPath].Contains(line))
break;
Insert = Insert.Insert(InsertPosition, line);
addedFields[IndexPath].Add(line);
}
RecursiveHandle(item.Value.ToObject<JObject>(), entryPoint, depth + 1);
break;
}
case JTokenType.Integer:
{
_logger.LogDebug("Found Int '{0}'", item.Key);
var line = $"\n{new string(' ', depth * 4)}public int {CreateValidValueName(item.Key)};";
if (addedFields[IndexPath].Contains(line))
continue;
Insert = Insert.Insert(InsertPosition, line);
addedFields[IndexPath].Add(line);
break;
}
case JTokenType.Array:
{
_logger.LogDebug("Found Array '{0}'", item.Key);
var line = $"\n{new string(' ', depth * 4)}public {className}[] {fieldName};\n" +
$"{new string(' ', depth * 4)}public sealed class {className}\n" +
$"{new string(' ', depth * 4)}{{\n" +
$"{new string(' ', depth * 4)}// {entryPoint} InsertPoint\n" +
$"{new string(' ', depth * 4)}}}\n";
if (fieldName == "CommandList" && IndexPath == "// InsertPoint")
{
continue;
}
if (!addedFields[IndexPath].Contains(line))
{
Insert = Insert.Insert(InsertPosition, line);
addedFields[IndexPath].Add(line);
}
foreach (var b in item.Value.ToObject<JArray>())
RecursiveHandle(b.ToObject<JObject>(), entryPoint, depth + 1);
break;
}
default:
break;
}
}
}
RecursiveHandle(jsonFile, "", 1);
foreach (var b in Warnings)
{
_logger.LogWarn(b);
}
_logger.LogWarn("Source Generation finished with {Count} warnings.", Warnings.Count);
Insert = string.Join("\n", Insert.Split("\n").Where(x => !x.Contains("InsertPoint")));
File.WriteAllText(this.TranslationCs, string.Join("\n", this.MakotoSourceOrigin.Replace("// InsertPoint", Insert).ReplaceLineEndings("\n").Split("\n", StringSplitOptions.RemoveEmptyEntries).Where(x => !x.IsNullOrWhiteSpace())));
_logger.LogDebug("Updated Translations.cs.");
}
catch (Exception ex)
{
_logger.LogError("Failed to update Translations.cs.", ex);
}
}
lastModify = fileInfo.LastWriteTimeUtc;
await Task.Delay(1000);
}
catch (Exception ex)
{
_logger.LogError("Failed to watch file", ex);
await Task.Delay(10000);
}
}
});
await Task.Delay(-1);
}
}

View file

@ -0,0 +1,8 @@
{
"profiles": {
"TranslationSourceGenerator": {
"commandName": "Project",
"commandLineArgs": "\"C:\\Users\\Xorog\\Documents\\GitHub\\ProjectIchigo\\ProjectMakoto\\Translations\\strings.json\" \"C:\\Users\\Xorog\\Documents\\GitHub\\ProjectIchigo\\ProjectMakoto\\Entities\\Translation\\Translations.cs\""
}
}
}

View file

@ -0,0 +1 @@
dotnet run -- ../../ProjectMakoto/Translations/strings.json ../../ProjectMakoto/Entities/Translation/Translations.cs ProjectMakoto.Entities

View file

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>annotations</Nullable>
<Platforms>x64</Platforms>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Dependencies\Xorog.Logger\Xorog.Logger.csproj" />
<ProjectReference Include="..\..\Dependencies\Xorog.UniversalExtensions\Xorog.UniversalExtensions.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,44 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.8.34309.116
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TranslationSourceGenerator", "TranslationSourceGenerator.csproj", "{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xorog.Logger", "..\..\Dependencies\Xorog.Logger\Xorog.Logger.csproj", "{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Xorog.UniversalExtensions", "..\..\Dependencies\Xorog.UniversalExtensions\Xorog.UniversalExtensions.csproj", "{1082AEE5-F298-412D-BE0D-12253D25AF1C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
x64|x64 = x64|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Debug|x64.ActiveCfg = Debug|x64
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Debug|x64.Build.0 = Debug|x64
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Release|x64.ActiveCfg = Release|x64
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.Release|x64.Build.0 = Release|x64
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.x64|x64.ActiveCfg = Debug|x64
{1962E64F-BFA8-4ECA-83C6-FD09959D7E98}.x64|x64.Build.0 = Debug|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Debug|x64.ActiveCfg = Debug|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Debug|x64.Build.0 = Debug|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Release|x64.ActiveCfg = Release|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.Release|x64.Build.0 = Release|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.x64|x64.ActiveCfg = x64|x64
{8A8883E2-C01C-48A5-9CFF-16DB013DA0C8}.x64|x64.Build.0 = x64|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Debug|x64.ActiveCfg = Debug|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Debug|x64.Build.0 = Debug|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Release|x64.ActiveCfg = Release|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.Release|x64.Build.0 = Release|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.x64|x64.ActiveCfg = x64|x64
{1082AEE5-F298-412D-BE0D-12253D25AF1C}.x64|x64.Build.0 = x64|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0B29991B-405D-41AD-8AAA-56C1A701ED99}
EndGlobalSection
EndGlobal