scanoss 1.32.0__py3-none-any.whl → 1.34.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. protoc_gen_swagger/options/annotations_pb2.py +18 -12
  2. protoc_gen_swagger/options/annotations_pb2.pyi +48 -0
  3. protoc_gen_swagger/options/annotations_pb2_grpc.py +20 -0
  4. protoc_gen_swagger/options/openapiv2_pb2.py +110 -99
  5. protoc_gen_swagger/options/openapiv2_pb2.pyi +1317 -0
  6. protoc_gen_swagger/options/openapiv2_pb2_grpc.py +20 -0
  7. scanoss/__init__.py +1 -1
  8. scanoss/api/common/v2/scanoss_common_pb2.py +8 -6
  9. scanoss/api/common/v2/scanoss_common_pb2_grpc.py +5 -1
  10. scanoss/api/components/v2/scanoss_components_pb2.py +46 -32
  11. scanoss/api/components/v2/scanoss_components_pb2_grpc.py +6 -6
  12. scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +107 -29
  13. scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +545 -9
  14. scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +29 -21
  15. scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +1 -0
  16. scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2.py +51 -19
  17. scanoss/api/geoprovenance/v2/scanoss_geoprovenance_pb2_grpc.py +189 -1
  18. scanoss/api/licenses/v2/scanoss_licenses_pb2.py +27 -27
  19. scanoss/api/scanning/v2/scanoss_scanning_pb2.py +18 -18
  20. scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +29 -13
  21. scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +102 -8
  22. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +21 -21
  23. scanoss/cli.py +193 -146
  24. scanoss/components.py +57 -46
  25. scanoss/cryptography.py +64 -44
  26. scanoss/cyclonedx.py +22 -0
  27. scanoss/data/build_date.txt +1 -1
  28. scanoss/scanossgrpc.py +433 -314
  29. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/METADATA +4 -3
  30. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/RECORD +34 -32
  31. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/WHEEL +0 -0
  32. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/entry_points.txt +0 -0
  33. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/licenses/LICENSE +0 -0
  34. {scanoss-1.32.0.dist-info → scanoss-1.34.0.dist-info}/top_level.txt +0 -0
scanoss/cli.py CHANGED
@@ -34,7 +34,9 @@ import pypac
34
34
 
35
35
  from scanoss.cryptography import Cryptography, create_cryptography_config_from_args
36
36
  from scanoss.export.dependency_track import DependencyTrackExporter
37
- from scanoss.inspection.dependency_track.project_violation import DependencyTrackProjectViolationPolicyCheck
37
+ from scanoss.inspection.dependency_track.project_violation import (
38
+ DependencyTrackProjectViolationPolicyCheck,
39
+ )
38
40
  from scanoss.inspection.raw.component_summary import ComponentSummary
39
41
  from scanoss.inspection.raw.license_summary import LicenseSummary
40
42
  from scanoss.scanners.container_scanner import (
@@ -308,7 +310,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
308
310
  help='Retrieve vulnerabilities for the given components',
309
311
  )
310
312
  c_vulns.set_defaults(func=comp_vulns)
311
- c_vulns.add_argument('--grpc', action='store_true', help='Enable gRPC support')
313
+
314
+ # Component Sub-command: component licenses
315
+ c_licenses = comp_sub.add_parser(
316
+ 'licenses',
317
+ aliases=['lics'],
318
+ description=f'Show License details: {__version__}',
319
+ help='Retrieve licenses for the given components',
320
+ )
321
+ c_licenses.set_defaults(func=comp_licenses)
312
322
 
313
323
  # Component Sub-command: component semgrep
314
324
  c_semgrep = comp_sub.add_parser(
@@ -411,7 +421,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
411
421
  p_crypto_versions_in_range.set_defaults(func=crypto_versions_in_range)
412
422
 
413
423
  # Common purl Component sub-command options
414
- for p in [c_vulns, c_semgrep, c_provenance, p_crypto_algorithms, p_crypto_hints, p_crypto_versions_in_range]:
424
+ for p in [
425
+ c_vulns,
426
+ c_semgrep,
427
+ c_provenance,
428
+ p_crypto_algorithms,
429
+ p_crypto_hints,
430
+ p_crypto_versions_in_range,
431
+ c_licenses,
432
+ ]:
415
433
  p.add_argument('--purl', '-p', type=str, nargs='*', help='Package URL - PURL to process.')
416
434
  p.add_argument('--input', '-i', type=str, help='Input file name')
417
435
 
@@ -425,6 +443,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
425
443
  p_crypto_algorithms,
426
444
  p_crypto_hints,
427
445
  p_crypto_versions_in_range,
446
+ c_licenses,
428
447
  ]:
429
448
  p.add_argument(
430
449
  '--timeout',
@@ -541,32 +560,32 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
541
560
  # =========================================================================
542
561
  # INSPECT SUBCOMMAND - Analysis and validation of scan results
543
562
  # =========================================================================
544
-
563
+
545
564
  # Main inspect parser - provides tools for analyzing scan results
546
565
  p_inspect = subparsers.add_parser(
547
- 'inspect',
548
- aliases=['insp', 'ins'],
566
+ 'inspect',
567
+ aliases=['insp', 'ins'],
549
568
  description=f'Inspect and analyse scan results: {__version__}',
550
- help='Inspect and analyse scan results'
569
+ help='Inspect and analyse scan results',
551
570
  )
552
571
 
553
572
  # Inspect sub-commands parser
554
573
  p_inspect_sub = p_inspect.add_subparsers(
555
- title='Inspect Commands',
556
- dest='subparsercmd',
557
- description='Available inspection sub-commands',
558
- help='Choose an inspection type'
574
+ title='Inspect Commands',
575
+ dest='subparsercmd',
576
+ description='Available inspection sub-commands',
577
+ help='Choose an inspection type',
559
578
  )
560
579
 
561
580
  # -------------------------------------------------------------------------
562
581
  # RAW RESULTS INSPECTION - Analyse raw scan output
563
582
  # -------------------------------------------------------------------------
564
-
583
+
565
584
  # Raw results parser - handles inspection of unprocessed scan results
566
585
  p_inspect_raw = p_inspect_sub.add_parser(
567
586
  'raw',
568
587
  description='Inspect and analyse SCANOSS raw scan results',
569
- help='Analyse raw scan results for various compliance issues'
588
+ help='Analyse raw scan results for various compliance issues',
570
589
  )
571
590
 
572
591
  # Raw results sub-commands parser
@@ -574,15 +593,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
574
593
  title='Raw Results Inspection Commands',
575
594
  dest='subparser_subcmd',
576
595
  description='Tools for analyzing raw scan results',
577
- help='Choose a raw results analysis type'
596
+ help='Choose a raw results analysis type',
578
597
  )
579
598
 
580
599
  # Copyleft license inspection - identifies copyleft license violations
581
600
  p_inspect_raw_copyleft = p_inspect_raw_sub.add_parser(
582
- 'copyleft',
583
- aliases=['cp'],
584
- description='Identify components with copyleft licenses that may require compliance action',
585
- help='Find copyleft license violations'
601
+ 'copyleft',
602
+ aliases=['cp'],
603
+ description='Identify components with copyleft licenses that may require compliance action',
604
+ help='Find copyleft license violations',
586
605
  )
587
606
 
588
607
  # License summary inspection - provides overview of all detected licenses
@@ -590,7 +609,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
590
609
  'license-summary',
591
610
  aliases=['lic-summary', 'licsum'],
592
611
  description='Generate comprehensive summary of all licenses found in scan results',
593
- help='Generate license summary report'
612
+ help='Generate license summary report',
594
613
  )
595
614
 
596
615
  # Component summary inspection - provides overview of all detected components
@@ -598,7 +617,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
598
617
  'component-summary',
599
618
  aliases=['comp-summary', 'compsum'],
600
619
  description='Generate comprehensive summary of all components found in scan results',
601
- help='Generate component summary report'
620
+ help='Generate component summary report',
602
621
  )
603
622
 
604
623
  # Undeclared components inspection - finds components not declared in SBOM
@@ -606,7 +625,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
606
625
  'undeclared',
607
626
  aliases=['un'],
608
627
  description='Identify components present in code but not declared in SBOM files',
609
- help='Find undeclared components'
628
+ help='Find undeclared components',
610
629
  )
611
630
  # SBOM format option for undeclared components inspection
612
631
  p_inspect_raw_undeclared.add_argument(
@@ -614,19 +633,19 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
614
633
  required=False,
615
634
  choices=['legacy', 'settings'],
616
635
  default='settings',
617
- help='SBOM format type for comparison: legacy or settings (default)'
636
+ help='SBOM format type for comparison: legacy or settings (default)',
618
637
  )
619
638
 
620
639
  # -------------------------------------------------------------------------
621
640
  # BACKWARD COMPATIBILITY - Support old inspect command format
622
641
  # -------------------------------------------------------------------------
623
-
642
+
624
643
  # Legacy copyleft inspection - backward compatibility for 'scanoss-py inspect copyleft'
625
644
  p_inspect_legacy_copyleft = p_inspect_sub.add_parser(
626
- 'copyleft',
627
- aliases=['cp'],
628
- description='Identify components with copyleft licenses that may require compliance action',
629
- help='Find copyleft license violations (legacy format)'
645
+ 'copyleft',
646
+ aliases=['cp'],
647
+ description='Identify components with copyleft licenses that may require compliance action',
648
+ help='Find copyleft license violations (legacy format)',
630
649
  )
631
650
 
632
651
  # Legacy undeclared components inspection - backward compatibility for 'scanoss-py inspect undeclared'
@@ -634,16 +653,16 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
634
653
  'undeclared',
635
654
  aliases=['un'],
636
655
  description='Identify components present in code but not declared in SBOM files',
637
- help='Find undeclared components (legacy format)'
656
+ help='Find undeclared components (legacy format)',
638
657
  )
639
-
658
+
640
659
  # SBOM format option for legacy undeclared components inspection
641
660
  p_inspect_legacy_undeclared.add_argument(
642
661
  '--sbom-format',
643
662
  required=False,
644
663
  choices=['legacy', 'settings'],
645
664
  default='settings',
646
- help='SBOM format type for comparison: legacy or settings (default)'
665
+ help='SBOM format type for comparison: legacy or settings (default)',
647
666
  )
648
667
 
649
668
  # Legacy license summary inspection - backward compatibility for 'scanoss-py inspect license-summary'
@@ -651,7 +670,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
651
670
  'license-summary',
652
671
  aliases=['lic-summary', 'licsum'],
653
672
  description='Generate comprehensive summary of all licenses found in scan results',
654
- help='Generate license summary report (legacy format)'
673
+ help='Generate license summary report (legacy format)',
655
674
  )
656
675
 
657
676
  # Legacy component summary inspection - backward compatibility for 'scanoss-py inspect component-summary'
@@ -659,83 +678,63 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
659
678
  'component-summary',
660
679
  aliases=['comp-summary', 'compsum'],
661
680
  description='Generate comprehensive summary of all components found in scan results',
662
- help='Generate component summary report (legacy format)'
681
+ help='Generate component summary report (legacy format)',
663
682
  )
664
683
 
665
684
  # Applies the same configuration to both legacy and raw versions
666
685
  # License filtering options - common to (legacy) copyleft and license summary commands
667
- for p in [p_inspect_raw_copyleft, p_inspect_raw_license_summary,
668
- p_inspect_legacy_copyleft, p_inspect_legacy_license_summary]:
669
- p.add_argument(
670
- '--include',
671
- help='Additional licenses to include in analysis (comma-separated list)'
672
- )
673
- p.add_argument(
674
- '--exclude',
675
- help='Licenses to exclude from analysis (comma-separated list)'
676
- )
677
- p.add_argument(
678
- '--explicit',
679
- help='Use only these specific licenses for analysis (comma-separated list)'
680
- )
686
+ for p in [
687
+ p_inspect_raw_copyleft,
688
+ p_inspect_raw_license_summary,
689
+ p_inspect_legacy_copyleft,
690
+ p_inspect_legacy_license_summary,
691
+ ]:
692
+ p.add_argument('--include', help='Additional licenses to include in analysis (comma-separated list)')
693
+ p.add_argument('--exclude', help='Licenses to exclude from analysis (comma-separated list)')
694
+ p.add_argument('--explicit', help='Use only these specific licenses for analysis (comma-separated list)')
681
695
 
682
696
  # Common options for (legacy) copyleft and undeclared component inspection
683
697
  for p in [p_inspect_raw_copyleft, p_inspect_raw_undeclared, p_inspect_legacy_copyleft, p_inspect_legacy_undeclared]:
698
+ p.add_argument('-i', '--input', nargs='?', help='Path to scan results file to analyse')
684
699
  p.add_argument(
685
- '-i', '--input',
686
- nargs='?',
687
- help='Path to scan results file to analyse'
688
- )
689
- p.add_argument(
690
- '-f', '--format',
700
+ '-f',
701
+ '--format',
691
702
  required=False,
692
703
  choices=['json', 'md', 'jira_md'],
693
704
  default='json',
694
- help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)'
695
- )
696
- p.add_argument(
697
- '-o', '--output',
698
- type=str,
699
- help='Save detailed results to specified file'
700
- )
701
- p.add_argument(
702
- '-s', '--status',
703
- type=str,
704
- help='Save summary status report to Markdown file'
705
+ help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)',
705
706
  )
707
+ p.add_argument('-o', '--output', type=str, help='Save detailed results to specified file')
708
+ p.add_argument('-s', '--status', type=str, help='Save summary status report to Markdown file')
706
709
 
707
710
  # Common options for (legacy) license and component summary commands
708
- for p in [p_inspect_raw_license_summary, p_inspect_raw_component_summary,
709
- p_inspect_legacy_license_summary, p_inspect_legacy_component_summary]:
710
- p.add_argument(
711
- '-i', '--input',
712
- nargs='?',
713
- help='Path to scan results file to analyse'
714
- )
715
- p.add_argument(
716
- '-o', '--output',
717
- type=str,
718
- help='Save summary report to specified file'
719
- )
711
+ for p in [
712
+ p_inspect_raw_license_summary,
713
+ p_inspect_raw_component_summary,
714
+ p_inspect_legacy_license_summary,
715
+ p_inspect_legacy_component_summary,
716
+ ]:
717
+ p.add_argument('-i', '--input', nargs='?', help='Path to scan results file to analyse')
718
+ p.add_argument('-o', '--output', type=str, help='Save summary report to specified file')
720
719
 
721
720
  # -------------------------------------------------------------------------
722
721
  # DEPENDENCY TRACK INSPECTION - Analyse Dependency Track project data
723
722
  # -------------------------------------------------------------------------
724
-
723
+
725
724
  # Dependency Track parser - handles inspection of DT project status and violations
726
725
  p_dep_track_sub = p_inspect_sub.add_parser(
727
726
  'dependency-track',
728
727
  aliases=['dt'],
729
728
  description='Inspect and analyse Dependency Track project status and policy violations',
730
- help='Analyse Dependency Track projects'
729
+ help='Analyse Dependency Track projects',
731
730
  )
732
-
731
+
733
732
  # Dependency Track sub-commands parser
734
733
  p_inspect_dep_track_sub = p_dep_track_sub.add_subparsers(
735
734
  title='Dependency Track Inspection Commands',
736
735
  dest='subparser_subcmd',
737
736
  description='Tools for analysing Dependency Track project data',
738
- help='Choose a Dependency Track analysis type'
737
+ help='Choose a Dependency Track analysis type',
739
738
  )
740
739
 
741
740
  # Project violations inspection - analyses policy violations in DT projects
@@ -743,70 +742,52 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
743
742
  'project-violations',
744
743
  aliases=['pv'],
745
744
  description='Analyse policy violations and compliance issues in Dependency Track projects',
746
- help='Inspect project policy violations'
745
+ help='Inspect project policy violations',
747
746
  )
748
747
  # Dependency Track connection and authentication options
749
748
  p_inspect_dt_project_violation.add_argument(
750
- '--url',
751
- required=True,
752
- type=str,
753
- help='Dependency Track server base URL (e.g., https://dtrack.example.com)'
749
+ '--url', required=True, type=str, help='Dependency Track server base URL (e.g., https://dtrack.example.com)'
754
750
  )
755
751
  p_inspect_dt_project_violation.add_argument(
756
- '--upload-token', '-ut',
752
+ '--upload-token',
753
+ '-ut',
757
754
  required=False,
758
- type=str,
759
- help='Project-specific upload token for accessing DT project data'
755
+ type=str,
756
+ help='Project-specific upload token for accessing DT project data',
760
757
  )
761
758
  p_inspect_dt_project_violation.add_argument(
762
- '--project-id', '-pid',
763
- required=False,
764
- type=str,
765
- help='Dependency Track project UUID to inspect'
759
+ '--project-id', '-pid', required=False, type=str, help='Dependency Track project UUID to inspect'
766
760
  )
767
761
  p_inspect_dt_project_violation.add_argument(
768
- '--apikey', '-k',
769
- required=True,
770
- type=str,
771
- help='Dependency Track API key for authentication'
762
+ '--apikey', '-k', required=True, type=str, help='Dependency Track API key for authentication'
772
763
  )
773
764
  p_inspect_dt_project_violation.add_argument(
774
- '--project-name', '-pn',
775
- required=False,
776
- type=str,
777
- help='Dependency Track project name'
765
+ '--project-name', '-pn', required=False, type=str, help='Dependency Track project name'
778
766
  )
779
767
  p_inspect_dt_project_violation.add_argument(
780
- '--project-version', '-pv',
781
- required=False,
782
- type=str,
783
- help='Dependency Track project version'
768
+ '--project-version', '-pv', required=False, type=str, help='Dependency Track project version'
784
769
  )
785
770
  p_inspect_dt_project_violation.add_argument(
786
- '--output', '-o',
787
- required=False,
788
- type=str,
789
- help='Save inspection results to specified file'
771
+ '--output', '-o', required=False, type=str, help='Save inspection results to specified file'
790
772
  )
791
773
  p_inspect_dt_project_violation.add_argument(
792
- '--status',
793
- required=False,
794
- type=str,
795
- help='Save summary status report to specified file'
774
+ '--status', required=False, type=str, help='Save summary status report to specified file'
796
775
  )
797
776
  p_inspect_dt_project_violation.add_argument(
798
- '--format', '-f',
777
+ '--format',
778
+ '-f',
799
779
  required=False,
800
780
  choices=['json', 'md', 'jira_md'],
801
781
  default='json',
802
- help='Output format: json (default), md (Markdown) or jira_md (JIRA Markdown)'
782
+ help='Output format: json (default), md (Markdown) or jira_md (JIRA Markdown)',
803
783
  )
804
784
  p_inspect_dt_project_violation.add_argument(
805
- '--timeout', '-M',
785
+ '--timeout',
786
+ '-M',
806
787
  required=False,
807
788
  default=300,
808
789
  type=float,
809
- help='Timeout (in seconds) for API communication (optional - default 300 sec)'
790
+ help='Timeout (in seconds) for API communication (optional - default 300 sec)',
810
791
  )
811
792
 
812
793
  # TODO Move to the command call def location
@@ -852,7 +833,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
852
833
  e_dt.add_argument('-i', '--input', type=str, required=True, help='Input SBOM file (CycloneDX JSON format)')
853
834
  e_dt.add_argument('--url', type=str, required=True, help='Dependency Track base URL')
854
835
  e_dt.add_argument('--apikey', '-k', type=str, required=True, help='Dependency Track API key')
855
- e_dt.add_argument('--output', '-o', type=str, help='File to save export token and uuid into')
836
+ e_dt.add_argument('--output', '-o', type=str, help='File to save export token and uuid into')
856
837
  e_dt.add_argument('--project-id', '-pid', type=str, help='Dependency Track project UUID')
857
838
  e_dt.add_argument('--project-name', '-pn', type=str, help='Dependency Track project name')
858
839
  e_dt.add_argument('--project-version', '-pv', type=str, help='Dependency Track project version')
@@ -927,6 +908,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
927
908
  p_crypto_algorithms,
928
909
  p_crypto_hints,
929
910
  p_crypto_versions_in_range,
911
+ c_licenses,
930
912
  ]:
931
913
  p.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
932
914
 
@@ -965,7 +947,6 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
965
947
  p.add_argument(
966
948
  '--apiurl', type=str, help='SCANOSS API URL (optional - default: https://api.osskb.org/scan/direct)'
967
949
  )
968
- p.add_argument('--grpc', action='store_true', help='Enable gRPC support')
969
950
 
970
951
  # Global Scan/Fingerprint filter options
971
952
  for p in [p_scan, p_wfp]:
@@ -1001,6 +982,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1001
982
  p_crypto_algorithms,
1002
983
  p_crypto_hints,
1003
984
  p_crypto_versions_in_range,
985
+ c_licenses,
1004
986
  ]:
1005
987
  p.add_argument(
1006
988
  '--key', '-k', type=str, help='SCANOSS API Key token (optional - not required for default OSSKB URL)'
@@ -1039,6 +1021,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1039
1021
  p_crypto_algorithms,
1040
1022
  p_crypto_hints,
1041
1023
  p_crypto_versions_in_range,
1024
+ c_licenses,
1042
1025
  ]:
1043
1026
  p.add_argument(
1044
1027
  '--api2url', type=str, help='SCANOSS gRPC API 2.0 URL (optional - default: https://api.osskb.org)'
@@ -1073,6 +1056,22 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1073
1056
  help='Timeout (in seconds) for syft to complete (optional - default 600)',
1074
1057
  )
1075
1058
 
1059
+ # gRPC support options
1060
+ for p in [
1061
+ c_vulns,
1062
+ p_scan,
1063
+ p_cs,
1064
+ p_crypto_algorithms,
1065
+ p_crypto_hints,
1066
+ p_crypto_versions_in_range,
1067
+ c_semgrep,
1068
+ c_provenance,
1069
+ c_search,
1070
+ c_versions,
1071
+ c_licenses,
1072
+ ]:
1073
+ p.add_argument('--grpc', action='store_true', help='Enable gRPC support')
1074
+
1076
1075
  # Help/Trace command options
1077
1076
  for p in [
1078
1077
  p_scan,
@@ -1104,6 +1103,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1104
1103
  p_crypto_algorithms,
1105
1104
  p_crypto_hints,
1106
1105
  p_crypto_versions_in_range,
1106
+ c_licenses,
1107
1107
  e_dt,
1108
1108
  ]:
1109
1109
  p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages')
@@ -1420,7 +1420,7 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
1420
1420
  strip_snippet_ids=args.strip_snippet,
1421
1421
  scan_settings=scan_settings,
1422
1422
  req_headers=process_req_headers(args.header),
1423
- use_grpc=args.grpc
1423
+ use_grpc=args.grpc,
1424
1424
  )
1425
1425
  if args.wfp:
1426
1426
  if not scanner.is_file_or_snippet_scan():
@@ -1554,13 +1554,14 @@ def convert(parser, args):
1554
1554
  # INSPECT COMMAND HANDLERS - Functions that execute inspection operations
1555
1555
  # =============================================================================
1556
1556
 
1557
+
1557
1558
  def inspect_copyleft(parser, args):
1558
1559
  """
1559
1560
  Handle copyleft license inspection command.
1560
-
1561
+
1561
1562
  Analyses scan results to identify components using copyleft licenses
1562
1563
  that may require compliance actions such as source code disclosure.
1563
-
1564
+
1564
1565
  Parameters
1565
1566
  ----------
1566
1567
  parser : ArgumentParser
@@ -1594,9 +1595,9 @@ def inspect_copyleft(parser, args):
1594
1595
  format_type=args.format,
1595
1596
  status=args.status,
1596
1597
  output=args.output,
1597
- include=args.include, # Additional licenses to check
1598
- exclude=args.exclude, # Licenses to ignore
1599
- explicit=args.explicit, # Explicit license list
1598
+ include=args.include, # Additional licenses to check
1599
+ exclude=args.exclude, # Licenses to ignore
1600
+ explicit=args.explicit, # Explicit license list
1600
1601
  )
1601
1602
 
1602
1603
  # Execute inspection and exit with appropriate status code
@@ -1612,11 +1613,11 @@ def inspect_copyleft(parser, args):
1612
1613
  def inspect_undeclared(parser, args):
1613
1614
  """
1614
1615
  Handle undeclared components inspection command.
1615
-
1616
+
1616
1617
  Analyses scan results to identify components that are present in the
1617
1618
  codebase but not declared in SBOM or manifest files, which may indicate
1618
1619
  security or compliance risks.
1619
-
1620
+
1620
1621
  Parameters
1621
1622
  ----------
1622
1623
  parser : ArgumentParser
@@ -1634,7 +1635,7 @@ def inspect_undeclared(parser, args):
1634
1635
  print_stderr('ERROR: Input file is required for undeclared component inspection')
1635
1636
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1636
1637
  sys.exit(1)
1637
-
1638
+
1638
1639
  # Initialise output file if specified
1639
1640
  if args.output:
1640
1641
  initialise_empty_file(args.output)
@@ -1669,10 +1670,10 @@ def inspect_undeclared(parser, args):
1669
1670
  def inspect_license_summary(parser, args):
1670
1671
  """
1671
1672
  Handle license summary inspection command.
1672
-
1673
+
1673
1674
  Generates comprehensive summary of all licenses detected in scan results,
1674
1675
  including license counts, risk levels, and compliance recommendations.
1675
-
1676
+
1676
1677
  Parameters
1677
1678
  ----------
1678
1679
  parser : ArgumentParser
@@ -1688,7 +1689,7 @@ def inspect_license_summary(parser, args):
1688
1689
  print_stderr('ERROR: Input file is required for license summary')
1689
1690
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1690
1691
  sys.exit(1)
1691
-
1692
+
1692
1693
  # Initialise output file if specified
1693
1694
  if args.output:
1694
1695
  initialise_empty_file(args.output)
@@ -1700,9 +1701,9 @@ def inspect_license_summary(parser, args):
1700
1701
  quiet=args.quiet,
1701
1702
  filepath=args.input,
1702
1703
  output=args.output,
1703
- include=args.include, # Additional licenses to include
1704
- exclude=args.exclude, # Licenses to exclude from summary
1705
- explicit=args.explicit, # Explicit license list to summarize
1704
+ include=args.include, # Additional licenses to include
1705
+ exclude=args.exclude, # Licenses to exclude from summary
1706
+ explicit=args.explicit, # Explicit license list to summarize
1706
1707
  )
1707
1708
  try:
1708
1709
  # Execute summary generation
@@ -1713,13 +1714,14 @@ def inspect_license_summary(parser, args):
1713
1714
  traceback.print_exc()
1714
1715
  sys.exit(1)
1715
1716
 
1717
+
1716
1718
  def inspect_component_summary(parser, args):
1717
1719
  """
1718
1720
  Handle component summary inspection command.
1719
-
1721
+
1720
1722
  Generates a comprehensive summary of all components detected in scan results,
1721
1723
  including component counts, versions, match types, and security information.
1722
-
1724
+
1723
1725
  Parameters
1724
1726
  ----------
1725
1727
  parser : ArgumentParser
@@ -1734,10 +1736,10 @@ def inspect_component_summary(parser, args):
1734
1736
  print_stderr('ERROR: Input file is required for component summary')
1735
1737
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1736
1738
  sys.exit(1)
1737
-
1739
+
1738
1740
  # Initialise an output file if specified
1739
1741
  if args.output:
1740
- initialise_empty_file(args.output) # Create/clear output file
1742
+ initialise_empty_file(args.output) # Create/clear output file
1741
1743
 
1742
1744
  # Create and configure component summary generator
1743
1745
  i_component_summary = ComponentSummary(
@@ -1757,14 +1759,15 @@ def inspect_component_summary(parser, args):
1757
1759
  traceback.print_exc()
1758
1760
  sys.exit(1)
1759
1761
 
1762
+
1760
1763
  def inspect_dep_track_project_violations(parser, args):
1761
1764
  """
1762
1765
  Handle Dependency Track project inspection command.
1763
-
1766
+
1764
1767
  Analyses Dependency Track projects for policy violations, security issues,
1765
1768
  and compliance status. Connects to DT API to retrieve project data and
1766
1769
  generate detailed violation reports.
1767
-
1770
+
1768
1771
  Parameters
1769
1772
  ----------
1770
1773
  parser : ArgumentParser
@@ -1794,14 +1797,14 @@ def inspect_dep_track_project_violations(parser, args):
1794
1797
  trace=args.trace,
1795
1798
  quiet=args.quiet,
1796
1799
  output=args.output,
1797
- status= args.status,
1800
+ status=args.status,
1798
1801
  format_type=args.format,
1799
- url=args.url, # DT server URL
1800
- api_key=args.apikey, # Authentication key
1801
- project_id=args.project_id, # Target project UUID
1802
+ url=args.url, # DT server URL
1803
+ api_key=args.apikey, # Authentication key
1804
+ project_id=args.project_id, # Target project UUID
1802
1805
  upload_token=args.upload_token, # Upload access token
1803
- project_name=args.project_name, # DT project name
1804
- project_version=args.project_version, # DT project version
1806
+ project_name=args.project_name, # DT project name
1807
+ project_version=args.project_version, # DT project version
1805
1808
  timeout=args.timeout,
1806
1809
  )
1807
1810
  # Execute inspection and exit with appropriate status code
@@ -1818,6 +1821,7 @@ def inspect_dep_track_project_violations(parser, args):
1818
1821
  # END INSPECT COMMAND HANDLERS
1819
1822
  # =============================================================================
1820
1823
 
1824
+
1821
1825
  def export_dt(parser, args):
1822
1826
  """
1823
1827
  Validates and exports a Software Bill of Materials (SBOM) to a Dependency-Track server.
@@ -1845,8 +1849,9 @@ def export_dt(parser, args):
1845
1849
  trace=args.trace,
1846
1850
  quiet=args.quiet,
1847
1851
  )
1848
- success = dt_exporter.upload_sbom_file(args.input, args.project_id, args.project_name,
1849
- args.project_version, args.output)
1852
+ success = dt_exporter.upload_sbom_file(
1853
+ args.input, args.project_id, args.project_name, args.project_version, args.output
1854
+ )
1850
1855
  if not success:
1851
1856
  sys.exit(1)
1852
1857
  except Exception as e:
@@ -1855,6 +1860,7 @@ def export_dt(parser, args):
1855
1860
  traceback.print_exc()
1856
1861
  sys.exit(1)
1857
1862
 
1863
+
1858
1864
  def _dt_args_validator(parser, args):
1859
1865
  """
1860
1866
  Validates command-line arguments related to project identification.
@@ -1884,6 +1890,7 @@ def _dt_args_validator(parser, args):
1884
1890
  print_stderr('Please supply a project name (--project-name) and version (--project-version)')
1885
1891
  sys.exit(1)
1886
1892
 
1893
+
1887
1894
  def utils_certloc(*_):
1888
1895
  """
1889
1896
  Run the "utils certloc" sub-command
@@ -2184,6 +2191,7 @@ def comp_semgrep(parser, args):
2184
2191
  pac=pac_file,
2185
2192
  timeout=args.timeout,
2186
2193
  req_headers=process_req_headers(args.header),
2194
+ use_grpc=args.grpc,
2187
2195
  )
2188
2196
  if not comps.get_semgrep_details(args.input, args.purl, args.output):
2189
2197
  sys.exit(1)
@@ -2222,6 +2230,7 @@ def comp_search(parser, args):
2222
2230
  pac=pac_file,
2223
2231
  timeout=args.timeout,
2224
2232
  req_headers=process_req_headers(args.header),
2233
+ use_grpc=args.grpc,
2225
2234
  )
2226
2235
  if not comps.search_components(
2227
2236
  args.output,
@@ -2267,6 +2276,7 @@ def comp_versions(parser, args):
2267
2276
  pac=pac_file,
2268
2277
  timeout=args.timeout,
2269
2278
  req_headers=process_req_headers(args.header),
2279
+ use_grpc=args.grpc,
2270
2280
  )
2271
2281
  if not comps.get_component_versions(args.output, json_file=args.input, purl=args.purl, limit=args.limit):
2272
2282
  sys.exit(1)
@@ -2302,11 +2312,48 @@ def comp_provenance(parser, args):
2302
2312
  pac=pac_file,
2303
2313
  timeout=args.timeout,
2304
2314
  req_headers=process_req_headers(args.header),
2315
+ use_grpc=args.grpc,
2305
2316
  )
2306
2317
  if not comps.get_provenance_details(args.input, args.purl, args.output, args.origin):
2307
2318
  sys.exit(1)
2308
2319
 
2309
2320
 
2321
+ def comp_licenses(parser, args):
2322
+ """
2323
+ Run the "component licenses" sub-command
2324
+ Parameters
2325
+ ----------
2326
+ parser: ArgumentParser
2327
+ command line parser object
2328
+ args: Namespace
2329
+ Parsed arguments
2330
+ """
2331
+ if (not args.purl and not args.input) or (args.purl and args.input):
2332
+ print_stderr('ERROR: Please specify an input file or purl to decorate (--purl or --input)')
2333
+ parser.parse_args([args.subparser, args.subparsercmd, '-h'])
2334
+ sys.exit(1)
2335
+ if args.ca_cert and not os.path.exists(args.ca_cert):
2336
+ print_stderr(f'ERROR: Certificate file does not exist: {args.ca_cert}.')
2337
+ sys.exit(1)
2338
+ pac_file = get_pac_file(args.pac)
2339
+ comps = Components(
2340
+ debug=args.debug,
2341
+ trace=args.trace,
2342
+ quiet=args.quiet,
2343
+ grpc_url=args.api2url,
2344
+ api_key=args.key,
2345
+ ca_cert=args.ca_cert,
2346
+ proxy=args.proxy,
2347
+ grpc_proxy=args.grpc_proxy,
2348
+ pac=pac_file,
2349
+ timeout=args.timeout,
2350
+ req_headers=process_req_headers(args.header),
2351
+ use_grpc=args.grpc,
2352
+ )
2353
+ if not comps.get_licenses(args.input, args.purl, args.output):
2354
+ sys.exit(1)
2355
+
2356
+
2310
2357
  def results(parser, args):
2311
2358
  """
2312
2359
  Run the "results" sub-command