Ejemplo n.º 1
0
        private static NugetPackage GetInstalledPacakge(NugetPackage package)
        {
            IEnumerable <NugetPackage> installedPackages = NugetHelper.InstalledPackages;
            var installed = installedPackages.FirstOrDefault(p => p.Id == package.Id);

            return(installed);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads a list of all currently installed packages by reading the packages.config file.
        /// </summary>
        /// <returns>A newly created <see cref="PackagesConfigFile"/>.</returns>
        public static PackagesConfigFile Load(string filepath)
        {
            PackagesConfigFile configFile = new PackagesConfigFile();

            configFile.Packages = new List <NugetPackageIdentifier>();

            // Create a package.config file, if there isn't already one in the project
            if (!File.Exists(filepath))
            {
                Debug.LogFormat("No packages.config file found. Creating default at {0}", filepath);

                configFile.Save(filepath);

                AssetDatabase.Refresh();
            }

            XDocument packagesFile = XDocument.Load(filepath);

            foreach (var packageElement in packagesFile.Root.Elements())
            {
                NugetPackage package = new NugetPackage();
                package.Id      = packageElement.Attribute("id").Value;
                package.Version = packageElement.Attribute("version").Value;
                configFile.Packages.Add(package);
            }

            return(configFile);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets a list of all available packages from a local source (not a web server) that match the given filters.
        /// </summary>
        /// <param name="searchTerm">The search term to use to filter packages. Defaults to the empty string.</param>
        /// <param name="includeAllVersions">True to include older versions that are not the latest version.</param>
        /// <param name="includePrerelease">True to include prerelease packages (alpha, beta, etc).</param>
        /// <param name="numberToGet">The number of packages to fetch.</param>
        /// <param name="numberToSkip">The number of packages to skip before fetching.</param>
        /// <returns>The list of available packages.</returns>
        private List <NugetPackage> GetLocalPackages(string searchTerm = "", bool includeAllVersions = false, bool includePrerelease = false, int numberToGet = 15, int numberToSkip = 0)
        {
            List <NugetPackage> localPackages = new List <NugetPackage>();

            if (numberToSkip != 0)
            {
                // we return the entire list the first time, so no more to add
                return(localPackages);
            }

            string path = ExpandedPath;

            if (Directory.Exists(path))
            {
                string[] packagePaths = Directory.GetFiles(path, string.Format("*{0}*.nupkg", searchTerm));

                foreach (var packagePath in packagePaths)
                {
                    var package = NugetPackage.FromNupkgFile(packagePath);
                    package.PackageSource = this;

                    if (package.IsPrerelease && !includePrerelease)
                    {
                        // if it's a prerelease package and we aren't supposed to return prerelease packages, just skip it
                        continue;
                    }

                    if (includeAllVersions)
                    {
                        // if all versions are being included, simply add it and move on
                        localPackages.Add(package);
                        //LogVerbose("Adding {0} {1}", package.Id, package.Version);
                        continue;
                    }

                    var existingPackage = localPackages.FirstOrDefault(x => x.Id == package.Id);
                    if (existingPackage != null)
                    {
                        // there is already a package with the same ID in the list
                        if (existingPackage < package)
                        {
                            // if the current package is newer than the existing package, swap them
                            localPackages.Remove(existingPackage);
                            localPackages.Add(package);
                        }
                    }
                    else
                    {
                        // there is no package with the same ID in the list yet
                        localPackages.Add(package);
                    }
                }
            }
            else
            {
                Debug.LogErrorFormat("Local folder not found: {0}", path);
            }

            return(localPackages);
        }
        /// <summary>
        /// Gets a NugetPackage from the NuGet server that matches (or is in range of) the <see cref="NugetPackageIdentifier"/> given.
        /// </summary>
        /// <param name="package">The <see cref="NugetPackageIdentifier"/> containing the ID and Version of the package to get.</param>
        /// <returns>The retrieved package, if there is one.  Null if no matching package was found.</returns>
        public NugetPackage GetSpecificPackage(NugetPackageIdentifier package)
        {
            if (package.HasVersionRange)
            {
                return(FindPackagesById(package).FirstOrDefault());
            }

            if (IsLocalPath)
            {
                string localPackagePath = Path.Combine(ExpandedPath, string.Format("./{0}.{1}.nupkg", package.Id, package.Version));
                if (File.Exists(localPackagePath))
                {
                    NugetPackage localPackage = NugetPackage.FromNupkgFile(localPackagePath);
                    return(localPackage);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                string url = string.Format("{0}Packages(Id='{1}',Version='{2}')", ExpandedPath, package.Id, package.Version);
                try
                {
                    return(GetPackagesFromUrl(url, UserName, ExpandedPassword).First());
                }
                catch (Exception e)
                {
                    Debug.LogErrorFormat("Unable to retrieve package from {0}\n{1}", url, e.ToString());
                    return(null);
                }
            }
        }
Ejemplo n.º 5
0
 private void DrawProjectUrl(NugetPackage package)
 {
     if (!string.IsNullOrEmpty(package.ProjectUrl))
     {
         GUILayoutLink(package.ProjectUrl);
     }
 }
Ejemplo n.º 6
0
        private void DrawPackageNameAndIcon(NugetPackage package)
        {
            GUILayout.BeginHorizontal(GUILayout.ExpandHeight(false));
            GUILayout.Space(34);
            GUILayout.Label(string.Format("{1} [{0}]", package.Version, package.Title), EditorStyles.boldLabel, GUILayout.Height(24));
            GUILayout.EndHorizontal();

            var lastRect = GUILayoutUtility.GetLastRect();

            const int iconSize    = 24;
            const int leftPadding = 5;

            lastRect.x     += leftPadding;
            lastRect.y     += 3;
            lastRect.width  = iconSize;
            lastRect.height = iconSize;

            if (package.Icon != null)
            {
                GUI.DrawTexture(lastRect, package.Icon, ScaleMode.StretchToFill);
            }
            else
            {
                GUI.DrawTexture(lastRect, defaultIcon, ScaleMode.StretchToFill);
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Some NuGet feeds such as Visual Studio Team Services do not implement the GetUpdates function.
        /// In that case this fallback function can be used to retrieve updates by using the FindPackagesById function.
        /// </summary>
        /// <param name="installedPackages">The list of currently installed packages.</param>
        /// <param name="includePrerelease">True to include prerelease packages (alpha, beta, etc).</param>
        /// <param name="includeAllVersions">True to include older versions that are not the latest version.</param>
        /// <param name="targetFrameworks">The specific frameworks to target?</param>
        /// <param name="versionContraints">The version constraints?</param>
        /// <returns>A list of all updates available.</returns>
        private List <NugetPackage> GetUpdatesFallback(IEnumerable <NugetPackage> installedPackages, bool includePrerelease = false, bool includeAllVersions = false, string targetFrameworks = "", string versionContraints = "")
        {
            Debug.Assert(string.IsNullOrEmpty(targetFrameworks) && string.IsNullOrEmpty(versionContraints)); // These features are not supported by this version of GetUpdates.

            List <NugetPackage> updates = new List <NugetPackage>();

            foreach (NugetPackage installedPackage in installedPackages)
            {
                List <NugetPackage> packageUpdates = new List <NugetPackage>();
                string versionRange       = string.Format("({0},)", installedPackage.Version); // Minimum of Current ID (exclusive) with no maximum (exclusive).
                NugetPackageIdentifier id = new NugetPackageIdentifier(installedPackage.Id, versionRange);
                packageUpdates = FindPackagesById(id);

                NugetPackage mostRecentPrerelease = includePrerelease ? packageUpdates.FindLast(p => p.IsPrerelease) : default(NugetPackage);
                packageUpdates.RemoveAll(p => p.IsPrerelease && p != mostRecentPrerelease);

                if (!includeAllVersions && packageUpdates.Count > 0)
                {
                    packageUpdates.RemoveRange(0, packageUpdates.Count - 1);
                }

                updates.AddRange(packageUpdates);
            }

            return(updates);
        }
Ejemplo n.º 8
0
        private void DrawCloneButton(NugetPackage package)
        {
            if (package.RepositoryType == RepositoryType.Git || package.RepositoryType == RepositoryType.TfsGit)
            {
                if (!string.IsNullOrEmpty(package.RepositoryUrl))
                {
                    bool showCloneWindow = openCloneWindows.Contains(package);

                    if (GUILayout.Button("Clone", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
                    {
                        showCloneWindow = !showCloneWindow;

                        if (showCloneWindow)
                        {
                            openCloneWindows.Add(package);
                        }
                        else
                        {
                            openCloneWindows.Remove(package);
                        }
                    }

                    if (showCloneWindow)
                    {
                        DrawCloneWindow(package);
                    }
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Loads a list of all currently installed packages by reading the packages.config file.
        /// </summary>
        /// <returns>A newly created <see cref="PackagesConfigFile"/>.</returns>
        public static PackagesConfigFile Load(string filepath)
        {
            var configFile = new PackagesConfigFile {
                Packages = new List <NugetPackageIdentifier>()
            };

            // Create a package.config file, if there isn't already one in the project
            if (!File.Exists(filepath))
            {
                SystemProxy.Log($"No packages.config file found. Creating default at {filepath}");

                configFile.Save(filepath);

                SystemProxy.RefreshAssets();
            }

            var packagesFile = XDocument.Load(filepath);

            foreach (var packageElement in packagesFile.Root.Elements())
            {
                var package = new NugetPackage
                {
                    Id                  = packageElement.Attribute("id").Value,
                    Version             = packageElement.Attribute("version").Value,
                    IsManuallyInstalled = packageElement.Attribute("manual") != null
                };
                configFile.Packages.Add(package);
            }

            return(configFile);
        }
Ejemplo n.º 10
0
 public static void DownloadAndSetIcon(NugetPackage package, string url)
 {
     if (!NugetWindow.IsOpened)
     {
         return;
     }
     StartCoroutine(DownloadAndSetIconRoutine(package, url));
 }
Ejemplo n.º 11
0
        private void DrawCurrentInstalledVersion(NugetPackage package)
        {
            NugetPackage installed = GetInstalledPacakge(package);

            if (installed != null)
            {
                GUILayout.Label(string.Format("currently [{0}]  ", installed.Version), EditorStyles.miniLabel, installButtonWidth);
            }
        }
Ejemplo n.º 12
0
        private void DrawPackageDescription(NugetPackage package)
        {
            EditorStyles.miniBoldLabel.fontStyle = FontStyle.Bold;
            GUILayout.Label("Description:", EditorStyles.miniBoldLabel);

            GUILayout.BeginVertical(EditorStyles.helpBox);
            GUILayout.Label(string.Format("{0}", package.Description), GetDescriptionStyle());
            GUILayout.EndVertical();
        }
Ejemplo n.º 13
0
        public int CompareTo(NugetPackage other)
        {
            if (this.Id != other.Id)
            {
                return(string.Compare(this.Id, other.Id));
            }

            return(CompareVersions(this.Version, other.Version));
        }
Ejemplo n.º 14
0
 private static void DrawReleaseNotes(NugetPackage package)
 {
     if (!string.IsNullOrEmpty(package.ReleaseNotes))
     {
         GUILayout.Label(string.Format("Release Notes:"), EditorStyles.miniBoldLabel);
         GUILayout.BeginVertical(EditorStyles.helpBox);
         GUILayout.Label(string.Format("{0}", package.ReleaseNotes), EditorStyles.miniLabel);
         GUILayout.EndVertical();
     }
 }
Ejemplo n.º 15
0
 private static void DrawLicenseButton(NugetPackage package)
 {
     if (!string.IsNullOrEmpty(package.LicenseUrl) && package.LicenseUrl != "http://your_license_url_here")
     {
         // Show the license button
         if (GUILayout.Button("View License", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
         {
             Application.OpenURL(package.LicenseUrl);
         }
     }
 }
Ejemplo n.º 16
0
        private static void DrawCloneWindow(NugetPackage package)
        {
            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            {
                // Clone latest label
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(20f);
                EditorGUILayout.LabelField("clone latest");
                EditorGUILayout.EndHorizontal();

                // Clone latest row
                EditorGUILayout.BeginHorizontal();
                {
                    if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false)))
                    {
                        GUI.FocusControl(package.Id + package.Version + "repoUrl");
                        GUIUtility.systemCopyBuffer = package.RepositoryUrl;
                    }

                    GUI.SetNextControlName(package.Id + package.Version + "repoUrl");
                    EditorGUILayout.TextField(package.RepositoryUrl);
                }
                EditorGUILayout.EndHorizontal();

                // Clone @ commit label
                GUILayout.Space(4f);
                EditorGUILayout.BeginHorizontal();
                GUILayout.Space(20f);
                EditorGUILayout.LabelField("clone @ commit");
                EditorGUILayout.EndHorizontal();

                // Clone @ commit row
                EditorGUILayout.BeginHorizontal();
                {
                    // Create the three commands a user will need to run to get the repo @ the commit. Intentionally leave off the last newline for better UI appearance
                    string commands = string.Format("git clone {0} {1} --no-checkout{2}cd {1}{2}git checkout {3}", package.RepositoryUrl, package.Id, Environment.NewLine, package.RepositoryCommit);

                    if (GUILayout.Button("Copy", GUILayout.ExpandWidth(false)))
                    {
                        GUI.FocusControl(package.Id + package.Version + "commands");

                        // Add a newline so the last command will execute when pasted to the CL
                        GUIUtility.systemCopyBuffer = (commands + Environment.NewLine);
                    }

                    EditorGUILayout.BeginVertical();
                    GUI.SetNextControlName(package.Id + package.Version + "commands");
                    EditorGUILayout.TextArea(commands);
                    EditorGUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndVertical();
        }
Ejemplo n.º 17
0
        private void DrawInstallUninstallPackageButtons(NugetPackage package)
        {
            IEnumerable <NugetPackage> installedPackages = NugetHelper.InstalledPackages;
            var installed = installedPackages.FirstOrDefault(p => p.Id == package.Id);

            if (installedPackages.Contains(package))
            {
                // This specific version is installed
                if (GUILayout.Button("Uninstall", EditorStyles.toolbarButton, installButtonWidth, installButtonHeight))
                {
                    // TODO: Perhaps use a "mark as dirty" system instead of updating all of the data all the time?
                    NugetHelper.Uninstall(package);
                    NugetHelper.UpdateInstalledPackages();
                    UpdateUpdatePackages();
                }
            }
            else
            {
                if (installed != null)
                {
                    if (installed < package)
                    {
                        // An older version is installed
                        if (GUILayout.Button(string.Format("Update to [{0}]", package.Version), EditorStyles.toolbarButton, installButtonWidth, installButtonHeight))
                        {
                            NugetHelper.Update(installed, package);
                            NugetHelper.UpdateInstalledPackages();
                            UpdateUpdatePackages();
                        }
                    }
                    else if (installed > package)
                    {
                        // A newer version is installed
                        if (GUILayout.Button(string.Format("Downgrade to [{0}]", package.Version), EditorStyles.toolbarButton, installButtonWidth, installButtonHeight))
                        {
                            NugetHelper.Update(installed, package);
                            NugetHelper.UpdateInstalledPackages();
                            UpdateUpdatePackages();
                        }
                    }
                }
                else
                {
                    if (GUILayout.Button("Install", EditorStyles.toolbarButton, installButtonWidth, installButtonHeight))
                    {
                        NugetHelper.InstallIdentifier(package);
                        AssetDatabase.Refresh();
                        NugetHelper.UpdateInstalledPackages();
                        UpdateUpdatePackages();
                    }
                }
            }
        }
Ejemplo n.º 18
0
        private void DrawDepencency(NugetPackageIdentifier dependency)
        {
            NugetPackage fullDependency = installedPackages.Find(p => p.Id == dependency.Id);

            if (fullDependency != null)
            {
                DrawPackage(fullDependency);
            }
            else
            {
                Debug.LogErrorFormat("{0} {1} is not installed!", dependency.Id, dependency.Version);
            }
        }
Ejemplo n.º 19
0
        private void DrawPackageDetail(NugetPackage package)
        {
            GUILayout.BeginHorizontal(EditorStyles.toolbarButton);
            DrawInstallUninstallPackageButtons(package);
            DrawLicenseButton(package);
            DrawCloneButton(package);
            GUILayout.EndHorizontal();

            DrawPackageNameAndIcon(package);
            DrawPackageDescription(package);
            DrawReleaseNotes(package);
            DrawPackageDependencies(package);
            DrawProjectUrl(package);
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Downloads an image at the given URL and converts it to a Unity Texture2D.
        /// </summary>
        /// <param name="package">The package to set the icon on</param>
        /// <param name="url">The URL of the image to download.</param>
        private static IEnumerator DownloadAndSetIconRoutine(NugetPackage package, string url)
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var fromCache = false;

            if (ExistsInDiskCache(url))
            {
                url       = "file:///" + GetFilePath(url);
                fromCache = true;
            }

            Texture2D result = null;

            using (var request = UnityWebRequestTexture.GetTexture(url, false))
            {
                const int timeout = 5;
                request.timeout = timeout;
                // Since we are handling coroutines by ourselves we can't yield return this directly
                request.SendWebRequest();
                while (!request.isDone && stopwatch.ElapsedMilliseconds < timeout * 1000)
                {
                    yield return(null);
                }

                if (request.isDone && !request.isNetworkError && !request.isHttpError)
                {
                    result = DownloadHandlerTexture.GetContent(request);
                }
                else if (!string.IsNullOrEmpty(request.error))
                {
                    LogWarning($"Request {url} error after {stopwatch.ElapsedMilliseconds} ms: {request.error}");
                }
                else
                {
                    LogWarning($"Request {url} timed out after {stopwatch.ElapsedMilliseconds} ms");
                }


                if (result != null && !fromCache)
                {
                    CacheTextureOnDisk(url, request.downloadHandler.data);
                }
            }

            package.Icon = result;
        }
Ejemplo n.º 21
0
        private static void DrawPackageDependencies(NugetPackage package)
        {
            if (package.Dependencies.Count > 0)
            {
                GUILayout.Label("Dependencies:", EditorStyles.miniBoldLabel);

                StringBuilder builder = new StringBuilder();
                foreach (var dependency in package.Dependencies)
                {
                    builder.Append(string.Format(" {0} {1};", dependency.Id, dependency.Version));
                }

                GUILayout.BeginVertical(EditorStyles.helpBox);
                GUILayout.Label(string.Format("Depends on:{0}", builder.ToString()), EditorStyles.miniLabel);
                GUILayout.EndVertical();
            }
        }
Ejemplo n.º 22
0
        private void DrawPackage(NugetPackage package)
        {
            if (package.Dependencies != null && package.Dependencies.Count > 0)
            {
                expanded[package] = EditorGUILayout.Foldout(expanded[package], string.Format("{0} {1}", package.Id, package.Version));

                if (expanded[package])
                {
                    EditorGUI.indentLevel++;
                    foreach (NugetPackageIdentifier dependency in package.Dependencies)
                    {
                        DrawDepencency(dependency);
                    }
                    EditorGUI.indentLevel--;
                }
            }
            else
            {
                EditorGUILayout.LabelField(string.Format("{0} {1}", package.Id, package.Version));
            }
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Draws the given <see cref="NugetPackage"/>.
        /// </summary>
        /// <param name="package">The <see cref="NugetPackage"/> to draw.</param>
        private void DrawPackage(NugetPackage package, GUIStyle packageStyle)
        {
            GUILayout.BeginVertical();

            DrawPackageNameAndIcon(package);
            DrawPackageDescription(package);
            DrawProjectUrl(package);

            GUILayout.EndVertical();

            var packageRect = GUILayoutUtility.GetLastRect();

            if (Event.current.type == EventType.MouseDown && packageRect.Contains(Event.current.mousePosition))
            {
                SelectPackageForDetail(package);
                GUIUtility.ExitGUI();

                Repaint();
            }

            DrawCurrentInstalledVersion(package);
        }
Ejemplo n.º 24
0
        private void DrawPackage(NugetPackage package)
        {
            if (package.Dependencies != null && package.Dependencies.Count > 0)
            {
                expanded[package] = EditorGUILayout.Foldout(expanded[package], $"{package.Id} {package.Version}");

                if (expanded[package])
                {
                    EditorGUI.indentLevel++;

                    var frameworkGroup = NugetHelper.GetBestDependencyFrameworkGroupForCurrentSettings(package);
                    foreach (var dependency in frameworkGroup.Dependencies)
                    {
                        DrawDepencency(dependency);
                    }
                    EditorGUI.indentLevel--;
                }
            }
            else
            {
                EditorGUILayout.LabelField($"{package.Id} {package.Version}");
            }
        }
        private void DrawPackage(NugetPackage package)
        {
            if (package.Dependencies != null && package.Dependencies.Count > 0)
            {
                expanded[package] = EditorGUILayout.Foldout(expanded[package], string.Format("{0} {1}", package.Id, package.Version));

                if (expanded[package])
                {
                    EditorGUI.indentLevel++;

                    NugetFrameworkGroup frameworkGroup = NugetHelper.GetBestDependencyFrameworkGroupForCurrentSettings(package);
                    foreach (NugetPackageIdentifier dependency in frameworkGroup.Dependencies)
                    {
                        DrawDepencency(dependency);
                    }
                    EditorGUI.indentLevel--;
                }
            }
            else
            {
                EditorGUILayout.LabelField(string.Format("{0} {1}", package.Id, package.Version));
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Some NuGet feeds such as Visual Studio Team Services do not implement the GetUpdates function.
        /// In that case this fallback function can be used to retrieve updates by using the FindPackagesById function.
        /// </summary>
        /// <param name="installedPackages">The list of currently installed packages.</param>
        /// <param name="includePrerelease">True to include prerelease packages (alpha, beta, etc).</param>
        /// <param name="includeAllVersions">True to include older versions that are not the latest version.</param>
        /// <param name="targetFrameworks">The specific frameworks to target?</param>
        /// <param name="versionContraints">The version constraints?</param>
        /// <returns>A list of all updates available.</returns>
        private List <NugetPackage> GetUpdatesFallback(IEnumerable <NugetPackage> installedPackages, bool includePrerelease = false, bool includeAllVersions = false, string targetFrameworks = "", string versionContraints = "")
        {
            Stopwatch stopwatch = new Stopwatch();

            stopwatch.Start();
            Debug.Assert(string.IsNullOrEmpty(targetFrameworks) && string.IsNullOrEmpty(versionContraints)); // These features are not supported by this version of GetUpdates.

            List <NugetPackage> updates = new List <NugetPackage>();

            foreach (NugetPackage installedPackage in installedPackages)
            {
                string versionRange       = string.Format("({0},)", installedPackage.Version); // Minimum of Current ID (exclusive) with no maximum (exclusive).
                NugetPackageIdentifier id = new NugetPackageIdentifier(installedPackage.Id, versionRange);

                List <NugetPackage> packageUpdates = FindPackagesById(id);
                packageUpdates = FindPackagesById(id);

                NugetPackage mostRecentPrerelease = includePrerelease ? packageUpdates.FindLast(p => p.IsPrerelease) : default(NugetPackage);
                packageUpdates.RemoveAll(p => p.IsPrerelease && p != mostRecentPrerelease);

                if (!includePrerelease)
                {
                    packageUpdates.RemoveAll(p => p.IsPrerelease);
                }
                if (packageUpdates.Count == 0)
                {
                    continue;
                }

                int skip = includeAllVersions ? 0 : packageUpdates.Count - 1;
                updates.AddRange(packageUpdates.Skip(skip));
            }

            NugetHelper.LogVerbose("NugetPackageSource.GetUpdatesFallback took {0} ms", stopwatch.ElapsedMilliseconds);
            return(updates);
        }
Ejemplo n.º 27
0
        /// <summary>
        /// Parses the given <see cref="XDocument"/> and returns the list of <see cref="NugetPackage"/>s contained within.
        /// </summary>
        /// <param name="document">The <see cref="XDocument"/> that is the OData XML response from the NuGet server.</param>
        /// <returns>The list of <see cref="NugetPackage"/>s read from the given XML.</returns>
        public static List <NugetPackage> Parse(XDocument document)
        {
            List <NugetPackage> packages = new List <NugetPackage>();

            var packageEntries = document.Root.Elements(XName.Get("entry", AtomNamespace));

            foreach (var entry in packageEntries)
            {
                NugetPackage package = new NugetPackage();
                package.Id          = entry.GetAtomElement("title").Value;
                package.DownloadUrl = entry.GetAtomElement("content").Attribute("src").Value;

                var entryProperties = entry.Element(XName.Get("properties", MetaDataNamespace));
                package.Title        = entryProperties.GetProperty("Title");
                package.Version      = entryProperties.GetProperty("Version");
                package.Description  = entryProperties.GetProperty("Description");
                package.ReleaseNotes = entryProperties.GetProperty("ReleaseNotes");
                package.LicenseUrl   = entryProperties.GetProperty("LicenseUrl");
                package.ProjectUrl   = entryProperties.GetProperty("ProjectUrl");

                string iconUrl = entryProperties.GetProperty("IconUrl");
                if (!string.IsNullOrEmpty(iconUrl))
                {
                    NugetImageLoader.TryDownloadImage(iconUrl, tex => {
                        package.Icon = tex;
                    });
                }

                // if there is no title, just use the ID as the title
                if (string.IsNullOrEmpty(package.Title))
                {
                    package.Title = package.Id;
                }

                // Get dependencies
                package.Dependencies = new List <NugetPackageIdentifier>();
                string rawDependencies = entryProperties.GetProperty("Dependencies");
                if (!string.IsNullOrEmpty(rawDependencies))
                {
                    var dependencyGroups = new Dictionary <string, NugetFrameworkGroup>();

                    string[] dependencies = rawDependencies.Split('|');
                    foreach (var dependencyString in dependencies)
                    {
                        string[] details    = dependencyString.Split(':');
                        var      dependency = new NugetPackageIdentifier(details[0], details[1]);

                        // some packages (ex: FSharp.Data - 2.1.0) have inproper "semi-empty" dependencies such as:
                        // "Zlib.Portable:1.10.0:portable-net40+sl50+wp80+win80|::net40"
                        // so we need to only add valid dependencies and skip invalid ones
                        if (string.IsNullOrEmpty(dependency.Id) && string.IsNullOrEmpty(dependency.Version))
                        {
                            continue;
                        }

                        string framework = string.Empty;
                        if (details.Length > 2)
                        {
                            framework = details[2];
                        }

                        NugetFrameworkGroup group;
                        if (dependencyGroups.TryGetValue(framework, out group))
                        {
                            group.Dependencies.Add(dependency);
                        }
                        else
                        {
                            group = new NugetFrameworkGroup();
                            group.Dependencies = new List <NugetPackageIdentifier>();
                            group.Dependencies.Add(dependency);
                            dependencyGroups.Add(framework, group);
                        }
                    }

                    // find the correct group for this project
                    int intDotNetVersion = (int)NugetHelper.DotNetVersion;
                    //bool using46 = DotNetVersion == ApiCompatibilityLevel.NET_4_6; // NET_4_6 option was added in Unity 5.6
                    bool using46 = intDotNetVersion == 3; // NET_4_6 = 3 in Unity 5.6 and Unity 2017.1 - use the hard-coded int value to ensure it works in earlier versions of Unity
                    NugetFrameworkGroup selectedGroup = null;

                    foreach (var kvPair in dependencyGroups.OrderByDescending(x => x.Key))
                    {
                        string framework          = kvPair.Key;
                        NugetFrameworkGroup group = kvPair.Value;

                        // Select the highest .NET library available that is supported
                        // See here: https://docs.nuget.org/ndocs/schema/target-frameworks
                        if (using46 && framework == "net462")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net461")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net46")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net452")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net451")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net45")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && framework == "net403")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (using46 && (framework == "net40" || framework == "net4"))
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (framework == "net35")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (framework == "net20")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (framework == "net11")
                        {
                            selectedGroup = group;
                            break;
                        }
                        else if (framework == string.Empty)
                        {
                            selectedGroup = group;
                            break;
                        }
                    }

                    if (selectedGroup != null)
                    {
                        package.Dependencies = selectedGroup.Dependencies;
                    }
                }

                packages.Add(package);
            }

            return(packages);
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Gets a list of all available packages from a local source (not a web server) that match the given filters.
        /// </summary>
        /// <param name="searchTerm">The search term to use to filter packages. Defaults to the empty string.</param>
        /// <param name="includeAllVersions">True to include older versions that are not the latest version.</param>
        /// <param name="includePrerelease">True to include prerelease packages (alpha, beta, etc).</param>
        /// <param name="numberToGet">The number of packages to fetch.</param>
        /// <param name="numberToSkip">The number of packages to skip before fetching.</param>
        /// <returns>The list of available packages.</returns>
        private List <NugetPackage> GetLocalPackages(string searchTerm = "", bool includeAllVersions = false, bool includePrerelease = false, int numberToGet = 15, int numberToSkip = 0)
        {
            NugetHelper.LogVerbose("{0}: Getting local packages {1}", typeof(NugetPackageSource).Name, ExpandedPath);

            List <NugetPackage> localPackages = new List <NugetPackage>();

            if (numberToSkip != 0)
            {
                // we return the entire list the first time, so no more to add
                return(localPackages);
            }

            string path = ExpandedPath;

            if (Directory.Exists(path))
            {
                List <string> packagePaths = new List <string>();

                if (!IsLocalPathAndVersion33)                                                                  // 3.3-
                {
                    packagePaths.AddRange(Directory.GetFiles(path, string.Format("*{0}*.nupkg", searchTerm))); // adding loose packages
                }
                else // 3.3+
                {
                    // https://docs.microsoft.com/en-us/nuget/hosting-packages/local-feeds

                    // hierarchy of local feed
                    // 0.\\myserver\packages
                    // 1. └─<packageID>
                    // 2. └─<version>
                    // 3.   ├─<packageID>.<version>.nupkg
                    // 4.   └─<other files>

                    string aPackage = "";

                    // nuget v3 support
                    foreach (DirectoryInfo aDirPackageID in new DirectoryInfo(path).GetDirectories(string.Format("*{0}*", searchTerm))) // 0; for each package directory which matches the terms
                    {
                        NugetHelper.LogVerbose("{0}: Found a matching directory {1}", typeof(NugetPackageSource).Name, aDirPackageID);

                        aPackage = aDirPackageID.Name; // example: sinedustries.collections

                        //~ could optimize version checks while iterating?

                        foreach (DirectoryInfo aDirVersion in aDirPackageID.GetDirectories()) // 1; for each version directory for a package directory
                        {
                            NugetHelper.LogVerbose("{0}: Found a version directory {1}", typeof(NugetPackageSource).Name, aDirVersion);

                            aPackage = NugetPackage.PathLocal33Get(path, aDirPackageID.Name, aDirVersion.Name); // 2; path for package;

                            if (File.Exists(aPackage))                                                          // expected package exists
                            {
                                packagePaths.Add(aPackage);                                                     // add the package to paths
                                NugetHelper.LogVerbose("{0}: Added package {1}", typeof(NugetPackageSource).Name, aPackage);
                            }
                            else // no find path
                            {
                                throw new FileNotFoundException("Could not find NuGet package: {0};", aPackage);
                            }
                        }
                    }
                }

                foreach (var packagePath in packagePaths)
                {
                    var package = NugetPackage.FromNupkgFile(packagePath);
                    package.PackageSource = this;

                    if (package.IsPrerelease && !includePrerelease)
                    {
                        // if it's a prerelease package and we aren't supposed to return prerelease packages, just skip it
                        continue;
                    }

                    if (includeAllVersions)
                    {
                        // if all versions are being included, simply add it and move on
                        localPackages.Add(package);
                        NugetHelper.LogVerbose("Adding {0} {1}", package.Id, package.Version);
                        continue;
                    }

                    var existingPackage = localPackages.FirstOrDefault(x => x.Id == package.Id);
                    if (existingPackage != null)
                    {
                        // there is already a package with the same ID in the list
                        if (existingPackage < package)
                        {
                            // if the current package is newer than the existing package, swap them
                            localPackages.Remove(existingPackage);
                            localPackages.Add(package);
                        }
                    }
                    else
                    {
                        // there is no package with the same ID in the list yet
                        localPackages.Add(package);
                    }
                }
            }
            else
            {
                Debug.LogErrorFormat("Local folder not found: {0}", path);
            }

            return(localPackages);
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Gets a NugetPackage from the NuGet server that matches (or is in range of) the <see cref="NugetPackageIdentifier"/> given.
        /// If an exact match isn't found, it selects the next closest version available.
        /// </summary>
        /// <param name="package">The <see cref="NugetPackageIdentifier"/> containing the ID and Version of the package to get.</param>
        /// <returns>The retrieved package, if there is one.  Null if no matching package was found.</returns>
        public List <NugetPackage> FindPackagesById(NugetPackageIdentifier package)
        {
            List <NugetPackage> foundPackages = null;

            if (IsLocalPath)
            {
                // determine local path
                string localPackagePath;
                if (IsLocalPathAndVersion33)
                {
                    localPackagePath = NugetPackage.PathLocal33Get(ExpandedPath, package.Id, package.Version);
                }
                else
                {
                    localPackagePath = NugetPackage.PathLocalGet(ExpandedPath, package.Id, package.Version);
                }

                if (File.Exists(localPackagePath))
                {
                    NugetPackage localPackage = NugetPackage.FromNupkgFile(localPackagePath);
                    foundPackages = new List <NugetPackage> {
                        localPackage
                    };
                }
                else
                {
                    // TODO: Sort the local packages?  Currently assuming they are in alphabetical order due to the filesystem.
                    // TODO: Optimize to no longer use GetLocalPackages, since that loads the .nupkg itself

                    // Try to find later versions of the same package
                    var packages = GetLocalPackages(package.Id, true, true);
                    foundPackages = new List <NugetPackage>(packages.SkipWhile(x => !package.InRange(x)));
                }
            }
            else
            {
                // See here: http://www.odata.org/documentation/odata-version-2-0/uri-conventions/
                string url = string.Empty;

                // We used to rely on expressions such as &$filter=Version ge '9.0.1' to find versions in a range, but the results were sorted alphabetically. This
                // caused version 10.0.0 to be less than version 9.0.0. In order to work around this issue, we'll request all versions and perform filtering ourselves.

                url = string.Format("{0}FindPackagesById()?$orderby=Version asc&id='{1}'", ExpandedPath, package.Id);

                try
                {
                    foundPackages = GetPackagesFromUrl(url, ExpandedPassword);
                }
                catch (System.Exception e)
                {
                    foundPackages = new List <NugetPackage>();
                    Debug.LogErrorFormat("Unable to retrieve package list from {0}\n{1}", url, e.ToString());
                }

                foundPackages.Sort();
                if (foundPackages.Exists(p => package.InRange(p)))
                {
                    // Return all the packages in the range of versions specified by 'package'.
                    foundPackages.RemoveAll(p => !package.InRange(p));
                }
                else
                {
                    // There are no packages in the range of versions specified by 'package'.
                    // Return the most recent version after the version specified by 'package'.
                    foundPackages.RemoveAll(p => package.CompareVersion(p.Version) < 0);
                    if (foundPackages.Count > 0)
                    {
                        foundPackages.RemoveRange(1, foundPackages.Count - 1);
                    }
                }
            }

            if (foundPackages != null)
            {
                foreach (NugetPackage foundPackage in foundPackages)
                {
                    foundPackage.PackageSource = this;
                }
            }

            return(foundPackages);
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Draws the given <see cref="NugetPackage"/>.
        /// </summary>
        /// <param name="package">The <see cref="NugetPackage"/> to draw.</param>
        private void DrawPackage(NugetPackage package)
        {
            var installed = installedPackages.FirstOrDefault(p => p.Id == package.Id);

            EditorGUILayout.BeginHorizontal();
            {
                // The Unity GUI system (in the Editor) is terrible.  This probably requires some explanation.
                // Every time you use a Horizontal block, Unity appears to divide the space evenly.
                // (i.e. 2 components have half of the window width, 3 components have a third of the window width, etc)
                // GUILayoutUtility.GetRect is SUPPOSED to return a rect with the given height and width, but in the GUI layout.  It doesn't.
                // We have to use GUILayoutUtility to get SOME rect properties, but then manually calculate others.
                EditorGUILayout.BeginHorizontal();
                {
                    const int iconSize    = 32;
                    const int leftPadding = 5;
                    Rect      rect        = GUILayoutUtility.GetRect(iconSize, iconSize);
                    // only use GetRect's Y position.  It doesn't correctly set the width or X position.
                    rect.x      = leftPadding;
                    rect.y     += 3;
                    rect.width  = iconSize;
                    rect.height = iconSize;

                    if (package.Icon != null)
                    {
                        GUI.DrawTexture(rect, package.Icon, ScaleMode.StretchToFill);
                    }
                    else
                    {
                        GUI.DrawTexture(rect, defaultIcon, ScaleMode.StretchToFill);
                    }

                    rect    = GUILayoutUtility.GetRect(position.width / 2 - (iconSize + leftPadding), 20);
                    rect.x  = iconSize + leftPadding;
                    rect.y += 10;

                    EditorStyles.label.fontStyle = FontStyle.Bold;
                    EditorStyles.label.fontSize  = 14;
                    ////EditorGUILayout.LabelField(string.Format("{1} [{0}]", package.Version, package.Id), GUILayout.Height(20), GUILayout.Width(position.width / 2 - 32));
                    GUI.Label(rect, string.Format("{1} [{0}]", package.Version, package.Title), EditorStyles.label);
                    EditorStyles.label.fontSize  = 10;
                    EditorStyles.label.fontStyle = FontStyle.Normal;
                }
                EditorGUILayout.EndHorizontal();

                if (installedPackages.Contains(package))
                {
                    // This specific version is installed
                    if (GUILayout.Button("Uninstall", installButtonWidth, installButtonHeight))
                    {
                        // TODO: Perhaps use a "mark as dirty" system instead of updating all of the data all the time?
                        NugetHelper.Uninstall(package);
                        UpdateInstalledPackages();
                        UpdateUpdatePackages();
                    }
                }
                else
                {
                    if (installed != null)
                    {
                        if (installed < package)
                        {
                            // An older version is installed
                            if (GUILayout.Button(string.Format("Update to [{0}]", package.Version), installButtonWidth, installButtonHeight))
                            {
                                NugetHelper.Update(installed, package);
                                UpdateInstalledPackages();
                                UpdateUpdatePackages();
                            }
                        }
                        else if (installed > package)
                        {
                            // A newer version is installed
                            if (GUILayout.Button(string.Format("Downgrade to [{0}]", package.Version), installButtonWidth, installButtonHeight))
                            {
                                NugetHelper.Update(installed, package);
                                UpdateInstalledPackages();
                                UpdateUpdatePackages();
                            }
                        }
                    }
                    else
                    {
                        if (GUILayout.Button("Install", installButtonWidth, installButtonHeight))
                        {
                            NugetHelper.InstallIdentifier(package);
                            AssetDatabase.Refresh();
                            UpdateInstalledPackages();
                            UpdateUpdatePackages();
                        }
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.BeginVertical();
                {
                    // Show the package description
                    EditorStyles.label.wordWrap = true;
                    //EditorStyles.label.fontStyle = FontStyle.Bold;
                    //EditorGUILayout.LabelField(string.Format("Description:"));
                    EditorStyles.label.fontStyle = FontStyle.Normal;
                    EditorGUILayout.LabelField(string.Format("{0}", package.Description));

                    // Show the package release notes
                    if (!string.IsNullOrEmpty(package.ReleaseNotes))
                    {
                        EditorStyles.label.wordWrap  = true;
                        EditorStyles.label.fontStyle = FontStyle.Bold;
                        EditorGUILayout.LabelField(string.Format("Release Notes:"));
                        EditorStyles.label.fontStyle = FontStyle.Normal;
                        EditorGUILayout.LabelField(string.Format("{0}", package.ReleaseNotes));
                    }

                    // Show the dependencies
                    if (package.Dependencies.Count > 0)
                    {
                        EditorStyles.label.wordWrap  = true;
                        EditorStyles.label.fontStyle = FontStyle.Italic;
                        StringBuilder builder = new StringBuilder();
                        foreach (var dependency in package.Dependencies)
                        {
                            builder.Append(string.Format(" {0} {1};", dependency.Id, dependency.Version));
                        }
                        EditorGUILayout.Space();
                        EditorGUILayout.LabelField(string.Format("Depends on:{0}", builder.ToString()));
                        EditorStyles.label.fontStyle = FontStyle.Normal;
                    }

                    // Show the license button
                    if (!string.IsNullOrEmpty(package.LicenseUrl) && package.LicenseUrl != "http://your_license_url_here")
                    {
                        if (GUILayout.Button("View License", GUILayout.Width(120)))
                        {
                            Application.OpenURL(package.LicenseUrl);
                        }
                    }

                    EditorGUILayout.Separator();
                    EditorGUILayout.Separator();
                }
                EditorGUILayout.EndVertical();

                if (installed != null)
                {
                    GUIStyle labelStyle = new GUIStyle(EditorStyles.label);
                    labelStyle.alignment = TextAnchor.UpperRight;
                    GUILayout.Label(string.Format("currently [{0}]  ", installed.Version), labelStyle, installButtonWidth);
                }
            }
            EditorGUILayout.EndHorizontal();
        }