using System; using System.Collections.Generic; using System.Linq; using NugetForUnity.Configuration; using NugetForUnity.Models; using UnityEditor; using UnityEngine; namespace NugetForUnity.Ui { /// /// A viewer for all of the packages and their dependencies currently installed in the project. /// public class DependencyTreeViewer : EditorWindow { private readonly Dictionary expanded = new Dictionary(); /// /// The list of packages that depend on the specified package. /// private readonly List parentPackages = new List(); /// /// The titles of the tabs in the window. /// private readonly string[] tabTitles = { "Dependency Tree", "Who Depends on Me?" }; /// /// The currently selected tab in the window. /// private int currentTab; /// /// The array of currently installed package IDs. /// private string[] installedPackageIds; /// /// The list of currently installed packages. /// private List installedPackages; private List roots; private Vector2 scrollPosition; private int selectedPackageIndex = -1; /// /// Opens the NuGet Package Manager Window. /// [MenuItem("NuGet/Show Dependency Tree", false, 5)] protected static void DisplayDependencyTree() { GetWindow(); } /// /// Automatically called by Unity to draw the GUI. /// protected void OnGUI() { currentTab = GUILayout.Toolbar(currentTab, tabTitles); switch (currentTab) { case 0: scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); foreach (var package in roots) { DrawPackage(package); } EditorGUILayout.EndScrollView(); break; case 1: EditorStyles.label.fontStyle = FontStyle.Bold; EditorStyles.label.fontSize = 14; EditorGUILayout.LabelField("Select Dependency:", GUILayout.Height(20)); EditorStyles.label.fontStyle = FontStyle.Normal; EditorStyles.label.fontSize = 10; EditorGUI.indentLevel++; var newIndex = EditorGUILayout.Popup(selectedPackageIndex, installedPackageIds); EditorGUI.indentLevel--; if (newIndex != selectedPackageIndex) { selectedPackageIndex = newIndex; parentPackages.Clear(); var selectedPackage = installedPackages[selectedPackageIndex]; foreach (var package in installedPackages) { var frameworkDependencies = package.CurrentFrameworkDependencies; foreach (var dependency in frameworkDependencies) { if (dependency.Id == selectedPackage.Id) { parentPackages.Add(package); } } } } EditorGUILayout.Space(); EditorStyles.label.fontStyle = FontStyle.Bold; EditorStyles.label.fontSize = 14; EditorGUILayout.LabelField("Packages That Depend on Above:", GUILayout.Height(20)); EditorStyles.label.fontStyle = FontStyle.Normal; EditorStyles.label.fontSize = 10; scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition); EditorGUI.indentLevel++; if (parentPackages.Count <= 0) { EditorGUILayout.LabelField("NONE"); } else { foreach (var parent in parentPackages) { DrawPackage(parent); } } EditorGUI.indentLevel--; EditorGUILayout.EndScrollView(); break; } } /// /// Called when enabling the window. /// private void OnEnable() { try { // reload the NuGet.config file, in case it was changed after Unity opened, but before the manager window opened (now) ConfigurationManager.LoadNugetConfigFile(); // set the window title titleContent = new GUIContent("Dependencies"); EditorUtility.DisplayProgressBar("Building Dependency Tree", "Reading installed packages...", 0.5f); InstalledPackagesManager.UpdateInstalledPackages(); installedPackages = InstalledPackagesManager.InstalledPackages.ToList(); var installedPackageNames = new List(); foreach (var package in installedPackages) { if (!expanded.ContainsKey(package)) { expanded.Add(package, false); } installedPackageNames.Add(package.Id); } installedPackageIds = installedPackageNames.ToArray(); BuildTree(); } catch (Exception e) { Debug.LogErrorFormat("{0}", e); } finally { EditorUtility.ClearProgressBar(); } } private void BuildTree() { roots = InstalledPackagesManager.GetInstalledRootPackages(); } private void DrawDependency(INugetPackageIdentifier dependency) { var fullDependency = installedPackages.Find(p => p.Id == dependency.Id); if (fullDependency != null) { DrawPackage(fullDependency); } else if (!InstalledPackagesManager.IsInstalled(dependency, true)) { Debug.LogErrorFormat("{0} {1} is not installed!", dependency.Id, dependency.Version); } } private void DrawPackage(INugetPackage package) { if (package.Dependencies.Count > 0) { expanded[package] = EditorGUILayout.Foldout(expanded[package], $"{package.Id} {package.Version}"); if (expanded[package]) { EditorGUI.indentLevel++; var frameworkDependencies = package.CurrentFrameworkDependencies; foreach (var dependency in frameworkDependencies) { DrawDependency(dependency); } EditorGUI.indentLevel--; } } else { EditorGUILayout.LabelField($"{package.Id} {package.Version}"); } } } }