diff --git a/src/packagedcode/nuget.py b/src/packagedcode/nuget.py index a1cf1036390..b7340201d95 100644 --- a/src/packagedcode/nuget.py +++ b/src/packagedcode/nuget.py @@ -12,10 +12,92 @@ from packagedcode import models from packagedcode.utils import build_description + """ Handle NuGet packages and their manifests. """ -# TODO: add dependencies + +# TODO: Add section to handle dependencies of dependencies + + +def get_dependencies(nuspec): + """ + Return a list of Dependent package objects found in a NuGet `nuspec` object. + """ + dependencies = [] + try: + if "dependencies" in nuspec: + if "group" in nuspec["dependencies"]: + for group in nuspec["dependencies"]["group"]: + if "dependency" in group: + for dependency in group["dependency"]: + #dependencies.append(dependency) + dpurl = models.PackageURL( + type='nuget', + namespace=None, + name=dependency.get("@id"), + version=dependency.get("@version"), + qualifiers=None + ) + dep_pack = models.DependentPackage( + purl=str(dpurl), + extracted_requirement=dependency.get("@version"), + scope="dependency", + is_runtime=False, + is_optional=False, + is_resolved=True, + ) + + dependencies.append(dep_pack) + + if "dependency" in nuspec.get("dependencies"): + if "@id" and "@version" in nuspec.get("dependencies").get("dependency"): + dpurl = models.PackageURL( + type='nuget', + namespace=None, + name=nuspec.get("dependencies").get( + "dependency").get("@id"), + version=nuspec.get("dependencies").get( + "dependency").get("@version"), + qualifiers=None + ) + dep_pack = models.DependentPackage( + purl=str(dpurl), + extracted_requirement=nuspec.get("dependencies").get( + "dependency").get("@version"), + scope="dependency", + is_runtime=False, + is_optional=False, + is_resolved=True, + ) + + dependencies.append(dep_pack) + + else: + for dependency in nuspec.get("dependencies").get("dependency"): + dpurl = models.PackageURL( + type='nuget', + namespace=None, + name=dependency.get("@id"), + version=dependency.get("@version"), + qualifiers=None + ) + dep_pack = models.DependentPackage( + purl=str(dpurl), + extracted_requirement=dependency.get( + "@version"), + scope="dependency", + is_runtime=False, + is_optional=False, + is_resolved=True, + ) + dependencies.append(dep_pack) + + return dependencies + + except Exception as e: + print(e) + return dependencies def get_urls(name, version, **kwargs): @@ -46,7 +128,7 @@ class NugetNuspecHandler(models.DatafileHandler): @classmethod def parse(cls, location): - with open(location , 'rb') as loc: + with open(location, 'rb') as loc: parsed = xmltodict.parse(loc) if not parsed: @@ -62,14 +144,15 @@ def parse(cls, location): # Summary: A short description of the package for UI display. If omitted, a # truncated version of description is used. - description = build_description(nuspec.get('summary') , nuspec.get('description')) + description = build_description( + nuspec.get('summary'), nuspec.get('description')) # title: A human-friendly title of the package, typically used in UI # displays as on nuget.org and the Package Manager in Visual Studio. If not # specified, the package ID is used. title = nuspec.get('title') if title and title != name: - description = build_description(nuspec.get('title') , description) + description = build_description(nuspec.get('title'), description) parties = [] authors = nuspec.get('authors') @@ -102,7 +185,7 @@ def parse(cls, location): # Deprecated and not a license expression, just a URL elif 'licenseUrl' in nuspec: extracted_license_statement = nuspec.get('licenseUrl') - + yield models.PackageData( datasource_id=cls.datasource_id, type=cls.default_package_type, @@ -111,8 +194,10 @@ def parse(cls, location): description=description or None, homepage_url=nuspec.get('projectUrl') or None, parties=parties, + dependencies=get_dependencies(nuspec), extracted_license_statement=extracted_license_statement, copyright=nuspec.get('copyright') or None, vcs_url=vcs_url, **urls, ) + diff --git a/tests/packagedcode/data/nuget/Castle.Core.nuspec.json.expected b/tests/packagedcode/data/nuget/Castle.Core.nuspec.json.expected index 75917239923..13a4b133749 100644 --- a/tests/packagedcode/data/nuget/Castle.Core.nuspec.json.expected +++ b/tests/packagedcode/data/nuget/Castle.Core.nuspec.json.expected @@ -94,7 +94,108 @@ "source_packages": [], "file_references": [], "extra_data": {}, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:nuget/NETStandard.Library@1.6.1", + "extracted_requirement": "1.6.1", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Diagnostics.TraceSource@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Reflection.TypeExtensions@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Xml.XmlDocument@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Dynamic.Runtime@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Reflection@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Reflection.Emit@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.Collections.Specialized@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.ComponentModel@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/System.ComponentModel.TypeConverter@4.3.0", + "extracted_requirement": "4.3.0", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://www.nuget.org/packages/Castle.Core/4.2.1", "repository_download_url": "https://www.nuget.org/api/v2/package/Castle.Core/4.2.1", "api_data_url": "https://api.nuget.org/v3/registration3/castle.core/4.2.1.json", diff --git a/tests/packagedcode/data/nuget/Microsoft.AspNet.Mvc.nuspec.json.expected b/tests/packagedcode/data/nuget/Microsoft.AspNet.Mvc.nuspec.json.expected index 1f12966bff7..c5d8d4f5729 100644 --- a/tests/packagedcode/data/nuget/Microsoft.AspNet.Mvc.nuspec.json.expected +++ b/tests/packagedcode/data/nuget/Microsoft.AspNet.Mvc.nuspec.json.expected @@ -94,7 +94,188 @@ "source_packages": [], "file_references": [], "extra_data": {}, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.ApiExplorer@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Cors@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.DataAnnotations@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Formatters.Json@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Localization@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Razor@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.ViewFeatures@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.Framework.Caching.Memory@1.0.0-beta7", + "extracted_requirement": "1.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.Framework.DependencyInjection@1.0.0-beta7", + "extracted_requirement": "1.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.ApiExplorer@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Cors@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.DataAnnotations@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Formatters.Json@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Localization@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.Razor@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.AspNet.Mvc.ViewFeatures@6.0.0-beta7", + "extracted_requirement": "6.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.Framework.Caching.Memory@1.0.0-beta7", + "extracted_requirement": "1.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.Framework.DependencyInjection@1.0.0-beta7", + "extracted_requirement": "1.0.0-beta7", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://www.nuget.org/packages/Microsoft.AspNet.Mvc/6.0.0-beta7", "repository_download_url": "https://www.nuget.org/api/v2/package/Microsoft.AspNet.Mvc/6.0.0-beta7", "api_data_url": "https://api.nuget.org/v3/registration3/microsoft.aspnet.mvc/6.0.0-beta7.json", diff --git a/tests/packagedcode/data/nuget/Microsoft.Net.Http.nuspec.json.expected b/tests/packagedcode/data/nuget/Microsoft.Net.Http.nuspec.json.expected index f539e8dc069..1b153842951 100644 --- a/tests/packagedcode/data/nuget/Microsoft.Net.Http.nuspec.json.expected +++ b/tests/packagedcode/data/nuget/Microsoft.Net.Http.nuspec.json.expected @@ -94,7 +94,28 @@ "source_packages": [], "file_references": [], "extra_data": {}, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:nuget/Microsoft.Bcl@1.1.10", + "extracted_requirement": "1.1.10", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + }, + { + "purl": "pkg:nuget/Microsoft.Bcl.Build@1.0.14", + "extracted_requirement": "1.0.14", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://www.nuget.org/packages/Microsoft.Net.Http/2.2.29", "repository_download_url": "https://www.nuget.org/api/v2/package/Microsoft.Net.Http/2.2.29", "api_data_url": "https://api.nuget.org/v3/registration3/microsoft.net.http/2.2.29.json", diff --git a/tests/packagedcode/data/nuget/bootstrap.nuspec.json.expected b/tests/packagedcode/data/nuget/bootstrap.nuspec.json.expected index ff150952d3a..2444fa97e2c 100644 --- a/tests/packagedcode/data/nuget/bootstrap.nuspec.json.expected +++ b/tests/packagedcode/data/nuget/bootstrap.nuspec.json.expected @@ -1,104 +1,115 @@ [ { - "type": "nuget", - "namespace": null, - "name": "bootstrap", - "version": "4.0.0-alpha", - "qualifiers": {}, - "subpath": null, - "primary_language": null, - "description": "Bootstrap CSS\nBootstrap framework in CSS. Includes fonts and JavaScript\nThe most popular front-end framework for developing responsive, mobile first projects on the web.", - "release_date": null, - "parties": [ - { - "type": null, - "role": "author", - "name": "Twitter, Inc.", - "email": null, - "url": null - }, - { - "type": null, - "role": "owner", - "name": "bootstrap", - "email": null, - "url": null - } - ], - "keywords": [], - "homepage_url": "http://getbootstrap.com", - "download_url": null, - "size": null, - "sha1": null, - "md5": null, - "sha256": null, - "sha512": null, - "bug_tracking_url": null, - "code_view_url": null, - "vcs_url": null, - "copyright": "Copyright 2015", - "declared_license_expression": "mit", - "declared_license_expression_spdx": "MIT", - "license_detections": [ - { - "license_expression": "mit", - "detection_log": [ - "not-combined" - ], - "matches": [ - { - "score": 100.0, - "start_line": 1, - "end_line": 1, - "matched_length": 8, - "match_coverage": 100.0, - "matcher": "1-hash", - "license_expression": "mit", - "rule_identifier": "mit_180.RULE", - "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_180.RULE", - "referenced_filenames": [], - "is_license_text": false, - "is_license_notice": false, - "is_license_reference": true, - "is_license_tag": false, - "is_license_intro": false, - "rule_length": 8, - "rule_relevance": 100, - "matched_text": "https://github.com/twbs/bootstrap/blob/master/LICENSE", - "licenses": [ - { - "key": "mit", - "name": "MIT License", - "short_name": "MIT License", - "category": "Permissive", - "is_exception": false, - "is_unknown": false, - "owner": "MIT", - "homepage_url": "http://opensource.org/licenses/mit-license.php", - "text_url": "http://opensource.org/licenses/mit-license.php", - "reference_url": "https://scancode-licensedb.aboutcode.org/mit", - "scancode_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", - "spdx_license_key": "MIT", - "spdx_url": "https://spdx.org/licenses/MIT" - } - ] - } - ] - } - ], - "other_license_expression": null, - "other_license_expression_spdx": null, - "other_license_detections": [], - "extracted_license_statement": "https://github.com/twbs/bootstrap/blob/master/LICENSE", - "notice_text": null, - "source_packages": [], - "file_references": [], - "extra_data": {}, - "dependencies": [], - "repository_homepage_url": "https://www.nuget.org/packages/bootstrap/4.0.0-alpha", - "repository_download_url": "https://www.nuget.org/api/v2/package/bootstrap/4.0.0-alpha", - "api_data_url": "https://api.nuget.org/v3/registration3/bootstrap/4.0.0-alpha.json", - "datasource_id": "nuget_nupsec", - "purl": "pkg:nuget/bootstrap@4.0.0-alpha" - } + "type": "nuget", + "namespace": null, + "name": "bootstrap", + "version": "4.0.0-alpha", + "qualifiers": {}, + "subpath": null, + "primary_language": null, + "description": "Bootstrap CSS\nBootstrap framework in CSS. Includes fonts and JavaScript\nThe most popular front-end framework for developing responsive, mobile first projects on the web.", + "release_date": null, + "parties": [ + { + "type": null, + "role": "author", + "name": "Twitter, Inc.", + "email": null, + "url": null + }, + { + "type": null, + "role": "owner", + "name": "bootstrap", + "email": null, + "url": null + } + ], + "keywords": [], + "homepage_url": "http://getbootstrap.com", + "download_url": null, + "size": null, + "sha1": null, + "md5": null, + "sha256": null, + "sha512": null, + "bug_tracking_url": null, + "code_view_url": null, + "vcs_url": null, + "copyright": "Copyright 2015", + "declared_license_expression": "mit", + "declared_license_expression_spdx": "MIT", + "license_detections": [ + { + "license_expression": "mit", + "detection_log": [ + "not-combined" + ], + "matches": [ + { + "score": 100.0, + "start_line": 1, + "end_line": 1, + "matched_length": 8, + "match_coverage": 100.0, + "matcher": "1-hash", + "license_expression": "mit", + "rule_identifier": "mit_180.RULE", + "rule_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/rules/mit_180.RULE", + "referenced_filenames": [], + "is_license_text": false, + "is_license_notice": false, + "is_license_reference": true, + "is_license_tag": false, + "is_license_intro": false, + "rule_length": 8, + "rule_relevance": 100, + "matched_text": "https://github.com/twbs/bootstrap/blob/master/LICENSE", + "licenses": [ + { + "key": "mit", + "name": "MIT License", + "short_name": "MIT License", + "category": "Permissive", + "is_exception": false, + "is_unknown": false, + "owner": "MIT", + "homepage_url": "http://opensource.org/licenses/mit-license.php", + "text_url": "http://opensource.org/licenses/mit-license.php", + "reference_url": "https://scancode-licensedb.aboutcode.org/mit", + "scancode_url": "https://github.com/nexB/scancode-toolkit/tree/develop/src/licensedcode/data/licenses/mit.LICENSE", + "spdx_license_key": "MIT", + "spdx_url": "https://spdx.org/licenses/MIT" + } + ] + } + ] + } + ], + "other_license_expression": null, + "other_license_expression_spdx": null, + "other_license_detections": [], + "extracted_license_statement": "https://github.com/twbs/bootstrap/blob/master/LICENSE", + "notice_text": null, + "source_packages": [], + "file_references": [], + "extra_data": {}, + "dependencies": [ + { + "purl": "pkg:nuget/jQuery@1.9.1", + "extracted_requirement": "1.9.1", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + } + ], + "repository_homepage_url": "https://www.nuget.org/packages/bootstrap/4.0.0-alpha", + "repository_download_url": "https://www.nuget.org/api/v2/package/bootstrap/4.0.0-alpha", + "api_data_url": "https://api.nuget.org/v3/registration3/bootstrap/4.0.0-alpha.json", + "datasource_id": "nuget_nupsec", + "purl": "pkg:nuget/bootstrap@4.0.0-alpha" + } ] \ No newline at end of file diff --git a/tests/packagedcode/data/nuget/jQuery.UI.Combined.nuspec.json.expected b/tests/packagedcode/data/nuget/jQuery.UI.Combined.nuspec.json.expected index ba27fa78510..d71de542726 100644 --- a/tests/packagedcode/data/nuget/jQuery.UI.Combined.nuspec.json.expected +++ b/tests/packagedcode/data/nuget/jQuery.UI.Combined.nuspec.json.expected @@ -94,7 +94,18 @@ "source_packages": [], "file_references": [], "extra_data": {}, - "dependencies": [], + "dependencies": [ + { + "purl": "pkg:nuget/jQuery@1.6.4", + "extracted_requirement": "1.6.4", + "scope": "dependency", + "is_runtime": false, + "is_optional": false, + "is_resolved": true, + "resolved_package": {}, + "extra_data": {} + } + ], "repository_homepage_url": "https://www.nuget.org/packages/jQuery.UI.Combined/1.11.4", "repository_download_url": "https://www.nuget.org/api/v2/package/jQuery.UI.Combined/1.11.4", "api_data_url": "https://api.nuget.org/v3/registration3/jquery.ui.combined/1.11.4.json",