scanoss 1.19.6__py3-none-any.whl → 1.20.1__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 (71) hide show
  1. protoc_gen_swagger/__init__.py +13 -13
  2. protoc_gen_swagger/options/__init__.py +13 -13
  3. protoc_gen_swagger/options/annotations_pb2.py +12 -9
  4. protoc_gen_swagger/options/annotations_pb2_grpc.py +1 -1
  5. protoc_gen_swagger/options/openapiv2_pb2.py +98 -96
  6. protoc_gen_swagger/options/openapiv2_pb2_grpc.py +1 -1
  7. scanoss/__init__.py +18 -18
  8. scanoss/api/__init__.py +17 -17
  9. scanoss/api/common/__init__.py +17 -17
  10. scanoss/api/common/v2/__init__.py +17 -17
  11. scanoss/api/common/v2/scanoss_common_pb2.py +18 -18
  12. scanoss/api/common/v2/scanoss_common_pb2_grpc.py +1 -1
  13. scanoss/api/components/__init__.py +17 -17
  14. scanoss/api/components/v2/__init__.py +17 -17
  15. scanoss/api/components/v2/scanoss_components_pb2.py +48 -38
  16. scanoss/api/components/v2/scanoss_components_pb2_grpc.py +142 -96
  17. scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +22 -16
  18. scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +75 -49
  19. scanoss/api/dependencies/__init__.py +17 -17
  20. scanoss/api/dependencies/v2/__init__.py +17 -17
  21. scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +30 -24
  22. scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +75 -49
  23. scanoss/api/provenance/__init__.py +23 -0
  24. scanoss/api/provenance/v2/__init__.py +23 -0
  25. scanoss/api/provenance/v2/scanoss_provenance_pb2.py +42 -0
  26. scanoss/api/provenance/v2/scanoss_provenance_pb2_grpc.py +108 -0
  27. scanoss/api/scanning/__init__.py +17 -17
  28. scanoss/api/scanning/v2/__init__.py +17 -17
  29. scanoss/api/scanning/v2/scanoss_scanning_pb2.py +10 -8
  30. scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +40 -32
  31. scanoss/api/semgrep/__init__.py +17 -17
  32. scanoss/api/semgrep/v2/__init__.py +17 -17
  33. scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +22 -18
  34. scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +71 -49
  35. scanoss/api/vulnerabilities/__init__.py +17 -17
  36. scanoss/api/vulnerabilities/v2/__init__.py +17 -17
  37. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +37 -27
  38. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +109 -72
  39. scanoss/cli.py +578 -264
  40. scanoss/components.py +99 -48
  41. scanoss/csvoutput.py +83 -56
  42. scanoss/cyclonedx.py +48 -46
  43. scanoss/data/build_date.txt +1 -1
  44. scanoss/file_filters.py +13 -15
  45. scanoss/filecount.py +43 -36
  46. scanoss/inspection/__init__.py +17 -17
  47. scanoss/inspection/copyleft.py +71 -58
  48. scanoss/inspection/policy_check.py +76 -53
  49. scanoss/inspection/undeclared_component.py +98 -75
  50. scanoss/inspection/utils/license_utils.py +66 -44
  51. scanoss/results.py +51 -60
  52. scanoss/scancodedeps.py +61 -38
  53. scanoss/scanner.py +203 -135
  54. scanoss/scanoss_settings.py +5 -3
  55. scanoss/scanossapi.py +98 -69
  56. scanoss/scanossbase.py +19 -19
  57. scanoss/scanossgrpc.py +107 -51
  58. scanoss/scanpostprocessor.py +9 -6
  59. scanoss/scantype.py +22 -21
  60. scanoss/spdxlite.py +265 -171
  61. scanoss/threadeddependencies.py +91 -61
  62. scanoss/threadedscanning.py +37 -31
  63. scanoss/utils/file.py +4 -4
  64. scanoss/winnowing.py +111 -47
  65. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/METADATA +1 -1
  66. scanoss-1.20.1.dist-info/RECORD +74 -0
  67. scanoss-1.19.6.dist-info/RECORD +0 -70
  68. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/LICENSE +0 -0
  69. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/WHEEL +0 -0
  70. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/entry_points.txt +0 -0
  71. {scanoss-1.19.6.dist-info → scanoss-1.20.1.dist-info}/top_level.txt +0 -0
scanoss/cli.py CHANGED
@@ -1,47 +1,48 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2021, SCANOSS
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
- THE SOFTWARE.
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2021, SCANOSS
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
23
23
  """
24
+
24
25
  import argparse
25
26
  import os
26
- from pathlib import Path
27
27
  import sys
28
+ from pathlib import Path
29
+
28
30
  import pypac
29
31
 
32
+ from . import __version__
33
+ from .components import Components
34
+ from .csvoutput import CsvOutput
35
+ from .cyclonedx import CycloneDx
36
+ from .filecount import FileCount
30
37
  from .inspection.copyleft import Copyleft
31
38
  from .inspection.undeclared_component import UndeclaredComponent
32
- from .threadeddependencies import SCOPE
33
- from .scanoss_settings import ScanossSettings, ScanossSettingsError
39
+ from .results import Results
34
40
  from .scancodedeps import ScancodeDeps
35
- from .scanner import Scanner
41
+ from .scanner import FAST_WINNOWING, Scanner
42
+ from .scanoss_settings import ScanossSettings, ScanossSettingsError
36
43
  from .scantype import ScanType
37
- from .filecount import FileCount
38
- from .cyclonedx import CycloneDx
39
44
  from .spdxlite import SpdxLite
40
- from .csvoutput import CsvOutput
41
- from .components import Components
42
- from . import __version__
43
- from .scanner import FAST_WINNOWING
44
- from .results import Results
45
+ from .threadeddependencies import SCOPE
45
46
  from .utils.file import validate_json_file
46
47
 
47
48
 
@@ -56,152 +57,248 @@ def setup_args() -> None:
56
57
  """
57
58
  Setup all the command line arguments for processing
58
59
  """
59
- parser = argparse.ArgumentParser(description=f'SCANOSS Python CLI. Ver: {__version__}, License: MIT, Fast Winnowing: {FAST_WINNOWING}')
60
+ parser = argparse.ArgumentParser(
61
+ description=f'SCANOSS Python CLI. Ver: {__version__}, License: MIT, Fast Winnowing: {FAST_WINNOWING}'
62
+ )
60
63
  parser.add_argument('--version', '-v', action='store_true', help='Display version details')
61
64
 
62
- subparsers = parser.add_subparsers(title='Sub Commands', dest='subparser', description='valid subcommands',
63
- help='sub-command help')
65
+ subparsers = parser.add_subparsers(
66
+ title='Sub Commands', dest='subparser', description='valid subcommands', help='sub-command help'
67
+ )
64
68
  # Sub-command: version
65
- p_ver = subparsers.add_parser('version', aliases=['ver'],
66
- description=f'Version of SCANOSS CLI: {__version__}', help='SCANOSS version')
69
+ p_ver = subparsers.add_parser(
70
+ 'version', aliases=['ver'], description=f'Version of SCANOSS CLI: {__version__}', help='SCANOSS version'
71
+ )
67
72
  p_ver.set_defaults(func=ver)
68
73
 
69
74
  # Sub-command: scan
70
- p_scan = subparsers.add_parser('scan', aliases=['sc'],
71
- description=f'Analyse/scan the given source base: {__version__}',
72
- help='Scan source code')
75
+ p_scan = subparsers.add_parser(
76
+ 'scan',
77
+ aliases=['sc'],
78
+ description=f'Analyse/scan the given source base: {__version__}',
79
+ help='Scan source code',
80
+ )
73
81
  p_scan.set_defaults(func=scan)
74
82
  p_scan.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?', help='A file or folder to scan')
75
- p_scan.add_argument('--wfp', '-w', type=str,
76
- help='Scan a WFP File instead of a folder (optional)')
77
- p_scan.add_argument('--dep', '-p', type=str,
78
- help='Use a dependency file instead of a folder (optional)')
79
- p_scan.add_argument('--stdin', '-s', metavar='STDIN-FILENAME', type=str,
80
- help='Scan the file contents supplied via STDIN (optional)')
81
- p_scan.add_argument('--files', '-e', type=str, nargs="*", help='List of files to scan.')
83
+ p_scan.add_argument('--wfp', '-w', type=str, help='Scan a WFP File instead of a folder (optional)')
84
+ p_scan.add_argument('--dep', '-p', type=str, help='Use a dependency file instead of a folder (optional)')
85
+ p_scan.add_argument(
86
+ '--stdin', '-s', metavar='STDIN-FILENAME', type=str, help='Scan the file contents supplied via STDIN (optional)'
87
+ )
88
+ p_scan.add_argument('--files', '-e', type=str, nargs='*', help='List of files to scan.')
82
89
  p_scan.add_argument('--identify', '-i', type=str, help='Scan and identify components in SBOM file')
83
- p_scan.add_argument('--ignore', '-n', type=str, help='Ignore components specified in the SBOM file')
84
- p_scan.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
85
- p_scan.add_argument('--format', '-f', type=str, choices=['plain', 'cyclonedx', 'spdxlite', 'csv'],
86
- help='Result output format (optional - default: plain)')
87
- p_scan.add_argument('--threads', '-T', type=int, default=5,
88
- help='Number of threads to use while scanning (optional - default 5)')
89
- p_scan.add_argument('--flags', '-F', type=int,
90
- help='Scanning engine flags (1: disable snippet matching, 2 enable snippet ids, '
91
- '4: disable dependencies, 8: disable licenses, 16: disable copyrights,'
92
- '32: disable vulnerabilities, 64: disable quality, 128: disable cryptography,'
93
- '256: disable best match only, 512: hide identified files, '
94
- '1024: enable download_url, 2048: enable GitHub full path, '
95
- '4096: disable extended server stats)')
96
- p_scan.add_argument('--post-size', '-P', type=int, default=32,
97
- help='Number of kilobytes to limit the post to while scanning (optional - default 32)')
98
- p_scan.add_argument('--timeout', '-M', type=int, default=180,
99
- help='Timeout (in seconds) for API communication (optional - default 180)')
100
- p_scan.add_argument('--retry', '-R', type=int, default=5,
101
- help='Retry limit for API communication (optional - default 5)')
90
+ p_scan.add_argument('--ignore', '-n', type=str, help='Ignore components specified in the SBOM file')
91
+ p_scan.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
92
+ p_scan.add_argument(
93
+ '--format',
94
+ '-f',
95
+ type=str,
96
+ choices=['plain', 'cyclonedx', 'spdxlite', 'csv'],
97
+ help='Result output format (optional - default: plain)',
98
+ )
99
+ p_scan.add_argument(
100
+ '--threads', '-T', type=int, default=5, help='Number of threads to use while scanning (optional - default 5)'
101
+ )
102
+ p_scan.add_argument(
103
+ '--flags',
104
+ '-F',
105
+ type=int,
106
+ help='Scanning engine flags (1: disable snippet matching, 2 enable snippet ids, '
107
+ '4: disable dependencies, 8: disable licenses, 16: disable copyrights,'
108
+ '32: disable vulnerabilities, 64: disable quality, 128: disable cryptography,'
109
+ '256: disable best match only, 512: hide identified files, '
110
+ '1024: enable download_url, 2048: enable GitHub full path, '
111
+ '4096: disable extended server stats)',
112
+ )
113
+ p_scan.add_argument(
114
+ '--post-size',
115
+ '-P',
116
+ type=int,
117
+ default=32,
118
+ help='Number of kilobytes to limit the post to while scanning (optional - default 32)',
119
+ )
120
+ p_scan.add_argument(
121
+ '--timeout',
122
+ '-M',
123
+ type=int,
124
+ default=180,
125
+ help='Timeout (in seconds) for API communication (optional - default 180)',
126
+ )
127
+ p_scan.add_argument(
128
+ '--retry', '-R', type=int, default=5, help='Retry limit for API communication (optional - default 5)'
129
+ )
102
130
  p_scan.add_argument('--no-wfp-output', action='store_true', help='Skip WFP file generation')
103
131
  p_scan.add_argument('--dependencies', '-D', action='store_true', help='Add Dependency scanning')
104
132
  p_scan.add_argument('--dependencies-only', action='store_true', help='Run Dependency scanning only')
105
- p_scan.add_argument('--sc-command', type=str,
106
- help='Scancode command and path if required (optional - default scancode).')
107
- p_scan.add_argument('--sc-timeout', type=int, default=600,
108
- help='Timeout (in seconds) for scancode to complete (optional - default 600)')
109
- p_scan.add_argument('--dep-scope', '-ds', type=SCOPE, help='Filter dependencies by scope - default all (options: dev/prod)')
110
- p_scan.add_argument('--dep-scope-inc', '-dsi', type=str,help='Include dependencies with declared scopes')
133
+ p_scan.add_argument(
134
+ '--sc-command', type=str, help='Scancode command and path if required (optional - default scancode).'
135
+ )
136
+ p_scan.add_argument(
137
+ '--sc-timeout',
138
+ type=int,
139
+ default=600,
140
+ help='Timeout (in seconds) for scancode to complete (optional - default 600)',
141
+ )
142
+ p_scan.add_argument(
143
+ '--dep-scope', '-ds', type=SCOPE, help='Filter dependencies by scope - default all (options: dev/prod)'
144
+ )
145
+ p_scan.add_argument('--dep-scope-inc', '-dsi', type=str, help='Include dependencies with declared scopes')
111
146
  p_scan.add_argument('--dep-scope-exc', '-dse', type=str, help='Exclude dependencies with declared scopes')
112
147
  p_scan.add_argument(
113
- '--settings', '-st',
148
+ '--settings',
149
+ '-st',
114
150
  type=str,
115
151
  help='Settings file to use for scanning (optional - default scanoss.json)',
116
152
  )
117
153
  p_scan.add_argument(
118
- '--skip-settings-file', '-stf', action='store_true',
154
+ '--skip-settings-file',
155
+ '-stf',
156
+ action='store_true',
119
157
  help='Skip default settings file (scanoss.json) if it exists',
120
158
  )
121
159
 
122
160
  # Sub-command: fingerprint
123
- p_wfp = subparsers.add_parser('fingerprint', aliases=['fp', 'wfp'],
124
- description=f'Fingerprint the given source base: {__version__}',
125
- help='Fingerprint source code')
161
+ p_wfp = subparsers.add_parser(
162
+ 'fingerprint',
163
+ aliases=['fp', 'wfp'],
164
+ description=f'Fingerprint the given source base: {__version__}',
165
+ help='Fingerprint source code',
166
+ )
126
167
  p_wfp.set_defaults(func=wfp)
127
- p_wfp.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?',
128
- help='A file or folder to scan')
129
- p_wfp.add_argument('--stdin', '-s', metavar='STDIN-FILENAME', type=str,
130
- help='Fingerprint the file contents supplied via STDIN (optional)')
168
+ p_wfp.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?', help='A file or folder to scan')
169
+ p_wfp.add_argument(
170
+ '--stdin',
171
+ '-s',
172
+ metavar='STDIN-FILENAME',
173
+ type=str,
174
+ help='Fingerprint the file contents supplied via STDIN (optional)',
175
+ )
131
176
  p_wfp.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
132
177
  p_wfp.add_argument(
133
- '--settings', '-st',
178
+ '--settings',
179
+ '-st',
134
180
  type=str,
135
181
  help='Settings file to use for fingerprinting (optional - default scanoss.json)',
136
182
  )
137
183
  p_wfp.add_argument(
138
- '--skip-settings-file', '-stf', action='store_true',
184
+ '--skip-settings-file',
185
+ '-stf',
186
+ action='store_true',
139
187
  help='Skip default settings file (scanoss.json) if it exists',
140
188
  )
141
189
 
142
190
  # Sub-command: dependency
143
- p_dep = subparsers.add_parser('dependencies', aliases=['dp', 'dep'],
144
- description=f'Produce dependency file summary: {__version__}',
145
- help='Scan source code for dependencies, but do not decorate them')
191
+ p_dep = subparsers.add_parser(
192
+ 'dependencies',
193
+ aliases=['dp', 'dep'],
194
+ description=f'Produce dependency file summary: {__version__}',
195
+ help='Scan source code for dependencies, but do not decorate them',
196
+ )
146
197
  p_dep.set_defaults(func=dependency)
147
198
  p_dep.add_argument('scan_dir', metavar='FILE/DIR', type=str, nargs='?', help='A file or folder to scan')
148
199
  p_dep.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
149
- p_dep.add_argument('--sc-command', type=str,
150
- help='Scancode command and path if required (optional - default scancode).')
151
- p_dep.add_argument('--sc-timeout', type=int, default=600,
152
- help='Timeout (in seconds) for scancode to complete (optional - default 600)')
200
+ p_dep.add_argument(
201
+ '--sc-command', type=str, help='Scancode command and path if required (optional - default scancode).'
202
+ )
203
+ p_dep.add_argument(
204
+ '--sc-timeout',
205
+ type=int,
206
+ default=600,
207
+ help='Timeout (in seconds) for scancode to complete (optional - default 600)',
208
+ )
153
209
 
154
210
  # Sub-command: file_count
155
- p_fc = subparsers.add_parser('file_count', aliases=['fc'],
156
- description=f'Produce a file type count summary: {__version__}',
157
- help='Search the source tree and produce a file type summary')
211
+ p_fc = subparsers.add_parser(
212
+ 'file_count',
213
+ aliases=['fc'],
214
+ description=f'Produce a file type count summary: {__version__}',
215
+ help='Search the source tree and produce a file type summary',
216
+ )
158
217
  p_fc.set_defaults(func=file_count)
159
218
  p_fc.add_argument('scan_dir', metavar='DIR', type=str, nargs='?', help='A folder to search')
160
219
  p_fc.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
161
220
  p_fc.add_argument('--all-hidden', action='store_true', help='Scan all hidden files/folders')
162
221
 
163
222
  # Sub-command: convert
164
- p_cnv = subparsers.add_parser('convert', aliases=['cv', 'cnv', 'cvrt'],
165
- description=f'Convert results files between formats: {__version__}',
166
- help='Convert file format')
223
+ p_cnv = subparsers.add_parser(
224
+ 'convert',
225
+ aliases=['cv', 'cnv', 'cvrt'],
226
+ description=f'Convert results files between formats: {__version__}',
227
+ help='Convert file format',
228
+ )
167
229
  p_cnv.set_defaults(func=convert)
168
230
  p_cnv.add_argument('--input', '-i', type=str, required=True, help='Input file name')
169
231
  p_cnv.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
170
- p_cnv.add_argument('--format', '-f', type=str, choices=['cyclonedx', 'spdxlite', 'csv'], default='spdxlite',
171
- help='Output format (optional - default: spdxlite)')
172
- p_cnv.add_argument('--input-format', type=str, choices=['plain'], default='plain',
173
- help='Input format (optional - default: plain)')
232
+ p_cnv.add_argument(
233
+ '--format',
234
+ '-f',
235
+ type=str,
236
+ choices=['cyclonedx', 'spdxlite', 'csv'],
237
+ default='spdxlite',
238
+ help='Output format (optional - default: spdxlite)',
239
+ )
240
+ p_cnv.add_argument(
241
+ '--input-format', type=str, choices=['plain'], default='plain', help='Input format (optional - default: plain)'
242
+ )
174
243
 
175
244
  # Sub-command: component
176
- p_comp = subparsers.add_parser('component', aliases=['comp'],
177
- description=f'SCANOSS Component commands: {__version__}',
178
- help='Component support commands')
245
+ p_comp = subparsers.add_parser(
246
+ 'component',
247
+ aliases=['comp'],
248
+ description=f'SCANOSS Component commands: {__version__}',
249
+ help='Component support commands',
250
+ )
179
251
 
180
- comp_sub = p_comp.add_subparsers(title='Component Commands', dest='subparsercmd', description='component sub-commands',
181
- help='component sub-commands')
252
+ comp_sub = p_comp.add_subparsers(
253
+ title='Component Commands',
254
+ dest='subparsercmd',
255
+ description='component sub-commands',
256
+ help='component sub-commands',
257
+ )
182
258
 
183
259
  # Component Sub-command: component crypto
184
- c_crypto = comp_sub.add_parser('crypto', aliases=['cr'],
185
- description=f'Show Cryptographic algorithms: {__version__}',
186
- help='Retrieve cryptographic algorithms for the given components')
260
+ c_crypto = comp_sub.add_parser(
261
+ 'crypto',
262
+ aliases=['cr'],
263
+ description=f'Show Cryptographic algorithms: {__version__}',
264
+ help='Retrieve cryptographic algorithms for the given components',
265
+ )
187
266
  c_crypto.set_defaults(func=comp_crypto)
188
267
 
189
268
  # Component Sub-command: component vulns
190
- c_vulns = comp_sub.add_parser('vulns', aliases=['vulnerabilities', 'vu'],
191
- description=f'Show Vulnerability details: {__version__}',
192
- help='Retrieve vulnerabilities for the given components')
269
+ c_vulns = comp_sub.add_parser(
270
+ 'vulns',
271
+ aliases=['vulnerabilities', 'vu'],
272
+ description=f'Show Vulnerability details: {__version__}',
273
+ help='Retrieve vulnerabilities for the given components',
274
+ )
193
275
  c_vulns.set_defaults(func=comp_vulns)
194
276
 
195
277
  # Component Sub-command: component semgrep
196
- c_semgrep = comp_sub.add_parser('semgrep', aliases=['sp'],
197
- description=f'Show Semgrep findings: {__version__}',
198
- help='Retrieve semgrep issues/findings for the given components')
278
+ c_semgrep = comp_sub.add_parser(
279
+ 'semgrep',
280
+ aliases=['sp'],
281
+ description=f'Show Semgrep findings: {__version__}',
282
+ help='Retrieve semgrep issues/findings for the given components',
283
+ )
199
284
  c_semgrep.set_defaults(func=comp_semgrep)
200
285
 
286
+ # Component Sub-command: component provenance
287
+ c_provenance = comp_sub.add_parser(
288
+ 'provenance',
289
+ aliases=['prov', 'prv'],
290
+ description=f'Show Provenance findings: {__version__}',
291
+ help='Retrieve provenance for the given components',
292
+ )
293
+ c_provenance.set_defaults(func=c_provenance)
294
+
201
295
  # Component Sub-command: component search
202
- c_search = comp_sub.add_parser('search', aliases=['sc'],
203
- description=f'Search component details: {__version__}',
204
- help='Search for a KB component')
296
+ c_search = comp_sub.add_parser(
297
+ 'search',
298
+ aliases=['sc'],
299
+ description=f'Search component details: {__version__}',
300
+ help='Search for a KB component',
301
+ )
205
302
  c_search.add_argument('--input', '-i', type=str, help='Input file name')
206
303
  c_search.add_argument('--search', '-s', type=str, help='Generic component search')
207
304
  c_search.add_argument('--vendor', '-v', type=str, help='Generic component search')
@@ -212,9 +309,12 @@ def setup_args() -> None:
212
309
  c_search.set_defaults(func=comp_search)
213
310
 
214
311
  # Component Sub-command: component versions
215
- c_versions = comp_sub.add_parser('versions', aliases=['vs'],
216
- description=f'Get component version details: {__version__}',
217
- help='Search for component versions')
312
+ c_versions = comp_sub.add_parser(
313
+ 'versions',
314
+ aliases=['vs'],
315
+ description=f'Get component version details: {__version__}',
316
+ help='Search for component versions',
317
+ )
218
318
  c_versions.add_argument('--input', '-i', type=str, help='Input file name')
219
319
  c_versions.add_argument('--purl', '-p', type=str, help='Generic component search')
220
320
  c_versions.add_argument('--limit', '-l', type=int, help='Generic component search')
@@ -222,58 +322,87 @@ def setup_args() -> None:
222
322
 
223
323
  # Common purl Component sub-command options
224
324
  for p in [c_crypto, c_vulns, c_semgrep]:
225
- p.add_argument('--purl', '-p', type=str, nargs="*", help='Package URL - PURL to process.')
325
+ p.add_argument('--purl', '-p', type=str, nargs='*', help='Package URL - PURL to process.')
226
326
  p.add_argument('--input', '-i', type=str, help='Input file name')
227
327
  # Common Component sub-command options
228
- for p in [c_crypto, c_vulns, c_search, c_versions, c_semgrep]:
328
+ for p in [c_crypto, c_vulns, c_search, c_versions, c_semgrep, c_provenance]:
229
329
  p.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
230
- p.add_argument('--timeout', '-M', type=int, default=600,
231
- help='Timeout (in seconds) for API communication (optional - default 600)')
330
+ p.add_argument(
331
+ '--timeout',
332
+ '-M',
333
+ type=int,
334
+ default=600,
335
+ help='Timeout (in seconds) for API communication (optional - default 600)',
336
+ )
232
337
 
233
338
  # Sub-command: utils
234
- p_util = subparsers.add_parser('utils', aliases=['ut'],
235
- description=f'SCANOSS Utility commands: {__version__}',
236
- help='General utility support commands')
339
+ p_util = subparsers.add_parser(
340
+ 'utils',
341
+ aliases=['ut'],
342
+ description=f'SCANOSS Utility commands: {__version__}',
343
+ help='General utility support commands',
344
+ )
237
345
 
238
- utils_sub = p_util.add_subparsers(title='Utils Commands', dest='subparsercmd', description='utils sub-commands',
239
- help='utils sub-commands')
346
+ utils_sub = p_util.add_subparsers(
347
+ title='Utils Commands', dest='subparsercmd', description='utils sub-commands', help='utils sub-commands'
348
+ )
240
349
 
241
350
  # Utils Sub-command: utils fast
242
- p_f_f = utils_sub.add_parser('fast',
243
- description=f'Is fast winnowing enabled: {__version__}', help='SCANOSS fast winnowing')
351
+ p_f_f = utils_sub.add_parser(
352
+ 'fast', description=f'Is fast winnowing enabled: {__version__}', help='SCANOSS fast winnowing'
353
+ )
244
354
  p_f_f.set_defaults(func=fast)
245
355
 
246
356
  # Utils Sub-command: utils certloc
247
- p_c_loc = utils_sub.add_parser('certloc', aliases=['cl'],
248
- description=f'Show location of Python CA Certs: {__version__}',
249
- help='Display the location of Python CA Certs')
357
+ p_c_loc = utils_sub.add_parser(
358
+ 'certloc',
359
+ aliases=['cl'],
360
+ description=f'Show location of Python CA Certs: {__version__}',
361
+ help='Display the location of Python CA Certs',
362
+ )
250
363
  p_c_loc.set_defaults(func=utils_certloc)
251
364
 
252
365
  # Utils Sub-command: utils cert-download
253
- p_c_dwnld = utils_sub.add_parser('cert-download', aliases=['cdl', 'cert-dl'],
254
- description=f'Download Server SSL Cert: {__version__}',
255
- help='Download the specified server\'s SSL PEM certificate')
366
+ p_c_dwnld = utils_sub.add_parser(
367
+ 'cert-download',
368
+ aliases=['cdl', 'cert-dl'],
369
+ description=f'Download Server SSL Cert: {__version__}',
370
+ help="Download the specified server's SSL PEM certificate",
371
+ )
256
372
  p_c_dwnld.set_defaults(func=utils_cert_download)
257
373
  p_c_dwnld.add_argument('--hostname', '-n', required=True, type=str, help='Server hostname to download cert from.')
258
- p_c_dwnld.add_argument('--port', '-p', required=False, type=int, default=443,
259
- help='Server port number (default: 443).')
374
+ p_c_dwnld.add_argument(
375
+ '--port', '-p', required=False, type=int, default=443, help='Server port number (default: 443).'
376
+ )
260
377
  p_c_dwnld.add_argument('--output', '-o', type=str, help='Output result file name (optional - default stdout).')
261
378
 
262
379
  # Utils Sub-command: utils pac-proxy
263
- p_p_proxy = utils_sub.add_parser('pac-proxy', aliases=['pac'],
264
- description=f'Determine Proxy from PAC: {__version__}',
265
- help='Use Proxy Auto-Config to determine proxy configuration')
380
+ p_p_proxy = utils_sub.add_parser(
381
+ 'pac-proxy',
382
+ aliases=['pac'],
383
+ description=f'Determine Proxy from PAC: {__version__}',
384
+ help='Use Proxy Auto-Config to determine proxy configuration',
385
+ )
266
386
  p_p_proxy.set_defaults(func=utils_pac_proxy)
267
- p_p_proxy.add_argument('--pac', required=False, type=str, default="auto",
268
- help='Proxy auto configuration. Specify a file, http url or "auto" to try to discover it.'
269
- )
270
- p_p_proxy.add_argument('--url', required=False, type=str, default="https://api.osskb.org",
271
- help='URL to test (default: https://api.osskb.org).')
387
+ p_p_proxy.add_argument(
388
+ '--pac',
389
+ required=False,
390
+ type=str,
391
+ default='auto',
392
+ help='Proxy auto configuration. Specify a file, http url or "auto" to try to discover it.',
393
+ )
394
+ p_p_proxy.add_argument(
395
+ '--url',
396
+ required=False,
397
+ type=str,
398
+ default='https://api.osskb.org',
399
+ help='URL to test (default: https://api.osskb.org).',
400
+ )
272
401
 
273
402
  p_results = subparsers.add_parser(
274
403
  'results',
275
404
  aliases=['res'],
276
- description=f"SCANOSS Results commands: {__version__}",
405
+ description=f'SCANOSS Results commands: {__version__}',
277
406
  help='Process scan results',
278
407
  )
279
408
  p_results.add_argument(
@@ -311,37 +440,66 @@ def setup_args() -> None:
311
440
  )
312
441
  p_results.set_defaults(func=results)
313
442
 
314
-
315
443
  # Sub-command: inspect
316
- p_inspect = subparsers.add_parser('inspect', aliases=['insp', 'ins'],
317
- description=f'Inspect results: {__version__}',
318
- help='Inspect results')
444
+ p_inspect = subparsers.add_parser(
445
+ 'inspect', aliases=['insp', 'ins'], description=f'Inspect results: {__version__}', help='Inspect results'
446
+ )
319
447
  # Sub-parser: inspect
320
- p_inspect_sub = p_inspect.add_subparsers(title='Inspect Commands', dest='subparsercmd',
321
- description='Inspect sub-commands', help='Inspect sub-commands')
448
+ p_inspect_sub = p_inspect.add_subparsers(
449
+ title='Inspect Commands', dest='subparsercmd', description='Inspect sub-commands', help='Inspect sub-commands'
450
+ )
322
451
  # Inspect Sub-command: inspect copyleft
323
- p_copyleft = p_inspect_sub.add_parser('copyleft', aliases=['cp'],description="Inspect for copyleft licenses", help='Inspect for copyleft licenses')
324
- p_copyleft.add_argument('--include', help='List of Copyleft licenses to append to the default list. Provide licenses as a comma-separated list.')
325
- p_copyleft.add_argument('--exclude', help='List of Copyleft licenses to remove from default list. Provide licenses as a comma-separated list.')
326
- p_copyleft.add_argument('--explicit', help='Explicit list of Copyleft licenses to consider. Provide licenses as a comma-separated list.s')
452
+ p_copyleft = p_inspect_sub.add_parser(
453
+ 'copyleft', aliases=['cp'], description='Inspect for copyleft licenses', help='Inspect for copyleft licenses'
454
+ )
455
+ p_copyleft.add_argument(
456
+ '--include',
457
+ help='List of Copyleft licenses to append to the default list. Provide licenses as a comma-separated list.',
458
+ )
459
+ p_copyleft.add_argument(
460
+ '--exclude',
461
+ help='List of Copyleft licenses to remove from default list. Provide licenses as a comma-separated list.',
462
+ )
463
+ p_copyleft.add_argument(
464
+ '--explicit',
465
+ help='Explicit list of Copyleft licenses to consider. Provide licenses as a comma-separated list.s',
466
+ )
327
467
  p_copyleft.set_defaults(func=inspect_copyleft)
328
468
 
329
469
  # Inspect Sub-command: inspect undeclared
330
- p_undeclared = p_inspect_sub.add_parser('undeclared', aliases=['un'],description="Inspect for undeclared components", help='Inspect for undeclared components')
331
- p_undeclared.add_argument('--sbom-format',required=False ,choices=['legacy', 'settings'],
332
- default="settings",help='Sbom format for status output')
470
+ p_undeclared = p_inspect_sub.add_parser(
471
+ 'undeclared',
472
+ aliases=['un'],
473
+ description='Inspect for undeclared components',
474
+ help='Inspect for undeclared components',
475
+ )
476
+ p_undeclared.add_argument(
477
+ '--sbom-format',
478
+ required=False,
479
+ choices=['legacy', 'settings'],
480
+ default='settings',
481
+ help='Sbom format for status output',
482
+ )
333
483
  p_undeclared.set_defaults(func=inspect_undeclared)
334
484
 
335
485
  for p in [p_copyleft, p_undeclared]:
336
486
  p.add_argument('-i', '--input', nargs='?', help='Path to results file')
337
- p.add_argument('-f', '--format',required=False ,choices=['json', 'md', 'jira_md'], default='json', help='Output format (default: json)')
487
+ p.add_argument(
488
+ '-f',
489
+ '--format',
490
+ required=False,
491
+ choices=['json', 'md', 'jira_md'],
492
+ default='json',
493
+ help='Output format (default: json)',
494
+ )
338
495
  p.add_argument('-o', '--output', type=str, help='Save details into a file')
339
496
  p.add_argument('-s', '--status', type=str, help='Save summary data into Markdown file')
340
497
 
341
498
  # Global Scan command options
342
499
  for p in [p_scan]:
343
- p.add_argument('--apiurl', type=str,
344
- help='SCANOSS API URL (optional - default: https://api.osskb.org/scan/direct)')
500
+ p.add_argument(
501
+ '--apiurl', type=str, help='SCANOSS API URL (optional - default: https://api.osskb.org/scan/direct)'
502
+ )
345
503
  p.add_argument('--ignore-cert-errors', action='store_true', help='Ignore certificate errors')
346
504
 
347
505
  # Global Scan/Fingerprint filter options
@@ -354,36 +512,74 @@ def setup_args() -> None:
354
512
  p.add_argument('--skip-snippets', '-S', action='store_true', help='Skip the generation of snippets')
355
513
  p.add_argument('--skip-extension', '-E', type=str, action='append', help='File Extension to skip.')
356
514
  p.add_argument('--skip-folder', '-O', type=str, action='append', help='Folder to skip.')
357
- p.add_argument('--skip-size', '-Z', type=int, default=0,
358
- help='Minimum file size to consider for fingerprinting (optional - default 0 bytes [unlimited])')
515
+ p.add_argument(
516
+ '--skip-size',
517
+ '-Z',
518
+ type=int,
519
+ default=0,
520
+ help='Minimum file size to consider for fingerprinting (optional - default 0 bytes [unlimited])',
521
+ )
359
522
  p.add_argument('--skip-md5', '-5', type=str, action='append', help='Skip files matching MD5.')
360
523
  p.add_argument('--strip-hpsm', '-G', type=str, action='append', help='Strip HPSM string from WFP.')
361
524
  p.add_argument('--strip-snippet', '-N', type=str, action='append', help='Strip Snippet ID string from WFP.')
362
525
 
363
526
  # Global Scan/GRPC options
364
527
  for p in [p_scan, c_crypto, c_vulns, c_search, c_versions, c_semgrep]:
365
- p.add_argument('--key', '-k', type=str,
366
- help='SCANOSS API Key token (optional - not required for default OSSKB URL)')
367
- p.add_argument('--proxy', type=str, help='Proxy URL to use for connections (optional). '
368
- 'Can also use the environment variable "HTTPS_PROXY=<ip>:<port>" '
369
- 'and "grcp_proxy=<ip>:<port>" for gRPC')
370
- p.add_argument('--pac', type=str, help='Proxy auto configuration (optional). '
371
- 'Specify a file, http url or "auto" to try to discover it.')
372
- p.add_argument('--ca-cert', type=str, help='Alternative certificate PEM file (optional). '
373
- 'Can also use the environment variable '
374
- '"REQUESTS_CA_BUNDLE=/path/to/cacert.pem" and '
375
- '"GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=/path/to/cacert.pem" for gRPC')
528
+ p.add_argument(
529
+ '--key', '-k', type=str, help='SCANOSS API Key token (optional - not required for default OSSKB URL)'
530
+ )
531
+ p.add_argument(
532
+ '--proxy',
533
+ type=str,
534
+ help='Proxy URL to use for connections (optional). '
535
+ 'Can also use the environment variable "HTTPS_PROXY=<ip>:<port>" '
536
+ 'and "grcp_proxy=<ip>:<port>" for gRPC',
537
+ )
538
+ p.add_argument(
539
+ '--pac',
540
+ type=str,
541
+ help='Proxy auto configuration (optional). Specify a file, http url or "auto" to try to discover it.',
542
+ )
543
+ p.add_argument(
544
+ '--ca-cert',
545
+ type=str,
546
+ help='Alternative certificate PEM file (optional). '
547
+ 'Can also use the environment variable '
548
+ '"REQUESTS_CA_BUNDLE=/path/to/cacert.pem" and '
549
+ '"GRPC_DEFAULT_SSL_ROOTS_FILE_PATH=/path/to/cacert.pem" for gRPC',
550
+ )
376
551
 
377
552
  # Global GRPC options
378
553
  for p in [p_scan, c_crypto, c_vulns, c_search, c_versions, c_semgrep]:
379
- p.add_argument('--api2url', type=str,
380
- help='SCANOSS gRPC API 2.0 URL (optional - default: https://api.osskb.org)')
381
- p.add_argument('--grpc-proxy', type=str, help='GRPC Proxy URL to use for connections (optional). '
382
- 'Can also use the environment variable "grcp_proxy=<ip>:<port>"')
554
+ p.add_argument(
555
+ '--api2url', type=str, help='SCANOSS gRPC API 2.0 URL (optional - default: https://api.osskb.org)'
556
+ )
557
+ p.add_argument(
558
+ '--grpc-proxy',
559
+ type=str,
560
+ help='GRPC Proxy URL to use for connections (optional). '
561
+ 'Can also use the environment variable "grcp_proxy=<ip>:<port>"',
562
+ )
383
563
 
384
564
  # Help/Trace command options
385
- for p in [p_scan, p_wfp, p_dep, p_fc, p_cnv, p_c_loc, p_c_dwnld, p_p_proxy, c_crypto, c_vulns, c_search,
386
- c_versions, c_semgrep, p_results, p_undeclared, p_copyleft]:
565
+ for p in [
566
+ p_scan,
567
+ p_wfp,
568
+ p_dep,
569
+ p_fc,
570
+ p_cnv,
571
+ p_c_loc,
572
+ p_c_dwnld,
573
+ p_p_proxy,
574
+ c_crypto,
575
+ c_vulns,
576
+ c_search,
577
+ c_versions,
578
+ c_semgrep,
579
+ p_results,
580
+ p_undeclared,
581
+ p_copyleft,
582
+ ]:
387
583
  p.add_argument('--debug', '-d', action='store_true', help='Enable debug messages')
388
584
  p.add_argument('--trace', '-t', action='store_true', help='Enable trace messages, including API posts')
389
585
  p.add_argument('--quiet', '-q', action='store_true', help='Enable quiet mode')
@@ -395,13 +591,17 @@ def setup_args() -> None:
395
591
  if not args.subparser:
396
592
  parser.print_help() # No sub command subcommand, print general help
397
593
  exit(1)
398
- else:
399
- if ((args.subparser == 'utils' or args.subparser == 'ut' or
400
- args.subparser == 'component' or args.subparser == 'comp' or
401
- args.subparser == 'inspect' or args.subparser == 'insp' or args.subparser == 'ins')
402
- and not args.subparsercmd):
403
- parser.parse_args([args.subparser, '--help']) # Force utils helps to be displayed
404
- exit(1)
594
+ elif (
595
+ args.subparser == 'utils'
596
+ or args.subparser == 'ut'
597
+ or args.subparser == 'component'
598
+ or args.subparser == 'comp'
599
+ or args.subparser == 'inspect'
600
+ or args.subparser == 'insp'
601
+ or args.subparser == 'ins'
602
+ ) and not args.subparsercmd:
603
+ parser.parse_args([args.subparser, '--help']) # Force utils helps to be displayed
604
+ exit(1)
405
605
  args.func(parser, args) # Execute the function associated with the sub-command
406
606
 
407
607
 
@@ -440,9 +640,13 @@ def file_count(parser, args):
440
640
  scan_output = args.output
441
641
  open(scan_output, 'w').close()
442
642
 
443
- counter = FileCount(debug=args.debug, quiet=args.quiet, trace=args.trace, scan_output=scan_output,
444
- hidden_files_folders=args.all_hidden
445
- )
643
+ counter = FileCount(
644
+ debug=args.debug,
645
+ quiet=args.quiet,
646
+ trace=args.trace,
647
+ scan_output=scan_output,
648
+ hidden_files_folders=args.all_hidden,
649
+ )
446
650
  if not os.path.exists(args.scan_dir):
447
651
  print_stderr(f'Error: Folder specified does not exist: {args.scan_dir}.')
448
652
  exit(1)
@@ -468,12 +672,12 @@ def wfp(parser, args):
468
672
  parser.parse_args([args.subparser, '-h'])
469
673
  exit(1)
470
674
  if args.strip_hpsm and not args.hpsm and not args.quiet:
471
- print_stderr(f'Warning: --strip-hpsm option supplied without enabling HPSM (--hpsm). Ignoring.')
675
+ print_stderr('Warning: --strip-hpsm option supplied without enabling HPSM (--hpsm). Ignoring.')
472
676
  scan_output: str = None
473
677
  if args.output:
474
678
  scan_output = args.output
475
679
  open(scan_output, 'w').close()
476
-
680
+
477
681
  # Load scan settings
478
682
  scan_settings = None
479
683
  if not args.skip_settings_file:
@@ -485,13 +689,24 @@ def wfp(parser, args):
485
689
  exit(1)
486
690
 
487
691
  scan_options = 0 if args.skip_snippets else ScanType.SCAN_SNIPPETS.value # Skip snippet generation or not
488
- scanner = Scanner(debug=args.debug, trace=args.trace, quiet=args.quiet, obfuscate=args.obfuscate,
489
- scan_options=scan_options, all_extensions=args.all_extensions,
490
- all_folders=args.all_folders, hidden_files_folders=args.all_hidden, hpsm=args.hpsm,
491
- skip_size=args.skip_size, skip_extensions=args.skip_extension, skip_folders=args.skip_folder,
492
- skip_md5_ids=args.skip_md5, strip_hpsm_ids=args.strip_hpsm, strip_snippet_ids=args.strip_snippet,
493
- scan_settings=scan_settings
494
- )
692
+ scanner = Scanner(
693
+ debug=args.debug,
694
+ trace=args.trace,
695
+ quiet=args.quiet,
696
+ obfuscate=args.obfuscate,
697
+ scan_options=scan_options,
698
+ all_extensions=args.all_extensions,
699
+ all_folders=args.all_folders,
700
+ hidden_files_folders=args.all_hidden,
701
+ hpsm=args.hpsm,
702
+ skip_size=args.skip_size,
703
+ skip_extensions=args.skip_extension,
704
+ skip_folders=args.skip_folder,
705
+ skip_md5_ids=args.skip_md5,
706
+ strip_hpsm_ids=args.strip_hpsm,
707
+ strip_snippet_ids=args.strip_snippet,
708
+ scan_settings=scan_settings,
709
+ )
495
710
  if args.stdin:
496
711
  contents = sys.stdin.buffer.read()
497
712
  scanner.wfp_contents(args.stdin, contents, scan_output)
@@ -532,11 +747,11 @@ def get_scan_options(args):
532
747
 
533
748
  if args.debug:
534
749
  if ScanType.SCAN_FILES.value & scan_options:
535
- print_stderr(f'Scan Files')
750
+ print_stderr('Scan Files')
536
751
  if ScanType.SCAN_SNIPPETS.value & scan_options:
537
- print_stderr(f'Scan Snippets')
752
+ print_stderr('Scan Snippets')
538
753
  if ScanType.SCAN_DEPENDENCIES.value & scan_options:
539
- print_stderr(f'Scan Dependencies')
754
+ print_stderr('Scan Dependencies')
540
755
  if scan_options <= 0:
541
756
  print_stderr(f'Error: No valid scan options configured: {scan_options}')
542
757
  exit(1)
@@ -575,11 +790,17 @@ def scan(parser, args):
575
790
  scan_settings = ScanossSettings(debug=args.debug, trace=args.trace, quiet=args.quiet)
576
791
  try:
577
792
  if args.identify:
578
- scan_settings.load_json_file(args.identify, args.scan_dir).set_file_type('legacy').set_scan_type('identify')
793
+ scan_settings.load_json_file(args.identify, args.scan_dir).set_file_type('legacy').set_scan_type(
794
+ 'identify'
795
+ )
579
796
  elif args.ignore:
580
- scan_settings.load_json_file(args.ignore, args.scan_dir).set_file_type('legacy').set_scan_type('blacklist')
797
+ scan_settings.load_json_file(args.ignore, args.scan_dir).set_file_type('legacy').set_scan_type(
798
+ 'blacklist'
799
+ )
581
800
  else:
582
- scan_settings.load_json_file(args.settings, args.scan_dir).set_file_type('new').set_scan_type('identify')
801
+ scan_settings.load_json_file(args.settings, args.scan_dir).set_file_type('new').set_scan_type(
802
+ 'identify'
803
+ )
583
804
  except ScanossSettingsError as e:
584
805
  print_stderr(f'Error: {e}')
585
806
  exit(1)
@@ -604,13 +825,13 @@ def scan(parser, args):
604
825
  if args.skip_settings_file:
605
826
  print_stderr('Skipping Settings file...')
606
827
  if args.all_extensions:
607
- print_stderr("Scanning all file extensions/types...")
828
+ print_stderr('Scanning all file extensions/types...')
608
829
  if args.all_folders:
609
- print_stderr("Scanning all folders...")
830
+ print_stderr('Scanning all folders...')
610
831
  if args.all_hidden:
611
- print_stderr("Scanning all hidden files/folders...")
832
+ print_stderr('Scanning all hidden files/folders...')
612
833
  if args.skip_snippets:
613
- print_stderr("Skipping snippets...")
834
+ print_stderr('Skipping snippets...')
614
835
  if args.post_size != 32:
615
836
  print_stderr(f'Changing scanning POST size to: {args.post_size}k...')
616
837
  if args.timeout != 180:
@@ -618,7 +839,7 @@ def scan(parser, args):
618
839
  if args.retry != 5:
619
840
  print_stderr(f'Changing scanning POST retry to: {args.retry}...')
620
841
  if args.obfuscate:
621
- print_stderr("Obfuscating file fingerprints...")
842
+ print_stderr('Obfuscating file fingerprints...')
622
843
  if args.proxy:
623
844
  print_stderr(f'Using Proxy {args.proxy}...')
624
845
  if args.grpc_proxy:
@@ -628,7 +849,7 @@ def scan(parser, args):
628
849
  if args.ca_cert:
629
850
  print_stderr(f'Using Certificate {args.ca_cert}...')
630
851
  if args.hpsm:
631
- print_stderr("Setting HPSM mode...")
852
+ print_stderr('Setting HPSM mode...')
632
853
  if flags:
633
854
  print_stderr(f'Using flags {flags}...')
634
855
  elif not args.quiet:
@@ -647,8 +868,11 @@ def scan(parser, args):
647
868
  scan_options = get_scan_options(args) # Figure out what scanning options we have
648
869
 
649
870
  scanner = Scanner(
650
- debug=args.debug, trace=args.trace, quiet=args.quiet,
651
- api_key=args.key, url=args.apiurl,
871
+ debug=args.debug,
872
+ trace=args.trace,
873
+ quiet=args.quiet,
874
+ api_key=args.key,
875
+ url=args.apiurl,
652
876
  scan_output=scan_output,
653
877
  output_format=output_format,
654
878
  flags=flags,
@@ -684,7 +908,7 @@ def scan(parser, args):
684
908
  print_stderr(f'Error: Cannot specify WFP scanning if file/snippet options are disabled ({scan_options})')
685
909
  exit(1)
686
910
  if scanner.is_dependency_scan() and not args.dep:
687
- print_stderr(f'Error: Cannot specify WFP & Dependency scanning without a dependency file (--dep)')
911
+ print_stderr('Error: Cannot specify WFP & Dependency scanning without a dependency file (--dep)')
688
912
  exit(1)
689
913
  scanner.scan_wfp_with_options(args.wfp, args.dep)
690
914
  elif args.stdin:
@@ -692,21 +916,31 @@ def scan(parser, args):
692
916
  if not scanner.scan_contents(args.stdin, contents):
693
917
  exit(1)
694
918
  elif args.files:
695
- if not scanner.scan_files_with_options(
696
- args.files, args.dep, scanner.winnowing.file_map
697
- ):
919
+ if not scanner.scan_files_with_options(args.files, args.dep, scanner.winnowing.file_map):
698
920
  exit(1)
699
921
  elif args.scan_dir:
700
922
  if not os.path.exists(args.scan_dir):
701
923
  print_stderr(f'Error: File or folder specified does not exist: {args.scan_dir}.')
702
924
  exit(1)
703
925
  if os.path.isdir(args.scan_dir):
704
- if not scanner.scan_folder_with_options(args.scan_dir, args.dep, scanner.winnowing.file_map,
705
- args.dep_scope, args.dep_scope_inc, args.dep_scope_exc):
926
+ if not scanner.scan_folder_with_options(
927
+ args.scan_dir,
928
+ args.dep,
929
+ scanner.winnowing.file_map,
930
+ args.dep_scope,
931
+ args.dep_scope_inc,
932
+ args.dep_scope_exc,
933
+ ):
706
934
  exit(1)
707
935
  elif os.path.isfile(args.scan_dir):
708
- if not scanner.scan_file_with_options(args.scan_dir, args.dep, scanner.winnowing.file_map,
709
- args.dep_scope, args.dep_scope_inc, args.dep_scope_exc):
936
+ if not scanner.scan_file_with_options(
937
+ args.scan_dir,
938
+ args.dep,
939
+ scanner.winnowing.file_map,
940
+ args.dep_scope,
941
+ args.dep_scope_inc,
942
+ args.dep_scope_exc,
943
+ ):
710
944
  exit(1)
711
945
  else:
712
946
  print_stderr(f'Error: Path specified is neither a file or a folder: {args.scan_dir}.')
@@ -714,11 +948,12 @@ def scan(parser, args):
714
948
  elif args.dep:
715
949
  if not args.dependencies_only:
716
950
  print_stderr(
717
- f'Error: No file or folder specified to scan. Please add --dependencies-only to decorate dependency file only.'
951
+ 'Error: No file or folder specified to scan. Please add --dependencies-only to decorate dependency file only.'
718
952
  )
719
953
  exit(1)
720
- if not scanner.scan_folder_with_options(".", args.dep, scanner.winnowing.file_map,args.dep_scope,
721
- args.dep_scope_inc, args.dep_scope_exc):
954
+ if not scanner.scan_folder_with_options(
955
+ '.', args.dep, scanner.winnowing.file_map, args.dep_scope, args.dep_scope_inc, args.dep_scope_exc
956
+ ):
722
957
  exit(1)
723
958
  else:
724
959
  print_stderr('No action found to process')
@@ -747,9 +982,9 @@ def dependency(parser, args):
747
982
  scan_output = args.output
748
983
  open(scan_output, 'w').close()
749
984
 
750
- sc_deps = ScancodeDeps(debug=args.debug, quiet=args.quiet, trace=args.trace, sc_command=args.sc_command,
751
- timeout=args.sc_timeout
752
- )
985
+ sc_deps = ScancodeDeps(
986
+ debug=args.debug, quiet=args.quiet, trace=args.trace, sc_command=args.sc_command, timeout=args.sc_timeout
987
+ )
753
988
  if not sc_deps.get_dependencies(what_to_scan=args.scan_dir, result_output=scan_output):
754
989
  exit(1)
755
990
 
@@ -771,17 +1006,17 @@ def convert(parser, args):
771
1006
  success = False
772
1007
  if args.format == 'cyclonedx':
773
1008
  if not args.quiet:
774
- print_stderr(f'Producing CycloneDX report...')
1009
+ print_stderr('Producing CycloneDX report...')
775
1010
  cdx = CycloneDx(debug=args.debug, output_file=args.output)
776
1011
  success = cdx.produce_from_file(args.input)
777
1012
  elif args.format == 'spdxlite':
778
1013
  if not args.quiet:
779
- print_stderr(f'Producing SPDX Lite report...')
1014
+ print_stderr('Producing SPDX Lite report...')
780
1015
  spdxlite = SpdxLite(debug=args.debug, output_file=args.output)
781
1016
  success = spdxlite.produce_from_file(args.input)
782
1017
  elif args.format == 'csv':
783
1018
  if not args.quiet:
784
- print_stderr(f'Producing CSV report...')
1019
+ print_stderr('Producing CSV report...')
785
1020
  csvo = CsvOutput(debug=args.debug, output_file=args.output)
786
1021
  success = csvo.produce_from_file(args.input)
787
1022
  else:
@@ -789,6 +1024,7 @@ def convert(parser, args):
789
1024
  if not success:
790
1025
  exit(1)
791
1026
 
1027
+
792
1028
  def inspect_copyleft(parser, args):
793
1029
  """
794
1030
  Run the "inspect" sub-command
@@ -813,12 +1049,22 @@ def inspect_copyleft(parser, args):
813
1049
  status_output = args.status
814
1050
  open(status_output, 'w').close()
815
1051
 
816
- i_copyleft = Copyleft(debug=args.debug, trace=args.trace, quiet=args.quiet, filepath=args.input,
817
- format_type=args.format, status=status_output, output=output, include=args.include,
818
- exclude=args.exclude, explicit=args.explicit)
1052
+ i_copyleft = Copyleft(
1053
+ debug=args.debug,
1054
+ trace=args.trace,
1055
+ quiet=args.quiet,
1056
+ filepath=args.input,
1057
+ format_type=args.format,
1058
+ status=status_output,
1059
+ output=output,
1060
+ include=args.include,
1061
+ exclude=args.exclude,
1062
+ explicit=args.explicit,
1063
+ )
819
1064
  status, _ = i_copyleft.run()
820
1065
  sys.exit(status)
821
1066
 
1067
+
822
1068
  def inspect_undeclared(parser, args):
823
1069
  """
824
1070
  Run the "inspect" sub-command
@@ -842,20 +1088,30 @@ def inspect_undeclared(parser, args):
842
1088
  if args.status:
843
1089
  status_output = args.status
844
1090
  open(status_output, 'w').close()
845
- i_undeclared = UndeclaredComponent(debug=args.debug, trace=args.trace, quiet=args.quiet,
846
- filepath=args.input, format_type=args.format,
847
- status=status_output, output=output, sbom_format=args.sbom_format)
1091
+ i_undeclared = UndeclaredComponent(
1092
+ debug=args.debug,
1093
+ trace=args.trace,
1094
+ quiet=args.quiet,
1095
+ filepath=args.input,
1096
+ format_type=args.format,
1097
+ status=status_output,
1098
+ output=output,
1099
+ sbom_format=args.sbom_format,
1100
+ )
848
1101
  status, _ = i_undeclared.run()
849
1102
  sys.exit(status)
850
1103
 
1104
+
851
1105
  def utils_certloc(*_):
852
1106
  """
853
1107
  Run the "utils certloc" sub-command
854
1108
  :param _: ignored/unused
855
1109
  """
856
1110
  import certifi
1111
+
857
1112
  print(f'CA Cert File: {certifi.where()}')
858
1113
 
1114
+
859
1115
  def utils_cert_download(_, args):
860
1116
  """
861
1117
  Run the "utils cert-download" sub-command
@@ -890,7 +1146,9 @@ def utils_cert_download(_, args):
890
1146
  if not args.quiet:
891
1147
  print_stderr(f'Certificate {index} - CN: {cn}')
892
1148
  if sys.version_info[0] >= 3:
893
- print((crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')).strip(), file=file) # Print the downloaded PEM certificate
1149
+ print(
1150
+ (crypto.dump_certificate(crypto.FILETYPE_PEM, cert).decode('utf-8')).strip(), file=file
1151
+ ) # Print the downloaded PEM certificate
894
1152
  else:
895
1153
  print((crypto.dump_certificate(crypto.FILETYPE_PEM, cert)).strip(), file=file)
896
1154
  except SSL.Error as e:
@@ -912,8 +1170,9 @@ def utils_pac_proxy(_, args):
912
1170
  :param args: Parsed arguments
913
1171
  """
914
1172
  from pypac.resolver import ProxyResolver
1173
+
915
1174
  if not args.pac:
916
- print_stderr(f'Error: No pac file option specified.')
1175
+ print_stderr('Error: No pac file option specified.')
917
1176
  exit(1)
918
1177
  pac_file = get_pac_file(args.pac)
919
1178
  if pac_file is None:
@@ -967,9 +1226,18 @@ def comp_crypto(parser, args):
967
1226
  print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
968
1227
  exit(1)
969
1228
  pac_file = get_pac_file(args.pac)
970
- comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
971
- ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
972
- timeout=args.timeout)
1229
+ comps = Components(
1230
+ debug=args.debug,
1231
+ trace=args.trace,
1232
+ quiet=args.quiet,
1233
+ grpc_url=args.api2url,
1234
+ api_key=args.key,
1235
+ ca_cert=args.ca_cert,
1236
+ proxy=args.proxy,
1237
+ grpc_proxy=args.grpc_proxy,
1238
+ pac=pac_file,
1239
+ timeout=args.timeout,
1240
+ )
973
1241
  if not comps.get_crypto_details(args.input, args.purl, args.output):
974
1242
  exit(1)
975
1243
 
@@ -992,12 +1260,22 @@ def comp_vulns(parser, args):
992
1260
  print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
993
1261
  exit(1)
994
1262
  pac_file = get_pac_file(args.pac)
995
- comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
996
- ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
997
- timeout=args.timeout)
1263
+ comps = Components(
1264
+ debug=args.debug,
1265
+ trace=args.trace,
1266
+ quiet=args.quiet,
1267
+ grpc_url=args.api2url,
1268
+ api_key=args.key,
1269
+ ca_cert=args.ca_cert,
1270
+ proxy=args.proxy,
1271
+ grpc_proxy=args.grpc_proxy,
1272
+ pac=pac_file,
1273
+ timeout=args.timeout,
1274
+ )
998
1275
  if not comps.get_vulnerabilities(args.input, args.purl, args.output):
999
1276
  exit(1)
1000
1277
 
1278
+
1001
1279
  def comp_semgrep(parser, args):
1002
1280
  """
1003
1281
  Run the "component semgrep" sub-command
@@ -1016,12 +1294,22 @@ def comp_semgrep(parser, args):
1016
1294
  print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
1017
1295
  exit(1)
1018
1296
  pac_file = get_pac_file(args.pac)
1019
- comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
1020
- ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
1021
- timeout=args.timeout)
1297
+ comps = Components(
1298
+ debug=args.debug,
1299
+ trace=args.trace,
1300
+ quiet=args.quiet,
1301
+ grpc_url=args.api2url,
1302
+ api_key=args.key,
1303
+ ca_cert=args.ca_cert,
1304
+ proxy=args.proxy,
1305
+ grpc_proxy=args.grpc_proxy,
1306
+ pac=pac_file,
1307
+ timeout=args.timeout,
1308
+ )
1022
1309
  if not comps.get_semgrep_details(args.input, args.purl, args.output):
1023
1310
  exit(1)
1024
1311
 
1312
+
1025
1313
  def comp_search(parser, args):
1026
1314
  """
1027
1315
  Run the "component search" sub-command
@@ -1032,8 +1320,9 @@ def comp_search(parser, args):
1032
1320
  args: Namespace
1033
1321
  Parsed arguments
1034
1322
  """
1035
- if ((not args.input and not args.search and not args.vendor and not args.comp) or
1036
- (args.input and (args.search or args.vendor or args.comp))):
1323
+ if (not args.input and not args.search and not args.vendor and not args.comp) or (
1324
+ args.input and (args.search or args.vendor or args.comp)
1325
+ ):
1037
1326
  print_stderr('Please specify an input file or search terms (--input or --search, or --vendor or --comp.)')
1038
1327
  parser.parse_args([args.subparser, args.subparsercmd, '-h'])
1039
1328
  exit(1)
@@ -1042,12 +1331,28 @@ def comp_search(parser, args):
1042
1331
  print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
1043
1332
  exit(1)
1044
1333
  pac_file = get_pac_file(args.pac)
1045
- comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
1046
- ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
1047
- timeout=args.timeout)
1048
- if not comps.search_components(args.output, json_file=args.input,
1049
- search=args.search, vendor=args.vendor, comp=args.comp, package=args.package,
1050
- limit=args.limit, offset=args.offset):
1334
+ comps = Components(
1335
+ debug=args.debug,
1336
+ trace=args.trace,
1337
+ quiet=args.quiet,
1338
+ grpc_url=args.api2url,
1339
+ api_key=args.key,
1340
+ ca_cert=args.ca_cert,
1341
+ proxy=args.proxy,
1342
+ grpc_proxy=args.grpc_proxy,
1343
+ pac=pac_file,
1344
+ timeout=args.timeout,
1345
+ )
1346
+ if not comps.search_components(
1347
+ args.output,
1348
+ json_file=args.input,
1349
+ search=args.search,
1350
+ vendor=args.vendor,
1351
+ comp=args.comp,
1352
+ package=args.package,
1353
+ limit=args.limit,
1354
+ offset=args.offset,
1355
+ ):
1051
1356
  exit(1)
1052
1357
 
1053
1358
 
@@ -1070,9 +1375,18 @@ def comp_versions(parser, args):
1070
1375
  print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
1071
1376
  exit(1)
1072
1377
  pac_file = get_pac_file(args.pac)
1073
- comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
1074
- ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
1075
- timeout=args.timeout)
1378
+ comps = Components(
1379
+ debug=args.debug,
1380
+ trace=args.trace,
1381
+ quiet=args.quiet,
1382
+ grpc_url=args.api2url,
1383
+ api_key=args.key,
1384
+ ca_cert=args.ca_cert,
1385
+ proxy=args.proxy,
1386
+ grpc_proxy=args.grpc_proxy,
1387
+ pac=pac_file,
1388
+ timeout=args.timeout,
1389
+ )
1076
1390
  if not comps.get_component_versions(args.output, json_file=args.input, purl=args.purl, limit=args.limit):
1077
1391
  exit(1)
1078
1392
 
@@ -1089,13 +1403,13 @@ def results(parser, args):
1089
1403
  """
1090
1404
  if not args.filepath:
1091
1405
  print_stderr('ERROR: Please specify a file containing the results')
1092
- parser.parse_args([args.subparser, "-h"])
1406
+ parser.parse_args([args.subparser, '-h'])
1093
1407
  exit(1)
1094
1408
 
1095
1409
  file_path = Path(args.filepath).resolve()
1096
1410
 
1097
1411
  if not file_path.is_file():
1098
- print_stderr(f"The specified file {args.filepath} does not exist")
1412
+ print_stderr(f'The specified file {args.filepath} does not exist')
1099
1413
  exit(1)
1100
1414
 
1101
1415
  results = Results(
@@ -1124,5 +1438,5 @@ def main():
1124
1438
  setup_args()
1125
1439
 
1126
1440
 
1127
- if __name__ == "__main__":
1441
+ if __name__ == '__main__':
1128
1442
  main()