Skip to content

Commit 0708369

Browse files
committed
packagedcode: address deps.json PR review feedback
Signed-off-by: kumarasantosh <santosh.pulikond02@gmail.com>
1 parent 98766fe commit 0708369

11 files changed

Lines changed: 1370 additions & 1156 deletions

src/packagedcode/nuget.py

Lines changed: 109 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,7 @@ class DotNetDepsJsonHandler(models.DatafileHandler):
276276
@classmethod
277277
def parse(cls, location, package_only=False):
278278
with open(location) as loc:
279-
try:
280-
parsed = json.load(loc)
281-
except Exception:
282-
return
279+
parsed = json.load(loc)
283280

284281
if not parsed or not isinstance(parsed, dict):
285282
return
@@ -320,66 +317,115 @@ def parse(cls, location, package_only=False):
320317
if not selected_targets:
321318
selected_targets = available_targets
322319

323-
for lib_key, lib_info in libraries.items():
324-
if not lib_key or '/' not in lib_key:
320+
packages = parse_deps_json_libraries(
321+
libraries=libraries,
322+
selected_targets=selected_targets,
323+
runtime_target_matched=runtime_target_matched,
324+
target_framework=target_framework,
325+
datasource_id=cls.datasource_id,
326+
default_package_type=cls.default_package_type,
327+
)
328+
329+
for package_data in packages:
330+
yield models.PackageData.from_data(package_data, package_only)
331+
332+
333+
def parse_deps_json_libraries(
334+
libraries,
335+
selected_targets,
336+
runtime_target_matched,
337+
target_framework,
338+
datasource_id,
339+
default_package_type,
340+
):
341+
"""
342+
Parse the libraries and targets sections of a .deps.json file.
343+
Returns a list of package dictionaries.
344+
"""
345+
packages = []
346+
if not selected_targets:
347+
selected_targets = []
348+
349+
for lib_key, lib_info in libraries.items():
350+
if not lib_key or '/' not in lib_key:
351+
continue
352+
if not isinstance(lib_info, dict):
353+
continue
354+
355+
name, version = lib_key.split('/', 1)
356+
package_type = lib_info.get('type')
357+
dependencies = get_deps_json_dependencies(
358+
lib_key=lib_key,
359+
selected_targets=selected_targets,
360+
default_package_type=default_package_type,
361+
)
362+
363+
extra_data = {}
364+
if runtime_target_matched:
365+
extra_data['target_framework'] = target_framework
366+
elif len(selected_targets) == 1:
367+
extra_data['target_framework'] = selected_targets[0][0]
368+
elif selected_targets:
369+
extra_data['target_frameworks'] = [scope for scope, _target_obj in selected_targets]
370+
371+
if package_type:
372+
extra_data['type'] = package_type
373+
374+
package_data = dict(
375+
datasource_id=datasource_id,
376+
type=default_package_type,
377+
name=name,
378+
version=version,
379+
dependencies=dependencies,
380+
extra_data=extra_data,
381+
)
382+
packages.append(package_data)
383+
384+
return packages
385+
386+
387+
def get_deps_json_dependencies(lib_key, selected_targets, default_package_type):
388+
"""
389+
Return dependency mappings for ``lib_key`` gathered from all ``selected_targets``.
390+
"""
391+
dependencies = []
392+
seen_dependencies = set()
393+
394+
for scope, target_obj in selected_targets:
395+
target_lib = target_obj.get(lib_key) or {}
396+
if not isinstance(target_lib, dict):
397+
continue
398+
399+
deps = target_lib.get('dependencies')
400+
if not deps or not isinstance(deps, dict):
401+
continue
402+
403+
for dep_name, dep_version in deps.items():
404+
if not dep_name:
325405
continue
326-
if not isinstance(lib_info, dict):
406+
407+
dep_key = (dep_name, dep_version, scope)
408+
if dep_key in seen_dependencies:
327409
continue
410+
seen_dependencies.add(dep_key)
328411

329-
name, version = lib_key.split('/', 1)
330-
331-
package_type = lib_info.get('type')
332-
333-
# Extract dependencies from targets
334-
dependencies = []
335-
seen_dependencies = set()
336-
for scope, target_obj in selected_targets:
337-
target_lib = target_obj.get(lib_key) or {}
338-
if not isinstance(target_lib, dict):
339-
continue
340-
341-
deps = target_lib.get('dependencies')
342-
if not deps or not isinstance(deps, dict):
343-
continue
344-
345-
for dep_name, dep_version in deps.items():
346-
if not dep_name:
347-
continue
348-
349-
dep_key = (dep_name, dep_version, scope)
350-
if dep_key in seen_dependencies:
351-
continue
352-
seen_dependencies.add(dep_key)
353-
354-
dependencies.append(
355-
models.DependentPackage(
356-
purl=str(PackageURL(type='nuget', name=dep_name, version=dep_version)),
357-
extracted_requirement=dep_version,
358-
scope=scope,
359-
is_runtime=True,
360-
is_optional=False,
361-
is_pinned=True,
362-
is_direct=True,
363-
).to_dict()
364-
)
365-
366-
extra_data = {}
367-
if runtime_target_matched:
368-
extra_data['target_framework'] = target_framework
369-
elif len(selected_targets) == 1:
370-
extra_data['target_framework'] = selected_targets[0][0]
371-
elif selected_targets:
372-
extra_data['target_frameworks'] = [scope for scope, _target_obj in selected_targets]
373-
374-
if package_type:
375-
extra_data['type'] = package_type
376-
377-
package_data = dict(
378-
datasource_id=cls.datasource_id,
379-
type=cls.default_package_type,
380-
name=name,
381-
version=version,
382-
dependencies=dependencies,
383-
extra_data=extra_data,
412+
purl = PackageURL(type=default_package_type, name=dep_name, version=dep_version)
413+
resolved_package = models.PackageData(
414+
type=purl.type,
415+
name=dep_name,
416+
version=dep_version,
417+
).to_dict()
418+
419+
dependency = models.DependentPackage(
420+
purl=str(purl),
421+
extracted_requirement=dep_version,
422+
scope=scope,
423+
is_runtime=True,
424+
is_optional=False,
425+
is_pinned=True,
426+
is_direct=True,
427+
resolved_package=resolved_package,
384428
)
385-
yield models.PackageData.from_data(package_data, package_only)
429+
dependencies.append(dependency.to_dict())
430+
431+
return dependencies

0 commit comments

Comments
 (0)