Files
Installer/Development~/UnityProject/Assets/Editor/ShrinkInstallerDevelopmentValidation.cs
cneicy 885da4366d
Publish UPM package / publish (push) Successful in 2s
chore(release): 发布 v0.2.3
2026-08-28 03:44:10 +08:00

116 lines
5.0 KiB
C#

#if UNITY_EDITOR
using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public static class ShrinkInstallerDevelopmentValidation
{
public static void Run()
{
try
{
var windowType = FindType("ShrinkSDK.Installer.ShrinkSdkInstallerWindow");
var window = ScriptableObject.CreateInstance(windowType) as EditorWindow
?? throw new InvalidOperationException("无法创建包管理窗口。");
try
{
windowType.GetMethod("CreateGUI", BindingFlags.Public | BindingFlags.Instance)?.Invoke(window, null);
var texts = window.rootVisualElement.Query<Label>().ToList()
.Select(label => label.text)
.Where(text => !string.IsNullOrWhiteSpace(text))
.ToArray();
Require(texts.Contains("ShrinkSDK 包管理"), "缺少中文窗口标题。");
Require(texts.Any(text => text.Contains("以 Context 为组合基础")), "缺少 Context 架构说明。");
Require(window.rootVisualElement.Query<Button>().ToList().Any(button => button.text == "安装组合"),
"缺少组合安装按钮。");
Require(window.rootVisualElement.Query<Foldout>().ToList().Any(), "组合内容未使用 UI Toolkit Foldout。");
var catalog = FindType("ShrinkSDK.Installer.ShrinkSdkPackageCatalog");
var packages = catalog.GetField("Packages", BindingFlags.Static | BindingFlags.NonPublic)
?.GetValue(null) as IEnumerable;
var bundles = catalog.GetField("Bundles", BindingFlags.Static | BindingFlags.NonPublic)
?.GetValue(null) as IEnumerable;
Require(Count(packages) == 20, "包目录数量不是 20。");
Require(Count(bundles) == 8, "推荐组合数量不是 8。");
Require(BundleContainsInstallRoot(bundles, "基础应用(推荐)",
"com.cneicy.shrink-context-eventbus-adapter"),
"基础应用组合没有显式安装 Context 事件适配。");
Require(BundleContainsInstallRoot(bundles, "常用完整套件",
"com.cneicy.shrink-context-eventbus-adapter"),
"常用完整套件没有显式安装 Context 事件适配。");
Require(BundleContainsInstallRoot(bundles, "常用完整套件",
"com.cneicy.shrink-app-starter-basic"),
"常用完整套件没有显式安装 Starter。");
Require(BundleContainsInstallRoot(bundles, "常用完整套件",
"com.cneicy.shrink-mod-framework"),
"常用完整套件没有显式安装 ModFramework。");
Require(BundleContainsInstallRoot(bundles, "常用完整套件",
"com.cneicy.shrink-tutorial"),
"常用完整套件没有显式安装 Tutorial。");
}
finally
{
UnityEngine.Object.DestroyImmediate(window);
}
Debug.Log("ShrinkInstaller development validation passed: UI Toolkit, Chinese UI, package status surface and Context bundles.");
EditorApplication.Exit(0);
}
catch (Exception exception)
{
Debug.LogException(exception);
EditorApplication.Exit(1);
}
}
private static int Count(IEnumerable enumerable)
{
var count = 0;
foreach (var _ in enumerable)
count++;
return count;
}
private static bool BundleContainsInstallRoot(IEnumerable bundles, string bundleName, string packageName)
{
foreach (var bundle in bundles)
{
var bundleType = bundle.GetType();
if (!string.Equals(bundleType.GetProperty("DisplayName")?.GetValue(bundle) as string, bundleName,
StringComparison.Ordinal))
continue;
var roots = bundleType.GetProperty("InstallRoots")?.GetValue(bundle) as IEnumerable;
if (roots == null)
return false;
foreach (var root in roots)
{
var value = root.GetType().GetProperty("PackageName")?.GetValue(root) as string;
if (string.Equals(value, packageName, StringComparison.Ordinal))
return true;
}
return false;
}
return false;
}
private static Type FindType(string fullName) => AppDomain.CurrentDomain.GetAssemblies()
.Select(assembly => assembly.GetType(fullName, false))
.FirstOrDefault(type => type != null)
?? throw new InvalidOperationException("未加载类型:" + fullName);
private static void Require(bool condition, string message)
{
if (!condition)
throw new InvalidOperationException(message);
}
}
#endif