first commit

This commit is contained in:
Kirill Chikalin
2024-11-16 13:20:07 +03:00
commit a3072a3693
538 changed files with 108153 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
using UnityEditor;
using UnityEngine;
namespace AssetStoreTools.Validator.Data
{
internal interface IMessageAction
{
string ActionTooltip { get; }
void Execute();
}
internal enum ClickActionType
{
None = 0,
HighlightObject = 1,
OpenAsset = 2
}
internal class MessageActionHighlight : IMessageAction
{
private Object _objectToHighlight;
public GlobalObjectId GlobalObjectIdentifier { get; set; }
public string ActionTooltip => "Click to highlight the associated object in Hierarchy/Project view";
public MessageActionHighlight(Object objectToHighlight)
{
this._objectToHighlight = objectToHighlight;
GlobalObjectIdentifier = GlobalObjectId.GetGlobalObjectIdSlow(objectToHighlight);
}
public MessageActionHighlight(string globalObjectId)
{
GlobalObjectId.TryParse(globalObjectId, out GlobalObjectId globalObjectIdentifier);
GlobalObjectIdentifier = globalObjectIdentifier;
}
public void Execute()
{
if(_objectToHighlight == null)
_objectToHighlight = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(GlobalObjectIdentifier);
EditorGUIUtility.PingObject(_objectToHighlight);
}
}
internal class MessageActionOpenAsset : IMessageAction
{
private Object _objectToOpen;
public int LineNumber { get; set; }
public GlobalObjectId GlobalObjectIdentifier { get; set; }
public string ActionTooltip => "Click to open the associated asset";
public MessageActionOpenAsset(Object objectToOpen)
{
this._objectToOpen = objectToOpen;
GlobalObjectIdentifier = GlobalObjectId.GetGlobalObjectIdSlow(objectToOpen);
}
public MessageActionOpenAsset(string globalObjectId)
{
GlobalObjectId.TryParse(globalObjectId, out GlobalObjectId globalObjectIdentifier);
GlobalObjectIdentifier = globalObjectIdentifier;
}
public void Execute()
{
if (_objectToOpen == null)
_objectToOpen = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(GlobalObjectIdentifier);
AssetDatabase.OpenAsset(_objectToOpen, LineNumber);
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c6c8b1f23bf5c8841be44b13374e7baf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Data/MessageActions.cs
uploadId: 681981

View File

@@ -0,0 +1,173 @@
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEditor;
using Object = UnityEngine.Object;
namespace AssetStoreTools.Validator.Data
{
[Serializable]
internal struct TestResult
{
public ResultStatus Result;
[SerializeField, HideInInspector]
private List<TestResultMessage> Messages;
public int MessageCount => Messages?.Count ?? 0;
public void AddMessage(string msg)
{
AddMessage(msg, null, null);
}
public void AddMessage(string msg, IMessageAction clickAction)
{
AddMessage(msg, clickAction, null);
}
public void AddMessage(string msg, IMessageAction clickAction, params UnityEngine.Object[] messageObjects)
{
if (Messages == null)
Messages = new List<TestResultMessage>();
var message = new TestResultMessage(msg, clickAction);
AddMessageObjects(messageObjects, message);
Messages.Add(message);
}
private void AddMessageObjects(Object[] messageObjects, TestResultMessage message)
{
if (messageObjects == null)
return;
foreach (var obj in messageObjects)
{
#if AB_BUILDER
string path = AssetDatabase.GetAssetPath(obj);
message.AppendText($"\nAsset at: {path}");
#else
message.AddMessageObject(obj);
#endif
}
}
public TestResultMessage GetMessage(int index)
{
if (Messages == null || index >= Messages.Count)
throw new InvalidOperationException();
return Messages[index];
}
public enum ResultStatus
{
Undefined = 0,
Pass = 1,
Fail = 2,
Warning = 3,
VariableSeverityIssue = 4
}
[Serializable]
internal class TestResultMessage : ISerializationCallbackReceiver
{
[SerializeField, HideInInspector]
private string Text;
[SerializeField, HideInInspector]
private List<string> MessageObjects;
// Serialization
[SerializeField, HideInInspector]
private string SerializedClickAction;
private IMessageAction _clickAction;
public IMessageAction ClickAction => _clickAction;
public TestResultMessage() { }
public TestResultMessage(string text)
{
Text = text;
}
public TestResultMessage(string text, IMessageAction clickAction) : this(text)
{
_clickAction = clickAction;
}
public void AddMessageObject(Object obj)
{
if (MessageObjects == null)
MessageObjects = new List<string>();
var globalObjectId = GlobalObjectId.GetGlobalObjectIdSlow(obj).ToString();
if (globalObjectId != "GlobalObjectId_V1-0-00000000000000000000000000000000-0-0")
MessageObjects.Add(GlobalObjectId.GetGlobalObjectIdSlow(obj).ToString());
else
Text += $"\n{obj.name}";
}
public Object[] GetMessageObjects()
{
if (MessageObjects == null)
return Array.Empty<Object>();
var objects = new Object[MessageObjects.Count];
for (int i = 0; i < objects.Length; i++)
{
GlobalObjectId.TryParse(MessageObjects[i], out GlobalObjectId id);
objects[i] = GlobalObjectId.GlobalObjectIdentifierToObjectSlow(id);
}
return objects;
}
public void OnBeforeSerialize()
{
SerializedClickAction = ((int)ClickActionType.None).ToString();
switch (_clickAction)
{
case MessageActionHighlight action:
var objectId = action.GlobalObjectIdentifier.ToString();
SerializedClickAction = $"{(int)ClickActionType.HighlightObject}|{objectId}";
break;
case MessageActionOpenAsset action:
objectId = action.GlobalObjectIdentifier.ToString();
SerializedClickAction = $"{(int)ClickActionType.OpenAsset}|{objectId}|{action.LineNumber}";
break;
}
}
public void OnAfterDeserialize()
{
string[] splitAction = SerializedClickAction.Split('|');
bool parsed = Enum.TryParse(splitAction[0], out ClickActionType clickActionType);
if (!parsed) return;
switch (clickActionType)
{
case ClickActionType.HighlightObject:
_clickAction = new MessageActionHighlight(splitAction[1]);
break;
case ClickActionType.OpenAsset:
_clickAction = new MessageActionOpenAsset(splitAction[1])
{ LineNumber = Convert.ToInt32(splitAction[2]) };
break;
case ClickActionType.None:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
public void AppendText(string value)
{
Text += value;
}
public string GetText()
{
return Text;
}
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 05d7d92bbda6bf44f8ed5fbd0cde57e6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Data/TestResult.cs
uploadId: 681981

View File

@@ -0,0 +1,31 @@
using AssetStoreTools.Validator.TestDefinitions;
using System.Collections.Generic;
namespace AssetStoreTools.Validator.Data
{
internal enum ValidationStatus
{
NotRun,
RanToCompletion,
Failed,
Cancelled
}
internal class ValidationResult
{
public ValidationStatus Status;
public List<AutomatedTest> AutomatedTests;
public bool HadCompilationErrors;
public string ProjectPath;
public string Error;
public ValidationResult()
{
Status = ValidationStatus.NotRun;
AutomatedTests = new List<AutomatedTest>();
HadCompilationErrors = false;
ProjectPath = string.Empty;
Error = string.Empty;
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b15525b8dcf3e654ca2f895472ab7cb1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Data/ValidationResult.cs
uploadId: 681981

View File

@@ -0,0 +1,10 @@
using System.Collections.Generic;
namespace AssetStoreTools.Validator.Data
{
internal class ValidationSettings
{
public List<string> ValidationPaths;
public string Category;
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: dd3bbba60e92d4843a393874a9de9a63
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Data/ValidationSettings.cs
uploadId: 681981

View File

@@ -0,0 +1,170 @@
using AssetStoreTools.Utility;
using AssetStoreTools.Utility.Json;
using AssetStoreTools.Validator.Utility;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;
namespace AssetStoreTools.Validator.Data
{
[Serializable]
internal class ValidationStateData
{
public List<string> SerializedValidationPaths;
public string SerializedCategory;
public List<int> SerializedKeys;
public List<TestResultData> SerializedValues;
public bool HasCompilationErrors;
}
[Serializable]
internal class TestResultData
{
public TestResult Result;
}
internal class ValidationState
{
public const string ValidationDataFilename = "AssetStoreValidationState.asset";
public const string PersistentDataLocation = "Library";
public Dictionary<int, TestResultData> TestResults = new Dictionary<int, TestResultData>();
public ValidationStateData ValidationStateData;
public Action OnJsonSave;
private static ValidationState s_instance;
public static ValidationState Instance
{
get
{
if (s_instance == null)
s_instance = new ValidationState();
s_instance.LoadJson();
return s_instance;
}
}
private void LoadJson()
{
if (s_instance.TestResults.Count != 0)
return;
var saveFile = $"{PersistentDataLocation}/{ValidationDataFilename}";
if (!File.Exists(saveFile))
{
s_instance.ValidationStateData = new ValidationStateData
{
SerializedValidationPaths = new List<string>() { "Assets" },
SerializedCategory = ""
};
return;
}
var fileContents = File.ReadAllText(saveFile);
var data = JsonUtility.FromJson<ValidationStateData>(fileContents);
if (data.SerializedValidationPaths.Count == 0)
data.SerializedValidationPaths.Add("Assets");
s_instance.ValidationStateData = data;
var implementedTests = ValidatorUtility.GetAutomatedTestCases();
for (var i = 0; i < s_instance.ValidationStateData.SerializedKeys.Count; i++)
{
// Skip any potential tests that were serialized, but are no longer implemented
if (!implementedTests.Any(x => x.Id == s_instance.ValidationStateData.SerializedKeys[i]))
continue;
s_instance.TestResults.Add(s_instance.ValidationStateData.SerializedKeys[i], s_instance.ValidationStateData.SerializedValues[i]);
}
}
public void SaveJson()
{
var saveFile = $"{PersistentDataLocation}/{ValidationDataFilename}";
if (TestResults.Keys.Count == 0)
return;
ValidationStateData.SerializedKeys = TestResults.Keys.ToList();
ValidationStateData.SerializedValues = TestResults.Values.ToList();
var jsonString = JsonUtility.ToJson(ValidationStateData);
File.WriteAllText(saveFile, jsonString);
OnJsonSave?.Invoke();
}
public static bool GetValidationSummaryJson(ValidationStateData data, out string validationSummaryJson)
{
validationSummaryJson = string.Empty;
try
{
var json = JsonValue.NewDict();
// Construct compilation state
json["has_compilation_errors"] = data.HasCompilationErrors;
// Construct validation paths
var pathsList = JsonValue.NewList();
foreach (var path in data.SerializedValidationPaths)
pathsList.Add(path);
json["validation_paths"] = pathsList;
// Construct validation results
var resultsDict = JsonValue.NewDict();
for (int i = 0; i < data.SerializedKeys.Count; i++)
{
var key = data.SerializedKeys[i].ToString();
var value = JsonValue.NewDict();
value["int"] = (int)data.SerializedValues[i].Result.Result;
value["string"] = data.SerializedValues[i].Result.Result.ToString();
resultsDict[key] = value;
}
json["validation_results"] = resultsDict;
validationSummaryJson = json.ToString();
return true;
}
catch (Exception e)
{
ASDebug.LogError($"Failed to parse a validation summary json:\n{e}");
return false;
}
}
public void CreateTestContainer(int testId)
{
s_instance.TestResults.Add(testId, new TestResultData());
}
public void ChangeResult(int index, TestResult result)
{
if (!s_instance.TestResults.ContainsKey(index))
CreateTestContainer(index);
s_instance.TestResults[index].Result = result;
}
public void SetCompilationState(bool hasCompilationErrors)
{
s_instance.ValidationStateData.HasCompilationErrors = hasCompilationErrors;
}
public void SetValidationPaths(string[] paths)
{
s_instance.ValidationStateData.SerializedValidationPaths = paths.ToList();
}
public void SetCategory(string category)
{
s_instance.ValidationStateData.SerializedCategory = category;
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: bbd993a57160414b93583792dbe5241e
timeCreated: 1653399871
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/Data/ValidationState.cs
uploadId: 681981