mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-28 21:35:42 +00:00
Speed up Unity editmode asset audits (#7263)
This commit is contained in:
+8
-1
@@ -47,7 +47,14 @@ namespace eagle0.Tests {
|
||||
var violations = new List<string>();
|
||||
|
||||
foreach (var path in TextFilesToScan(projectRoot)) {
|
||||
var lines = File.ReadAllLines(path);
|
||||
var text = File.ReadAllText(path);
|
||||
if (!PostProcessingPatterns.Any(
|
||||
pattern => text.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >=
|
||||
0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var lines = text.Split('\n');
|
||||
for (var i = 0; i < lines.Length; i++) {
|
||||
foreach (var pattern in PostProcessingPatterns) {
|
||||
if (lines[i].IndexOf(pattern, StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
|
||||
+61
-41
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using NUnit.Framework;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
@@ -50,6 +51,9 @@ namespace eagle0.Tests {
|
||||
"Assets/TextMesh Pro/",
|
||||
};
|
||||
|
||||
private static readonly Regex SerializedGuidRegex =
|
||||
new(@"\bguid:\s*([0-9a-f]{32})\b", RegexOptions.IgnoreCase);
|
||||
|
||||
[Test]
|
||||
public void ProductionAssetsDoNotReferenceBuiltInOnlyShaders() {
|
||||
var projectRoot = Directory.GetParent(Application.dataPath).FullName;
|
||||
@@ -59,22 +63,15 @@ namespace eagle0.Tests {
|
||||
|
||||
foreach (var assetPath in ProductionReferencePaths(projectRoot)) {
|
||||
var text = File.ReadAllText(Path.Combine(projectRoot, assetPath));
|
||||
|
||||
foreach (var shader in riskyShaders.Values) {
|
||||
if (text.IndexOf(shader.Guid, StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
continue;
|
||||
foreach (var guid in SerializedGuids(text)) {
|
||||
if (riskyShaders.TryGetValue(guid, out var shader)) {
|
||||
violations.Add($"{assetPath}: shader {shader.Path}");
|
||||
}
|
||||
|
||||
violations.Add($"{assetPath}: shader {shader.Path}");
|
||||
}
|
||||
|
||||
foreach (var material in riskyMaterials.Values) {
|
||||
if (text.IndexOf(material.Guid, StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
continue;
|
||||
if (riskyMaterials.TryGetValue(guid, out var material)) {
|
||||
violations.Add(
|
||||
$"{assetPath}: material {material.Path} uses shader {material.ShaderPath}");
|
||||
}
|
||||
|
||||
violations.Add(
|
||||
$"{assetPath}: material {material.Path} uses shader {material.ShaderPath}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,12 +102,11 @@ namespace eagle0.Tests {
|
||||
}
|
||||
|
||||
private static Dictionary<string, ShaderRecord> RiskyShaderGuids(string projectRoot) {
|
||||
return AssetDatabase.GetAllAssetPaths()
|
||||
.Where(IsShaderLikePath)
|
||||
return AssetFilePaths(projectRoot, new[] { "Assets/" }, ShaderLikeExtensions)
|
||||
.Where(path => !IsAllowedRiskyShaderPath(path))
|
||||
.Where(path => FileContainsAnyPattern(projectRoot, path, BuiltInOnlyPatterns))
|
||||
.Select(path => new ShaderRecord {
|
||||
Guid = AssetDatabase.AssetPathToGUID(path),
|
||||
Guid = AssetGuid(projectRoot, path),
|
||||
Path = path,
|
||||
})
|
||||
.Where(record => !string.IsNullOrEmpty(record.Guid))
|
||||
@@ -121,22 +117,24 @@ namespace eagle0.Tests {
|
||||
string projectRoot,
|
||||
IReadOnlyDictionary<string, ShaderRecord> riskyShaders) {
|
||||
var results = new Dictionary<string, MaterialRecord>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var guid in AssetDatabase.FindAssets("t:Material")) {
|
||||
var path = AssetDatabase.GUIDToAssetPath(guid);
|
||||
foreach (var path in AssetFilePaths(
|
||||
projectRoot,
|
||||
new[] { "Assets/" },
|
||||
new[] { ".mat" })) {
|
||||
var fullPath = Path.Combine(projectRoot, path);
|
||||
if (!File.Exists(fullPath)) { continue; }
|
||||
|
||||
var text = File.ReadAllText(fullPath);
|
||||
foreach (var shader in riskyShaders.Values) {
|
||||
if (text.IndexOf(shader.Guid, StringComparison.OrdinalIgnoreCase) < 0) {
|
||||
continue;
|
||||
}
|
||||
foreach (var guid in SerializedGuids(text)) {
|
||||
if (!riskyShaders.TryGetValue(guid, out var shader)) { continue; }
|
||||
|
||||
results[guid] = new MaterialRecord {
|
||||
Guid = guid,
|
||||
var materialGuid = AssetGuid(projectRoot, path);
|
||||
if (string.IsNullOrEmpty(materialGuid)) { continue; }
|
||||
|
||||
results[materialGuid] = new MaterialRecord {
|
||||
Guid = materialGuid,
|
||||
Path = path,
|
||||
ShaderPath = shader.Path,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +142,7 @@ namespace eagle0.Tests {
|
||||
}
|
||||
|
||||
private static IEnumerable<string> ProductionReferencePaths(string projectRoot) {
|
||||
return AssetDatabase.GetAllAssetPaths()
|
||||
.Where(IsProductionReferencePath)
|
||||
.Where(path => ReferenceScanExtensions.Contains(
|
||||
Path.GetExtension(path),
|
||||
StringComparer.OrdinalIgnoreCase))
|
||||
.Where(path => File.Exists(Path.Combine(projectRoot, path)))
|
||||
.OrderBy(path => path, StringComparer.Ordinal);
|
||||
return AssetFilePaths(projectRoot, ProductionReferenceRoots, ReferenceScanExtensions);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> ProductionMaterialPaths() {
|
||||
@@ -160,11 +152,9 @@ namespace eagle0.Tests {
|
||||
.OrderBy(path => path, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
private static bool IsShaderLikePath(string assetPath) {
|
||||
return assetPath.StartsWith("Assets/", StringComparison.Ordinal) &&
|
||||
ShaderLikeExtensions.Contains(
|
||||
Path.GetExtension(assetPath),
|
||||
StringComparer.OrdinalIgnoreCase);
|
||||
private static bool IsAllowedRiskyShaderPath(string assetPath) {
|
||||
return AllowedRiskyShaderRoots.Any(
|
||||
root => assetPath.StartsWith(root, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private static bool IsProductionReferencePath(string assetPath) {
|
||||
@@ -172,9 +162,32 @@ namespace eagle0.Tests {
|
||||
root => assetPath.StartsWith(root, StringComparison.Ordinal));
|
||||
}
|
||||
|
||||
private static bool IsAllowedRiskyShaderPath(string assetPath) {
|
||||
return AllowedRiskyShaderRoots.Any(
|
||||
root => assetPath.StartsWith(root, StringComparison.Ordinal));
|
||||
private static IEnumerable<string> AssetFilePaths(
|
||||
string projectRoot,
|
||||
IEnumerable<string> assetRoots,
|
||||
IReadOnlyCollection<string> extensions) {
|
||||
return assetRoots.Select(root => Path.Combine(projectRoot, root))
|
||||
.Where(Directory.Exists)
|
||||
.SelectMany(
|
||||
root => Directory
|
||||
.EnumerateFiles(root, "*", SearchOption.AllDirectories))
|
||||
.Where(path => extensions.Contains(
|
||||
Path.GetExtension(path),
|
||||
StringComparer.OrdinalIgnoreCase))
|
||||
.Select(path => RelativeAssetPath(projectRoot, path))
|
||||
.OrderBy(path => path, StringComparer.Ordinal);
|
||||
}
|
||||
|
||||
private static string AssetGuid(string projectRoot, string assetPath) {
|
||||
var metaPath = Path.Combine(projectRoot, assetPath + ".meta");
|
||||
if (!File.Exists(metaPath)) { return null; }
|
||||
|
||||
var match = SerializedGuidRegex.Match(File.ReadAllText(metaPath));
|
||||
return match.Success ? match.Groups[1].Value : null;
|
||||
}
|
||||
|
||||
private static string RelativeAssetPath(string projectRoot, string path) {
|
||||
return path.Substring(projectRoot.Length + 1).Replace(Path.DirectorySeparatorChar, '/');
|
||||
}
|
||||
|
||||
private static bool
|
||||
@@ -187,6 +200,13 @@ namespace eagle0.Tests {
|
||||
pattern => text.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) >= 0);
|
||||
}
|
||||
|
||||
private static IEnumerable<string> SerializedGuids(string text) {
|
||||
var seenGuids = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (Match match in SerializedGuidRegex.Matches(text)) {
|
||||
if (seenGuids.Add(match.Groups[1].Value)) { yield return match.Groups[1].Value; }
|
||||
}
|
||||
}
|
||||
|
||||
private struct ShaderRecord {
|
||||
public string Guid;
|
||||
public string Path;
|
||||
|
||||
Reference in New Issue
Block a user