Example #1
0
        /// <summary>
        /// Retrieves the specified component from NuGet.
        /// </summary>
        /// <param name="name">NuGet package name</param>
        /// <param name="version">Package version</param>
        /// <returns></returns>
        public async Task <Component> GetComponentAsync(string name, string version)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            Console.WriteLine("Retrieving " + name + " " + version);

            var component = new Component
            {
                Name    = name,
                Version = version,
                Purl    = Utils.GeneratePackageUrl(name, version)
            };

            var url = _baseUrl + name + "/" + version + "/" + name + ".nuspec";
            var doc = await _httpClient.GetXmlAsync(url);

            if (doc == null)
            {
                return(component);
            }

            var root     = doc.DocumentElement;
            var metadata = root.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']");

            component.Publisher = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'authors']");
            component.Copyright = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'copyright']");
            var title       = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'title']");
            var summary     = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'summary']");
            var description = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'description']");

            if (summary != null)
            {
                component.Description = summary;
            }
            else if (description != null)
            {
                component.Description = description;
            }
            else if (title != null)
            {
                component.Description = title;
            }

            // Utilize the new license expression field present in more recent packages
            // TODO: Need to have more robust parsing to support composite expressions seen in (https://github.com/NuGet/Home/wiki/Packaging-License-within-the-nupkg#project-properties)
            var licenseNode    = metadata.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'license']");
            var licenseUrlNode = metadata.SelectSingleNode("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'licenseUrl']");

            if (licenseNode?.Attributes["type"].Value == "expression")
            {
                var licenses = licenseNode.FirstChild.Value
                               .Replace("AND", ";")
                               .Replace("OR", ";")
                               .Replace("WITH", ";")
                               .Replace("+", "")
                               .Split(';').ToList();
                foreach (var license in licenses)
                {
                    component.Licenses.Add(new Models.License
                    {
                        Id   = license.Trim(),
                        Name = license.Trim()
                    });
                }
            }
            else if (licenseUrlNode != null)
            {
                var licenseUrl = licenseUrlNode.FirstChild.Value;
                var license    = await _githubService.GetLicenseAsync(licenseUrl.Trim());

                component.Licenses.Add(license ?? new Models.License
                {
                    Url = licenseUrl.Trim()
                });
            }

            var projectUrl = GetNodeValue(metadata, "/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'projectUrl']");

            if (projectUrl != null)
            {
                var externalReference = new Models.ExternalReference();
                externalReference.Type = Models.ExternalReference.WEBSITE;
                externalReference.Url  = projectUrl;
                component.ExternalReferences.Add(externalReference);
            }

            var dependencies = metadata.SelectNodes("/*[local-name() = 'package']/*[local-name() = 'metadata']/*[local-name() = 'dependencies']/*[local-name() = 'dependency']");

            foreach (XmlNode dependency in dependencies)
            {
                var dependencyName    = dependency.Attributes["id"];
                var dependencyVersion = dependency.Attributes["version"];
                if (dependencyName != null && dependencyVersion != null)
                {
                    var nugetDependency = new NugetPackage {
                        Name    = dependencyName.Value,
                        Version = dependencyVersion.Value,
                    };
                    component.Dependencies.Add(nugetDependency);
                }
            }

            return(component);
        }
        /// <summary>
        /// Retrieves the specified component from NuGet.
        /// </summary>
        /// <param name="name">NuGet package name</param>
        /// <param name="version">Package version</param>
        /// <returns></returns>
        public async Task <Component> GetComponentAsync(string name, string version, string scope)
        {
            if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(version))
            {
                return(null);
            }

            Console.WriteLine("Retrieving " + name + " " + version);

            var component = new Component
            {
                Name    = name,
                Version = version,
                Scope   = scope,
                Purl    = Utils.GeneratePackageUrl(name, version)
            };

            var nuspecFilename = GetCachedNuspecFilename(name, version);

            NuspecReader nuspecReader = null;

            if (nuspecFilename == null)
            {
                var url = _baseUrl + name + "/" + version + "/" + name + ".nuspec";
                using (var xmlStream = await _httpClient.GetXmlStreamAsync(url).ConfigureAwait(false))
                {
                    if (xmlStream != null)
                    {
                        nuspecReader = new NuspecReader(xmlStream);
                    }
                }
            }
            else
            {
                using (var xmlStream = _fileSystem.File.Open(nuspecFilename, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                {
                    nuspecReader = new NuspecReader(xmlStream);
                }
            }

            if (nuspecReader == null)
            {
                return(component);
            }

            component.Publisher = nuspecReader.GetAuthors();
            component.Copyright = nuspecReader.GetCopyright();
            // this prevents empty copyright values in the JSON BOM
            if (string.IsNullOrEmpty(component.Copyright))
            {
                component.Copyright = null;
            }
            var title       = nuspecReader.GetTitle();
            var summary     = nuspecReader.GetSummary();
            var description = nuspecReader.GetDescription();

            if (!string.IsNullOrEmpty(summary))
            {
                component.Description = summary;
            }
            else if (!string.IsNullOrEmpty(description))
            {
                component.Description = description;
            }
            else if (!string.IsNullOrEmpty(title))
            {
                component.Description = title;
            }

            var licenseMetadata = nuspecReader.GetLicenseMetadata();

            if (licenseMetadata != null && licenseMetadata.Type == NuGet.Packaging.LicenseType.Expression)
            {
                Action <NuGetLicense> licenseProcessor = delegate(NuGetLicense nugetLicense)
                {
                    var license = new Models.License
                    {
                        Id   = nugetLicense.Identifier,
                        Name = nugetLicense.Identifier
                    };
                    component.Licenses.Add(new ComponentLicense
                    {
                        License = license
                    });
                };
                licenseMetadata.LicenseExpression.OnEachLeafNode(licenseProcessor, null);
            }
            else
            {
                var licenseUrl = nuspecReader.GetLicenseUrl();
                if (!string.IsNullOrEmpty(licenseUrl))
                {
                    Models.License license = null;

                    if (_githubService != null)
                    {
                        license = await _githubService.GetLicenseAsync(licenseUrl).ConfigureAwait(false);
                    }

                    if (license == null)
                    {
                        license = new Models.License
                        {
                            Url = licenseUrl
                        };
                    }

                    component.Licenses.Add(new ComponentLicense
                    {
                        License = license
                    });
                }
            }

            var projectUrl = nuspecReader.GetProjectUrl();

            if (projectUrl != null)
            {
                var externalReference = new Models.ExternalReference();
                externalReference.Type = Models.ExternalReference.WEBSITE;
                externalReference.Url  = projectUrl;
                component.ExternalReferences.Add(externalReference);
            }

            return(component);
        }