private static NugetPackage GetInstalledPacakge(NugetPackage package) { IEnumerable <NugetPackage> installedPackages = NugetHelper.InstalledPackages; var installed = installedPackages.FirstOrDefault(p => p.Id == package.Id); return(installed); }
/// <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); }
/// <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); } } }
private void DrawProjectUrl(NugetPackage package) { if (!string.IsNullOrEmpty(package.ProjectUrl)) { GUILayoutLink(package.ProjectUrl); } }
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); } }
/// <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); }
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); } } } }
/// <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); }
public static void DownloadAndSetIcon(NugetPackage package, string url) { if (!NugetWindow.IsOpened) { return; } StartCoroutine(DownloadAndSetIconRoutine(package, url)); }
private void DrawCurrentInstalledVersion(NugetPackage package) { NugetPackage installed = GetInstalledPacakge(package); if (installed != null) { GUILayout.Label(string.Format("currently [{0}] ", installed.Version), EditorStyles.miniLabel, installButtonWidth); } }
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(); }
public int CompareTo(NugetPackage other) { if (this.Id != other.Id) { return(string.Compare(this.Id, other.Id)); } return(CompareVersions(this.Version, other.Version)); }
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(); } }
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); } } }
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(); }
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(); } } } }
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); } }
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); }
/// <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; }
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(); } }
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)); } }
/// <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); }
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)); } }
/// <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); }
/// <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); }
/// <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); }
/// <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); }
/// <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(); }