/// <summary> /// Creates a new <see cref="NugetPackage"/> from the given <see cref="NuspecFile"/>. /// </summary> /// <param name="nuspec">The <see cref="NuspecFile"/> to use to create the <see cref="NugetPackage"/>.</param> /// <returns>The newly created <see cref="NugetPackage"/>.</returns> public static NugetPackage FromNuspec(NuspecFile nuspec) { var package = new NugetPackage { Id = nuspec.Id, Version = nuspec.Version, Title = nuspec.Title, Description = nuspec.Description, ReleaseNotes = nuspec.ReleaseNotes, LicenseUrl = nuspec.LicenseUrl, ProjectUrl = nuspec.ProjectUrl, Authors = nuspec.Authors, Summary = nuspec.Summary }; if (!string.IsNullOrEmpty(nuspec.IconUrl)) { SystemProxy.DownloadAndSetIcon(package, nuspec.IconUrl); } package.RepositoryUrl = nuspec.RepositoryUrl; try { package.RepositoryType = (RepositoryType)Enum.Parse(typeof(RepositoryType), nuspec.RepositoryType, true); } catch (Exception) { } package.RepositoryBranch = nuspec.RepositoryBranch; package.RepositoryCommit = nuspec.RepositoryCommit; // if there is no title, just use the ID as the title if (string.IsNullOrEmpty(package.Title)) { package.Title = package.Id; } package.Dependencies = nuspec.Dependencies; return(package); }
/// <summary> /// Adds a package to the packages.config file. /// </summary> /// <param name="package">The NugetPackage to add to the packages.config file.</param> public void AddPackage(NugetPackageIdentifier package) { var existingPackage = Packages.Find(p => p.Id.ToLower() == package.Id.ToLower()); if (existingPackage != null) { if (existingPackage < package) { SystemProxy.LogWarning($"{existingPackage.Id} {existingPackage.Version} is already listed in the packages.config file. Updating to {package.Version}"); Packages.Remove(existingPackage); Packages.Add(package); } else if (existingPackage > package) { SystemProxy.LogWarning($"Trying to add {package.Id} {package.Version} to the packages.config file. {existingPackage.Version} is already listed, so using that."); } } else { Packages.Add(package); } }
/// <summary> /// Compares two version numbers in the form "1.2". Also supports an optional 3rd and 4th number as well as a prerelease tag, such as "1.3.0.1-alpha2". /// Returns: /// -1 if versionA is less than versionB /// 0 if versionA is equal to versionB /// +1 if versionA is greater than versionB /// </summary> /// <param name="versionA">The first version number to compare.</param> /// <param name="versionB">The second version number to compare.</param> /// <returns>-1 if versionA is less than versionB. 0 if versionA is equal to versionB. +1 if versionA is greater than versionB</returns> private static int CompareVersions(string versionA, string versionB) { try { var splitStringsA = versionA.Split('-'); versionA = splitStringsA[0]; var prereleaseA = "\uFFFF"; if (splitStringsA.Length > 1) { prereleaseA = splitStringsA[1]; for (var i = 2; i < splitStringsA.Length; i++) { prereleaseA += "-" + splitStringsA[i]; } } var splitA = versionA.Split('.'); var majorA = int.Parse(splitA[0]); var minorA = int.Parse(splitA[1]); var patchA = 0; if (splitA.Length >= 3) { patchA = int.Parse(splitA[2]); } var buildA = 0; if (splitA.Length >= 4) { buildA = int.Parse(splitA[3]); } var splitStringsB = versionB.Split('-'); versionB = splitStringsB[0]; var prereleaseB = "\uFFFF"; if (splitStringsB.Length > 1) { prereleaseB = splitStringsB[1]; for (var i = 2; i < splitStringsB.Length; i++) { prereleaseB += "-" + splitStringsB[i]; } } var splitB = versionB.Split('.'); var majorB = int.Parse(splitB[0]); var minorB = int.Parse(splitB[1]); var patchB = 0; if (splitB.Length >= 3) { patchB = int.Parse(splitB[2]); } var buildB = 0; if (splitB.Length >= 4) { buildB = int.Parse(splitB[3]); } var major = majorA <majorB ? -1 : majorA> majorB ? 1 : 0; var minor = minorA <minorB ? -1 : minorA> minorB ? 1 : 0; var patch = patchA <patchB ? -1 : patchA> patchB ? 1 : 0; var build = buildA <buildB ? -1 : buildA> buildB ? 1 : 0; var prerelease = string.CompareOrdinal(prereleaseA, prereleaseB); if (major != 0) { return(major); } if (minor != 0) { return(minor); } if (patch != 0) { return(patch); } if (build != 0) { return(build); } return(prerelease); } catch (Exception) { SystemProxy.LogError($"Compare Error: {versionA} {versionB}"); return(-1); } }
/// <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) { var packages = new List <NugetPackage>(); IEnumerable <XElement> packageEntries; if (document.Root.Name.Equals(XName.Get("entry", AtomNamespace))) { packageEntries = Enumerable.Repeat(document.Root, 1); } else { packageEntries = document.Root.Elements(XName.Get("entry", AtomNamespace)); } foreach (var entry in packageEntries) { var package = new NugetPackage { Id = entry.GetAtomElement("title").Value, 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.Summary = entryProperties.GetProperty("Summary"); package.ReleaseNotes = entryProperties.GetProperty("ReleaseNotes"); package.LicenseUrl = entryProperties.GetProperty("LicenseUrl"); package.ProjectUrl = entryProperties.GetProperty("ProjectUrl"); package.Authors = entryProperties.GetProperty("Authors"); package.DownloadCount = int.Parse(entryProperties.GetProperty("DownloadCount")); var iconUrl = entryProperties.GetProperty("IconUrl"); if (!string.IsNullOrEmpty(iconUrl)) { SystemProxy.DownloadAndSetIcon(package, iconUrl); } // if there is no title, just use the ID as the title if (string.IsNullOrEmpty(package.Title)) { package.Title = package.Id; } // Get dependencies var rawDependencies = entryProperties.GetProperty("Dependencies"); if (!string.IsNullOrEmpty(rawDependencies)) { var dependencyGroups = new Dictionary <string, NugetFrameworkGroup>(); var dependencies = rawDependencies.Split('|'); foreach (var dependencyString in dependencies) { var details = dependencyString.Split(':'); var framework = string.Empty; if (details.Length > 2) { framework = details[2]; } if (!dependencyGroups.TryGetValue(framework, out var group)) { group = new NugetFrameworkGroup { TargetFramework = framework }; dependencyGroups.Add(framework, group); } var dependency = new NugetPackageIdentifier(details[0], details[1]); // some packages (ex: FSharp.Data - 2.1.0) have improper "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) && dependency.Id != "NETStandard.Library") { group.Dependencies.Add(dependency); } } foreach (var group in dependencyGroups.Values) { if (group.Dependencies.Count > 0) { package.Dependencies.Add(group); } } } packages.Add(package); } return(packages); }