scanoss 1.32.0__py3-none-any.whl → 1.35.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 +200 -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.35.0.dist-info}/METADATA +4 -3
  30. {scanoss-1.32.0.dist-info → scanoss-1.35.0.dist-info}/RECORD +34 -32
  31. {scanoss-1.32.0.dist-info → scanoss-1.35.0.dist-info}/WHEEL +0 -0
  32. {scanoss-1.32.0.dist-info → scanoss-1.35.0.dist-info}/entry_points.txt +0 -0
  33. {scanoss-1.32.0.dist-info → scanoss-1.35.0.dist-info}/licenses/LICENSE +0 -0
  34. {scanoss-1.32.0.dist-info → scanoss-1.35.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,23 @@ 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', default=True, help='Use gRPC (default)')
1074
+ p.add_argument('--rest', action='store_true', dest='rest', help='Use REST instead of gRPC')
1075
+
1076
1076
  # Help/Trace command options
1077
1077
  for p in [
1078
1078
  p_scan,
@@ -1104,6 +1104,7 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1104
1104
  p_crypto_algorithms,
1105
1105
  p_crypto_hints,
1106
1106
  p_crypto_versions_in_range,
1107
+ c_licenses,
1107
1108
  e_dt,
1108
1109
  ]:
1109
1110
  p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages')
@@ -1111,6 +1112,12 @@ def setup_args() -> None: # noqa: PLR0912, PLR0915
1111
1112
  p.add_argument('--quiet', '-q', action='store_true', help='Enable quiet mode')
1112
1113
 
1113
1114
  args = parser.parse_args()
1115
+
1116
+ # TODO: Remove this hack once we go back to using REST as default
1117
+ # Handle --rest overriding --grpc default
1118
+ if hasattr(args, 'rest') and args.rest:
1119
+ args.grpc = False
1120
+
1114
1121
  if args.version:
1115
1122
  ver(parser, args)
1116
1123
  sys.exit(0)
@@ -1420,7 +1427,7 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
1420
1427
  strip_snippet_ids=args.strip_snippet,
1421
1428
  scan_settings=scan_settings,
1422
1429
  req_headers=process_req_headers(args.header),
1423
- use_grpc=args.grpc
1430
+ use_grpc=args.grpc,
1424
1431
  )
1425
1432
  if args.wfp:
1426
1433
  if not scanner.is_file_or_snippet_scan():
@@ -1554,13 +1561,14 @@ def convert(parser, args):
1554
1561
  # INSPECT COMMAND HANDLERS - Functions that execute inspection operations
1555
1562
  # =============================================================================
1556
1563
 
1564
+
1557
1565
  def inspect_copyleft(parser, args):
1558
1566
  """
1559
1567
  Handle copyleft license inspection command.
1560
-
1568
+
1561
1569
  Analyses scan results to identify components using copyleft licenses
1562
1570
  that may require compliance actions such as source code disclosure.
1563
-
1571
+
1564
1572
  Parameters
1565
1573
  ----------
1566
1574
  parser : ArgumentParser
@@ -1594,9 +1602,9 @@ def inspect_copyleft(parser, args):
1594
1602
  format_type=args.format,
1595
1603
  status=args.status,
1596
1604
  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
1605
+ include=args.include, # Additional licenses to check
1606
+ exclude=args.exclude, # Licenses to ignore
1607
+ explicit=args.explicit, # Explicit license list
1600
1608
  )
1601
1609
 
1602
1610
  # Execute inspection and exit with appropriate status code
@@ -1612,11 +1620,11 @@ def inspect_copyleft(parser, args):
1612
1620
  def inspect_undeclared(parser, args):
1613
1621
  """
1614
1622
  Handle undeclared components inspection command.
1615
-
1623
+
1616
1624
  Analyses scan results to identify components that are present in the
1617
1625
  codebase but not declared in SBOM or manifest files, which may indicate
1618
1626
  security or compliance risks.
1619
-
1627
+
1620
1628
  Parameters
1621
1629
  ----------
1622
1630
  parser : ArgumentParser
@@ -1634,7 +1642,7 @@ def inspect_undeclared(parser, args):
1634
1642
  print_stderr('ERROR: Input file is required for undeclared component inspection')
1635
1643
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1636
1644
  sys.exit(1)
1637
-
1645
+
1638
1646
  # Initialise output file if specified
1639
1647
  if args.output:
1640
1648
  initialise_empty_file(args.output)
@@ -1669,10 +1677,10 @@ def inspect_undeclared(parser, args):
1669
1677
  def inspect_license_summary(parser, args):
1670
1678
  """
1671
1679
  Handle license summary inspection command.
1672
-
1680
+
1673
1681
  Generates comprehensive summary of all licenses detected in scan results,
1674
1682
  including license counts, risk levels, and compliance recommendations.
1675
-
1683
+
1676
1684
  Parameters
1677
1685
  ----------
1678
1686
  parser : ArgumentParser
@@ -1688,7 +1696,7 @@ def inspect_license_summary(parser, args):
1688
1696
  print_stderr('ERROR: Input file is required for license summary')
1689
1697
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1690
1698
  sys.exit(1)
1691
-
1699
+
1692
1700
  # Initialise output file if specified
1693
1701
  if args.output:
1694
1702
  initialise_empty_file(args.output)
@@ -1700,9 +1708,9 @@ def inspect_license_summary(parser, args):
1700
1708
  quiet=args.quiet,
1701
1709
  filepath=args.input,
1702
1710
  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
1711
+ include=args.include, # Additional licenses to include
1712
+ exclude=args.exclude, # Licenses to exclude from summary
1713
+ explicit=args.explicit, # Explicit license list to summarize
1706
1714
  )
1707
1715
  try:
1708
1716
  # Execute summary generation
@@ -1713,13 +1721,14 @@ def inspect_license_summary(parser, args):
1713
1721
  traceback.print_exc()
1714
1722
  sys.exit(1)
1715
1723
 
1724
+
1716
1725
  def inspect_component_summary(parser, args):
1717
1726
  """
1718
1727
  Handle component summary inspection command.
1719
-
1728
+
1720
1729
  Generates a comprehensive summary of all components detected in scan results,
1721
1730
  including component counts, versions, match types, and security information.
1722
-
1731
+
1723
1732
  Parameters
1724
1733
  ----------
1725
1734
  parser : ArgumentParser
@@ -1734,10 +1743,10 @@ def inspect_component_summary(parser, args):
1734
1743
  print_stderr('ERROR: Input file is required for component summary')
1735
1744
  parser.parse_args([args.subparser, args.subparsercmd, args.subparser_subcmd, '-h'])
1736
1745
  sys.exit(1)
1737
-
1746
+
1738
1747
  # Initialise an output file if specified
1739
1748
  if args.output:
1740
- initialise_empty_file(args.output) # Create/clear output file
1749
+ initialise_empty_file(args.output) # Create/clear output file
1741
1750
 
1742
1751
  # Create and configure component summary generator
1743
1752
  i_component_summary = ComponentSummary(
@@ -1757,14 +1766,15 @@ def inspect_component_summary(parser, args):
1757
1766
  traceback.print_exc()
1758
1767
  sys.exit(1)
1759
1768
 
1769
+
1760
1770
  def inspect_dep_track_project_violations(parser, args):
1761
1771
  """
1762
1772
  Handle Dependency Track project inspection command.
1763
-
1773
+
1764
1774
  Analyses Dependency Track projects for policy violations, security issues,
1765
1775
  and compliance status. Connects to DT API to retrieve project data and
1766
1776
  generate detailed violation reports.
1767
-
1777
+
1768
1778
  Parameters
1769
1779
  ----------
1770
1780
  parser : ArgumentParser
@@ -1794,14 +1804,14 @@ def inspect_dep_track_project_violations(parser, args):
1794
1804
  trace=args.trace,
1795
1805
  quiet=args.quiet,
1796
1806
  output=args.output,
1797
- status= args.status,
1807
+ status=args.status,
1798
1808
  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
1809
+ url=args.url, # DT server URL
1810
+ api_key=args.apikey, # Authentication key
1811
+ project_id=args.project_id, # Target project UUID
1802
1812
  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
1813
+ project_name=args.project_name, # DT project name
1814
+ project_version=args.project_version, # DT project version
1805
1815
  timeout=args.timeout,
1806
1816
  )
1807
1817
  # Execute inspection and exit with appropriate status code
@@ -1818,6 +1828,7 @@ def inspect_dep_track_project_violations(parser, args):
1818
1828
  # END INSPECT COMMAND HANDLERS
1819
1829
  # =============================================================================
1820
1830
 
1831
+
1821
1832
  def export_dt(parser, args):
1822
1833
  """
1823
1834
  Validates and exports a Software Bill of Materials (SBOM) to a Dependency-Track server.
@@ -1845,8 +1856,9 @@ def export_dt(parser, args):
1845
1856
  trace=args.trace,
1846
1857
  quiet=args.quiet,
1847
1858
  )
1848
- success = dt_exporter.upload_sbom_file(args.input, args.project_id, args.project_name,
1849
- args.project_version, args.output)
1859
+ success = dt_exporter.upload_sbom_file(
1860
+ args.input, args.project_id, args.project_name, args.project_version, args.output
1861
+ )
1850
1862
  if not success:
1851
1863
  sys.exit(1)
1852
1864
  except Exception as e:
@@ -1855,6 +1867,7 @@ def export_dt(parser, args):
1855
1867
  traceback.print_exc()
1856
1868
  sys.exit(1)
1857
1869
 
1870
+
1858
1871
  def _dt_args_validator(parser, args):
1859
1872
  """
1860
1873
  Validates command-line arguments related to project identification.
@@ -1884,6 +1897,7 @@ def _dt_args_validator(parser, args):
1884
1897
  print_stderr('Please supply a project name (--project-name) and version (--project-version)')
1885
1898
  sys.exit(1)
1886
1899
 
1900
+
1887
1901
  def utils_certloc(*_):
1888
1902
  """
1889
1903
  Run the "utils certloc" sub-command
@@ -2184,6 +2198,7 @@ def comp_semgrep(parser, args):
2184
2198
  pac=pac_file,
2185
2199
  timeout=args.timeout,
2186
2200
  req_headers=process_req_headers(args.header),
2201
+ use_grpc=args.grpc,
2187
2202
  )
2188
2203
  if not comps.get_semgrep_details(args.input, args.purl, args.output):
2189
2204
  sys.exit(1)
@@ -2222,6 +2237,7 @@ def comp_search(parser, args):
2222
2237
  pac=pac_file,
2223
2238
  timeout=args.timeout,
2224
2239
  req_headers=process_req_headers(args.header),
2240
+ use_grpc=args.grpc,
2225
2241
  )
2226
2242
  if not comps.search_components(
2227
2243
  args.output,
@@ -2267,6 +2283,7 @@ def comp_versions(parser, args):
2267
2283
  pac=pac_file,
2268
2284
  timeout=args.timeout,
2269
2285
  req_headers=process_req_headers(args.header),
2286
+ use_grpc=args.grpc,
2270
2287
  )
2271
2288
  if not comps.get_component_versions(args.output, json_file=args.input, purl=args.purl, limit=args.limit):
2272
2289
  sys.exit(1)
@@ -2302,11 +2319,48 @@ def comp_provenance(parser, args):
2302
2319
  pac=pac_file,
2303
2320
  timeout=args.timeout,
2304
2321
  req_headers=process_req_headers(args.header),
2322
+ use_grpc=args.grpc,
2305
2323
  )
2306
2324
  if not comps.get_provenance_details(args.input, args.purl, args.output, args.origin):
2307
2325
  sys.exit(1)
2308
2326
 
2309
2327
 
2328
+ def comp_licenses(parser, args):
2329
+ """
2330
+ Run the "component licenses" sub-command
2331
+ Parameters
2332
+ ----------
2333
+ parser: ArgumentParser
2334
+ command line parser object
2335
+ args: Namespace
2336
+ Parsed arguments
2337
+ """
2338
+ if (not args.purl and not args.input) or (args.purl and args.input):
2339
+ print_stderr('ERROR: Please specify an input file or purl to decorate (--purl or --input)')
2340
+ parser.parse_args([args.subparser, args.subparsercmd, '-h'])
2341
+ sys.exit(1)
2342
+ if args.ca_cert and not os.path.exists(args.ca_cert):
2343
+ print_stderr(f'ERROR: Certificate file does not exist: {args.ca_cert}.')
2344
+ sys.exit(1)
2345
+ pac_file = get_pac_file(args.pac)
2346
+ comps = Components(
2347
+ debug=args.debug,
2348
+ trace=args.trace,
2349
+ quiet=args.quiet,
2350
+ grpc_url=args.api2url,
2351
+ api_key=args.key,
2352
+ ca_cert=args.ca_cert,
2353
+ proxy=args.proxy,
2354
+ grpc_proxy=args.grpc_proxy,
2355
+ pac=pac_file,
2356
+ timeout=args.timeout,
2357
+ req_headers=process_req_headers(args.header),
2358
+ use_grpc=args.grpc,
2359
+ )
2360
+ if not comps.get_licenses(args.input, args.purl, args.output):
2361
+ sys.exit(1)
2362
+
2363
+
2310
2364
  def results(parser, args):
2311
2365
  """
2312
2366
  Run the "results" sub-command