Example #1
0
        /// <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);
        }