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,237 @@
using AssetStoreTools.Validator.Data;
using AssetStoreTools.Validator.TestDefinitions;
using System;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEditor.UIElements;
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Validator.UIElements
{
internal class AutomatedTestElement : VisualElement
{
private const string IconsPath = "Packages/com.unity.asset-store-tools/Editor/Validator/Icons";
private readonly AutomatedTest _test;
private TestResult.ResultStatus _lastStatus;
private VisualElement _expandedBox;
private VisualElement _resultMessagesBox;
private Label _expanderLabel;
private Button _foldoutBox;
private Image _testImage;
private bool _expanded;
public AutomatedTestElement(AutomatedTest test)
{
_test = test;
ConstructAutomatedTest();
var sceneChangeHandler = new EditorSceneManager.SceneOpenedCallback((_, __) => ResultChanged());
EditorSceneManager.sceneOpened += sceneChangeHandler;
AssetStoreValidator.OnWindowDestroyed += () => EditorSceneManager.sceneOpened -= sceneChangeHandler;
}
public AutomatedTest GetAutomatedTest()
{
return _test;
}
public TestResult.ResultStatus GetLastStatus()
{
return _lastStatus;
}
public void ResultChanged()
{
ClearMessages();
_testImage.image = GetIconByStatus();
_lastStatus = _test.Result.Result;
if (_test.Result.MessageCount == 0)
return;
ShowMessages();
}
private void ClearMessages()
{
_resultMessagesBox?.Clear();
}
private void ShowMessages()
{
var result = _test.Result;
_resultMessagesBox?.RemoveFromHierarchy();
_resultMessagesBox = new VisualElement();
_resultMessagesBox.AddToClassList("result-messages-box");
switch (result.Result)
{
case TestResult.ResultStatus.Pass:
_resultMessagesBox.AddToClassList("result-messages-box-pass");
break;
case TestResult.ResultStatus.Warning:
_resultMessagesBox.AddToClassList("result-messages-box-warning");
break;
case TestResult.ResultStatus.Fail:
_resultMessagesBox.AddToClassList("result-messages-box-fail");
break;
}
_expandedBox.Add(_resultMessagesBox);
for (int i = 0; i < result.MessageCount; i++)
{
var resultText = result.GetMessage(i).GetText();
var clickAction = result.GetMessage(i).ClickAction;
var messageObjects = result.GetMessage(i).GetMessageObjects();
var resultMessage = new VisualElement {name = "ResultMessageElement"};
resultMessage.AddToClassList("information-box");
var informationButton = new Button();
informationButton.AddToClassList("result-information-button");
if (result.GetMessage(i).ClickAction != null)
{
informationButton.tooltip = clickAction.ActionTooltip;
informationButton.clicked += clickAction.Execute;
informationButton.SetEnabled(true);
}
var informationDescription = new Label {name = "InfoDesc", text = resultText};
informationDescription.AddToClassList("test-reason-desc");
informationButton.Add(informationDescription);
resultMessage.Add(informationButton);
foreach (var obj in messageObjects)
{
if (obj == null)
continue;
var objectField = new ObjectField() {objectType = obj.GetType(), value = obj};
objectField.RegisterCallback<ChangeEvent<UnityEngine.Object>>((evt) =>
objectField.SetValueWithoutNotify(evt.previousValue));
resultMessage.Add(objectField);
}
_resultMessagesBox.Add(resultMessage);
if (i == result.MessageCount - 1)
continue;
var separator = new VisualElement() {name = "Separator"};
separator.AddToClassList("message-separator");
_resultMessagesBox.Add(separator);
}
}
private void ShowFunctions(bool? show=null)
{
if (show == null)
_expanded = !_expanded;
else
_expanded = (bool) show;
if (_expanded)
_foldoutBox.AddToClassList("foldout-box-expanded");
else
_foldoutBox.RemoveFromClassList("foldout-box-expanded");
_expanderLabel.text = !_expanded ? "►" : "▼";
_expandedBox.style.display = _expanded ? DisplayStyle.Flex : DisplayStyle.None;
}
private void ConstructAutomatedTest()
{
name = "TestRow";
AddToClassList("full-test-box");
_foldoutBox = new Button (() => {ShowFunctions();}) {name = _test.Title};
_foldoutBox.AddToClassList("foldout-box");
// Expander and Asset Label
VisualElement labelExpanderRow = new VisualElement { name = "labelExpanderRow" };
labelExpanderRow.AddToClassList("expander-label-row");
_expanderLabel = new Label { name = "ExpanderLabel", text = "►" };
_expanderLabel.AddToClassList("expander");
Label testLabel = new Label { name = "TestLabel", text = _test.Title };
testLabel.AddToClassList("test-label");
labelExpanderRow.Add(_expanderLabel);
labelExpanderRow.Add(testLabel);
_testImage = new Image
{
name = "TestImage",
image = GetIconByStatus()
};
_testImage.AddToClassList("test-result-image");
_foldoutBox.Add(labelExpanderRow);
_foldoutBox.Add(_testImage);
var testCaseDescription = new TextField
{
name = "Description",
value = _test.Description,
isReadOnly = true,
multiline = true,
focusable = false,
doubleClickSelectsWord = false,
tripleClickSelectsLine = false
};
testCaseDescription.AddToClassList("test-description");
#if UNITY_2022_1_OR_NEWER
testCaseDescription.focusable = true;
testCaseDescription.selectAllOnFocus = false;
testCaseDescription.selectAllOnMouseUp = false;
#endif
_expandedBox = new VisualElement();
_expandedBox.AddToClassList("test-expanded-box");
_expandedBox.Add(testCaseDescription);
Add(_foldoutBox);
Add(_expandedBox);
ShowFunctions(false);
ResultChanged();
}
private Texture GetIconByStatus()
{
var iconTheme = "";
if (!EditorGUIUtility.isProSkin)
iconTheme = "_d";
switch (_test.Result.Result)
{
case TestResult.ResultStatus.Pass:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/success{iconTheme}.png");
case TestResult.ResultStatus.Warning:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/warning{iconTheme}.png");
case TestResult.ResultStatus.Fail:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/error{iconTheme}.png");
case TestResult.ResultStatus.Undefined:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/undefined{iconTheme}.png");
default:
return null;
}
}
}
}

View File

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

View File

@@ -0,0 +1,251 @@
using AssetStoreTools.Validator.Categories;
using AssetStoreTools.Validator.Data;
using AssetStoreTools.Validator.TestDefinitions;
using AssetStoreTools.Validator.Utility;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
namespace AssetStoreTools.Validator.UIElements
{
internal class AutomatedTestsGroup : VisualElement
{
private readonly Dictionary<int, AutomatedTestElement> _testElements = new Dictionary<int, AutomatedTestElement>();
private readonly Dictionary<TestResult.ResultStatus, AutomatedTestsGroupElement> _testGroupElements =
new Dictionary<TestResult.ResultStatus, AutomatedTestsGroupElement>();
private ScrollView _allTestsScrollView;
private ValidationInfoElement _validationInfoBox;
private PathBoxElement _pathBox;
private Button _validateButton;
private ToolbarMenu _categoryMenu;
private static readonly TestResult.ResultStatus[] StatusOrder = {TestResult.ResultStatus.Undefined,
TestResult.ResultStatus.Fail, TestResult.ResultStatus.Warning, TestResult.ResultStatus.Pass,
TestResult.ResultStatus.VariableSeverityIssue}; // VariableSeverityFail should always be convered to Warning/Fail, but is defined as a failsafe
private PackageValidator _validator;
private string _selectedCategory;
public AutomatedTestsGroup()
{
_validator = PackageValidator.Instance;
ConstructInfoPart();
ConstructAutomatedTests();
ValidationState.Instance.OnJsonSave -= Reinitialize;
ValidationState.Instance.OnJsonSave += Reinitialize;
}
private void Reinitialize()
{
this.Clear();
_testElements.Clear();
_testGroupElements.Clear();
ConstructInfoPart();
ConstructAutomatedTests();
}
private void ConstructInfoPart()
{
_validationInfoBox = new ValidationInfoElement();
_pathBox = new PathBoxElement();
var categorySelectionBox = new VisualElement();
categorySelectionBox.AddToClassList("selection-box-row");
VisualElement labelHelpRow = new VisualElement();
labelHelpRow.AddToClassList("label-help-row");
Label categoryLabel = new Label { text = "Category" };
Image categoryLabelTooltip = new Image
{
tooltip = "Choose a base category of your package" +
"\n\nThis can be found in the Publishing Portal when creating the package listing or just " +
"selecting a planned one." +
"\n\nNote: Different categories could have different severities of several test cases."
};
labelHelpRow.Add(categoryLabel);
labelHelpRow.Add(categoryLabelTooltip);
_categoryMenu = new ToolbarMenu {name = "CategoryMenu"};
_categoryMenu.AddToClassList("category-menu");
PopulateCategoryDropdown();
categorySelectionBox.Add(labelHelpRow);
categorySelectionBox.Add(_categoryMenu);
_validateButton = new Button(RunAllTests) {text = "Validate"};
_validateButton.AddToClassList("run-all-button");
_validationInfoBox.Add(categorySelectionBox);
_validationInfoBox.Add(_pathBox);
_validationInfoBox.Add(_validateButton);
Add(_validationInfoBox);
}
private void ConstructAutomatedTests()
{
name = "AutomatedTests";
_allTestsScrollView = new ScrollView
{
viewDataKey = "scrollViewKey",
};
_allTestsScrollView.AddToClassList("tests-scroll-view");
var groupedTests = GroupTestsByStatus(_validator.AutomatedTests);
foreach (var status in StatusOrder)
{
var group = new AutomatedTestsGroupElement(status.ToString(), status, true);
_testGroupElements.Add(status, group);
_allTestsScrollView.Add(group);
if (!groupedTests.ContainsKey(status))
continue;
foreach (var test in groupedTests[status])
{
var testElement = new AutomatedTestElement(test);
_testElements.Add(test.Id, testElement);
group.AddTest(testElement);
}
if (StatusOrder[StatusOrder.Length - 1] != status)
group.AddSeparator();
}
Add(_allTestsScrollView);
}
private void PopulateCategoryDropdown()
{
var list = _categoryMenu.menu;
var validationStateData = ValidationState.Instance.ValidationStateData;
HashSet<string> categories = new HashSet<string>();
var testData = ValidatorUtility.GetAutomatedTestCases();
foreach (var test in testData)
{
AddCategoriesToSet(categories, test.CategoryInfo);
}
foreach (var category in categories.OrderBy(x => x))
{
list.AppendAction(ConvertSlashToUnicodeSlash(category), _ => OnCategoryValueChange(category));
}
list.AppendAction("Other", _ => OnCategoryValueChange(string.Empty));
_selectedCategory = _validator.Category;
if (validationStateData.SerializedKeys == null)
_categoryMenu.text = "Select Category";
else if (string.IsNullOrEmpty(_selectedCategory))
_categoryMenu.text = "Other";
else
_categoryMenu.text = _validator.Category;
}
private string ConvertSlashToUnicodeSlash(string text)
{
return text.Replace('/', '\u2215');
}
private void AddCategoriesToSet(HashSet<string> set, ValidatorCategory category)
{
if (category == null)
return;
foreach (var filter in category.Filter)
set.Add(filter);
}
private Dictionary<TestResult.ResultStatus, List<AutomatedTest>> GroupTestsByStatus(List<AutomatedTest> tests)
{
var groupedDictionary = new Dictionary<TestResult.ResultStatus, List<AutomatedTest>>();
foreach (var t in tests)
{
if (!groupedDictionary.ContainsKey(t.Result.Result))
groupedDictionary.Add(t.Result.Result, new List<AutomatedTest>());
groupedDictionary[t.Result.Result].Add(t);
}
return groupedDictionary;
}
private async void RunAllTests()
{
var validationPaths = _pathBox.GetValidationPaths();
if (validationPaths.Count == 0)
return;
_validateButton.SetEnabled(false);
// Make sure everything is collected and validation button is disabled
await Task.Delay(100);
var validationSettings = new ValidationSettings()
{
ValidationPaths = validationPaths,
Category = _selectedCategory
};
var validationResult = _validator.RunAllTests(validationSettings);
if(validationResult.Status != ValidationStatus.RanToCompletion)
{
EditorUtility.DisplayDialog("Validation failed", $"Package validation failed: {validationResult.Error}", "OK");
return;
}
// Update UI
foreach(var test in validationResult.AutomatedTests)
{
var testElement = _testElements[test.Id];
var currentStatus = test.Result.Result;
var lastStatus = testElement.GetLastStatus();
if (_testGroupElements.ContainsKey(lastStatus) && _testGroupElements.ContainsKey(currentStatus))
{
if (lastStatus != currentStatus)
{
_testGroupElements[lastStatus].RemoveTest(testElement);
_testGroupElements[currentStatus].AddTest(testElement);
testElement.GetAutomatedTest().Result = test.Result;
}
}
testElement.ResultChanged();
}
_validateButton.SetEnabled(true);
}
private void OnCategoryValueChange(string value)
{
if (string.IsNullOrEmpty(value))
{
_categoryMenu.text = "Other";
_selectedCategory = value;
}
else
{
_categoryMenu.text = value;
_selectedCategory = value;
}
}
}
}

View File

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

View File

@@ -0,0 +1,143 @@
using AssetStoreTools.Validator.Data;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Validator.UIElements
{
internal class AutomatedTestsGroupElement : VisualElement
{
private const string IconsPath = "Packages/com.unity.asset-store-tools/Editor/Validator/Icons";
private string GroupName { get; }
private TestResult.ResultStatus GroupStatus { get; }
private readonly List<AutomatedTestElement> _tests;
private Button _groupExpanderBox;
private Image _groupImage;
private VisualElement _groupContent;
private Label _expanderLabel;
private Label _groupLabel;
private bool _expanded;
public AutomatedTestsGroupElement(string groupName, TestResult.ResultStatus groupStatus, bool createExpanded)
{
GroupName = groupName;
GroupStatus = groupStatus;
AddToClassList("tests-group");
_tests = new List<AutomatedTestElement>();
_expanded = createExpanded;
SetupSingleGroupElement();
HandleExpanding();
}
public void AddTest(AutomatedTestElement test)
{
_tests.Add(test);
_groupContent.Add(test);
UpdateGroupLabel();
ShowGroup();
}
public void RemoveTest(AutomatedTestElement test)
{
if (_tests.Contains(test))
_tests.Remove(test);
if (_groupContent.Contains(test))
_groupContent.Remove(test);
ShowGroup();
}
public void AddSeparator()
{
var groupSeparator = new VisualElement {name = "GroupSeparator"};
groupSeparator.AddToClassList("group-separator");
_groupContent.Add(groupSeparator);
}
private void ShowGroup()
{
style.display = _tests.Count > 0 ? DisplayStyle.Flex : DisplayStyle.None;
}
private void SetupSingleGroupElement()
{
_groupExpanderBox = new Button();
_groupExpanderBox.AddToClassList("group-expander-box");
_expanderLabel = new Label { name = "ExpanderLabel", text = "►" };
_expanderLabel.AddToClassList("expander");
_groupImage = new Image
{
name = "TestImage",
image = GetIconByStatus()
};
_groupImage.AddToClassList("group-image");
_groupLabel = new Label {text = $"{GroupName} ({_tests.Count})"};
_groupLabel.AddToClassList("group-label");
_groupExpanderBox.Add(_expanderLabel);
_groupExpanderBox.Add(_groupImage);
_groupExpanderBox.Add(_groupLabel);
_groupContent = new VisualElement {name = "GroupContentBox"};
_groupContent.AddToClassList("group-content-box");
_groupExpanderBox.clicked += () =>
{
_expanded = !_expanded;
HandleExpanding();
};
Add(_groupExpanderBox);
Add(_groupContent);
}
private void HandleExpanding()
{
var expanded = _expanded;
_expanderLabel.text = !expanded ? "►" : "▼";
var displayStyle = expanded ? DisplayStyle.Flex : DisplayStyle.None;
_groupContent.style.display = displayStyle;
}
private void UpdateGroupLabel()
{
_groupLabel.text = $"{GroupName} ({_tests.Count})";
}
private Texture GetIconByStatus()
{
var iconTheme = "";
if (!EditorGUIUtility.isProSkin)
iconTheme = "_d";
switch (GroupStatus)
{
case TestResult.ResultStatus.Pass:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/success{iconTheme}.png");
case TestResult.ResultStatus.Warning:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/warning{iconTheme}.png");
case TestResult.ResultStatus.Fail:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/error{iconTheme}.png");
case TestResult.ResultStatus.Undefined:
return (Texture) EditorGUIUtility.Load($"{IconsPath}/undefined{iconTheme}.png");
default:
return null;
}
}
}
}

View File

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

View File

@@ -0,0 +1,248 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AssetStoreTools.Utility;
using AssetStoreTools.Validator.Data;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Validator.UIElements
{
internal class PathBoxElement : VisualElement
{
private VisualElement _pathSelectionColumn;
private List<Label> _validationPaths;
private ScrollView _pathBoxScrollView;
public PathBoxElement()
{
ConstructPathBox();
}
public List<string> GetValidationPaths()
{
return FilterValidationPaths();
}
private List<string> FilterValidationPaths()
{
var filteredPaths = new List<string>();
foreach(var textField in _validationPaths)
{
var path = textField.text;
// Exclude empty paths
if (string.IsNullOrEmpty(path))
continue;
// Exclude hidden paths
if(path.Split('/').Any(x => x.EndsWith("~")))
{
Debug.LogWarning($"Path '{path}' cannot be validated as it is a hidden folder and not part of the Asset Database");
continue;
}
// Exclude paths that were serialized during previous validations, but no longer exist
if(!Directory.Exists(path))
{
Debug.LogWarning($"Path '{path}' cannot be validated because it no longer exists");
continue;
}
// Prevent redundancy for new paths
if (filteredPaths.Any(x => path.StartsWith(x + "/")))
continue;
// Prevent redundancy for already added paths
var redundantPaths = filteredPaths.Where(x => x.StartsWith(path + "/")).ToArray();
foreach (var redundantPath in redundantPaths)
filteredPaths.Remove(redundantPath);
filteredPaths.Add(path);
}
return filteredPaths;
}
private void ConstructPathBox()
{
AddToClassList("path-box");
_pathSelectionColumn = new VisualElement();
_pathSelectionColumn.AddToClassList("selection-box-column");
var pathSelectionRow = new VisualElement();
pathSelectionRow.AddToClassList("selection-box-row");
VisualElement labelHelpRow = new VisualElement();
labelHelpRow.AddToClassList("label-help-row");
labelHelpRow.style.alignSelf = Align.FlexStart;
Label pathLabel = new Label { text = "Validation paths" };
Image pathLabelTooltip = new Image
{
tooltip = "Select the folder (or multiple folders) that your package consists of." +
"\n\nAll files and folders of your package should be contained within " +
"a single root folder that is named after your package " +
"(e.g. 'Assets/[MyPackageName]' or 'Packages/[MyPackageName]')" +
"\n\nIf your package includes special folders that cannot be nested within " +
"the root package folder (e.g. 'WebGLTemplates'), they should be added to this list " +
"together with the root package folder"
};
labelHelpRow.Add(pathLabel);
labelHelpRow.Add(pathLabelTooltip);
_validationPaths = new List<Label>();
var serializedValidationState = ValidationState.Instance.ValidationStateData;
var fullPathBox = new VisualElement() { name = "ValidationPaths" };
fullPathBox.AddToClassList("validation-paths-box");
_pathBoxScrollView = new ScrollView { name = "ValidationPathsScrollView" };
_pathBoxScrollView.AddToClassList("validation-paths-scroll-view");
VisualElement scrollViewBottomRow = new VisualElement();
scrollViewBottomRow.AddToClassList("validation-paths-scroll-view-bottom-row");
var addExtraPathsButton = new Button(Browse) { text = "Add a path" };
addExtraPathsButton.AddToClassList("validation-path-add-button");
scrollViewBottomRow.Add(addExtraPathsButton);
fullPathBox.Add(_pathBoxScrollView);
fullPathBox.Add(scrollViewBottomRow);
pathSelectionRow.Add(labelHelpRow);
pathSelectionRow.Add(fullPathBox);
_pathSelectionColumn.Add(pathSelectionRow);
foreach (var serializedPath in serializedValidationState.SerializedValidationPaths)
AddPathToList(serializedPath);
Add(_pathSelectionColumn);
}
private void AddPathToList(string path)
{
var validationPath = new VisualElement();
validationPath.AddToClassList("validation-path-row");
var folderPathLabel = new Label(path);
folderPathLabel.AddToClassList("path-input-field");
_validationPaths.Add(folderPathLabel);
var removeButton = new Button(() =>
{
_pathBoxScrollView.Remove(validationPath);
_validationPaths.Remove(folderPathLabel);
});
removeButton.text = "X";
removeButton.AddToClassList("validation-path-remove-button");
validationPath.Add(folderPathLabel);
validationPath.Add(removeButton);
_pathBoxScrollView.Add(validationPath);
}
private void Browse()
{
string result = EditorUtility.OpenFolderPanel("Select a directory", "Assets", "");
if (result == string.Empty)
return;
if (ValidateFolderPath(ref result) && !_validationPaths.Any(x => x.text == result))
AddPathToList(result);
else
return;
}
private bool ValidateFolderPath(ref string resultPath)
{
var folderPath = resultPath;
var pathWithinProject = Application.dataPath.Substring(0, Application.dataPath.Length - "Assets".Length);
// Selected path is within the project
if (folderPath.StartsWith(pathWithinProject))
{
var localPath = folderPath.Substring(pathWithinProject.Length);
if (localPath.StartsWith("Assets/") || localPath == "Assets")
{
resultPath = localPath;
return true;
}
if (IsValidLocalPackage(localPath, out var adbPath))
{
resultPath = adbPath;
return true;
}
DisplayMessage("Folder not found", "Selection must be within Assets folder or a local package.");
return false;
}
bool validLocalPackage = IsValidLocalPackage(folderPath, out var relativePackagePath);
bool isSymlinkedPath = false;
string relativeSymlinkPath = string.Empty;
if (ASToolsPreferences.Instance.EnableSymlinkSupport)
isSymlinkedPath = SymlinkUtil.FindSymlinkFolderRelative(folderPath, out relativeSymlinkPath);
// Selected path is not within the project, but could be a local package or symlinked folder
if (!validLocalPackage && !isSymlinkedPath)
{
DisplayMessage("Folder not found", "Selection must be within Assets folder or a local package.");
return false;
}
resultPath = validLocalPackage ? relativePackagePath : relativeSymlinkPath;
return true;
}
private bool IsValidLocalPackage(string packageFolderPath, out string assetDatabasePackagePath)
{
assetDatabasePackagePath = string.Empty;
string packageManifestPath = $"{packageFolderPath}/package.json";
if (!File.Exists(packageManifestPath))
return false;
try
{
var localPackages = PackageUtility.GetAllLocalPackages();
if (localPackages == null || localPackages.Length == 0)
return false;
foreach (var package in localPackages)
{
var localPackagePath = package.GetConvenientPath();
if (localPackagePath != packageFolderPath)
continue;
assetDatabasePackagePath = package.assetPath;
return true;
}
}
catch
{
return false;
}
return false;
}
private void DisplayMessage(string title, string message)
{
if (EditorUtility.DisplayDialog(title, message, "Okay", "Cancel"))
Browse();
}
}
}

View File

@@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f856d841ca50d7842b2850015d8b1f62
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/UI Elements/PathBoxElement.cs
uploadId: 681981

View File

@@ -0,0 +1,58 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace AssetStoreTools.Validator.UIElements
{
internal class ValidationInfoElement : VisualElement
{
private const string GuidelinesUrl = "https://assetstore.unity.com/publishing/submission-guidelines#Overview";
private const string SupportUrl = "https://support.unity.com/hc/en-us/requests/new?ticket_form_id=65905";
public ValidationInfoElement()
{
ConstructInformationElement();
}
private void ConstructInformationElement()
{
AddToClassList("validation-info-box");
var validatorDescription = new Label
{
text = "Validate your package to ensure your content follows the chosen submission guidelines. " +
"The validations below do not cover all of the content standards, and passing all validations does not " +
"guarantee that your package will be accepted to the Asset Store.\n\n" +
"The tests are not obligatory for submitting your assets, but they can help avoid instant rejection by the " +
"automated vetting system, or clarify reasons of rejection communicated by the vetting team.\n\n" +
"For more information about the validations, view the message by expanding the tests or contact our support team."
};
validatorDescription.AddToClassList("validator-description");
var submissionGuidelinesButton = new Button(() => OpenURL(GuidelinesUrl))
{
name = "GuidelinesButton",
text = "Submission guidelines"
};
submissionGuidelinesButton.AddToClassList("hyperlink-button");
var supportTicketButton = new Button(() => OpenURL(SupportUrl))
{
name = "SupportTicket",
text = "Contact our support team"
};
supportTicketButton.AddToClassList("hyperlink-button");
Add(validatorDescription);
Add(submissionGuidelinesButton);
Add(supportTicketButton);
}
private void OpenURL(string url)
{
Application.OpenURL(url);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 9866d77420d947ba852055eed2bac895
timeCreated: 1653383883
AssetOrigin:
serializedVersion: 1
productId: 115
packageName: Asset Store Publishing Tools
packageVersion: 11.4.3
assetPath: Packages/com.unity.asset-store-tools/Editor/Validator/Scripts/UI Elements/ValidationInfoElement.cs
uploadId: 681981