1212from packagedcode import models
1313from packagedcode .utils import build_description
1414
15+
1516"""
1617Handle NuGet packages and their manifests.
1718"""
18- # TODO: add dependencies
19+
20+ # TODO: Add section to handle dependencies of dependencies
21+
22+
23+ def get_dependencies (nuspec ):
24+ """
25+ Return a list of Dependent package objects found in a NuGet `nuspec` object.
26+ """
27+ dependencies = []
28+ try :
29+ if "dependencies" in nuspec :
30+ if "dependency" in nuspec .get ("dependencies" ):
31+ if "@id" and "@version" in nuspec .get ("dependencies" ).get ("dependency" ):
32+ dpurl = models .PackageURL (
33+ type = 'nuget' ,
34+ namespace = None ,
35+ name = nuspec .get ("dependencies" ).get (
36+ "dependency" ).get ("@id" ),
37+ version = nuspec .get ("dependencies" ).get (
38+ "dependency" ).get ("@version" ),
39+ qualifiers = None
40+ )
41+ dep_pack = models .DependentPackage (
42+ purl = str (dpurl ),
43+ extracted_requirement = nuspec .get ("dependencies" ).get (
44+ "dependency" ).get ("@version" ),
45+ scope = "dependency" ,
46+ is_runtime = False ,
47+ is_optional = False ,
48+ is_resolved = True ,
49+ )
50+
51+ dependencies .append (dep_pack )
52+
53+ else :
54+ for dependency in nuspec .get ("dependencies" ).get ("dependency" ):
55+ dpurl = models .PackageURL (
56+ type = 'nuget' ,
57+ namespace = None ,
58+ name = dependency .get ("@id" ),
59+ version = dependency .get ("@version" ),
60+ qualifiers = None
61+ )
62+ dep_pack = models .DependentPackage (
63+ purl = str (dpurl ),
64+ extracted_requirement = dependency .get (
65+ "@version" ),
66+ scope = "dependency" ,
67+ is_runtime = False ,
68+ is_optional = False ,
69+ is_resolved = True ,
70+ )
71+ dependencies .append (dep_pack )
72+
73+ return dependencies
74+
75+ except Exception as e :
76+ print (e )
77+ return dependencies
1978
2079
2180def get_urls (name , version ):
@@ -46,7 +105,7 @@ class NugetNuspecHandler(models.DatafileHandler):
46105
47106 @classmethod
48107 def parse (cls , location ):
49- with open (location , 'rb' ) as loc :
108+ with open (location , 'rb' ) as loc :
50109 parsed = xmltodict .parse (loc )
51110
52111 if not parsed :
@@ -62,14 +121,15 @@ def parse(cls, location):
62121
63122 # Summary: A short description of the package for UI display. If omitted, a
64123 # truncated version of description is used.
65- description = build_description (nuspec .get ('summary' ) , nuspec .get ('description' ))
124+ description = build_description (
125+ nuspec .get ('summary' ), nuspec .get ('description' ))
66126
67127 # title: A human-friendly title of the package, typically used in UI
68128 # displays as on nuget.org and the Package Manager in Visual Studio. If not
69129 # specified, the package ID is used.
70130 title = nuspec .get ('title' )
71131 if title and title != name :
72- description = build_description (nuspec .get ('title' ) , description )
132+ description = build_description (nuspec .get ('title' ), description )
73133
74134 parties = []
75135 authors = nuspec .get ('authors' )
@@ -101,6 +161,7 @@ def parse(cls, location):
101161 description = description or None ,
102162 homepage_url = nuspec .get ('projectUrl' ) or None ,
103163 parties = parties ,
164+ dependencies = get_dependencies (nuspec ),
104165 # FIXME: license has evolved and is now SPDX...
105166 declared_license = nuspec .get ('licenseUrl' ) or None ,
106167 copyright = nuspec .get ('copyright' ) or None ,
@@ -109,6 +170,7 @@ def parse(cls, location):
109170 )
110171
111172 if not package_data .license_expression and package_data .declared_license :
112- package_data .license_expression = cls .compute_normalized_license (package_data )
173+ package_data .license_expression = cls .compute_normalized_license (
174+ package_data )
113175
114176 yield package_data
0 commit comments