Files
dingyuntian 7d7c8893fc feat(editor): 添加 Yarn 本地化校验工具
- 新增 Editor 窗口:AIBIS → Yarn 本地化校验
- 新增 BatchMode CLI:Tools/validate_yarn_l10n.py
- 新增文档:Docs/本地化校验工具.md
- 校验 Yarn 原文 string table 与各语言 CSV 的 line id 一致性
2026-07-04 23:12:21 +08:00

117 lines
4.0 KiB
C#

using System;
using System.IO;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
namespace AibisDream.YarnLocalizationValidation.Editor
{
public static class YarnL10nValidatorCli
{
private const string JsonBeginMarker = "YARN_L10N_JSON_BEGIN";
private const string JsonEndMarker = "YARN_L10N_JSON_END";
public static void Run()
{
try
{
var args = Environment.GetCommandLineArgs();
var path = GetArgumentValue(args, "-yarnL10nPath");
var scanAll = HasFlag(args, "-yarnL10nScanAll");
var exportPath = GetArgumentValue(args, "-yarnL10nExport");
var outputPath = GetArgumentValue(args, "-yarnL10nOutput");
if (string.IsNullOrWhiteSpace(outputPath))
{
outputPath = "Build/yarn_l10n_result.json";
}
if (string.IsNullOrWhiteSpace(path))
{
WriteFailure("缺少参数 -yarnL10nPath。", 2);
return;
}
var validationResult = scanAll
? YarnL10nValidator.ValidateScanAll(path)
: YarnL10nValidator.ValidateFolder(path);
var json = JsonConvert.SerializeObject(validationResult, Formatting.Indented);
WriteJson(json, outputPath);
if (!string.IsNullOrWhiteSpace(exportPath))
{
var absoluteExportPath = YarnL10nValidator.ToAbsolutePath(exportPath);
YarnL10nReportExporter.ExportToCsv(validationResult, absoluteExportPath);
}
var exitCode = validationResult.HasBlockingIssues ? 1 : 0;
Debug.Log($"[YarnL10nValidatorCli] Completed with exit code {exitCode}, issues={validationResult.TotalIssueCount}");
EditorApplication.Exit(exitCode);
}
catch (Exception ex)
{
WriteFailure(ex.ToString(), 3);
}
}
private static void WriteJson(string json, string outputPath)
{
Console.WriteLine(JsonBeginMarker);
Console.WriteLine(json);
Console.WriteLine(JsonEndMarker);
if (!string.IsNullOrWhiteSpace(outputPath))
{
var absoluteOutputPath = YarnL10nValidator.ToAbsolutePath(outputPath);
var directory = Path.GetDirectoryName(absoluteOutputPath);
if (!string.IsNullOrEmpty(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllText(absoluteOutputPath, json, new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
Debug.Log($"[YarnL10nValidatorCli] Wrote JSON to {absoluteOutputPath}");
}
}
private static void WriteFailure(string message, int exitCode)
{
Debug.LogError($"[YarnL10nValidatorCli] {message}");
Console.Error.WriteLine(message);
EditorApplication.Exit(exitCode);
}
private static bool HasFlag(string[] args, string flag)
{
foreach (var arg in args)
{
if (string.Equals(arg, flag, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
private static string GetArgumentValue(string[] args, string key)
{
for (var i = 0; i < args.Length; i++)
{
var arg = args[i];
if (arg.StartsWith(key + "=", StringComparison.OrdinalIgnoreCase))
{
return arg.Substring(key.Length + 1).Trim('"');
}
if (string.Equals(arg, key, StringComparison.OrdinalIgnoreCase) && i + 1 < args.Length)
{
return args[i + 1].Trim('"');
}
}
return string.Empty;
}
}
}