scanoss 1.20.0__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 (67) 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/scanning/__init__.py +17 -17
  24. scanoss/api/scanning/v2/__init__.py +17 -17
  25. scanoss/api/scanning/v2/scanoss_scanning_pb2.py +10 -8
  26. scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +40 -32
  27. scanoss/api/semgrep/__init__.py +17 -17
  28. scanoss/api/semgrep/v2/__init__.py +17 -17
  29. scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +22 -18
  30. scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +71 -49
  31. scanoss/api/vulnerabilities/__init__.py +17 -17
  32. scanoss/api/vulnerabilities/v2/__init__.py +17 -17
  33. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +37 -27
  34. scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +109 -72
  35. scanoss/cli.py +576 -293
  36. scanoss/components.py +67 -45
  37. scanoss/csvoutput.py +83 -56
  38. scanoss/cyclonedx.py +48 -46
  39. scanoss/data/build_date.txt +1 -1
  40. scanoss/file_filters.py +13 -15
  41. scanoss/filecount.py +43 -36
  42. scanoss/inspection/__init__.py +17 -17
  43. scanoss/inspection/copyleft.py +71 -58
  44. scanoss/inspection/policy_check.py +76 -53
  45. scanoss/inspection/undeclared_component.py +98 -75
  46. scanoss/inspection/utils/license_utils.py +66 -44
  47. scanoss/results.py +51 -60
  48. scanoss/scancodedeps.py +61 -38
  49. scanoss/scanner.py +203 -135
  50. scanoss/scanoss_settings.py +5 -3
  51. scanoss/scanossapi.py +98 -69
  52. scanoss/scanossbase.py +19 -19
  53. scanoss/scanossgrpc.py +73 -51
  54. scanoss/scanpostprocessor.py +9 -6
  55. scanoss/scantype.py +22 -21
  56. scanoss/spdxlite.py +265 -171
  57. scanoss/threadeddependencies.py +91 -61
  58. scanoss/threadedscanning.py +37 -31
  59. scanoss/utils/file.py +4 -4
  60. scanoss/winnowing.py +111 -47
  61. {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/METADATA +1 -1
  62. scanoss-1.20.1.dist-info/RECORD +74 -0
  63. scanoss-1.20.0.dist-info/RECORD +0 -74
  64. {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/LICENSE +0 -0
  65. {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/WHEEL +0 -0
  66. {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/entry_points.txt +0 -0
  67. {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/top_level.txt +0 -0
scanoss/filecount.py CHANGED
@@ -1,26 +1,27 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2022, 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) 2022, 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 csv
25
26
  import os
26
27
  import pathlib
@@ -36,9 +37,15 @@ class FileCount(ScanossBase):
36
37
  SCANOSS File Type Count class
37
38
  Handle the scanning of files, snippets and dependencies
38
39
  """
39
- def __init__(self, scan_output: str = None, hidden_files_folders: bool = False,
40
- debug: bool = False, trace: bool = False, quiet: bool = False
41
- ):
40
+
41
+ def __init__(
42
+ self,
43
+ scan_output: str = None,
44
+ hidden_files_folders: bool = False,
45
+ debug: bool = False,
46
+ trace: bool = False,
47
+ quiet: bool = False,
48
+ ):
42
49
  """
43
50
  Initialise scanning class
44
51
  """
@@ -56,7 +63,7 @@ class FileCount(ScanossBase):
56
63
  file_list = []
57
64
  for f in files:
58
65
  ignore = False
59
- if f.startswith(".") and not self.hidden_files_folders: # Ignore all . files unless requested
66
+ if f.startswith('.') and not self.hidden_files_folders: # Ignore all . files unless requested
60
67
  ignore = True
61
68
  if not ignore:
62
69
  file_list.append(f)
@@ -71,7 +78,7 @@ class FileCount(ScanossBase):
71
78
  dir_list = []
72
79
  for d in dirs:
73
80
  ignore = False
74
- if d.startswith(".") and not self.hidden_files_folders: # Ignore all . folders unless requested
81
+ if d.startswith('.') and not self.hidden_files_folders: # Ignore all . folders unless requested
75
82
  ignore = True
76
83
  if not ignore:
77
84
  dir_list.append(d)
@@ -84,7 +91,7 @@ class FileCount(ScanossBase):
84
91
  if not outfile and self.scan_output:
85
92
  outfile = self.scan_output
86
93
  if outfile:
87
- with open(outfile, "a") as rf:
94
+ with open(outfile, 'a') as rf:
88
95
  rf.write(string + '\n')
89
96
  else:
90
97
  print(string)
@@ -98,9 +105,9 @@ class FileCount(ScanossBase):
98
105
  """
99
106
  success = True
100
107
  if not scan_dir:
101
- raise Exception(f"ERROR: Please specify a folder to scan")
108
+ raise Exception(f'ERROR: Please specify a folder to scan')
102
109
  if not os.path.exists(scan_dir) or not os.path.isdir(scan_dir):
103
- raise Exception(f"ERROR: Specified folder does not exist or is not a folder: {scan_dir}")
110
+ raise Exception(f'ERROR: Specified folder does not exist or is not a folder: {scan_dir}')
104
111
 
105
112
  self.print_msg(f'Searching {scan_dir} for files to count...')
106
113
  spinner = None
@@ -111,17 +118,17 @@ class FileCount(ScanossBase):
111
118
  file_size = 0
112
119
  for root, dirs, files in os.walk(scan_dir):
113
120
  self.print_trace(f'U Root: {root}, Dirs: {dirs}, Files {files}')
114
- dirs[:] = self.__filter_dirs(dirs) # Strip out unwanted directories
115
- filtered_files = self.__filter_files(files) # Strip out unwanted files
121
+ dirs[:] = self.__filter_dirs(dirs) # Strip out unwanted directories
122
+ filtered_files = self.__filter_files(files) # Strip out unwanted files
116
123
  self.print_trace(f'F Root: {root}, Dirs: {dirs}, Files {filtered_files}')
117
- for file in filtered_files: # Cycle through each filtered file
124
+ for file in filtered_files: # Cycle through each filtered file
118
125
  path = os.path.join(root, file)
119
126
  f_size = 0
120
127
  try:
121
128
  f_size = os.stat(path).st_size
122
129
  except Exception as e:
123
130
  self.print_trace(f'Ignoring missing symlink file: {file} ({e})') # broken symlink
124
- if f_size > 0: # Ignore broken links and empty files
131
+ if f_size > 0: # Ignore broken links and empty files
125
132
  file_count = file_count + 1
126
133
  file_size = file_size + f_size
127
134
  f_suffix = pathlib.Path(file).suffix
@@ -140,18 +147,18 @@ class FileCount(ScanossBase):
140
147
  # End for loop
141
148
  if spinner:
142
149
  spinner.finish()
143
- self.print_stderr(f'Found {file_count:,.0f} files with a total size of {file_size/(1<<20):,.2f} MB.')
150
+ self.print_stderr(f'Found {file_count:,.0f} files with a total size of {file_size / (1 << 20):,.2f} MB.')
144
151
  if file_types:
145
152
  csv_dict = []
146
153
  for k in file_types:
147
154
  d = file_types[k]
148
- csv_dict.append({'extension': k, 'count': d[0], 'size(MB)': f'{d[1]/(1<<20):,.2f}'})
155
+ csv_dict.append({'extension': k, 'count': d[0], 'size(MB)': f'{d[1] / (1 << 20):,.2f}'})
149
156
  fields = ['extension', 'count', 'size(MB)']
150
157
  file = sys.stdout
151
158
  if self.scan_output:
152
159
  file = open(self.scan_output, 'w')
153
160
  writer = csv.DictWriter(file, fieldnames=fields)
154
- writer.writeheader() # writing headers (field names)
161
+ writer.writeheader() # writing headers (field names)
155
162
  writer.writerows(csv_dict) # writing data rows
156
163
  if self.scan_output:
157
164
  file.close()
@@ -1,23 +1,23 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
2
+ SPDX-License-Identifier: MIT
3
3
 
4
- Copyright (c) 2024, SCANOSS
4
+ Copyright (c) 2024, SCANOSS
5
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:
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
12
 
13
- The above copyright notice and this permission notice shall be included in
14
- all copies or substantial portions of the Software.
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
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.
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
  """
@@ -1,52 +1,64 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2024, 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) 2024, 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 json
25
26
  from typing import Dict, Any
26
27
  from .policy_check import PolicyCheck, PolicyStatus
27
28
 
29
+
28
30
  class Copyleft(PolicyCheck):
29
31
  """
30
32
  SCANOSS Copyleft class
31
33
  Inspects components for copyleft licenses
32
34
  """
33
35
 
34
- def __init__(self, debug: bool = False, trace: bool = True, quiet: bool = False, filepath: str = None,
35
- format_type: str = 'json', status: str = None, output: str = None, include: str = None,
36
- exclude: str = None, explicit: str = None):
36
+ def __init__(
37
+ self,
38
+ debug: bool = False,
39
+ trace: bool = True,
40
+ quiet: bool = False,
41
+ filepath: str = None,
42
+ format_type: str = 'json',
43
+ status: str = None,
44
+ output: str = None,
45
+ include: str = None,
46
+ exclude: str = None,
47
+ explicit: str = None,
48
+ ):
37
49
  """
38
- Initialize the Copyleft class.
39
-
40
- :param debug: Enable debug mode
41
- :param trace: Enable trace mode (default True)
42
- :param quiet: Enable quiet mode
43
- :param filepath: Path to the file containing component data
44
- :param format_type: Output format ('json' or 'md')
45
- :param status: Path to save the status output
46
- :param output: Path to save detailed output
47
- :param include: Licenses to include in the analysis
48
- :param exclude: Licenses to exclude from the analysis
49
- :param explicit: Explicitly defined licenses
50
+ Initialize the Copyleft class.
51
+
52
+ :param debug: Enable debug mode
53
+ :param trace: Enable trace mode (default True)
54
+ :param quiet: Enable quiet mode
55
+ :param filepath: Path to the file containing component data
56
+ :param format_type: Output format ('json' or 'md')
57
+ :param status: Path to save the status output
58
+ :param output: Path to save detailed output
59
+ :param include: Licenses to include in the analysis
60
+ :param exclude: Licenses to exclude from the analysis
61
+ :param explicit: Explicitly defined licenses
50
62
  """
51
63
  super().__init__(debug, trace, quiet, filepath, format_type, status, output, name='Copyleft Policy')
52
64
  self.license_util.init(include, exclude, explicit)
@@ -58,23 +70,22 @@ class Copyleft(PolicyCheck):
58
70
  self.exclude = exclude
59
71
  self.explicit = explicit
60
72
 
61
-
62
73
  def _json(self, components: list) -> Dict[str, Any]:
63
74
  """
64
- Format the components with copyleft licenses as JSON.
75
+ Format the components with copyleft licenses as JSON.
65
76
 
66
- :param components: List of components with copyleft licenses
67
- :return: Dictionary with formatted JSON details and summary
77
+ :param components: List of components with copyleft licenses
78
+ :return: Dictionary with formatted JSON details and summary
68
79
  """
69
80
  details = {}
70
81
  if len(components) > 0:
71
- details = { 'components': components }
82
+ details = {'components': components}
72
83
  return {
73
- 'details': f'{json.dumps(details, indent=2)}\n',
74
- 'summary': f'{len(components)} component(s) with copyleft licenses were found.\n'
84
+ 'details': f'{json.dumps(details, indent=2)}\n',
85
+ 'summary': f'{len(components)} component(s) with copyleft licenses were found.\n',
75
86
  }
76
87
 
77
- def _markdown(self, components: list) -> Dict[str,Any]:
88
+ def _markdown(self, components: list) -> Dict[str, Any]:
78
89
  """
79
90
  Format the components with copyleft licenses as Markdown.
80
91
 
@@ -83,7 +94,7 @@ class Copyleft(PolicyCheck):
83
94
  """
84
95
  headers = ['Component', 'Version', 'License', 'URL', 'Copyleft']
85
96
  centered_columns = [1, 4]
86
- rows: [[]]= []
97
+ rows: [[]] = []
87
98
  for component in components:
88
99
  for lic in component['licenses']:
89
100
  row = [
@@ -91,17 +102,17 @@ class Copyleft(PolicyCheck):
91
102
  component['version'],
92
103
  lic['spdxid'],
93
104
  lic['url'],
94
- 'YES' if lic['copyleft'] else 'NO'
105
+ 'YES' if lic['copyleft'] else 'NO',
95
106
  ]
96
107
  rows.append(row)
97
108
  # End license loop
98
109
  # End component loop
99
- return {
100
- 'details': f'### Copyleft licenses\n{self.generate_table(headers,rows,centered_columns)}\n',
101
- 'summary' : f'{len(components)} component(s) with copyleft licenses were found.\n'
110
+ return {
111
+ 'details': f'### Copyleft licenses\n{self.generate_table(headers, rows, centered_columns)}\n',
112
+ 'summary': f'{len(components)} component(s) with copyleft licenses were found.\n',
102
113
  }
103
114
 
104
- def _jira_markdown(self, components: list) -> Dict[str,Any]:
115
+ def _jira_markdown(self, components: list) -> Dict[str, Any]:
105
116
  """
106
117
  Format the components with copyleft licenses as Markdown.
107
118
 
@@ -110,7 +121,7 @@ class Copyleft(PolicyCheck):
110
121
  """
111
122
  headers = ['Component', 'Version', 'License', 'URL', 'Copyleft']
112
123
  centered_columns = [1, 4]
113
- rows: [[]]= []
124
+ rows: [[]] = []
114
125
  for component in components:
115
126
  for lic in component['licenses']:
116
127
  row = [
@@ -118,22 +129,22 @@ class Copyleft(PolicyCheck):
118
129
  component['version'],
119
130
  lic['spdxid'],
120
131
  lic['url'],
121
- 'YES' if lic['copyleft'] else 'NO'
132
+ 'YES' if lic['copyleft'] else 'NO',
122
133
  ]
123
134
  rows.append(row)
124
135
  # End license loop
125
136
  # End component loop
126
- return {
127
- 'details': f'{self.generate_jira_table(headers,rows,centered_columns)}',
128
- 'summary' : f'{len(components)} component(s) with copyleft licenses were found.\n'
137
+ return {
138
+ 'details': f'{self.generate_jira_table(headers, rows, centered_columns)}',
139
+ 'summary': f'{len(components)} component(s) with copyleft licenses were found.\n',
129
140
  }
130
141
 
131
142
  def _filter_components_with_copyleft_licenses(self, components: list) -> list:
132
143
  """
133
- Filter the components list to include only those with copyleft licenses.
144
+ Filter the components list to include only those with copyleft licenses.
134
145
 
135
- :param components: List of all components
136
- :return: List of components with copyleft licenses
146
+ :param components: List of all components
147
+ :return: List of components with copyleft licenses
137
148
  """
138
149
  filtered_components = []
139
150
  for component in components:
@@ -179,6 +190,8 @@ class Copyleft(PolicyCheck):
179
190
  if len(copyleft_components) <= 0:
180
191
  return PolicyStatus.FAIL.value, results
181
192
  return PolicyStatus.SUCCESS.value, results
193
+
194
+
182
195
  #
183
196
  # End of Copyleft Class
184
197
  #
@@ -1,26 +1,27 @@
1
1
  """
2
- SPDX-License-Identifier: MIT
3
-
4
- Copyright (c) 2024, 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) 2024, 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 json
25
26
  import os.path
26
27
  from abc import abstractmethod
@@ -39,13 +40,17 @@ class PolicyStatus(Enum):
39
40
  FAIL (int): Indicates that the policy check failed (value: 1).
40
41
  ERROR (int): Indicates that an error occurred during the policy check (value: 2).
41
42
  """
43
+
42
44
  SUCCESS = 0
43
45
  FAIL = 1
44
46
  ERROR = 2
47
+
48
+
45
49
  #
46
50
  # End of PolicyStatus Class
47
51
  #
48
52
 
53
+
49
54
  class ComponentID(Enum):
50
55
  """
51
56
  Enumeration representing different types of software components.
@@ -55,13 +60,17 @@ class ComponentID(Enum):
55
60
  SNIPPET (str): Represents a code snippet component (value: "snippet").
56
61
  DEPENDENCY (str): Represents a dependency component (value: "dependency").
57
62
  """
58
- FILE = "file"
59
- SNIPPET = "snippet"
60
- DEPENDENCY = "dependency"
63
+
64
+ FILE = 'file'
65
+ SNIPPET = 'snippet'
66
+ DEPENDENCY = 'dependency'
67
+
68
+
61
69
  #
62
70
  # End of ComponentID Class
63
71
  #
64
72
 
73
+
65
74
  class PolicyCheck(ScanossBase):
66
75
  """
67
76
  A base class for implementing various software policy checks.
@@ -78,8 +87,17 @@ class PolicyCheck(ScanossBase):
78
87
 
79
88
  VALID_FORMATS = {'md', 'json', 'jira_md'}
80
89
 
81
- def __init__(self, debug: bool = False, trace: bool = True, quiet: bool = False, filepath: str = None,
82
- format_type: str = None, status: str = None, output: str = None, name: str = None):
90
+ def __init__(
91
+ self,
92
+ debug: bool = False,
93
+ trace: bool = True,
94
+ quiet: bool = False,
95
+ filepath: str = None,
96
+ format_type: str = None,
97
+ status: str = None,
98
+ output: str = None,
99
+ name: str = None,
100
+ ):
83
101
  super().__init__(debug, trace, quiet)
84
102
  self.license_util = LicenseUtil()
85
103
  self.filepath = filepath
@@ -110,14 +128,14 @@ class PolicyCheck(ScanossBase):
110
128
  @abstractmethod
111
129
  def _json(self, components: list) -> Dict[str, Any]:
112
130
  """
113
- Format the policy checks results as JSON.
114
- This method should be implemented by subclasses to create a Markdown representation
115
- of the policy check results.
116
-
117
- :param components: List of components to be formatted.
118
- :return: A dictionary containing two keys:
119
- - 'details': A JSON-formatted string with the full list of components
120
- - 'summary': A string summarizing the number of components found
131
+ Format the policy checks results as JSON.
132
+ This method should be implemented by subclasses to create a Markdown representation
133
+ of the policy check results.
134
+
135
+ :param components: List of components to be formatted.
136
+ :return: A dictionary containing two keys:
137
+ - 'details': A JSON-formatted string with the full list of components
138
+ - 'summary': A string summarizing the number of components found
121
139
  """
122
140
  pass
123
141
 
@@ -147,8 +165,9 @@ class PolicyCheck(ScanossBase):
147
165
  """
148
166
  pass
149
167
 
150
- def _append_component(self,components: Dict[str, Any], new_component: Dict[str, Any],
151
- id: str, status: str) -> Dict[str, Any]:
168
+ def _append_component(
169
+ self, components: Dict[str, Any], new_component: Dict[str, Any], id: str, status: str
170
+ ) -> Dict[str, Any]:
152
171
  """
153
172
  Append a new component to the component's dictionary.
154
173
 
@@ -169,12 +188,12 @@ class PolicyCheck(ScanossBase):
169
188
  else:
170
189
  purl = new_component['purl']
171
190
 
172
- component_key = f"{purl}@{new_component['version']}"
191
+ component_key = f'{purl}@{new_component["version"]}'
173
192
  components[component_key] = {
174
- 'purl': purl,
175
- 'version': new_component['version'],
176
- 'licenses': {},
177
- 'status': status,
193
+ 'purl': purl,
194
+ 'version': new_component['version'],
195
+ 'licenses': {},
196
+ 'status': status,
178
197
  }
179
198
 
180
199
  if not new_component.get('licenses'):
@@ -191,16 +210,16 @@ class PolicyCheck(ScanossBase):
191
210
  }
192
211
  return components
193
212
 
194
- def _get_components_from_results(self,results: Dict[str, Any]) -> list or None:
213
+ def _get_components_from_results(self, results: Dict[str, Any]) -> list or None:
195
214
  """
196
- Process the results dictionary to extract and format component information.
215
+ Process the results dictionary to extract and format component information.
197
216
 
198
- This function iterates through the results dictionary, identifying components from
199
- different sources (files, snippets, and dependencies). It consolidates this information
200
- into a list of unique components, each with its associated licenses and other details.
217
+ This function iterates through the results dictionary, identifying components from
218
+ different sources (files, snippets, and dependencies). It consolidates this information
219
+ into a list of unique components, each with its associated licenses and other details.
201
220
 
202
- :param results: A dictionary containing the raw results of a component scan
203
- :return: A list of dictionaries, each representing a unique component with its details
221
+ :param results: A dictionary containing the raw results of a component scan
222
+ :return: A list of dictionaries, each representing a unique component with its details
204
223
  """
205
224
  if results is None:
206
225
  self.print_stderr(f'ERROR: Results cannot be empty')
@@ -226,7 +245,7 @@ class PolicyCheck(ScanossBase):
226
245
  if not c.get('version'):
227
246
  self.print_stderr(f'WARNING: Result missing version. Skipping.')
228
247
  continue
229
- component_key = f"{c['purl'][0]}@{c['version']}"
248
+ component_key = f'{c["purl"][0]}@{c["version"]}'
230
249
  # Initialize or update the component entry
231
250
  if component_key not in components:
232
251
  components = self._append_component(components, c, component_id, status)
@@ -244,7 +263,7 @@ class PolicyCheck(ScanossBase):
244
263
  if not d.get('version'):
245
264
  self.print_stderr(f'WARNING: Result missing version. Skipping.')
246
265
  continue
247
- component_key = f"{d['purl']}@{d['version']}"
266
+ component_key = f'{d["purl"]}@{d["version"]}'
248
267
  if component_key not in components:
249
268
  components = self._append_component(components, d, component_id, status)
250
269
  # End of dependencies loop
@@ -271,11 +290,13 @@ class PolicyCheck(ScanossBase):
271
290
  if headers is None:
272
291
  self.print_stderr('ERROR: Header are no set')
273
292
  return None
293
+
274
294
  # Decide which separator to use
275
295
  def create_separator(index):
276
296
  if centered_columns is None:
277
297
  return '-'
278
298
  return ':-:' if index in centered_column_set else '-'
299
+
279
300
  # Build the row separator
280
301
  row_separator = col_sep + col_sep.join(create_separator(index) for index, _ in enumerate(headers)) + col_sep
281
302
  # build table rows
@@ -297,7 +318,7 @@ class PolicyCheck(ScanossBase):
297
318
 
298
319
  return table
299
320
 
300
- def _get_formatter(self)-> Callable[[List[dict]], Dict[str,Any]] or None:
321
+ def _get_formatter(self) -> Callable[[List[dict]], Dict[str, Any]] or None:
301
322
  """
302
323
  Get the appropriate formatter function based on the specified format.
303
324
 
@@ -348,11 +369,11 @@ class PolicyCheck(ScanossBase):
348
369
 
349
370
  Returns:
350
371
  Dict[str, Any]: The parsed JSON data
351
- """
372
+ """
352
373
  if not os.path.exists(self.filepath):
353
374
  self.print_stderr(f'ERROR: The file "{self.filepath}" does not exist.')
354
375
  return None
355
- with open(self.filepath, "r") as jsonfile:
376
+ with open(self.filepath, 'r') as jsonfile:
356
377
  try:
357
378
  return json.load(jsonfile)
358
379
  except Exception as e:
@@ -381,6 +402,8 @@ class PolicyCheck(ScanossBase):
381
402
  return None
382
403
  components = self._get_components_from_results(self.results)
383
404
  return components
405
+
406
+
384
407
  #
385
408
  # End of PolicyCheck Class
386
409
  #