update AssetArtScanner

配置和报告容错性检测
pull/466/head^2
何冠峰 2025-02-10 16:21:43 +08:00
parent 7dfbac4a24
commit 2d6488abf4
9 changed files with 213 additions and 76 deletions

View File

@ -3,9 +3,24 @@ namespace YooAsset.Editor
{
public enum EHeaderType
{
/// <summary>
/// 资源路径
/// </summary>
AssetPath,
/// <summary>
/// 字符串
/// </summary>
StringValue,
/// <summary>
/// 整数数值
/// </summary>
LongValue,
/// <summary>
/// 浮点数数值
/// </summary>
DoubleValue,
}
}

View File

@ -31,12 +31,28 @@ namespace YooAsset.Editor
/// <summary>
/// 添加扫描信息
/// </summary>
public void AddScanInfo(string headerTitle, string scanInfo)
public void AddScanInfo(string headerTitle, string value)
{
var reportScanInfo = new ReportScanInfo(headerTitle, scanInfo);
var reportScanInfo = new ReportScanInfo(headerTitle, value);
ScanInfos.Add(reportScanInfo);
}
/// <summary>
/// 添加扫描信息
/// </summary>
public void AddScanInfo(string headerTitle, long value)
{
AddScanInfo(headerTitle, value.ToString());
}
/// <summary>
/// 添加扫描信息
/// </summary>
public void AddScanInfo(string headerTitle, double value)
{
AddScanInfo(headerTitle, value.ToString());
}
/// <summary>
/// 获取扫描信息
/// </summary>

View File

@ -1,4 +1,5 @@
using System;
using UnityEditor;
namespace YooAsset.Editor
{
@ -93,5 +94,35 @@ namespace YooAsset.Editor
HeaderType = value;
return this;
}
/// <summary>
/// 检测数值有效性
/// </summary>
public void CheckValueValid(string value)
{
if (HeaderType == EHeaderType.AssetPath)
{
string guid = AssetDatabase.AssetPathToGUID(value);
if (string.IsNullOrEmpty(guid))
throw new Exception($"{HeaderTitle} value is invalid asset path : {value}");
}
else if (HeaderType == EHeaderType.DoubleValue)
{
if (double.TryParse(value, out double doubleValue) == false)
throw new Exception($"{HeaderTitle} value is invalid double value : {value}");
}
else if (HeaderType == EHeaderType.LongValue)
{
if (long.TryParse(value, out long longValue) == false)
throw new Exception($"{HeaderTitle} value is invalid long value : {value}");
}
else if (HeaderType == EHeaderType.StringValue)
{
}
else
{
throw new System.NotImplementedException(HeaderType.ToString());
}
}
}
}

View File

@ -29,9 +29,9 @@ namespace YooAsset.Editor
/// <summary>
/// 报告标题
/// 报告名称
/// </summary>
public string ReportTitle;
public string ReportName;
/// <summary>
/// 报告介绍
@ -41,7 +41,7 @@ namespace YooAsset.Editor
/// <summary>
/// 报告的标题列表
/// </summary>
public List<ReportHeader> HeaderTitles = new List<ReportHeader>();
public List<ReportHeader> ReportHeaders = new List<ReportHeader>();
/// <summary>
/// 扫描的元素列表
@ -49,23 +49,70 @@ namespace YooAsset.Editor
public List<ReportElement> ReportElements = new List<ReportElement>();
public ScanReport(string reportTitle, string reportDesc)
public ScanReport(string reportName, string reportDesc)
{
ReportTitle = reportTitle;
ReportName = reportName;
ReportDesc = reportDesc;
}
/// <summary>
/// 添加标题
/// </summary>
public ReportHeader AddHeader(string headerTitle, int width)
{
var reportHeader = new ReportHeader(headerTitle, width);
HeaderTitles.Add(reportHeader);
ReportHeaders.Add(reportHeader);
return reportHeader;
}
/// <summary>
/// 添加标题
/// </summary>
public ReportHeader AddHeader(string headerTitle, int width, int minWidth, int maxWidth)
{
var reportHeader = new ReportHeader(headerTitle, width, minWidth, maxWidth);
HeaderTitles.Add(reportHeader);
ReportHeaders.Add(reportHeader);
return reportHeader;
}
/// <summary>
/// 检测错误
/// </summary>
public void CheckError()
{
// 检测标题
Dictionary<string, ReportHeader> headerMap = new Dictionary<string, ReportHeader>();
foreach (var header in ReportHeaders)
{
string headerTitle = header.HeaderTitle;
if (headerMap.ContainsKey(headerTitle))
throw new Exception($"The header title {headerTitle} already exists !");
else
headerMap.Add(headerTitle, header);
}
// 检测扫描元素
HashSet<string> elementMap = new HashSet<string>();
foreach (var element in ReportElements)
{
if (string.IsNullOrEmpty(element.GUID))
throw new Exception($"The report element GUID is null or empty !");
if (elementMap.Contains(element.GUID))
throw new Exception($"The report element GUID already exists ! {element.GUID}");
else
elementMap.Add(element.GUID);
foreach (var scanInfo in element.ScanInfos)
{
if (headerMap.ContainsKey(scanInfo.HeaderTitle) == false)
throw new Exception($"The report element header {scanInfo.HeaderTitle} is missing !");
// 检测数值有效性
var header = headerMap[scanInfo.HeaderTitle];
header.CheckValueValid(scanInfo.ScanInfo);
}
}
}
}
}

View File

@ -55,9 +55,9 @@ namespace YooAsset.Editor
if (string.IsNullOrEmpty(SchemaType))
{
SchemaType = scanReport.SchemaType;
ReportTitle = scanReport.ReportTitle;
ReportTitle = scanReport.ReportName;
ReportDesc = scanReport.ReportDesc;
Headers = scanReport.HeaderTitles;
Headers = scanReport.ReportHeaders;
}
if (SchemaType != scanReport.SchemaType)
@ -82,7 +82,7 @@ namespace YooAsset.Editor
List<ReportElement> elements = scanReport.ReportElements;
// 设置白名单
var scanner = AssetArtScannerSettingData.GetScannerByGUID(scannerGUID);
var scanner = AssetArtScannerSettingData.Setting.GetScanner(scannerGUID);
if (scanner != null)
{
foreach (var element in elements)
@ -144,7 +144,7 @@ namespace YooAsset.Editor
string scannerGUID = scanReport.ScannerGUID;
var elements = scanReport.ReportElements;
var scanner = AssetArtScannerSettingData.GetScannerByGUID(scannerGUID);
var scanner = AssetArtScannerSettingData.Setting.GetScanner(scannerGUID);
if (scanner != null)
{
List<string> whiteList = new List<string>(elements.Count);
@ -207,7 +207,7 @@ namespace YooAsset.Editor
private void FixInternal(string scannerGUID, List<ReportElement> fixList)
{
AssetArtScanner scanner = AssetArtScannerSettingData.GetScannerByGUID(scannerGUID);
AssetArtScanner scanner = AssetArtScannerSettingData.Setting.GetScanner(scannerGUID);
if (scanner != null)
{
var schema = scanner.LoadSchema();

View File

@ -30,7 +30,7 @@ namespace YooAsset.Editor
// 检测标题数和内容是否匹配
foreach (var element in report.ReportElements)
{
if (element.ScanInfos.Count != report.HeaderTitles.Count)
if (element.ScanInfos.Count != report.ReportHeaders.Count)
{
throw new Exception($"报告的标题数和内容不匹配!");
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using UnityEditor;
using UnityEngine;
@ -46,6 +47,17 @@ namespace YooAsset.Editor
public List<string> WhiteList = new List<string>();
/// <summary>
/// 检测关键字匹配
/// </summary>
public bool CheckKeyword(string keyword)
{
if (ScannerName.Contains(keyword) || ScannerDesc.Contains(keyword))
return true;
else
return false;
}
/// <summary>
/// 是否在白名单里
/// </summary>
@ -54,6 +66,24 @@ namespace YooAsset.Editor
return WhiteList.Contains(guid);
}
/// <summary>
/// 检测配置错误
/// </summary>
public void CheckConfigError()
{
if (string.IsNullOrEmpty(ScannerName))
throw new Exception($"Scanner name is null or empty !");
if (string.IsNullOrEmpty(ScannerSchema))
throw new Exception($"Scanner {ScannerName} schema is null !");
if (string.IsNullOrEmpty(SaveDirectory) == false)
{
if (Directory.Exists(SaveDirectory) == false)
throw new Exception($"Scanner {ScannerName} save directory is invalid : {SaveDirectory}");
}
}
/// <summary>
/// 加载扫描模式实例
/// </summary>
@ -85,14 +115,11 @@ namespace YooAsset.Editor
public ScanReport RunScanner()
{
if (Collectors.Count == 0)
{
Debug.LogWarning($"Scanner collector is empty : {ScannerName}");
return null;
}
Debug.LogWarning($"Scanner {ScannerName} collector is empty !");
ScannerSchema schema = LoadSchema();
if (schema == null)
return null;
throw new Exception($"Failed to load schema : {ScannerSchema}");
var report = schema.RunScanner(this);
report.FileSign = ScannerDefine.ReportFileSign;
@ -101,13 +128,5 @@ namespace YooAsset.Editor
report.ScannerGUID = ScannerGUID;
return report;
}
public bool CheckKeyword(string keyword)
{
if (ScannerName.Contains(keyword) || ScannerDesc.Contains(keyword))
return true;
else
return false;
}
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.IO;
using UnityEngine;
using NUnit.Framework.Constraints;
namespace YooAsset.Editor
{
@ -13,5 +14,55 @@ namespace YooAsset.Editor
/// 扫描器列表
/// </summary>
public List<AssetArtScanner> Scanners = new List<AssetArtScanner>();
/// <summary>
/// 开始扫描
/// </summary>
public ScannerResult BeginScan(string scannerGUID)
{
try
{
// 获取扫描器配置
var scanner = GetScanner(scannerGUID);
if (scanner == null)
throw new Exception($"Invalid scanner GUID : {scannerGUID}");
// 检测配置合法性
scanner.CheckConfigError();
// 开始扫描工作
ScanReport report = scanner.RunScanner();
// 检测报告合法性
report.CheckError();
// 保存扫描结果
string saveDirectory = scanner.SaveDirectory;
if (string.IsNullOrEmpty(saveDirectory))
saveDirectory = "Assets/";
string filePath = $"{saveDirectory}/{scanner.ScannerName}_{scanner.ScannerDesc}.json";
ScanReportConfig.ExportJsonConfig(filePath, report);
return new ScannerResult(filePath, report);
}
catch (Exception e)
{
return new ScannerResult(e.Message);
}
}
/// <summary>
/// 获取指定的扫描器
/// </summary>
public AssetArtScanner GetScanner(string scannerGUID)
{
foreach (var scanner in Scanners)
{
if (scanner.ScannerGUID == scannerGUID)
return scanner;
}
Debug.LogWarning($"Not found scanner : {scannerGUID}");
return null;
}
}
}

View File

@ -61,10 +61,10 @@ namespace YooAsset.Editor
{
foreach (var scanner in Setting.Scanners)
{
var scanResult = ScanInternal(scanner);
var scanResult = Setting.BeginScan(scanner.ScannerGUID);
if (scanResult.Succeed == false)
{
Debug.LogError($"Scanner {scanner.ScannerName} failed ! {scanResult.ErrorInfo}");
Debug.LogError($"{scanner.ScannerName} failed : {scanResult.ErrorInfo}");
}
}
}
@ -82,10 +82,10 @@ namespace YooAsset.Editor
continue;
}
var scanResult = ScanInternal(scanner);
var scanResult = Setting.BeginScan(scanner.ScannerGUID);
if (scanResult.Succeed == false)
{
Debug.LogError($"Scanner {scanner.ScannerName} failed ! {scanResult.ErrorInfo}");
Debug.LogError($"{scanner.ScannerName} failed : {scanResult.ErrorInfo}");
}
}
}
@ -95,30 +95,14 @@ namespace YooAsset.Editor
/// </summary>
public static ScannerResult Scan(string scannerGUID)
{
AssetArtScanner scanner = GetScannerByGUID(scannerGUID);
var scanResult = ScanInternal(scanner);
var scanResult = Setting.BeginScan(scannerGUID);
if (scanResult.Succeed == false)
{
Debug.LogError($"Scanner {scanner.ScannerName} failed ! {scanResult.ErrorInfo}");
Debug.LogError(scanResult.ErrorInfo);
}
return scanResult;
}
/// <summary>
/// 获取指定的扫描器
/// </summary>
public static AssetArtScanner GetScannerByGUID(string scannerGUID)
{
foreach (var scanner in Setting.Scanners)
{
if (scanner.ScannerGUID == scannerGUID)
return scanner;
}
Debug.LogWarning($"Not found scanner : {scannerGUID}");
return null;
}
// 扫描器编辑相关
public static AssetArtScanner CreateScanner(string name, string desc)
{
@ -173,31 +157,5 @@ namespace YooAsset.Editor
IsDirty = true;
}
}
private static ScannerResult ScanInternal(AssetArtScanner scanner)
{
if (scanner == null)
return new ScannerResult("Scanner is null !");
string saveDirectory = "Assets/";
if (string.IsNullOrEmpty(scanner.SaveDirectory) == false)
{
saveDirectory = scanner.SaveDirectory;
if (Directory.Exists(saveDirectory) == false)
return new ScannerResult($"Scanner save directory is invalid : {saveDirectory}");
}
ScanReport report = scanner.RunScanner();
if (report != null)
{
string filePath = $"{saveDirectory}/{scanner.ScannerName}_{scanner.ScannerDesc}.json";
ScanReportConfig.ExportJsonConfig(filePath, report);
return new ScannerResult(filePath, report);
}
else
{
return new ScannerResult($"Scanner run failed : {scanner.ScannerName}");
}
}
}
}