@@ -563,6 +563,94 @@ def parse(cls, location, package_only=False):
563
563
yield models .PackageData .from_data (package_data , package_only )
564
564
565
565
566
+ class PipInspectDeplockHandler (models .DatafileHandler ):
567
+ datasource_id = 'pypi_inspect_deplock'
568
+ path_patterns = ('*pip-inspect.deplock' ,)
569
+ default_package_type = 'pypi'
570
+ default_primary_language = 'Python'
571
+ description = 'Python poetry pyproject.toml'
572
+ # These are files generated by deplock, see https://github.com/nexB/dependency-inspector
573
+ documentation_url = 'https://pip.pypa.io/en/stable/cli/pip_inspect/'
574
+
575
+ @classmethod
576
+ def get_resolved_package_from_metadata (cls , metadata , package_only = False ):
577
+
578
+ requires_dist = metadata .get ('requires_dist' )
579
+ dependencies_for_resolved = get_requires_dependencies (
580
+ requires = requires_dist ,
581
+ )
582
+ package_data = dict (
583
+ datasource_id = cls .datasource_id ,
584
+ type = cls .default_package_type ,
585
+ primary_language = 'Python' ,
586
+ name = metadata .get ('name' ),
587
+ version = metadata .get ('version' ),
588
+ extracted_license_statement = metadata .get ('license' ),
589
+ description = metadata .get ('description' ),
590
+ keywords = metadata .get ('keywords' ),
591
+ is_virtual = True ,
592
+ dependencies = [
593
+ dep .to_dict ()
594
+ for dep in dependencies_for_resolved
595
+ ],
596
+ )
597
+ return models .PackageData .from_data (package_data , package_only )
598
+
599
+ @classmethod
600
+ def parse (cls , location , package_only = False ):
601
+
602
+ with open (location ) as f :
603
+ content = f .read ()
604
+
605
+ data = json .loads (content )
606
+ installed_packages = data .get ('installed' )
607
+ if not installed_packages :
608
+ return
609
+
610
+ main_package_metadata = {}
611
+ dependencies = []
612
+
613
+ for package_metadata in installed_packages :
614
+ package_metadata_dep = package_metadata .get ('metadata' )
615
+
616
+ # `direct_url` is only present for root package
617
+ # `requested` is true for root package and direct dependencies only
618
+ if package_metadata .get ('requested' ) and 'direct_url' in package_metadata :
619
+ main_package_metadata = package_metadata_dep
620
+ continue
621
+
622
+ package_data_dep = cls .get_resolved_package_from_metadata (
623
+ metadata = package_metadata_dep ,
624
+ package_only = package_only ,
625
+ )
626
+ dep_purl = package_data_dep .purl
627
+
628
+ dependency = models .DependentPackage (
629
+ purl = dep_purl ,
630
+ extracted_requirement = None ,
631
+ scope = None ,
632
+ is_runtime = True ,
633
+ is_optional = False ,
634
+ is_direct = False ,
635
+ is_resolved = True ,
636
+ resolved_package = package_data_dep .to_dict ()
637
+ )
638
+ dependencies .append (dependency .to_dict ())
639
+
640
+ pip_version = data .get ('pip_version' )
641
+ inspect_version = data .get ('version' )
642
+ extra_data = {
643
+ "pip_version" : pip_version ,
644
+ "inspect_version" : inspect_version ,
645
+ }
646
+
647
+ package_data_main = cls .get_resolved_package_from_metadata (
648
+ metadata = main_package_metadata ,
649
+ package_only = package_only ,
650
+ )
651
+ package_data_main .dependencies = dependencies
652
+ package_data_main .extra_data = extra_data
653
+ yield package_data_main
566
654
567
655
568
656
META_DIR_SUFFIXES = '.dist-info' , '.egg-info' , 'EGG-INFO' ,
0 commit comments