scanoss 1.31.5__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 (36) 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 +196 -144
  24. scanoss/components.py +80 -50
  25. scanoss/cryptography.py +64 -44
  26. scanoss/cyclonedx.py +22 -0
  27. scanoss/data/build_date.txt +1 -1
  28. scanoss/scanner.py +3 -0
  29. scanoss/scanossapi.py +22 -24
  30. scanoss/scanossgrpc.py +538 -287
  31. {scanoss-1.31.5.dist-info → scanoss-1.34.0.dist-info}/METADATA +4 -3
  32. {scanoss-1.31.5.dist-info → scanoss-1.34.0.dist-info}/RECORD +36 -34
  33. {scanoss-1.31.5.dist-info → scanoss-1.34.0.dist-info}/WHEEL +0 -0
  34. {scanoss-1.31.5.dist-info → scanoss-1.34.0.dist-info}/entry_points.txt +0 -0
  35. {scanoss-1.31.5.dist-info → scanoss-1.34.0.dist-info}/licenses/LICENSE +0 -0
  36. {scanoss-1.31.5.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 (
@@ -309,6 +311,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
309
311
  )
310
312
  c_vulns.set_defaults(func=comp_vulns)
311
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)
322
+
312
323
  # Component Sub-command: component semgrep
313
324
  c_semgrep = comp_sub.add_parser(
314
325
  'semgrep',
@@ -410,7 +421,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
410
421
  p_crypto_versions_in_range.set_defaults(func=crypto_versions_in_range)
411
422
 
412
423
  # Common purl Component sub-command options
413
- 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
+ ]:
414
433
  p.add_argument('--purl', '-p', type=str, nargs='*', help='Package URL - PURL to process.')
415
434
  p.add_argument('--input', '-i', type=str, help='Input file name')
416
435
 
@@ -424,6 +443,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
424
443
  p_crypto_algorithms,
425
444
  p_crypto_hints,
426
445
  p_crypto_versions_in_range,
446
+ c_licenses,
427
447
  ]:
428
448
  p.add_argument(
429
449
  '--timeout',
@@ -540,32 +560,32 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
540
560
  # =========================================================================
541
561
  # INSPECT SUBCOMMAND - Analysis and validation of scan results
542
562
  # =========================================================================
543
-
563
+
544
564
  # Main inspect parser - provides tools for analyzing scan results
545
565
  p_inspect = subparsers.add_parser(
546
- 'inspect',
547
- aliases=['insp', 'ins'],
566
+ 'inspect',
567
+ aliases=['insp', 'ins'],
548
568
  description=f'Inspect and analyse scan results: {__version__}',
549
- help='Inspect and analyse scan results'
569
+ help='Inspect and analyse scan results',
550
570
  )
551
571
 
552
572
  # Inspect sub-commands parser
553
573
  p_inspect_sub = p_inspect.add_subparsers(
554
- title='Inspect Commands',
555
- dest='subparsercmd',
556
- description='Available inspection sub-commands',
557
- help='Choose an inspection type'
574
+ title='Inspect Commands',
575
+ dest='subparsercmd',
576
+ description='Available inspection sub-commands',
577
+ help='Choose an inspection type',
558
578
  )
559
579
 
560
580
  # -------------------------------------------------------------------------
561
581
  # RAW RESULTS INSPECTION - Analyse raw scan output
562
582
  # -------------------------------------------------------------------------
563
-
583
+
564
584
  # Raw results parser - handles inspection of unprocessed scan results
565
585
  p_inspect_raw = p_inspect_sub.add_parser(
566
586
  'raw',
567
587
  description='Inspect and analyse SCANOSS raw scan results',
568
- help='Analyse raw scan results for various compliance issues'
588
+ help='Analyse raw scan results for various compliance issues',
569
589
  )
570
590
 
571
591
  # Raw results sub-commands parser
@@ -573,15 +593,15 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
573
593
  title='Raw Results Inspection Commands',
574
594
  dest='subparser_subcmd',
575
595
  description='Tools for analyzing raw scan results',
576
- help='Choose a raw results analysis type'
596
+ help='Choose a raw results analysis type',
577
597
  )
578
598
 
579
599
  # Copyleft license inspection - identifies copyleft license violations
580
600
  p_inspect_raw_copyleft = p_inspect_raw_sub.add_parser(
581
- 'copyleft',
582
- aliases=['cp'],
583
- description='Identify components with copyleft licenses that may require compliance action',
584
- 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',
585
605
  )
586
606
 
587
607
  # License summary inspection - provides overview of all detected licenses
@@ -589,7 +609,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
589
609
  'license-summary',
590
610
  aliases=['lic-summary', 'licsum'],
591
611
  description='Generate comprehensive summary of all licenses found in scan results',
592
- help='Generate license summary report'
612
+ help='Generate license summary report',
593
613
  )
594
614
 
595
615
  # Component summary inspection - provides overview of all detected components
@@ -597,7 +617,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
597
617
  'component-summary',
598
618
  aliases=['comp-summary', 'compsum'],
599
619
  description='Generate comprehensive summary of all components found in scan results',
600
- help='Generate component summary report'
620
+ help='Generate component summary report',
601
621
  )
602
622
 
603
623
  # Undeclared components inspection - finds components not declared in SBOM
@@ -605,7 +625,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
605
625
  'undeclared',
606
626
  aliases=['un'],
607
627
  description='Identify components present in code but not declared in SBOM files',
608
- help='Find undeclared components'
628
+ help='Find undeclared components',
609
629
  )
610
630
  # SBOM format option for undeclared components inspection
611
631
  p_inspect_raw_undeclared.add_argument(
@@ -613,19 +633,19 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
613
633
  required=False,
614
634
  choices=['legacy', 'settings'],
615
635
  default='settings',
616
- help='SBOM format type for comparison: legacy or settings (default)'
636
+ help='SBOM format type for comparison: legacy or settings (default)',
617
637
  )
618
638
 
619
639
  # -------------------------------------------------------------------------
620
640
  # BACKWARD COMPATIBILITY - Support old inspect command format
621
641
  # -------------------------------------------------------------------------
622
-
642
+
623
643
  # Legacy copyleft inspection - backward compatibility for 'scanoss-py inspect copyleft'
624
644
  p_inspect_legacy_copyleft = p_inspect_sub.add_parser(
625
- 'copyleft',
626
- aliases=['cp'],
627
- description='Identify components with copyleft licenses that may require compliance action',
628
- 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)',
629
649
  )
630
650
 
631
651
  # Legacy undeclared components inspection - backward compatibility for 'scanoss-py inspect undeclared'
@@ -633,16 +653,16 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
633
653
  'undeclared',
634
654
  aliases=['un'],
635
655
  description='Identify components present in code but not declared in SBOM files',
636
- help='Find undeclared components (legacy format)'
656
+ help='Find undeclared components (legacy format)',
637
657
  )
638
-
658
+
639
659
  # SBOM format option for legacy undeclared components inspection
640
660
  p_inspect_legacy_undeclared.add_argument(
641
661
  '--sbom-format',
642
662
  required=False,
643
663
  choices=['legacy', 'settings'],
644
664
  default='settings',
645
- help='SBOM format type for comparison: legacy or settings (default)'
665
+ help='SBOM format type for comparison: legacy or settings (default)',
646
666
  )
647
667
 
648
668
  # Legacy license summary inspection - backward compatibility for 'scanoss-py inspect license-summary'
@@ -650,7 +670,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
650
670
  'license-summary',
651
671
  aliases=['lic-summary', 'licsum'],
652
672
  description='Generate comprehensive summary of all licenses found in scan results',
653
- help='Generate license summary report (legacy format)'
673
+ help='Generate license summary report (legacy format)',
654
674
  )
655
675
 
656
676
  # Legacy component summary inspection - backward compatibility for 'scanoss-py inspect component-summary'
@@ -658,83 +678,63 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
658
678
  'component-summary',
659
679
  aliases=['comp-summary', 'compsum'],
660
680
  description='Generate comprehensive summary of all components found in scan results',
661
- help='Generate component summary report (legacy format)'
681
+ help='Generate component summary report (legacy format)',
662
682
  )
663
683
 
664
684
  # Applies the same configuration to both legacy and raw versions
665
685
  # License filtering options - common to (legacy) copyleft and license summary commands
666
- for p in [p_inspect_raw_copyleft, p_inspect_raw_license_summary,
667
- p_inspect_legacy_copyleft, p_inspect_legacy_license_summary]:
668
- p.add_argument(
669
- '--include',
670
- help='Additional licenses to include in analysis (comma-separated list)'
671
- )
672
- p.add_argument(
673
- '--exclude',
674
- help='Licenses to exclude from analysis (comma-separated list)'
675
- )
676
- p.add_argument(
677
- '--explicit',
678
- help='Use only these specific licenses for analysis (comma-separated list)'
679
- )
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)')
680
695
 
681
696
  # Common options for (legacy) copyleft and undeclared component inspection
682
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')
683
699
  p.add_argument(
684
- '-i', '--input',
685
- nargs='?',
686
- help='Path to scan results file to analyse'
687
- )
688
- p.add_argument(
689
- '-f', '--format',
700
+ '-f',
701
+ '--format',
690
702
  required=False,
691
703
  choices=['json', 'md', 'jira_md'],
692
704
  default='json',
693
- help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)'
694
- )
695
- p.add_argument(
696
- '-o', '--output',
697
- type=str,
698
- help='Save detailed results to specified file'
699
- )
700
- p.add_argument(
701
- '-s', '--status',
702
- type=str,
703
- help='Save summary status report to Markdown file'
705
+ help='Output format: json (default), md (Markdown), or jira_md (JIRA Markdown)',
704
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')
705
709
 
706
710
  # Common options for (legacy) license and component summary commands
707
- for p in [p_inspect_raw_license_summary, p_inspect_raw_component_summary,
708
- p_inspect_legacy_license_summary, p_inspect_legacy_component_summary]:
709
- p.add_argument(
710
- '-i', '--input',
711
- nargs='?',
712
- help='Path to scan results file to analyse'
713
- )
714
- p.add_argument(
715
- '-o', '--output',
716
- type=str,
717
- help='Save summary report to specified file'
718
- )
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')
719
719
 
720
720
  # -------------------------------------------------------------------------
721
721
  # DEPENDENCY TRACK INSPECTION - Analyse Dependency Track project data
722
722
  # -------------------------------------------------------------------------
723
-
723
+
724
724
  # Dependency Track parser - handles inspection of DT project status and violations
725
725
  p_dep_track_sub = p_inspect_sub.add_parser(
726
726
  'dependency-track',
727
727
  aliases=['dt'],
728
728
  description='Inspect and analyse Dependency Track project status and policy violations',
729
- help='Analyse Dependency Track projects'
729
+ help='Analyse Dependency Track projects',
730
730
  )
731
-
731
+
732
732
  # Dependency Track sub-commands parser
733
733
  p_inspect_dep_track_sub = p_dep_track_sub.add_subparsers(
734
734
  title='Dependency Track Inspection Commands',
735
735
  dest='subparser_subcmd',
736
736
  description='Tools for analysing Dependency Track project data',
737
- help='Choose a Dependency Track analysis type'
737
+ help='Choose a Dependency Track analysis type',
738
738
  )
739
739
 
740
740
  # Project violations inspection - analyses policy violations in DT projects
@@ -742,70 +742,52 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
742
742
  'project-violations',
743
743
  aliases=['pv'],
744
744
  description='Analyse policy violations and compliance issues in Dependency Track projects',
745
- help='Inspect project policy violations'
745
+ help='Inspect project policy violations',
746
746
  )
747
747
  # Dependency Track connection and authentication options
748
748
  p_inspect_dt_project_violation.add_argument(
749
- '--url',
750
- required=True,
751
- type=str,
752
- 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)'
753
750
  )
754
751
  p_inspect_dt_project_violation.add_argument(
755
- '--upload-token', '-ut',
752
+ '--upload-token',
753
+ '-ut',
756
754
  required=False,
757
- type=str,
758
- help='Project-specific upload token for accessing DT project data'
755
+ type=str,
756
+ help='Project-specific upload token for accessing DT project data',
759
757
  )
760
758
  p_inspect_dt_project_violation.add_argument(
761
- '--project-id', '-pid',
762
- required=False,
763
- type=str,
764
- help='Dependency Track project UUID to inspect'
759
+ '--project-id', '-pid', required=False, type=str, help='Dependency Track project UUID to inspect'
765
760
  )
766
761
  p_inspect_dt_project_violation.add_argument(
767
- '--apikey', '-k',
768
- required=True,
769
- type=str,
770
- help='Dependency Track API key for authentication'
762
+ '--apikey', '-k', required=True, type=str, help='Dependency Track API key for authentication'
771
763
  )
772
764
  p_inspect_dt_project_violation.add_argument(
773
- '--project-name', '-pn',
774
- required=False,
775
- type=str,
776
- help='Dependency Track project name'
765
+ '--project-name', '-pn', required=False, type=str, help='Dependency Track project name'
777
766
  )
778
767
  p_inspect_dt_project_violation.add_argument(
779
- '--project-version', '-pv',
780
- required=False,
781
- type=str,
782
- help='Dependency Track project version'
768
+ '--project-version', '-pv', required=False, type=str, help='Dependency Track project version'
783
769
  )
784
770
  p_inspect_dt_project_violation.add_argument(
785
- '--output', '-o',
786
- required=False,
787
- type=str,
788
- help='Save inspection results to specified file'
771
+ '--output', '-o', required=False, type=str, help='Save inspection results to specified file'
789
772
  )
790
773
  p_inspect_dt_project_violation.add_argument(
791
- '--status',
792
- required=False,
793
- type=str,
794
- help='Save summary status report to specified file'
774
+ '--status', required=False, type=str, help='Save summary status report to specified file'
795
775
  )
796
776
  p_inspect_dt_project_violation.add_argument(
797
- '--format', '-f',
777
+ '--format',
778
+ '-f',
798
779
  required=False,
799
780
  choices=['json', 'md', 'jira_md'],
800
781
  default='json',
801
- 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)',
802
783
  )
803
784
  p_inspect_dt_project_violation.add_argument(
804
- '--timeout', '-M',
785
+ '--timeout',
786
+ '-M',
805
787
  required=False,
806
788
  default=300,
807
789
  type=float,
808
- help='Timeout (in seconds) for API communication (optional - default 300 sec)'
790
+ help='Timeout (in seconds) for API communication (optional - default 300 sec)',
809
791
  )
810
792
 
811
793
  # TODO Move to the command call def location
@@ -851,7 +833,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
851
833
  e_dt.add_argument('-i', '--input', type=str, required=True, help='Input SBOM file (CycloneDX JSON format)')
852
834
  e_dt.add_argument('--url', type=str, required=True, help='Dependency Track base URL')
853
835
  e_dt.add_argument('--apikey', '-k', type=str, required=True, help='Dependency Track API key')
854
- 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')
855
837
  e_dt.add_argument('--project-id', '-pid', type=str, help='Dependency Track project UUID')
856
838
  e_dt.add_argument('--project-name', '-pn', type=str, help='Dependency Track project name')
857
839
  e_dt.add_argument('--project-version', '-pv', type=str, help='Dependency Track project version')
@@ -926,6 +908,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
926
908
  p_crypto_algorithms,
927
909
  p_crypto_hints,
928
910
  p_crypto_versions_in_range,
911
+ c_licenses,
929
912
  ]:
930
913
  p.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
931
914
 
@@ -964,7 +947,6 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
964
947
  p.add_argument(
965
948
  '--apiurl', type=str, help='SCANOSS API URL (optional - default: https://api.osskb.org/scan/direct)'
966
949
  )
967
- p.add_argument('--ignore-cert-errors', action='store_true', help='Ignore certificate errors')
968
950
 
969
951
  # Global Scan/Fingerprint filter options
970
952
  for p in [p_scan, p_wfp]:
@@ -1000,6 +982,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1000
982
  p_crypto_algorithms,
1001
983
  p_crypto_hints,
1002
984
  p_crypto_versions_in_range,
985
+ c_licenses,
1003
986
  ]:
1004
987
  p.add_argument(
1005
988
  '--key', '-k', type=str, help='SCANOSS API Key token (optional - not required for default OSSKB URL)'
@@ -1038,6 +1021,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1038
1021
  p_crypto_algorithms,
1039
1022
  p_crypto_hints,
1040
1023
  p_crypto_versions_in_range,
1024
+ c_licenses,
1041
1025
  ]:
1042
1026
  p.add_argument(
1043
1027
  '--api2url', type=str, help='SCANOSS gRPC API 2.0 URL (optional - default: https://api.osskb.org)'
@@ -1055,6 +1039,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1055
1039
  type=str,
1056
1040
  help='Headers to be sent on request (e.g., -hdr "Name: Value") - can be used multiple times',
1057
1041
  )
1042
+ p.add_argument('--ignore-cert-errors', action='store_true', help='Ignore certificate errors')
1058
1043
 
1059
1044
  # Syft options
1060
1045
  for p in [p_cs, p_dep]:
@@ -1071,6 +1056,22 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1071
1056
  help='Timeout (in seconds) for syft to complete (optional - default 600)',
1072
1057
  )
1073
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
+
1074
1075
  # Help/Trace command options
1075
1076
  for p in [
1076
1077
  p_scan,
@@ -1102,6 +1103,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1102
1103
  p_crypto_algorithms,
1103
1104
  p_crypto_hints,
1104
1105
  p_crypto_versions_in_range,
1106
+ c_licenses,
1105
1107
  e_dt,
1106
1108
  ]:
1107
1109
  p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages')
@@ -1418,6 +1420,7 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
1418
1420
  strip_snippet_ids=args.strip_snippet,
1419
1421
  scan_settings=scan_settings,
1420
1422
  req_headers=process_req_headers(args.header),
1423
+ use_grpc=args.grpc,
1421
1424
  )
1422
1425
  if args.wfp:
1423
1426
  if not scanner.is_file_or_snippet_scan():
@@ -1551,13 +1554,14 @@ def convert(parser, args):
1551
1554
  # INSPECT COMMAND HANDLERS - Functions that execute inspection operations
1552
1555
  # =============================================================================
1553
1556
 
1557
+
1554
1558
  def inspect_copyleft(parser, args):
1555
1559
  """
1556
1560
  Handle copyleft license inspection command.
1557
-
1561
+
1558
1562
  Analyses scan results to identify components using copyleft licenses
1559
1563
  that may require compliance actions such as source code disclosure.
1560
-
1564
+
1561
1565
  Parameters
1562
1566
  ----------
1563
1567
  parser : ArgumentParser
@@ -1591,9 +1595,9 @@ def inspect_copyleft(parser, args):
1591
1595
  format_type=args.format,
1592
1596
  status=args.status,
1593
1597
  output=args.output,
1594
- include=args.include, # Additional licenses to check
1595
- exclude=args.exclude, # Licenses to ignore
1596
- 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
1597
1601
  )
1598
1602
 
1599
1603
  # Execute inspection and exit with appropriate status code
@@ -1609,11 +1613,11 @@ def inspect_copyleft(parser, args):
1609
1613
  def inspect_undeclared(parser, args):
1610
1614
  """
1611
1615
  Handle undeclared components inspection command.
1612
-
1616
+
1613
1617
  Analyses scan results to identify components that are present in the
1614
1618
  codebase but not declared in SBOM or manifest files, which may indicate
1615
1619
  security or compliance risks.
1616
-
1620
+
1617
1621
  Parameters
1618
1622
  ----------
1619
1623
  parser : ArgumentParser
@@ -1631,7 +1635,7 @@ def inspect_undeclared(parser, args):
1631
1635
  print_stderr('ERROR: Input file is required for undeclared component inspection')
1632
1636
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1633
1637
  sys.exit(1)
1634
-
1638
+
1635
1639
  # Initialise output file if specified
1636
1640
  if args.output:
1637
1641
  initialise_empty_file(args.output)
@@ -1666,10 +1670,10 @@ def inspect_undeclared(parser, args):
1666
1670
  def inspect_license_summary(parser, args):
1667
1671
  """
1668
1672
  Handle license summary inspection command.
1669
-
1673
+
1670
1674
  Generates comprehensive summary of all licenses detected in scan results,
1671
1675
  including license counts, risk levels, and compliance recommendations.
1672
-
1676
+
1673
1677
  Parameters
1674
1678
  ----------
1675
1679
  parser : ArgumentParser
@@ -1685,7 +1689,7 @@ def inspect_license_summary(parser, args):
1685
1689
  print_stderr('ERROR: Input file is required for license summary')
1686
1690
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1687
1691
  sys.exit(1)
1688
-
1692
+
1689
1693
  # Initialise output file if specified
1690
1694
  if args.output:
1691
1695
  initialise_empty_file(args.output)
@@ -1697,9 +1701,9 @@ def inspect_license_summary(parser, args):
1697
1701
  quiet=args.quiet,
1698
1702
  filepath=args.input,
1699
1703
  output=args.output,
1700
- include=args.include, # Additional licenses to include
1701
- exclude=args.exclude, # Licenses to exclude from summary
1702
- 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
1703
1707
  )
1704
1708
  try:
1705
1709
  # Execute summary generation
@@ -1710,13 +1714,14 @@ def inspect_license_summary(parser, args):
1710
1714
  traceback.print_exc()
1711
1715
  sys.exit(1)
1712
1716
 
1717
+
1713
1718
  def inspect_component_summary(parser, args):
1714
1719
  """
1715
1720
  Handle component summary inspection command.
1716
-
1721
+
1717
1722
  Generates a comprehensive summary of all components detected in scan results,
1718
1723
  including component counts, versions, match types, and security information.
1719
-
1724
+
1720
1725
  Parameters
1721
1726
  ----------
1722
1727
  parser : ArgumentParser
@@ -1731,10 +1736,10 @@ def inspect_component_summary(parser, args):
1731
1736
  print_stderr('ERROR: Input file is required for component summary')
1732
1737
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1733
1738
  sys.exit(1)
1734
-
1739
+
1735
1740
  # Initialise an output file if specified
1736
1741
  if args.output:
1737
- initialise_empty_file(args.output) # Create/clear output file
1742
+ initialise_empty_file(args.output) # Create/clear output file
1738
1743
 
1739
1744
  # Create and configure component summary generator
1740
1745
  i_component_summary = ComponentSummary(
@@ -1754,14 +1759,15 @@ def inspect_component_summary(parser, args):
1754
1759
  traceback.print_exc()
1755
1760
  sys.exit(1)
1756
1761
 
1762
+
1757
1763
  def inspect_dep_track_project_violations(parser, args):
1758
1764
  """
1759
1765
  Handle Dependency Track project inspection command.
1760
-
1766
+
1761
1767
  Analyses Dependency Track projects for policy violations, security issues,
1762
1768
  and compliance status. Connects to DT API to retrieve project data and
1763
1769
  generate detailed violation reports.
1764
-
1770
+
1765
1771
  Parameters
1766
1772
  ----------
1767
1773
  parser : ArgumentParser
@@ -1791,14 +1797,14 @@ def inspect_dep_track_project_violations(parser, args):
1791
1797
  trace=args.trace,
1792
1798
  quiet=args.quiet,
1793
1799
  output=args.output,
1794
- status= args.status,
1800
+ status=args.status,
1795
1801
  format_type=args.format,
1796
- url=args.url, # DT server URL
1797
- api_key=args.apikey, # Authentication key
1798
- 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
1799
1805
  upload_token=args.upload_token, # Upload access token
1800
- project_name=args.project_name, # DT project name
1801
- 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
1802
1808
  timeout=args.timeout,
1803
1809
  )
1804
1810
  # Execute inspection and exit with appropriate status code
@@ -1815,6 +1821,7 @@ def inspect_dep_track_project_violations(parser, args):
1815
1821
  # END INSPECT COMMAND HANDLERS
1816
1822
  # =============================================================================
1817
1823
 
1824
+
1818
1825
  def export_dt(parser, args):
1819
1826
  """
1820
1827
  Validates and exports a Software Bill of Materials (SBOM) to a Dependency-Track server.
@@ -1842,8 +1849,9 @@ def export_dt(parser, args):
1842
1849
  trace=args.trace,
1843
1850
  quiet=args.quiet,
1844
1851
  )
1845
- success = dt_exporter.upload_sbom_file(args.input, args.project_id, args.project_name,
1846
- 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
+ )
1847
1855
  if not success:
1848
1856
  sys.exit(1)
1849
1857
  except Exception as e:
@@ -1852,6 +1860,7 @@ def export_dt(parser, args):
1852
1860
  traceback.print_exc()
1853
1861
  sys.exit(1)
1854
1862
 
1863
+
1855
1864
  def _dt_args_validator(parser, args):
1856
1865
  """
1857
1866
  Validates command-line arguments related to project identification.
@@ -1881,6 +1890,7 @@ def _dt_args_validator(parser, args):
1881
1890
  print_stderr('Please supply a project name (--project-name) and version (--project-version)')
1882
1891
  sys.exit(1)
1883
1892
 
1893
+
1884
1894
  def utils_certloc(*_):
1885
1895
  """
1886
1896
  Run the "utils certloc" sub-command
@@ -2144,6 +2154,8 @@ def comp_vulns(parser, args):
2144
2154
  pac=pac_file,
2145
2155
  timeout=args.timeout,
2146
2156
  req_headers=process_req_headers(args.header),
2157
+ ignore_cert_errors=args.ignore_cert_errors,
2158
+ use_grpc=args.grpc,
2147
2159
  )
2148
2160
  if not comps.get_vulnerabilities(args.input, args.purl, args.output):
2149
2161
  sys.exit(1)
@@ -2179,6 +2191,7 @@ def comp_semgrep(parser, args):
2179
2191
  pac=pac_file,
2180
2192
  timeout=args.timeout,
2181
2193
  req_headers=process_req_headers(args.header),
2194
+ use_grpc=args.grpc,
2182
2195
  )
2183
2196
  if not comps.get_semgrep_details(args.input, args.purl, args.output):
2184
2197
  sys.exit(1)
@@ -2217,6 +2230,7 @@ def comp_search(parser, args):
2217
2230
  pac=pac_file,
2218
2231
  timeout=args.timeout,
2219
2232
  req_headers=process_req_headers(args.header),
2233
+ use_grpc=args.grpc,
2220
2234
  )
2221
2235
  if not comps.search_components(
2222
2236
  args.output,
@@ -2262,6 +2276,7 @@ def comp_versions(parser, args):
2262
2276
  pac=pac_file,
2263
2277
  timeout=args.timeout,
2264
2278
  req_headers=process_req_headers(args.header),
2279
+ use_grpc=args.grpc,
2265
2280
  )
2266
2281
  if not comps.get_component_versions(args.output, json_file=args.input, purl=args.purl, limit=args.limit):
2267
2282
  sys.exit(1)
@@ -2297,11 +2312,48 @@ def comp_provenance(parser, args):
2297
2312
  pac=pac_file,
2298
2313
  timeout=args.timeout,
2299
2314
  req_headers=process_req_headers(args.header),
2315
+ use_grpc=args.grpc,
2300
2316
  )
2301
2317
  if not comps.get_provenance_details(args.input, args.purl, args.output, args.origin):
2302
2318
  sys.exit(1)
2303
2319
 
2304
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
+
2305
2357
  def results(parser, args):
2306
2358
  """
2307
2359
  Run the "results" sub-command