scanoss 1.38.0__py3-none-any.whl → 1.40.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.
@@ -0,0 +1,290 @@
1
+ """
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2025, 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
+ """
24
+
25
+ from dataclasses import dataclass
26
+
27
+ from ...scanossbase import ScanossBase
28
+ from ...utils import scanoss_scan_results_utils
29
+ from ..utils.file_utils import load_json_file
30
+ from ..utils.markdown_utils import generate_table
31
+
32
+
33
+ @dataclass
34
+ class MatchSummaryItem:
35
+ """
36
+ Represents a single match entry in the SCANOSS results.
37
+
38
+ This data class encapsulates all the relevant information about a component
39
+ match found during scanning, including file location, license details, and
40
+ match quality metrics.
41
+ """
42
+ file: str
43
+ file_url: str
44
+ license: str
45
+ similarity: str
46
+ purl: str
47
+ purl_url: str
48
+ version: str
49
+ lines: str
50
+
51
+
52
+ @dataclass
53
+ class ComponentMatchSummary:
54
+ """
55
+ Container for categorized SCANOSS match results.
56
+
57
+ Organizes matches into two categories: full file matches and snippet matches.
58
+ This separation allows for different presentation and analysis of match types.
59
+ """
60
+ files: list[MatchSummaryItem]
61
+ snippet: list[MatchSummaryItem]
62
+
63
+ class MatchSummary(ScanossBase):
64
+ """
65
+ Generates Markdown summaries from SCANOSS scan results.
66
+
67
+ This class processes SCANOSS scan results and creates human-readable Markdown
68
+ reports with collapsible sections for file and snippet matches. The reports
69
+ include clickable links to files when a line range
70
+ prefix is provided.
71
+ """
72
+
73
+ def __init__( # noqa: PLR0913
74
+ self,
75
+ debug: bool = False,
76
+ trace: bool = False,
77
+ quiet: bool = False,
78
+ line_range_prefix: str = None,
79
+ scanoss_results_path: str = None,
80
+ output: str = None,
81
+ ):
82
+ """
83
+ Initialize the Matches Summary generator.
84
+
85
+ :param debug: Enable debug output for troubleshooting
86
+ :param trace: Enable trace-level logging for detailed execution tracking
87
+ :param quiet: Suppress informational messages
88
+ :param line_range_prefix: Base URL prefix for GitLab file links with line ranges
89
+ (e.g., 'https://gitlab.com/org/project/-/blob/main')
90
+ :param scanoss_results_path: Path to SCANOSS scan results file in JSON format
91
+ :param output: Output file path for the generated Markdown report (default: stdout)
92
+ """
93
+ super().__init__(debug=debug, trace=trace, quiet=quiet)
94
+ self.scanoss_results_path = scanoss_results_path
95
+ self.line_range_prefix = line_range_prefix
96
+ self.output = output
97
+
98
+
99
+ def _get_match_summary_item(self, file_name: str, result: dict) -> MatchSummaryItem:
100
+ """
101
+ Create a MatchSummaryItem from a single scan result.
102
+
103
+ Processes a SCANOSS scan result and creates a MatchSummaryItem with appropriate
104
+ file URLs, license information, and line ranges. Handles both snippet matches
105
+ (with specific line ranges) and file matches (entire file).
106
+
107
+ :param file_name: Name of the scanned file (relative path in the repository)
108
+ :param result: SCANOSS scan result dictionary containing match details
109
+ :return: Populated match summary item with all relevant information
110
+ """
111
+ if result.get('id') == "snippet":
112
+ # Snippet match: create URL with line range anchor
113
+ lines = scanoss_scan_results_utils.get_lines(result.get('lines'))
114
+ end_line = lines[len(lines) - 1] if len(lines) > 1 else lines[0]
115
+ file_url = f"{self.line_range_prefix}/{file_name}#L{lines[0]}-L{end_line}"
116
+ return MatchSummaryItem(
117
+ file_url=file_url,
118
+ file=file_name,
119
+ license=result.get('licenses')[0].get('name'),
120
+ similarity=result.get('matched'),
121
+ purl=result.get('purl')[0],
122
+ purl_url=result.get('url'),
123
+ version=result.get('version'),
124
+ lines=f"{lines[0]}-{lines[len(lines) - 1] if len(lines) > 1 else lines[0]}"
125
+ )
126
+ # File match: create URL without line range
127
+ return MatchSummaryItem(
128
+ file=file_name,
129
+ file_url=f"{self.line_range_prefix}/{file_name}",
130
+ license=result.get('licenses')[0].get('name'),
131
+ similarity=result.get('matched'),
132
+ purl=result.get('purl')[0],
133
+ purl_url=result.get('url'),
134
+ version=result.get('version'),
135
+ lines="all"
136
+ )
137
+
138
+ def _validate_result(self, file_name: str, result: dict) -> bool:
139
+ """
140
+ Validate that a scan result has all required fields.
141
+
142
+ :param file_name: Name of the file being validated
143
+ :param result: The scan result to validate
144
+ :return: True if valid, False otherwise
145
+ """
146
+ validations = [
147
+ ('id', 'No id found'),
148
+ ('lines', 'No lines found'),
149
+ ('purl', 'No purl found'),
150
+ ('licenses', 'No licenses found'),
151
+ ('version', 'No version found'),
152
+ ('matched', 'No matched found'),
153
+ ('url', 'No url found'),
154
+ ]
155
+
156
+ for field, error_msg in validations:
157
+ if not result.get(field):
158
+ self.print_debug(f'ERROR: {error_msg} for file {file_name}')
159
+ return False
160
+
161
+ # Additional validation for non-empty lists
162
+ if len(result.get('purl')) == 0:
163
+ self.print_debug(f'ERROR: No purl found for file {file_name}')
164
+ return False
165
+ if len(result.get('licenses')) == 0:
166
+ self.print_debug(f'ERROR: Empty licenses list for file {file_name}')
167
+ return False
168
+
169
+ return True
170
+
171
+ def _get_matches_summary(self) -> ComponentMatchSummary:
172
+ """
173
+ Parse SCANOSS scan results and create categorized match summaries.
174
+
175
+ Loads the SCANOSS scan results file and processes each match, validating
176
+ required fields and categorizing matches into file matches and snippet matches.
177
+ Skips invalid or incomplete results with debug messages.
178
+ """
179
+ # Load scan results from JSON file
180
+ scan_results = load_json_file(self.scanoss_results_path)
181
+ gitlab_matches_summary = ComponentMatchSummary(files=[], snippet=[])
182
+
183
+ # Process each file and its results
184
+ for file_name, results in scan_results.items():
185
+ for result in results:
186
+ # Skip non-matches
187
+ if result.get('id') == "none":
188
+ self.print_debug(f'Skipping non-match for file {file_name}')
189
+ continue
190
+
191
+ # Validate required fields
192
+ if not self._validate_result(file_name, result):
193
+ continue
194
+
195
+ # Create summary item and categorize by match type
196
+ summary_item = self._get_match_summary_item(file_name, result)
197
+ if result.get('id') == "snippet":
198
+ gitlab_matches_summary.snippet.append(summary_item)
199
+ else:
200
+ gitlab_matches_summary.files.append(summary_item)
201
+
202
+ return gitlab_matches_summary
203
+
204
+
205
+ def _markdown(self, gitlab_matches_summary: ComponentMatchSummary) -> str:
206
+ """
207
+ Generate Markdown from match summaries.
208
+
209
+ Creates a formatted Markdown document with collapsible sections for file
210
+ and snippet matches.
211
+
212
+ :param gitlab_matches_summary: Container with categorized file and snippet matches to format
213
+ :return: Complete Markdown document with formatted match tables
214
+ """
215
+
216
+ if len(gitlab_matches_summary.files) == 0 and len(gitlab_matches_summary.snippet) == 0:
217
+ return ""
218
+
219
+ # Define table headers
220
+ file_match_headers = ['File', 'License', 'Similarity', 'PURL', 'Version']
221
+ snippet_match_headers = ['File', 'License', 'Similarity', 'PURL', 'Version', 'Lines']
222
+ # Build file matches table
223
+ file_match_rows = []
224
+ for file_match in gitlab_matches_summary.files:
225
+ row = [
226
+ f"[{file_match.file}]({file_match.file_url})",
227
+ file_match.license,
228
+ file_match.similarity,
229
+ f"[{file_match.purl}]({file_match.purl_url})",
230
+ file_match.version,
231
+ ]
232
+ file_match_rows.append(row)
233
+ file_match_table = generate_table(file_match_headers, file_match_rows)
234
+
235
+ # Build snippet matches table
236
+ snippet_match_rows = []
237
+ for snippet_match in gitlab_matches_summary.snippet:
238
+ row = [
239
+ f"[{snippet_match.file}]({snippet_match.file_url})",
240
+ snippet_match.license,
241
+ snippet_match.similarity,
242
+ f"[{snippet_match.purl}]({snippet_match.purl_url})",
243
+ snippet_match.version,
244
+ snippet_match.lines
245
+ ]
246
+ snippet_match_rows.append(row)
247
+ snippet_match_table = generate_table(snippet_match_headers, snippet_match_rows)
248
+
249
+ # Assemble complete Markdown document
250
+ markdown = ""
251
+ markdown += "### SCANOSS Match Summary\n\n"
252
+
253
+ # File matches section (collapsible)
254
+ markdown += "<details>\n"
255
+ markdown += "<summary>File Match Summary</summary>\n\n"
256
+ markdown += file_match_table
257
+ markdown += "\n</details>\n"
258
+
259
+ # Snippet matches section (collapsible)
260
+ markdown += "<details>\n"
261
+ markdown += "<summary>Snippet Match Summary</summary>\n\n"
262
+ markdown += snippet_match_table
263
+ markdown += "\n</details>\n"
264
+
265
+ return markdown
266
+
267
+ def run(self):
268
+ """
269
+ Execute the matches summary generation process.
270
+
271
+ This is the main entry point for generating the matches summary report.
272
+ It orchestrates the entire workflow:
273
+ 1. Loads and parses SCANOSS scan results
274
+ 2. Validates and categorizes matches
275
+ 3. Generates Markdown report
276
+ 4. Outputs to file or stdout
277
+ """
278
+ # Load and process scan results into categorized matches
279
+ matches = self._get_matches_summary()
280
+
281
+ # Format matches as GitLab-compatible Markdown
282
+ matches_md = self._markdown(matches)
283
+ if matches_md == "":
284
+ self.print_stdout("No matches found.")
285
+ return
286
+ # Output to file or stdout
287
+ self.print_to_file_or_stdout(matches_md, self.output)
288
+
289
+
290
+
@@ -22,13 +22,12 @@ SPDX-License-Identifier: MIT
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
- import json
26
- import os.path
27
25
  from abc import abstractmethod
28
26
  from enum import Enum
29
27
  from typing import Any, Dict, TypeVar
30
28
 
31
29
  from ..policy_check import PolicyCheck
30
+ from ..utils.file_utils import load_json_file
32
31
  from ..utils.license_utils import LicenseUtil
33
32
 
34
33
 
@@ -313,15 +312,11 @@ class RawBase(PolicyCheck[T]):
313
312
  Returns:
314
313
  Dict[str, Any]: The parsed JSON data
315
314
  """
316
- if not os.path.exists(self.filepath):
317
- self.print_stderr(f'ERROR: The file "{self.filepath}" does not exist.')
318
- return None
319
- with open(self.filepath, 'r') as jsonfile:
320
- try:
321
- return json.load(jsonfile)
322
- except Exception as e:
315
+ try:
316
+ return load_json_file(self.filepath)
317
+ except Exception as e:
323
318
  self.print_stderr(f'ERROR: Problem parsing input JSON: {e}')
324
- return None
319
+ return None
325
320
 
326
321
  def _convert_components_to_list(self, components: dict):
327
322
  if components is None:
@@ -27,6 +27,7 @@ from dataclasses import dataclass
27
27
  from typing import Any, Dict, List
28
28
 
29
29
  from ..policy_check import PolicyStatus
30
+ from ..utils.markdown_utils import generate_jira_table, generate_table
30
31
  from .raw_base import RawBase
31
32
 
32
33
 
@@ -193,7 +194,7 @@ class UndeclaredComponent(RawBase[Component]):
193
194
  for component in component_licenses:
194
195
  rows.append([component.get('purl'), component.get('spdxid')])
195
196
  return {
196
- 'details': f'### Undeclared components\n{self.generate_table(headers, rows)}\n',
197
+ 'details': f'### Undeclared components\n{generate_table(headers, rows)}\n',
197
198
  'summary': self._get_summary(component_licenses),
198
199
  }
199
200
 
@@ -211,7 +212,7 @@ class UndeclaredComponent(RawBase[Component]):
211
212
  for component in component_licenses:
212
213
  rows.append([component.get('purl'), component.get('spdxid')])
213
214
  return {
214
- 'details': f'{self.generate_jira_table(headers, rows)}',
215
+ 'details': f'{generate_jira_table(headers, rows)}',
215
216
  'summary': self._get_jira_summary(component_licenses),
216
217
  }
217
218
 
@@ -0,0 +1,44 @@
1
+ """
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2025, 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
+ """
24
+
25
+ import json
26
+ import os
27
+
28
+
29
+ def load_json_file(file_path: str) -> dict:
30
+ """
31
+ Load the file
32
+
33
+ :param file_path: file path to the JSON file
34
+
35
+ Returns:
36
+ Dict[str, Any]: The parsed JSON data
37
+ """
38
+ if not os.path.exists(file_path):
39
+ raise ValueError(f'The file "{file_path}" does not exist.')
40
+ with open(file_path, 'r') as jsonfile:
41
+ try:
42
+ return json.load(jsonfile)
43
+ except Exception as e:
44
+ raise ValueError(f'ERROR: Problem parsing input JSON: {e}')
@@ -0,0 +1,63 @@
1
+ """
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2025, 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
+ """
24
+
25
+ def generate_table(headers, rows, centered_columns=None):
26
+ """
27
+ Generate a Markdown table.
28
+
29
+ :param headers: List of headers for the table.
30
+ :param rows: List of rows for the table.
31
+ :param centered_columns: List of column indices to be centered.
32
+ :return: A string representing the Markdown table.
33
+ """
34
+ col_sep = ' | '
35
+ centered_column_set = set(centered_columns or [])
36
+ if headers is None:
37
+ return None
38
+
39
+ # Decide which separator to use
40
+ def create_separator(index):
41
+ if centered_columns is None:
42
+ return '-'
43
+ return ':-:' if index in centered_column_set else '-'
44
+
45
+ # Build the row separator
46
+ row_separator = col_sep + col_sep.join(create_separator(index) for index, _ in enumerate(headers)) + col_sep
47
+ # build table rows
48
+ table_rows = [col_sep + col_sep.join(headers) + col_sep, row_separator]
49
+ table_rows.extend(col_sep + col_sep.join(row) + col_sep for row in rows)
50
+ return '\n'.join(table_rows)
51
+
52
+ def generate_jira_table(headers, rows, centered_columns=None):
53
+ col_sep = '*|*'
54
+ if headers is None:
55
+ return None
56
+
57
+ table_header = '|*' + col_sep.join(headers) + '*|\n'
58
+ table = table_header
59
+ for row in rows:
60
+ if len(headers) == len(row):
61
+ table += '|' + '|'.join(row) + '|\n'
62
+
63
+ return table
@@ -158,6 +158,7 @@ class FolderHasher:
158
158
  filtered_files.sort()
159
159
 
160
160
  bar = Bar('Hashing files...', max=len(filtered_files))
161
+ full_file_path = ''
161
162
  for file_path in filtered_files:
162
163
  try:
163
164
  file_path_obj = Path(file_path) if isinstance(file_path, str) else file_path
@@ -63,6 +63,7 @@ class ScannerHFH:
63
63
  depth: int = DEFAULT_HFH_DEPTH,
64
64
  recursive_threshold: float = DEFAULT_HFH_RECURSIVE_THRESHOLD,
65
65
  min_accepted_score: float = DEFAULT_HFH_MIN_ACCEPTED_SCORE,
66
+ use_grpc: bool = False,
66
67
  ):
67
68
  """
68
69
  Initialize the ScannerHFH.
@@ -107,6 +108,7 @@ class ScannerHFH:
107
108
  self.rank_threshold = rank_threshold
108
109
  self.recursive_threshold = recursive_threshold
109
110
  self.min_accepted_score = min_accepted_score
111
+ self.use_grpc = use_grpc
110
112
 
111
113
  def scan(self) -> Optional[Dict]:
112
114
  """
@@ -134,7 +136,7 @@ class ScannerHFH:
134
136
  spinner_thread.start()
135
137
 
136
138
  try:
137
- response = self.client.folder_hash_scan(hfh_request)
139
+ response = self.client.folder_hash_scan(hfh_request, self.use_grpc)
138
140
  if response:
139
141
  self.scan_results = response
140
142
  finally:
scanoss/scanossgrpc.py CHANGED
@@ -426,21 +426,24 @@ class ScanossGrpc(ScanossBase):
426
426
  use_grpc=use_grpc,
427
427
  )
428
428
 
429
- def folder_hash_scan(self, request: Dict) -> Optional[Dict]:
429
+ def folder_hash_scan(self, request: Dict, use_grpc: Optional[bool] = None) -> Optional[Dict]:
430
430
  """
431
431
  Client function to call the rpc for Folder Hashing Scan
432
432
 
433
433
  Args:
434
434
  request (Dict): Folder Hash Request
435
+ use_grpc (Optional[bool]): Whether to use gRPC or REST API
435
436
 
436
437
  Returns:
437
438
  Optional[Dict]: Folder Hash Response, or None if the request was not succesfull
438
439
  """
439
- return self._call_rpc(
440
+ return self._call_api(
441
+ 'scanning.FolderHashScan',
440
442
  self.scanning_stub.FolderHashScan,
441
443
  request,
442
444
  HFHRequest,
443
445
  'Sending folder hash scan data (rqId: {rqId})...',
446
+ use_grpc=use_grpc,
444
447
  )
445
448
 
446
449
  def _call_api(
@@ -0,0 +1,41 @@
1
+ """
2
+ SPDX-License-Identifier: MIT
3
+
4
+ Copyright (c) 2025, 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
+ """
24
+
25
+ def get_lines(lines: str) -> list:
26
+ """
27
+ Parse line range string into a list of line numbers.
28
+
29
+ Converts SCANOSS line notation (e.g., '10-20,25-30') into a flat list
30
+ of individual line numbers for processing.
31
+
32
+ :param lines: Comma-separated line ranges in SCANOSS format (e.g., '10-20,25-30')
33
+ :return: Flat list of all line numbers extracted from the ranges
34
+ """
35
+ lines_list = []
36
+ lines = lines.split(',')
37
+ for line in lines:
38
+ line_parts = line.split('-')
39
+ for part in line_parts:
40
+ lines_list.append(int(part))
41
+ return lines_list
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scanoss
3
- Version: 1.38.0
3
+ Version: 1.40.0
4
4
  Summary: Simple Python library to leverage the SCANOSS APIs
5
5
  Home-page: https://scanoss.com
6
6
  Author: SCANOSS
@@ -6,8 +6,8 @@ protoc_gen_swagger/options/annotations_pb2_grpc.py,sha256=KZOW9Ciio-f9iL42FuLFnS
6
6
  protoc_gen_swagger/options/openapiv2_pb2.py,sha256=w0xDs63uyrWGgzRaQZXfJpfI7Jpyvh-i9ay_uzOR-aM,16475
7
7
  protoc_gen_swagger/options/openapiv2_pb2.pyi,sha256=hYOV6uQ2yqhP89042_V3GuAsvoBBiXf5CGuYmnFnfv4,54665
8
8
  protoc_gen_swagger/options/openapiv2_pb2_grpc.py,sha256=sje9Nh3yE7CHCUWZwtjTgwsKB4GvyGz5vOrGTnRXJfc,917
9
- scanoss/__init__.py,sha256=XYJ-FpfDnKK7tuc0ms8xzYcxUDkA9f2cQOSi2LvWfTA,1146
10
- scanoss/cli.py,sha256=1d6toykJ_rNY8XInFmzwXR2m6oB70GHO7kpb-uM-sm8,97834
9
+ scanoss/__init__.py,sha256=6IaHKZDhDx8hxXCPX8B5ueipZk0jEM6bGl8Vn_6-az8,1146
10
+ scanoss/cli.py,sha256=fw0iCF4CuIEwy8BIyBlgxFBlVESV30kYGy1uS74sP0E,103298
11
11
  scanoss/components.py,sha256=NFyt_w3aoMotr_ZaFU-ng00_89sruc0kgY7ERnJXkmM,15891
12
12
  scanoss/constants.py,sha256=GHLTaLNVxXdTXRj7ngRK4u4S653pHzM8qFy4JFLa0wQ,450
13
13
  scanoss/cryptography.py,sha256=lOoD_dW16ARQxYiYyb5R8S7gx0FqWIsnGkKfsB0nGaU,10627
@@ -16,13 +16,14 @@ scanoss/cyclonedx.py,sha256=mHeX66yQCk41N3YCIzKy_fI7fLqQnetYPFRIzUKy_M4,18416
16
16
  scanoss/delta.py,sha256=slmgnD7SsUOmfSE2zb0zdRAGo-JcjPJAtxyzuCSzO3I,9455
17
17
  scanoss/file_filters.py,sha256=QcLqunaBKQIafjNZ9_Snh9quBX5_-fsTusVmxwjC1q8,18511
18
18
  scanoss/filecount.py,sha256=RZjKQ6M5P_RQg0_PMD2tsRe5Z8f98ke0sxYVjPDN8iQ,6538
19
+ scanoss/gitlabqualityreport.py,sha256=JNDT63gxTOxLONe4dxUzn1o7eVniK0B3j6SiFTRLinw,6790
19
20
  scanoss/results.py,sha256=47ZXXuU2sDjYa5vhtbWTmikit9jHhA0rsYKwkvZFI5w,9252
20
21
  scanoss/scancodedeps.py,sha256=JbpoGW1POtPMmowzfwa4oh8sSBeeQCqaW9onvc4UFYM,11517
21
22
  scanoss/scanner.py,sha256=-RCxLX0EepUebK8jQKvlMxFEQrCc8SwEjxznoWjadkg,45510
22
23
  scanoss/scanoss_settings.py,sha256=W8uFQ6uRIqtE-DXXA56bO8I4GsbJ-aA1c84hQ_qBel4,12161
23
24
  scanoss/scanossapi.py,sha256=U3IytJXA0mQHYsylzjwCuFakuhD_dJhstY37NmyvtB8,13243
24
25
  scanoss/scanossbase.py,sha256=Dkpwxa8NH8XN1iRl03NM_Mkvby0JQ4qfvCiiUrJ5ul0,3163
25
- scanoss/scanossgrpc.py,sha256=6s5TH2i3XB4xaXylmxFu7chlVlYjCZE_DpvRkiiaoHk,41541
26
+ scanoss/scanossgrpc.py,sha256=9UuVPUjBLUhqim_tSntyoRZW-OAtiz5iP_VjjNr5RPY,41715
26
27
  scanoss/scanpostprocessor.py,sha256=-JsThlxrU70r92GHykTMERnicdd-6jmwNsE4PH0MN2o,11063
27
28
  scanoss/scantype.py,sha256=gFmyVmKQpHWogN2iCmMj032e_sZo4T92xS3_EH5B3Tc,1310
28
29
  scanoss/spdxlite.py,sha256=4JMxmyNmvcL6fjScihk8toWfSuQ-Pj1gzaT3SIn1fXA,29425
@@ -64,35 +65,40 @@ scanoss/api/vulnerabilities/__init__.py,sha256=IFrDk_DTJgKSZmmU-nuLXuq_s8sQZlrSC
64
65
  scanoss/api/vulnerabilities/v2/__init__.py,sha256=IFrDk_DTJgKSZmmU-nuLXuq_s8sQZlrSCHhIDMJT4r0,1122
65
66
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py,sha256=pmm0MSiXkdf8e4rCIIDRcsNRixR2vGvD1Xak4l-wdwI,16550
66
67
  scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py,sha256=BNxT5kUKQ-mgtOt5QYBM1Qrg5LNDqSpWKpfEZquIlsM,19127
67
- scanoss/data/build_date.txt,sha256=vIDp8v5oIkuI4Pxunu5cDrnq1xF9Ajjgdjwun5NfN74,40
68
+ scanoss/data/build_date.txt,sha256=EsAP44xbRYCL6Rg23-wKXjV_HwKJKnffQXg6uFnmiCY,40
68
69
  scanoss/data/scanoss-settings-schema.json,sha256=ClkRYAkjAN0Sk704G8BE_Ok006oQ6YnIGmX84CF8h9w,8798
69
70
  scanoss/data/spdx-exceptions.json,sha256=s7UTYxC7jqQXr11YBlIWYCNwN6lRDFTR33Y8rpN_dA4,17953
70
71
  scanoss/data/spdx-licenses.json,sha256=A6Z0q82gaTLtnopBfzeIVZjJFxkdRW1g2TuumQc-lII,228794
71
72
  scanoss/export/__init__.py,sha256=D4C0lWLuNp8k_BjQZEc07WZcUgAvriVwQWOk063b0ZU,1122
72
73
  scanoss/export/dependency_track.py,sha256=A_xQH6_r9xL_fth1Wr770GCTRFVyn7XcUPfVUsXp4-w,9271
73
74
  scanoss/inspection/__init__.py,sha256=D4C0lWLuNp8k_BjQZEc07WZcUgAvriVwQWOk063b0ZU,1122
74
- scanoss/inspection/policy_check.py,sha256=JOJko_QVB7_6I8VQiGFJmOmJheN5jlwtpGOS2kBMMCo,9756
75
- scanoss/inspection/dependency_track/project_violation.py,sha256=zmTxxUQe2xuq-mHq1audsvFF3co0BoHy-EuSpNErw7U,20593
76
- scanoss/inspection/raw/component_summary.py,sha256=J4DDGNg9WIxIaTeblk6u4tmtMf4veXDesuC4rmpHNkM,4090
77
- scanoss/inspection/raw/copyleft.py,sha256=xAKIYROUG-F9SbPs3iIDmTg8yqovh3NVZNni4-byd68,9324
78
- scanoss/inspection/raw/license_summary.py,sha256=m5JVcqnqViPLrwHI5-XCpIEQzUiKtnhFC3FWhfM0T00,5823
79
- scanoss/inspection/raw/raw_base.py,sha256=gQoInr8a82JxzGjtdBo61ffVJ8sYJ9HNcTNzze1JXKI,18346
80
- scanoss/inspection/raw/undeclared_component.py,sha256=uN-oVqQF8vWArTc2yDVoxudV0bbrkbZaZ-mdZn-Cntw,11361
75
+ scanoss/inspection/policy_check.py,sha256=DtDZKeNe_WltF42BoiMbns4v8m7XhHVziqIc3RWzDEA,8171
76
+ scanoss/inspection/dependency_track/project_violation.py,sha256=x9PVk9mh5BU9Qr9WiDiRvwTTZxPzYFjzd11miZP-lpM,20654
77
+ scanoss/inspection/raw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
+ scanoss/inspection/raw/component_summary.py,sha256=axuzDxMdWva4HAM_i9D-NpqzPZKRd2Jp3oKq9R1oE88,6407
79
+ scanoss/inspection/raw/copyleft.py,sha256=ZOJ6FOvg2kx2pYOOCVza301h9c3ZB_jGNp-Lp4TTFcY,9385
80
+ scanoss/inspection/raw/license_summary.py,sha256=kW0mHztuAbOXI7G1-7ajzq7A8qhgSqANi0W6n-jOF5Y,7786
81
+ scanoss/inspection/raw/match_summary.py,sha256=3Mhp-H7OmMxhvSxR_opfl-xHB4UfDfTM-io5HsEH4co,11386
82
+ scanoss/inspection/raw/raw_base.py,sha256=mzdBs2dAaZlmYW9U8PnkvnjWnWyXWMkHzyhZ9FCM5Hc,18166
83
+ scanoss/inspection/raw/undeclared_component.py,sha256=mnSJr7RjUs2YT46xiBNkwx3Jrulo_8QtuagWAFL5KLo,11422
84
+ scanoss/inspection/utils/file_utils.py,sha256=b-xTH6FSyPpl3EPZ9WzK0c4734yE9mAexT1_YLLqymE,1641
81
85
  scanoss/inspection/utils/license_utils.py,sha256=Zb6QLmVJb86lKCwZyBsmwakyAtY1SXa54kUyyKmWMqA,5093
86
+ scanoss/inspection/utils/markdown_utils.py,sha256=zkFs48TM-NR6nUHYOyQmHCwV82_fUsks5UB4BmyGifU,2446
82
87
  scanoss/scanners/__init__.py,sha256=D4C0lWLuNp8k_BjQZEc07WZcUgAvriVwQWOk063b0ZU,1122
83
88
  scanoss/scanners/container_scanner.py,sha256=fOrb64owrstX7LnTuxiIan059YgLeKXeBS6g2QaCyq0,16346
84
- scanoss/scanners/folder_hasher.py,sha256=tOlo8YXanC3sQ77oHvHcsWiu8BW2pCfTyWC07AmzHIQ,12845
89
+ scanoss/scanners/folder_hasher.py,sha256=PD1tghOrra3KtfsZJUbqKOmIBF-0Tg14FcBCKkqGUis,12873
85
90
  scanoss/scanners/scanner_config.py,sha256=egG7cw3S2akU-D9M1aLE5jLrfz_c8e7_DIotMnnpM84,2601
86
- scanoss/scanners/scanner_hfh.py,sha256=M2PB4wDTi4LD1DwuAVfWiqQkjOImSpNok7vgo5H_Spg,9190
91
+ scanoss/scanners/scanner_hfh.py,sha256=xrWxRB0SOq5FJbil3lXnBk6z_on7jxr2itPBj2kb0RA,9270
87
92
  scanoss/services/dependency_track_service.py,sha256=JIpqev4I-x_ZajMxD5W2Y3OAUvEJ_4nstzAPV90vfP8,5070
88
93
  scanoss/utils/__init__.py,sha256=0hjb5ktavp7utJzFhGMPImPaZiHWgilM2HwvTp5lXJE,1122
89
94
  scanoss/utils/abstract_presenter.py,sha256=teiDTxBj5jBMCk2T8i4l1BJPf_u4zBLWrtCTFHSSECM,3148
90
95
  scanoss/utils/crc64.py,sha256=TMrwQimSdE6imhFOUL7oAG6Kxu-8qMpGWMuMg8QpSVs,3169
91
96
  scanoss/utils/file.py,sha256=62cA9a17TU9ZvfA3FY5HY4-QOajJeSrc8S6xLA_f-3M,2980
97
+ scanoss/utils/scanoss_scan_results_utils.py,sha256=ho9-DKefHFJlVZkw4gXOmMI-mgPIbV9Y2ftkI83fC1k,1727
92
98
  scanoss/utils/simhash.py,sha256=6iu8DOcecPAY36SZjCOzrrLMT9oIE7-gI6QuYwUQ7B0,5793
93
- scanoss-1.38.0.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
94
- scanoss-1.38.0.dist-info/METADATA,sha256=nGYHuWaHvC-qnnBCwnLwVt3-jfPV1W3Riu0W_2QVraI,6181
95
- scanoss-1.38.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
96
- scanoss-1.38.0.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
97
- scanoss-1.38.0.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
98
- scanoss-1.38.0.dist-info/RECORD,,
99
+ scanoss-1.40.0.dist-info/licenses/LICENSE,sha256=LLUaXoiyOroIbr5ubAyrxBOwSRLTm35ETO2FmLpy8QQ,1074
100
+ scanoss-1.40.0.dist-info/METADATA,sha256=ZX_JjQXpdybrkeUWvaqxN8UhZyVs3-zlByU3UWkcRAU,6181
101
+ scanoss-1.40.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
102
+ scanoss-1.40.0.dist-info/entry_points.txt,sha256=Uy28xnaDL5KQ7V77sZD5VLDXPNxYYzSr5tsqtiXVzAs,48
103
+ scanoss-1.40.0.dist-info/top_level.txt,sha256=V11PrQ6Pnrc-nDF9xnisnJ8e6-i7HqSIKVNqduRWcL8,27
104
+ scanoss-1.40.0.dist-info/RECORD,,